From 43aeab68a69e443c528092b4424a498d813f96b7 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 26 Jan 2007 20:38:26 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33548 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMConstantIslandPass.cpp | 64 +++++++++++++++++++----- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index 26119059fed..ed88960ffb1 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -107,6 +107,7 @@ namespace { 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 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn, CPUser &U){ 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 @@ ARMConstantIslands::FixUpImmediateBranch(MachineFunction &Fn, ImmBranch &Br) { 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 @@ ARMConstantIslands::FixUpImmediateBranch(MachineFunction &Fn, ImmBranch &Br) { // 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 @@ ARMConstantIslands::FixUpImmediateBranch(MachineFunction &Fn, ImmBranch &Br) { 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();