mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 20:45:06 +00:00
Changes requested in review of last pass. Also pulled isThumb into a
member, instead of resetting in every function that uses it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34764 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ad78ef2154
commit
b71aa2b6ca
@ -122,6 +122,7 @@ namespace {
|
||||
|
||||
const TargetInstrInfo *TII;
|
||||
const ARMFunctionInfo *AFI;
|
||||
bool isThumb;
|
||||
public:
|
||||
virtual bool runOnMachineFunction(MachineFunction &Fn);
|
||||
|
||||
@ -140,6 +141,10 @@ namespace {
|
||||
void AdjustBBOffsetsAfter(MachineBasicBlock *BB, int delta);
|
||||
bool DecrementOldEntry(unsigned CPI, MachineInstr* CPEMI, unsigned Size);
|
||||
int LookForExistingCPEntry(CPUser& U, unsigned UserOffset);
|
||||
bool LookForWater(CPUser&U, unsigned UserOffset, bool* PadNewWater,
|
||||
MachineBasicBlock** NewMBB);
|
||||
void CreateNewWater(unsigned CPUserIndex, unsigned UserOffset,
|
||||
MachineBasicBlock** NewMBB);
|
||||
bool HandleConstantPoolUser(MachineFunction &Fn, unsigned CPUserIndex);
|
||||
bool CPEIsInRange(MachineInstr *MI, unsigned UserOffset,
|
||||
MachineInstr *CPEMI, unsigned Disp,
|
||||
@ -169,6 +174,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &Fn) {
|
||||
|
||||
TII = Fn.getTarget().getInstrInfo();
|
||||
AFI = Fn.getInfo<ARMFunctionInfo>();
|
||||
isThumb = AFI->isThumbFunction();
|
||||
|
||||
HasFarJump = false;
|
||||
|
||||
@ -207,7 +213,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &Fn) {
|
||||
|
||||
// If LR has been forced spilled and no far jumps (i.e. BL) has been issued.
|
||||
// Undo the spill / restore of LR if possible.
|
||||
if (!HasFarJump && AFI->isLRForceSpilled() && AFI->isThumbFunction())
|
||||
if (!HasFarJump && AFI->isLRForceSpilled() && isThumb)
|
||||
MadeChange |= UndoLRSpillRestore();
|
||||
|
||||
BBSizes.clear();
|
||||
@ -413,7 +419,7 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &Fn,
|
||||
// In thumb mode, if this block is a constpool island, pessimistically
|
||||
// assume it needs to be padded by two byte so it's aligned on 4 byte
|
||||
// boundary.
|
||||
if (AFI->isThumbFunction() &&
|
||||
if (isThumb &&
|
||||
!MBB.empty() &&
|
||||
MBB.begin()->getOpcode() == ARM::CONSTPOOL_ENTRY)
|
||||
MBBSize += 2;
|
||||
@ -478,7 +484,6 @@ void ARMConstantIslands::UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB) {
|
||||
/// account for this change and returns the newly created block.
|
||||
MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {
|
||||
MachineBasicBlock *OrigBB = MI->getParent();
|
||||
bool isThumb = AFI->isThumbFunction();
|
||||
|
||||
// Create a new MBB for the code after the OrigBB.
|
||||
MachineBasicBlock *NewBB = new MachineBasicBlock(OrigBB->getBasicBlock());
|
||||
@ -579,7 +584,6 @@ bool ARMConstantIslands::OffsetIsInRange(unsigned UserOffset,
|
||||
bool ARMConstantIslands::WaterIsInRange(unsigned UserOffset,
|
||||
MachineBasicBlock* Water, unsigned MaxDisp)
|
||||
{
|
||||
bool isThumb = AFI->isThumbFunction();
|
||||
unsigned CPEOffset = BBOffsets[Water->getNumber()] +
|
||||
BBSizes[Water->getNumber()];
|
||||
// If the Water is a constpool island, it has already been aligned.
|
||||
@ -599,7 +603,6 @@ bool ARMConstantIslands::CPEIsInRange(MachineInstr *MI, unsigned UserOffset,
|
||||
unsigned MaxDisp, bool DoDump) {
|
||||
// In thumb mode, pessimistically assumes the .align 2 before the first CPE
|
||||
// in the island adds two byte padding.
|
||||
bool isThumb = AFI->isThumbFunction();
|
||||
unsigned AlignAdj = isThumb ? 2 : 0;
|
||||
unsigned CPEOffset = GetOffsetOf(CPEMI) + AlignAdj;
|
||||
|
||||
@ -728,46 +731,22 @@ static inline unsigned getUnconditionalBrDisp(int Opc) {
|
||||
return (Opc == ARM::tB) ? ((1<<10)-1)*2 : ((1<<23)-1)*4;
|
||||
}
|
||||
|
||||
/// HandleConstantPoolUser - Analyze the specified user, checking to see if it
|
||||
/// is out-of-range. If so, pick it up the constant pool value and move it some
|
||||
/// place in-range. Return true if we changed any addresses (thus must run
|
||||
/// another pass of branch lengthening), false otherwise.
|
||||
bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn,
|
||||
unsigned CPUserIndex){
|
||||
CPUser &U = CPUsers[CPUserIndex];
|
||||
MachineInstr *UserMI = U.MI;
|
||||
MachineInstr *CPEMI = U.CPEMI;
|
||||
unsigned CPI = CPEMI->getOperand(1).getConstantPoolIndex();
|
||||
unsigned Size = CPEMI->getOperand(2).getImm();
|
||||
bool isThumb = AFI->isThumbFunction();
|
||||
MachineBasicBlock *NewMBB;
|
||||
// Compute this only once, it's expensive
|
||||
unsigned UserOffset = GetOffsetOf(UserMI) + (isThumb ? 4 : 8);
|
||||
/// LookForWater - look for an existing entry in the WaterList in which
|
||||
/// we can place the CPE referenced from U so it's within range of U's MI.
|
||||
/// Returns true if found, false if not. If it returns true, *NewMBB
|
||||
/// is set to the WaterList entry, and *PadNewWater is set to false if
|
||||
/// the WaterList entry is an island.
|
||||
|
||||
// See if the current entry is within range, or there is a clone of it
|
||||
// in range.
|
||||
int result = LookForExistingCPEntry(U, UserOffset);
|
||||
if (result==1) return false;
|
||||
else if (result==2) return true;
|
||||
|
||||
// No existing clone of this CPE is within range.
|
||||
// We will be generating a new clone. Get a UID for it.
|
||||
unsigned ID = NextUID++;
|
||||
|
||||
// Look for water where we can place this CPE. We look for the farthest one
|
||||
// away that will work. Forward references only for now (although later
|
||||
// we might find some that are backwards).
|
||||
bool WaterFound = false;
|
||||
bool PadNewWater = true;
|
||||
bool ARMConstantIslands::LookForWater(CPUser &U, unsigned UserOffset,
|
||||
bool *PadNewWater, MachineBasicBlock** NewMBB) {
|
||||
if (!WaterList.empty()) {
|
||||
for (std::vector<MachineBasicBlock*>::iterator IP = prior(WaterList.end()),
|
||||
B = WaterList.begin();; --IP) {
|
||||
MachineBasicBlock* WaterBB = *IP;
|
||||
if (WaterIsInRange(UserOffset, WaterBB, U.MaxDisp)) {
|
||||
WaterFound = true;
|
||||
DOUT << "found water in range\n";
|
||||
// CPE goes before following block (NewMBB).
|
||||
NewMBB = next(MachineFunction::iterator(WaterBB));
|
||||
*NewMBB = next(MachineFunction::iterator(WaterBB));
|
||||
// If WaterBB is an island, don't pad the new island.
|
||||
// If WaterBB is empty, go backwards until we find something that
|
||||
// isn't. WaterBB may become empty if it's an island whose
|
||||
@ -775,26 +754,37 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn,
|
||||
if (isThumb) {
|
||||
MachineBasicBlock* BB = WaterBB;
|
||||
while (BB->empty())
|
||||
BB = BB->Prev;
|
||||
BB = prior(MachineFunction::iterator(BB));
|
||||
if (BB->begin()->getOpcode() == ARM::CONSTPOOL_ENTRY)
|
||||
PadNewWater = false;
|
||||
*PadNewWater = false;
|
||||
}
|
||||
// Remove the original WaterList entry; we want subsequent
|
||||
// insertions in this vicinity to go after the one we're
|
||||
// about to insert. This considerably reduces the number
|
||||
// of times we have to move the same CPE more than once.
|
||||
WaterList.erase(IP);
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
if (IP == B)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WaterFound) {
|
||||
// No water found.
|
||||
/// CreateNewWater - No existing WaterList entry will work for
|
||||
/// CPUsers[CPUserIndex], so create a place to put the CPE. The end of the
|
||||
/// block is used if in range, and the conditional branch munged so control
|
||||
/// flow is correct. Otherwise the block is split to create a hole with an
|
||||
/// unconditional branch around it. In either case *NewMBB is set to a
|
||||
/// block following which the new island can be inserted (the WaterList
|
||||
/// is not adjusted).
|
||||
|
||||
DOUT << "No water found\n";
|
||||
void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex,
|
||||
unsigned UserOffset, MachineBasicBlock** NewMBB) {
|
||||
CPUser &U = CPUsers[CPUserIndex];
|
||||
MachineInstr *UserMI = U.MI;
|
||||
MachineInstr *CPEMI = U.CPEMI;
|
||||
MachineBasicBlock *UserMBB = UserMI->getParent();
|
||||
unsigned OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()] +
|
||||
BBSizes[UserMBB->getNumber()];
|
||||
@ -811,14 +801,14 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn,
|
||||
DOUT << "Split at end of block\n";
|
||||
if (&UserMBB->back() == UserMI)
|
||||
assert(BBHasFallthrough(UserMBB) && "Expected a fallthrough BB!");
|
||||
NewMBB = next(MachineFunction::iterator(UserMBB));
|
||||
*NewMBB = next(MachineFunction::iterator(UserMBB));
|
||||
// Add an unconditional branch from UserMBB to fallthrough block.
|
||||
// Record it for branch lengthening; this new branch will not get out of
|
||||
// range, but if the preceding conditional branch is out of range, the
|
||||
// targets will be exchanged, and the altered branch may be out of
|
||||
// range, so the machinery has to know about it.
|
||||
int UncondBr = isThumb ? ARM::tB : ARM::B;
|
||||
BuildMI(UserMBB, TII->get(UncondBr)).addMBB(NewMBB);
|
||||
BuildMI(UserMBB, TII->get(UncondBr)).addMBB(*NewMBB);
|
||||
unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
|
||||
ImmBranches.push_back(ImmBranch(&UserMBB->back(),
|
||||
MaxDisp, false, UncondBr));
|
||||
@ -840,12 +830,15 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn,
|
||||
unsigned BaseInsertOffset = UserOffset + U.MaxDisp -4 + (isThumb ? 2 : 0);
|
||||
// This could point off the end of the block if we've already got
|
||||
// constant pool entries following this block; only the last one is
|
||||
// in the water list. Back past any possible branches.
|
||||
// in the water list. Back past any possible branches (allow for a
|
||||
// conditional and a maximally long unconditional).
|
||||
if (BaseInsertOffset >= BBOffsets[UserMBB->getNumber()+1])
|
||||
BaseInsertOffset = BBOffsets[UserMBB->getNumber()+1] - 6;
|
||||
BaseInsertOffset = BBOffsets[UserMBB->getNumber()+1] -
|
||||
(isThumb ? 6 : 8);
|
||||
unsigned EndInsertOffset = BaseInsertOffset +
|
||||
CPEMI->getOperand(2).getImm();
|
||||
MachineBasicBlock::iterator MI = UserMI; ++MI;
|
||||
MachineBasicBlock::iterator MI = UserMI;
|
||||
++MI;
|
||||
unsigned CPUIndex = CPUserIndex+1;
|
||||
for (unsigned Offset = UserOffset+ARM::GetInstSize(UserMI);
|
||||
Offset < BaseInsertOffset;
|
||||
@ -864,8 +857,44 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn,
|
||||
}
|
||||
}
|
||||
DOUT << "Split in middle of big block\n";
|
||||
NewMBB = SplitBlockBeforeInstr(prior(MI));
|
||||
*NewMBB = SplitBlockBeforeInstr(prior(MI));
|
||||
}
|
||||
}
|
||||
|
||||
/// HandleConstantPoolUser - Analyze the specified user, checking to see if it
|
||||
/// is out-of-range. If so, pick it up the constant pool value and move it some
|
||||
/// place in-range. Return true if we changed any addresses (thus must run
|
||||
/// another pass of branch lengthening), false otherwise.
|
||||
bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn,
|
||||
unsigned CPUserIndex){
|
||||
CPUser &U = CPUsers[CPUserIndex];
|
||||
MachineInstr *UserMI = U.MI;
|
||||
MachineInstr *CPEMI = U.CPEMI;
|
||||
unsigned CPI = CPEMI->getOperand(1).getConstantPoolIndex();
|
||||
unsigned Size = CPEMI->getOperand(2).getImm();
|
||||
MachineBasicBlock *NewMBB;
|
||||
// Compute this only once, it's expensive
|
||||
unsigned UserOffset = GetOffsetOf(UserMI) + (isThumb ? 4 : 8);
|
||||
|
||||
// See if the current entry is within range, or there is a clone of it
|
||||
// in range.
|
||||
int result = LookForExistingCPEntry(U, UserOffset);
|
||||
if (result==1) return false;
|
||||
else if (result==2) return true;
|
||||
|
||||
// No existing clone of this CPE is within range.
|
||||
// We will be generating a new clone. Get a UID for it.
|
||||
unsigned ID = NextUID++;
|
||||
|
||||
// Look for water where we can place this CPE. We look for the farthest one
|
||||
// away that will work. Forward references only for now (although later
|
||||
// we might find some that are backwards).
|
||||
bool PadNewWater = true;
|
||||
|
||||
if (!LookForWater(U, UserOffset, &PadNewWater, &NewMBB)) {
|
||||
// No water found.
|
||||
DOUT << "No water found\n";
|
||||
CreateNewWater(CPUserIndex, UserOffset, &NewMBB);
|
||||
}
|
||||
|
||||
// Okay, we know we can put an island before NewMBB now, do it!
|
||||
@ -908,7 +937,7 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn,
|
||||
/// specific BB can fit in MI's displacement field.
|
||||
bool ARMConstantIslands::BBIsInRange(MachineInstr *MI,MachineBasicBlock *DestBB,
|
||||
unsigned MaxDisp) {
|
||||
unsigned PCAdj = AFI->isThumbFunction() ? 4 : 8;
|
||||
unsigned PCAdj = isThumb ? 4 : 8;
|
||||
unsigned BrOffset = GetOffsetOf(MI) + PCAdj;
|
||||
unsigned DestOffset = BBOffsets[DestBB->getNumber()];
|
||||
|
||||
@ -943,7 +972,7 @@ bool
|
||||
ARMConstantIslands::FixUpUnconditionalBr(MachineFunction &Fn, ImmBranch &Br) {
|
||||
MachineInstr *MI = Br.MI;
|
||||
MachineBasicBlock *MBB = MI->getParent();
|
||||
assert(AFI->isThumbFunction() && "Expected a Thumb function!");
|
||||
assert(isThumb && "Expected a Thumb function!");
|
||||
|
||||
// Use BL to implement far jump.
|
||||
Br.MaxDisp = (1 << 21) * 2;
|
||||
|
Loading…
Reference in New Issue
Block a user