[llvm-commits] CVS: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
Dale Johannesen
dalej at apple.com
Wed Feb 28 15:20:55 PST 2007
Changes in directory llvm/lib/Target/ARM:
ARMConstantIslandPass.cpp updated: 1.31 -> 1.32
---
Log message:
Changes requested in review of last pass. Also pulled isThumb into a
member, instead of resetting in every function that uses it.
---
Diffs of the changes: (+142 -113)
ARMConstantIslandPass.cpp | 255 +++++++++++++++++++++++++---------------------
1 files changed, 142 insertions(+), 113 deletions(-)
Index: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
diff -u llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.31 llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.32
--- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.31 Wed Feb 28 12:41:22 2007
+++ llvm/lib/Target/ARM/ARMConstantIslandPass.cpp Wed Feb 28 17:20:38 2007
@@ -122,6 +122,7 @@
const TargetInstrInfo *TII;
const ARMFunctionInfo *AFI;
+ bool isThumb;
public:
virtual bool runOnMachineFunction(MachineFunction &Fn);
@@ -140,6 +141,10 @@
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 @@
TII = Fn.getTarget().getInstrInfo();
AFI = Fn.getInfo<ARMFunctionInfo>();
+ isThumb = AFI->isThumbFunction();
HasFarJump = false;
@@ -207,7 +213,7 @@
// 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 @@
// 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 @@
/// 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::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 @@
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 @@
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);
-
- // 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++;
+/// 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.
- // 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,97 +754,147 @@
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";
- MachineBasicBlock *UserMBB = UserMI->getParent();
- unsigned OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()] +
- BBSizes[UserMBB->getNumber()];
- assert(OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()+1]);
-
- // If the use is at the end of the block, or the end of the block
- // is within range, make new water there. (The +2 or 4 below is
- // for the unconditional branch we will be adding. If the block ends in
- // an unconditional branch already, it is water, and is known to
- // be out of range, so we'll always be adding one.)
- if (&UserMBB->back() == UserMI ||
- OffsetIsInRange(UserOffset, OffsetOfNextBlock + (isThumb ? 2 : 4),
- U.MaxDisp, !isThumb)) {
- DOUT << "Split at end of block\n";
- if (&UserMBB->back() == UserMI)
- assert(BBHasFallthrough(UserMBB) && "Expected a fallthrough BB!");
- 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);
- unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
- ImmBranches.push_back(ImmBranch(&UserMBB->back(),
- MaxDisp, false, UncondBr));
- int delta = isThumb ? 2 : 4;
- BBSizes[UserMBB->getNumber()] += delta;
- AdjustBBOffsetsAfter(UserMBB, delta);
- } else {
- // What a big block. Find a place within the block to split it.
- // This is a little tricky on Thumb since instructions are 2 bytes
- // and constant pool entries are 4 bytes: if instruction I references
- // island CPE, and instruction I+1 references CPE', it will
- // not work well to put CPE as far forward as possible, since then
- // CPE' cannot immediately follow it (that location is 2 bytes
- // farther away from I+1 than CPE was from I) and we'd need to create
- // a new island.
- // The 4 in the following is for the unconditional branch we'll be
- // inserting (allows for long branch on Thumb). The 2 or 0 is for
- // alignment of the island.
- 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.
- if (BaseInsertOffset >= BBOffsets[UserMBB->getNumber()+1])
- BaseInsertOffset = BBOffsets[UserMBB->getNumber()+1] - 6;
- unsigned EndInsertOffset = BaseInsertOffset +
- CPEMI->getOperand(2).getImm();
- MachineBasicBlock::iterator MI = UserMI; ++MI;
- unsigned CPUIndex = CPUserIndex+1;
- for (unsigned Offset = UserOffset+ARM::GetInstSize(UserMI);
- Offset < BaseInsertOffset;
- Offset += ARM::GetInstSize(MI),
- MI = next(MI)) {
- if (CPUIndex < CPUsers.size() && CPUsers[CPUIndex].MI == MI) {
- if (!OffsetIsInRange(Offset, EndInsertOffset,
- CPUsers[CPUIndex].MaxDisp, !isThumb)) {
- BaseInsertOffset -= (isThumb ? 2 : 4);
- EndInsertOffset -= (isThumb ? 2 : 4);
- }
- // This is overly conservative, as we don't account for CPEMIs
- // being reused within the block, but it doesn't matter much.
- EndInsertOffset += CPUsers[CPUIndex].CPEMI->getOperand(2).getImm();
- CPUIndex++;
+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()];
+ assert(OffsetOfNextBlock = BBOffsets[UserMBB->getNumber()+1]);
+
+ // If the use is at the end of the block, or the end of the block
+ // is within range, make new water there. (The +2 or 4 below is
+ // for the unconditional branch we will be adding. If the block ends in
+ // an unconditional branch already, it is water, and is known to
+ // be out of range, so we'll always be adding one.)
+ if (&UserMBB->back() == UserMI ||
+ OffsetIsInRange(UserOffset, OffsetOfNextBlock + (isThumb ? 2 : 4),
+ U.MaxDisp, !isThumb)) {
+ DOUT << "Split at end of block\n";
+ if (&UserMBB->back() == UserMI)
+ assert(BBHasFallthrough(UserMBB) && "Expected a fallthrough BB!");
+ *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);
+ unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);
+ ImmBranches.push_back(ImmBranch(&UserMBB->back(),
+ MaxDisp, false, UncondBr));
+ int delta = isThumb ? 2 : 4;
+ BBSizes[UserMBB->getNumber()] += delta;
+ AdjustBBOffsetsAfter(UserMBB, delta);
+ } else {
+ // What a big block. Find a place within the block to split it.
+ // This is a little tricky on Thumb since instructions are 2 bytes
+ // and constant pool entries are 4 bytes: if instruction I references
+ // island CPE, and instruction I+1 references CPE', it will
+ // not work well to put CPE as far forward as possible, since then
+ // CPE' cannot immediately follow it (that location is 2 bytes
+ // farther away from I+1 than CPE was from I) and we'd need to create
+ // a new island.
+ // The 4 in the following is for the unconditional branch we'll be
+ // inserting (allows for long branch on Thumb). The 2 or 0 is for
+ // alignment of the island.
+ 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 (allow for a
+ // conditional and a maximally long unconditional).
+ if (BaseInsertOffset >= BBOffsets[UserMBB->getNumber()+1])
+ BaseInsertOffset = BBOffsets[UserMBB->getNumber()+1] -
+ (isThumb ? 6 : 8);
+ unsigned EndInsertOffset = BaseInsertOffset +
+ CPEMI->getOperand(2).getImm();
+ MachineBasicBlock::iterator MI = UserMI;
+ ++MI;
+ unsigned CPUIndex = CPUserIndex+1;
+ for (unsigned Offset = UserOffset+ARM::GetInstSize(UserMI);
+ Offset < BaseInsertOffset;
+ Offset += ARM::GetInstSize(MI),
+ MI = next(MI)) {
+ if (CPUIndex < CPUsers.size() && CPUsers[CPUIndex].MI == MI) {
+ if (!OffsetIsInRange(Offset, EndInsertOffset,
+ CPUsers[CPUIndex].MaxDisp, !isThumb)) {
+ BaseInsertOffset -= (isThumb ? 2 : 4);
+ EndInsertOffset -= (isThumb ? 2 : 4);
}
+ // This is overly conservative, as we don't account for CPEMIs
+ // being reused within the block, but it doesn't matter much.
+ EndInsertOffset += CPUsers[CPUIndex].CPEMI->getOperand(2).getImm();
+ CPUIndex++;
}
- DOUT << "Split in middle of big block\n";
- NewMBB = SplitBlockBeforeInstr(prior(MI));
}
+ DOUT << "Split in middle of big block\n";
+ *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 @@
/// 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 @@
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;
More information about the llvm-commits
mailing list