llvm.org GIT mirror llvm / 43aeab6
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 Evan Cheng 13 years ago
1 changed file(s) with 51 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
106106 void SplitBlockBeforeInstr(MachineInstr *MI);
107107 void UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB);
108108 bool HandleConstantPoolUser(MachineFunction &Fn, CPUser &U);
109 bool BBIsInBranchRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned D);
109110 bool FixUpImmediateBranch(MachineFunction &Fn, ImmBranch &Br);
110111
111112 unsigned GetInstSize(MachineInstr *MI) const;
560561 return true;
561562 }
562563
564 /// BBIsInBranchRange - Returns true is the distance between specific MI and
565 /// specific BB can fit in MI's displacement field.
566 bool ARMConstantIslands::BBIsInBranchRange(MachineInstr *MI,
567 MachineBasicBlock *DestBB,
568 unsigned MaxDisp) {
569 unsigned BrOffset = GetOffsetOf(MI);
570 unsigned DestOffset = GetOffsetOf(DestBB);
571
572 // Check to see if the destination BB is in range.
573 if (BrOffset < DestOffset) {
574 if (DestOffset - BrOffset < MaxDisp)
575 return true;
576 } else {
577 if (BrOffset - DestOffset <= MaxDisp)
578 return true;
579 }
580 return false;
581 }
582
583 static inline unsigned getUncondBranchDisp(int Opc) {
584 return (Opc == ARM::tB) ? (1<<10)*2 : (1<<23)*4;
585 }
586
563587 /// FixUpImmediateBranch - Fix up immediate branches whose destination is too
564588 /// far away to fit in its displacement field. If it is a conditional branch,
565589 /// then it is converted to an inverse conditional branch + an unconditional
570594 MachineInstr *MI = Br.MI;
571595 MachineBasicBlock *DestBB = MI->getOperand(0).getMachineBasicBlock();
572596
573 unsigned BrOffset = GetOffsetOf(MI);
574 unsigned DestOffset = GetOffsetOf(DestBB);
575
576 // Check to see if the destination BB is in range.
577 if (BrOffset < DestOffset) {
578 if (DestOffset - BrOffset < Br.MaxDisp)
579 return false;
580 } else {
581 if (BrOffset - DestOffset <= Br.MaxDisp)
582 return false;
583 }
597 if (BBIsInBranchRange(MI, DestBB, Br.MaxDisp))
598 return false;
584599
585600 if (!Br.isCond) {
586601 // Unconditional branch. We have to insert a branch somewhere to perform
603618 // direct the updated conditional branch to the fall-through block. Otherwise,
604619 // split the MBB before the next instruction.
605620 MachineBasicBlock *MBB = MI->getParent();
606 if (&MBB->back() != MI || !BBHasFallthrough(MBB)) {
621 MachineInstr *BackMI = &MBB->back();
622 bool NeedSplit = (BackMI != MI) || !BBHasFallthrough(MBB);
623
624 if (BackMI != MI) {
625 if (next(MachineBasicBlock::iterator(MI)) == MBB->back() &&
626 BackMI->getOpcode() == Br.UncondBr) {
627 // Last MI in the BB is a unconditional branch. Can we simply invert the
628 // condition and swap destinations:
629 // beq L1
630 // b L2
631 // =>
632 // bne L2
633 // b L1
634 MachineBasicBlock *NewDest = BackMI->getOperand(0).getMachineBasicBlock();
635 if (BBIsInBranchRange(MI, NewDest, Br.MaxDisp)) {
636 BackMI->getOperand(0).setMachineBasicBlock(DestBB);
637 MI->getOperand(0).setMachineBasicBlock(NewDest);
638 MI->getOperand(1).setImm(CC);
639 return true;
640 }
641 }
642 }
643
644 if (NeedSplit) {
607645 SplitBlockBeforeInstr(MI);
608646 // No need for the branch to the next block. We're adding a unconditional
609647 // branch to the destination.
616654 BuildMI(MBB, TII->get(MI->getOpcode())).addMBB(NextBB).addImm(CC);
617655 Br.MI = &MBB->back();
618656 BuildMI(MBB, TII->get(Br.UncondBr)).addMBB(DestBB);
619 unsigned MaxDisp = (Br.UncondBr == ARM::tB) ? (1<<10)*2 : (1<<23)*4;
657 unsigned MaxDisp = getUncondBranchDisp(Br.UncondBr);
620658 ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr));
621659 MI->eraseFromParent();
622660