[llvm-branch-commits] [llvm-branch] r87005 - /llvm/branches/Apple/Leela/lib/Target/ARM/ARMConstantIslandPass.cpp
Jim Grosbach
grosbach at apple.com
Thu Nov 12 10:08:48 PST 2009
Author: grosbach
Date: Thu Nov 12 12:08:48 2009
New Revision: 87005
URL: http://llvm.org/viewvc/llvm-project?rev=87005&view=rev
Log:
merge 86999
Modified:
llvm/branches/Apple/Leela/lib/Target/ARM/ARMConstantIslandPass.cpp
Modified: llvm/branches/Apple/Leela/lib/Target/ARM/ARMConstantIslandPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=87005&r1=87004&r2=87005&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/Target/ARM/ARMConstantIslandPass.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Target/ARM/ARMConstantIslandPass.cpp Thu Nov 12 12:08:48 2009
@@ -44,6 +44,7 @@
STATISTIC(NumT2BrShrunk, "Number of Thumb2 immediate branches shrunk");
STATISTIC(NumCBZ, "Number of CBZ / CBNZ formed");
STATISTIC(NumJTMoved, "Number of jump table destination blocks moved");
+STATISTIC(NumJTInserted, "Number of jump table intermediate blocks inserted");
static cl::opt<bool>
@@ -181,6 +182,7 @@
void DoInitialPlacement(MachineFunction &MF,
std::vector<MachineInstr*> &CPEMIs);
CPEntry *findConstPoolEntry(unsigned CPI, const MachineInstr *CPEMI);
+ void JumpTableFunctionScan(MachineFunction &MF);
void InitialFunctionScan(MachineFunction &MF,
const std::vector<MachineInstr*> &CPEMIs);
MachineBasicBlock *SplitBlockBeforeInstr(MachineInstr *MI);
@@ -208,6 +210,7 @@
bool UndoLRSpillRestore();
bool OptimizeThumb2Instructions(MachineFunction &MF);
bool OptimizeThumb2Branches(MachineFunction &MF);
+ bool ReorderThumb2JumpTables(MachineFunction &MF);
bool OptimizeThumb2JumpTables(MachineFunction &MF);
MachineBasicBlock *AdjustJTTargetBlockForward(MachineBasicBlock *BB,
MachineBasicBlock *JTBB);
@@ -271,6 +274,20 @@
// the numbers agree with the position of the block in the function.
MF.RenumberBlocks();
+ // Try to reorder and otherwise adjust the block layout to make good use
+ // of the TB[BH] instructions.
+ bool MadeChange = false;
+ if (isThumb2 && AdjustJumpTableBlocks) {
+ JumpTableFunctionScan(MF);
+ MadeChange |= ReorderThumb2JumpTables(MF);
+ // Data is out of date, so clear it. It'll be re-computed later.
+ BBSizes.clear();
+ BBOffsets.clear();
+ T2JumpTables.clear();
+ // Blocks may have shifted around. Keep the numbering up to date.
+ MF.RenumberBlocks();
+ }
+
// Thumb1 functions containing constant pools get 4-byte alignment.
// This is so we can keep exact track of where the alignment padding goes.
@@ -301,7 +318,6 @@
// Iteratively place constant pool entries and fix up branches until there
// is no change.
- bool MadeChange = false;
unsigned NoCPIters = 0, NoBRIters = 0;
while (true) {
bool CPChange = false;
@@ -418,6 +434,39 @@
return NULL;
}
+/// JumpTableFunctionScan - Do a scan of the function, building up
+/// information about the sizes of each block and the locations of all
+/// the jump tables.
+void ARMConstantIslands::JumpTableFunctionScan(MachineFunction &MF) {
+ unsigned Offset = 0;
+ for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
+ MBBI != E; ++MBBI) {
+ MachineBasicBlock &MBB = *MBBI;
+
+ unsigned MBBSize = 0;
+ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
+ I != E; ++I) {
+ // Add instruction size to MBBSize.
+ MBBSize += TII->GetInstSizeInBytes(I);
+
+ int Opc = I->getOpcode();
+ if (I->getDesc().isBranch()) {
+ switch (Opc) {
+ default:
+ continue; // Ignore other JT branches
+ case ARM::t2BR_JT:
+ T2JumpTables.push_back(I);
+ continue; // Does not get an entry in ImmBranches
+ }
+ }
+ }
+
+ BBSizes.push_back(MBBSize);
+ BBOffsets.push_back(Offset);
+ Offset += MBBSize;
+ }
+}
+
/// InitialFunctionScan - Do the initial scan of the function, building up
/// information about the sizes of each block, the location of all the water,
/// and finding all of the constant pool users.
@@ -1561,7 +1610,6 @@
return MadeChange;
}
-
/// OptimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller
/// jumptables when it's possible.
bool ARMConstantIslands::OptimizeThumb2JumpTables(MachineFunction &MF) {
@@ -1580,33 +1628,10 @@
unsigned JTI = JTOP.getIndex();
assert(JTI < JT.size());
- // We prefer if target blocks for the jump table come after the jump
- // instruction so we can use TB[BH]. Loop through the target blocks
- // and try to adjust them such that that's true.
- unsigned JTOffset = GetOffsetOf(MI) + 4;
- const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
- if (AdjustJumpTableBlocks) {
- for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) {
- MachineBasicBlock *MBB = JTBBs[j];
- unsigned DstOffset = BBOffsets[MBB->getNumber()];
-
- if (DstOffset < JTOffset) {
- // The destination precedes the switch. Try to move the block forward
- // so we have a positive offset.
- MachineBasicBlock *NewBB =
- AdjustJTTargetBlockForward(MBB, MI->getParent());
- if (NewBB) {
- MJTI->ReplaceMBBInJumpTables(JTBBs[j], NewBB);
- JTOffset = GetOffsetOf(MI) + 4;
- DstOffset = BBOffsets[MBB->getNumber()];
- }
- }
- }
- }
-
bool ByteOk = true;
bool HalfWordOk = true;
- JTOffset = GetOffsetOf(MI) + 4;
+ unsigned JTOffset = GetOffsetOf(MI) + 4;
+ const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) {
MachineBasicBlock *MBB = JTBBs[j];
unsigned DstOffset = BBOffsets[MBB->getNumber()];
@@ -1693,16 +1718,73 @@
return MadeChange;
}
+/// ReorderThumb2JumpTables - Use tbb / tbh instructions to generate smaller
+/// jumptables when it's possible.
+bool ARMConstantIslands::ReorderThumb2JumpTables(MachineFunction &MF) {
+ bool MadeChange = false;
+
+ MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ for (unsigned i = 0, e = T2JumpTables.size(); i != e; ++i) {
+ MachineInstr *MI = T2JumpTables[i];
+ const TargetInstrDesc &TID = MI->getDesc();
+ unsigned NumOps = TID.getNumOperands();
+ unsigned JTOpIdx = NumOps - (TID.isPredicable() ? 3 : 2);
+ MachineOperand JTOP = MI->getOperand(JTOpIdx);
+ unsigned JTI = JTOP.getIndex();
+ assert(JTI < JT.size());
+
+ // We prefer if target blocks for the jump table come after the jump
+ // instruction so we can use TB[BH]. Loop through the target blocks
+ // and try to adjust them such that that's true.
+ unsigned JTOffset = GetOffsetOf(MI) + 4;
+ const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
+ for (unsigned j = 0, ee = JTBBs.size(); j != ee; ++j) {
+ MachineBasicBlock *MBB = JTBBs[j];
+ unsigned DstOffset = BBOffsets[MBB->getNumber()];
+
+ if (DstOffset < JTOffset) {
+ // The destination precedes the switch. Try to move the block forward
+ // so we have a positive offset.
+ MachineBasicBlock *NewBB =
+ AdjustJTTargetBlockForward(MBB, MI->getParent());
+ if (NewBB)
+ MJTI->ReplaceMBBInJumpTables(JTBBs[j], NewBB);
+ MadeChange = true;
+ }
+ }
+ }
+
+ return MadeChange;
+}
+
MachineBasicBlock *ARMConstantIslands::
AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB)
{
MachineFunction &MF = *BB->getParent();
- // FIXME: For now, instead of moving the block, we'll create a new block
- // immediate following the jump that's an unconditional branch to the
- // actual target. This is obviously not what we want for a real solution,
- // but it's useful for proof of concept, and it may be a useful fallback
- // later for cases where we otherwise can't move a block.
+ // FIXME: If it's a small block terminated by an unconditional branch,
+ // try to move it; otherwise, create a new block following the jump
+ // table that branches back to the actual target. This is an overly
+ // simplistic heuristic here for proof-of-concept.
+
+ int BBI = BB->getNumber();
+ int Size = BBSizes[BBI];
+ MachineBasicBlock *TBB = 0, *FBB = 0;
+ SmallVector<MachineOperand, 4> Cond;
+ // If the block terminator isn't analyzable, don't try to move the block
+ if (TII->AnalyzeBranch(*BB, TBB, FBB, Cond))
+ return NULL;
+
+ // If the block is small and ends in an unconditional branch, move it.
+ if (Size < 50 && Cond.empty()) {
+ MachineFunction::iterator OldPrior = prior(BB);
+ BB->moveAfter(JTBB);
+ OldPrior->updateTerminator();
+ //BB->updateTerminator();
+ ++NumJTMoved;
+ return NULL;
+ }
// Create a new MBB for the code after the jump BB.
MachineBasicBlock *NewBB =
@@ -1750,6 +1832,6 @@
// All BBOffsets following these blocks must be modified.
AdjustBBOffsetsAfter(NewBB, 4);
- ++NumJTMoved;
+ ++NumJTInserted;
return NewBB;
}
More information about the llvm-branch-commits
mailing list