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:
Dale Johannesen 2007-02-28 23:20:38 +00:00
parent ad78ef2154
commit b71aa2b6ca

View File

@ -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;