Changes in directory llvm/lib/Target/ARM:
ARMConstantIslandPass.cpp updated: 1.9 -> 1.10 --- Log message: Conditional branch being fixed up is not the last MI in the BB, there is a unconditional branch following it. Simply invert the condition and swap destinations if the conditional branch can reach the destination of the unconditional branch: beq L1 b L2 => bne L2 b L1 --- Diffs of the changes: (+51 -13) ARMConstantIslandPass.cpp | 64 ++++++++++++++++++++++++++++++++++++---------- 1 files changed, 51 insertions(+), 13 deletions(-) Index: llvm/lib/Target/ARM/ARMConstantIslandPass.cpp diff -u llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.9 llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.10 --- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp:1.9 Fri Jan 26 08:34:51 2007 +++ llvm/lib/Target/ARM/ARMConstantIslandPass.cpp Fri Jan 26 14:38:26 2007 @@ -107,6 +107,7 @@ void SplitBlockBeforeInstr(MachineInstr *MI); void UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB); bool HandleConstantPoolUser(MachineFunction &Fn, CPUser &U); + bool BBIsInBranchRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned D); bool FixUpImmediateBranch(MachineFunction &Fn, ImmBranch &Br); unsigned GetInstSize(MachineInstr *MI) const; @@ -561,6 +562,29 @@ return true; } +/// BBIsInBranchRange - Returns true is the distance between specific MI and +/// specific BB can fit in MI's displacement field. +bool ARMConstantIslands::BBIsInBranchRange(MachineInstr *MI, + MachineBasicBlock *DestBB, + unsigned MaxDisp) { + unsigned BrOffset = GetOffsetOf(MI); + unsigned DestOffset = GetOffsetOf(DestBB); + + // Check to see if the destination BB is in range. + if (BrOffset < DestOffset) { + if (DestOffset - BrOffset < MaxDisp) + return true; + } else { + if (BrOffset - DestOffset <= MaxDisp) + return true; + } + return false; +} + +static inline unsigned getUncondBranchDisp(int Opc) { + return (Opc == ARM::tB) ? (1<<10)*2 : (1<<23)*4; +} + /// FixUpImmediateBranch - Fix up immediate branches whose destination is too /// far away to fit in its displacement field. If it is a conditional branch, /// then it is converted to an inverse conditional branch + an unconditional @@ -571,17 +595,8 @@ MachineInstr *MI = Br.MI; MachineBasicBlock *DestBB = MI->getOperand(0).getMachineBasicBlock(); - unsigned BrOffset = GetOffsetOf(MI); - unsigned DestOffset = GetOffsetOf(DestBB); - - // Check to see if the destination BB is in range. - if (BrOffset < DestOffset) { - if (DestOffset - BrOffset < Br.MaxDisp) - return false; - } else { - if (BrOffset - DestOffset <= Br.MaxDisp) - return false; - } + if (BBIsInBranchRange(MI, DestBB, Br.MaxDisp)) + return false; if (!Br.isCond) { // Unconditional branch. We have to insert a branch somewhere to perform @@ -604,7 +619,30 @@ // direct the updated conditional branch to the fall-through block. Otherwise, // split the MBB before the next instruction. MachineBasicBlock *MBB = MI->getParent(); - if (&MBB->back() != MI || !BBHasFallthrough(MBB)) { + MachineInstr *BackMI = &MBB->back(); + bool NeedSplit = (BackMI != MI) || !BBHasFallthrough(MBB); + + if (BackMI != MI) { + if (next(MachineBasicBlock::iterator(MI)) == MBB->back() && + BackMI->getOpcode() == Br.UncondBr) { + // Last MI in the BB is a unconditional branch. Can we simply invert the + // condition and swap destinations: + // beq L1 + // b L2 + // => + // bne L2 + // b L1 + MachineBasicBlock *NewDest = BackMI->getOperand(0).getMachineBasicBlock(); + if (BBIsInBranchRange(MI, NewDest, Br.MaxDisp)) { + BackMI->getOperand(0).setMachineBasicBlock(DestBB); + MI->getOperand(0).setMachineBasicBlock(NewDest); + MI->getOperand(1).setImm(CC); + return true; + } + } + } + + if (NeedSplit) { SplitBlockBeforeInstr(MI); // No need for the branch to the next block. We're adding a unconditional // branch to the destination. @@ -617,7 +655,7 @@ BuildMI(MBB, TII->get(MI->getOpcode())).addMBB(NextBB).addImm(CC); Br.MI = &MBB->back(); BuildMI(MBB, TII->get(Br.UncondBr)).addMBB(DestBB); - unsigned MaxDisp = (Br.UncondBr == ARM::tB) ? (1<<10)*2 : (1<<23)*4; + unsigned MaxDisp = getUncondBranchDisp(Br.UncondBr); ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr)); MI->eraseFromParent(); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits