Skip to content

Commit

Permalink
Account for CPE alignment when searching for new water.
Browse files Browse the repository at this point in the history
Constant pool entries with different alignment may cause more alignment
padding to be inserted. Compute the amount of padding needed, and try to
pick the location that requires the least amount of padding.

Also take the extra padding into account when the water is above the
use.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146458 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
stoklund committed Dec 13, 2011
1 parent e97b499 commit 2e29024
Showing 1 changed file with 51 additions and 31 deletions.
82 changes: 51 additions & 31 deletions lib/Target/ARM/ARMConstantIslandPass.cpp
Expand Up @@ -293,7 +293,7 @@ namespace {
MachineInstr *CPEMI, unsigned Disp, bool NegOk,
bool DoDump = false);
bool WaterIsInRange(unsigned UserOffset, MachineBasicBlock *Water,
CPUser &U);
CPUser &U, unsigned &Growth);
bool BBIsInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
bool FixUpImmediateBr(ImmBranch &Br);
bool FixUpConditionalBr(ImmBranch &Br);
Expand Down Expand Up @@ -967,15 +967,42 @@ bool ARMConstantIslands::OffsetIsInRange(unsigned UserOffset,

/// WaterIsInRange - Returns true if a CPE placed after the specified
/// Water (a basic block) will be in range for the specific MI.

///
/// Compute how much the function will grow by inserting a CPE after Water.
bool ARMConstantIslands::WaterIsInRange(unsigned UserOffset,
MachineBasicBlock* Water, CPUser &U) {
unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset();

// If the CPE is to be inserted before the instruction, that will raise
// the offset of the instruction.
if (CPEOffset < UserOffset)
UserOffset += U.CPEMI->getOperand(2).getImm();
MachineBasicBlock* Water, CPUser &U,
unsigned &Growth) {
unsigned CPELogAlign = getCPELogAlign(U.CPEMI);
unsigned CPEOffset = BBInfo[Water->getNumber()].postOffset(CPELogAlign);
unsigned NextBlockOffset, NextBlockAlignment;
MachineFunction::const_iterator NextBlock = Water;
if (++NextBlock == MF->end()) {
NextBlockOffset = BBInfo[Water->getNumber()].postOffset();
NextBlockAlignment = 0;
} else {
NextBlockOffset = BBInfo[NextBlock->getNumber()].Offset;
NextBlockAlignment = NextBlock->getAlignment();
}
unsigned Size = U.CPEMI->getOperand(2).getImm();
unsigned CPEEnd = CPEOffset + Size;

// The CPE may be able to hide in the alignment padding before the next
// block. It may also cause more padding to be required if it is more aligned
// that the next block.
if (CPEEnd > NextBlockOffset) {
Growth = CPEEnd - NextBlockOffset;
// Compute the padding that would go at the end of the CPE to align the next
// block.
Growth += OffsetToAlignment(CPEEnd, 1u << NextBlockAlignment);

// If the CPE is to be inserted before the instruction, that will raise
// the offset of the instruction. Also account for unknown alignment padding
// in blocks between CPE and the user.
if (CPEOffset < UserOffset)
UserOffset += Growth + UnknownPadding(MF->getAlignment(), CPELogAlign);
} else
// CPE fits in existing padding.
Growth = 0;

return OffsetIsInRange(UserOffset, CPEOffset, U);
}
Expand Down Expand Up @@ -1130,10 +1157,9 @@ bool ARMConstantIslands::LookForWater(CPUser &U, unsigned UserOffset,
if (WaterList.empty())
return false;

bool FoundWaterThatWouldPad = false;
water_iterator IPThatWouldPad;
for (water_iterator IP = prior(WaterList.end()),
B = WaterList.begin();; --IP) {
unsigned BestGrowth = ~0u;
for (water_iterator IP = prior(WaterList.end()), B = WaterList.begin();;
--IP) {
MachineBasicBlock* WaterBB = *IP;
// Check if water is in range and is either at a lower address than the
// current "high water mark" or a new water block that was created since
Expand All @@ -1143,30 +1169,24 @@ bool ARMConstantIslands::LookForWater(CPUser &U, unsigned UserOffset,
// should be relatively uncommon and when it does happen, we want to be
// sure to take advantage of it for all the CPEs near that block, so that
// we don't insert more branches than necessary.
if (WaterIsInRange(UserOffset, WaterBB, U) &&
unsigned Growth;
if (WaterIsInRange(UserOffset, WaterBB, U, Growth) &&
(WaterBB->getNumber() < U.HighWaterMark->getNumber() ||
NewWaterList.count(WaterBB))) {
unsigned WBBId = WaterBB->getNumber();
if (isThumb && BBInfo[WBBId].postOffset()%4 != 0) {
// This is valid Water, but would introduce padding. Remember
// it in case we don't find any Water that doesn't do this.
if (!FoundWaterThatWouldPad) {
FoundWaterThatWouldPad = true;
IPThatWouldPad = IP;
}
} else {
WaterIter = IP;
NewWaterList.count(WaterBB)) && Growth < BestGrowth) {
// This is the least amount of required padding seen so far.
BestGrowth = Growth;
WaterIter = IP;
DEBUG(dbgs() << "Found water after BB#" << WaterBB->getNumber()
<< " Growth=" << Growth << '\n');

// Keep looking unless it is perfect.
if (BestGrowth == 0)
return true;
}
}
if (IP == B)
break;
}
if (FoundWaterThatWouldPad) {
WaterIter = IPThatWouldPad;
return true;
}
return false;
return BestGrowth != ~0u;
}

/// CreateNewWater - No existing WaterList entry will work for
Expand Down

0 comments on commit 2e29024

Please sign in to comment.