LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64BranchRelaxation.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 153 180 85.0 %
Date: 2016-08-29 01:09:06 Functions: 21 21 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AArch64BranchRelaxation.cpp - AArch64 branch relaxation -----------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "AArch64.h"
      11             : #include "AArch64InstrInfo.h"
      12             : #include "AArch64MachineFunctionInfo.h"
      13             : #include "AArch64Subtarget.h"
      14             : #include "llvm/ADT/SmallVector.h"
      15             : #include "llvm/ADT/Statistic.h"
      16             : #include "llvm/CodeGen/MachineFunctionPass.h"
      17             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      18             : #include "llvm/Support/CommandLine.h"
      19             : #include "llvm/Support/Debug.h"
      20             : #include "llvm/Support/ErrorHandling.h"
      21             : #include "llvm/Support/Format.h"
      22             : #include "llvm/Support/raw_ostream.h"
      23             : using namespace llvm;
      24             : 
      25             : #define DEBUG_TYPE "aarch64-branch-relax"
      26             : 
      27             : STATISTIC(NumSplit, "Number of basic blocks split");
      28             : STATISTIC(NumConditionalRelaxed, "Number of conditional branches relaxed");
      29             : 
      30             : namespace llvm {
      31             : void initializeAArch64BranchRelaxationPass(PassRegistry &);
      32             : }
      33             : 
      34             : #define AARCH64_BR_RELAX_NAME "AArch64 branch relaxation pass"
      35             : 
      36             : namespace {
      37        2445 : class AArch64BranchRelaxation : public MachineFunctionPass {
      38             :   /// BasicBlockInfo - Information about the offset and size of a single
      39             :   /// basic block.
      40             :   struct BasicBlockInfo {
      41             :     /// Offset - Distance from the beginning of the function to the beginning
      42             :     /// of this basic block.
      43             :     ///
      44             :     /// The offset is always aligned as required by the basic block.
      45             :     unsigned Offset;
      46             : 
      47             :     /// Size - Size of the basic block in bytes.  If the block contains
      48             :     /// inline assembly, this is a worst case estimate.
      49             :     ///
      50             :     /// The size does not include any alignment padding whether from the
      51             :     /// beginning of the block, or from an aligned jump table at the end.
      52             :     unsigned Size;
      53             : 
      54       11508 :     BasicBlockInfo() : Offset(0), Size(0) {}
      55             : 
      56             :     /// Compute the offset immediately following this block.  If LogAlign is
      57             :     /// specified, return the offset the successor block will get if it has
      58             :     /// this alignment.
      59             :     unsigned postOffset(unsigned LogAlign = 0) const {
      60        1778 :       unsigned PO = Offset + Size;
      61        1778 :       unsigned Align = 1 << LogAlign;
      62        1778 :       return (PO + Align - 1) / Align * Align;
      63             :     }
      64             :   };
      65             : 
      66             :   SmallVector<BasicBlockInfo, 16> BlockInfo;
      67             : 
      68             :   MachineFunction *MF;
      69             :   const AArch64InstrInfo *TII;
      70             : 
      71             :   bool relaxBranchInstructions();
      72             :   void scanFunction();
      73             :   MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI);
      74             :   void adjustBlockOffsets(MachineBasicBlock &MBB);
      75             :   bool isBlockInRange(const MachineInstr &MI, const MachineBasicBlock &BB) const;
      76             : 
      77             :   unsigned insertInvertedConditionalBranch(MachineBasicBlock &SrcBB,
      78             :                                            MachineBasicBlock::iterator InsPt,
      79             :                                            const DebugLoc &DL,
      80             :                                            const MachineInstr &OldBr,
      81             :                                            MachineBasicBlock &NewDestBB) const;
      82             :   unsigned insertUnconditionalBranch(MachineBasicBlock &MBB,
      83             :                                      MachineBasicBlock &NewDestBB,
      84             :                                      const DebugLoc &DL) const;
      85             : 
      86             :   bool fixupConditionalBranch(MachineInstr &MI);
      87             :   void computeBlockSize(const MachineBasicBlock &MBB);
      88             :   unsigned getInstrOffset(const MachineInstr &MI) const;
      89             :   void dumpBBs();
      90             :   void verify();
      91             : 
      92             : public:
      93             :   static char ID;
      94        1644 :   AArch64BranchRelaxation() : MachineFunctionPass(ID) {
      95         822 :     initializeAArch64BranchRelaxationPass(*PassRegistry::getPassRegistry());
      96         822 :   }
      97             : 
      98             :   bool runOnMachineFunction(MachineFunction &MF) override;
      99             : 
     100         819 :   const char *getPassName() const override {
     101         819 :     return AARCH64_BR_RELAX_NAME;
     102             :   }
     103             : };
     104             : char AArch64BranchRelaxation::ID = 0;
     105             : }
     106             : 
     107      240270 : INITIALIZE_PASS(AArch64BranchRelaxation, "aarch64-branch-relax",
     108             :                 AARCH64_BR_RELAX_NAME, false, false)
     109             : 
     110             : /// verify - check BBOffsets, BBSizes, alignment of islands
     111             : void AArch64BranchRelaxation::verify() {
     112             : #ifndef NDEBUG
     113             :   unsigned PrevNum = MF->begin()->getNumber();
     114             :   for (MachineBasicBlock &MBB : *MF) {
     115             :     unsigned Align = MBB.getAlignment();
     116             :     unsigned Num = MBB.getNumber();
     117             :     assert(BlockInfo[Num].Offset % (1u << Align) == 0);
     118             :     assert(!Num || BlockInfo[PrevNum].postOffset() <= BlockInfo[Num].Offset);
     119             :     PrevNum = Num;
     120             :   }
     121             : #endif
     122             : }
     123             : 
     124             : /// print block size and offset information - debugging
     125             : void AArch64BranchRelaxation::dumpBBs() {
     126             :   for (auto &MBB : *MF) {
     127             :     const BasicBlockInfo &BBI = BlockInfo[MBB.getNumber()];
     128             :     dbgs() << format("BB#%u\toffset=%08x\t", MBB.getNumber(), BBI.Offset)
     129             :            << format("size=%#x\n", BBI.Size);
     130             :   }
     131             : }
     132             : 
     133             : // FIXME: This is a less precise version of MachineBasicBlock::canFallThrough?
     134             : 
     135             : /// \returns true if the specified basic block can fallthrough
     136             : /// into the block immediately after it.
     137           6 : static bool hasFallthrough(const MachineBasicBlock &MBB) {
     138             :   // Get the next machine basic block in the function.
     139           6 :   MachineFunction::const_iterator MBBI(MBB);
     140             : 
     141             :   // Can't fall off end of function.
     142           6 :   auto NextBB = std::next(MBBI);
     143          12 :   if (NextBB == MBB.getParent()->end())
     144             :     return false;
     145             : 
     146           6 :   return MBB.isSuccessor(&*NextBB);
     147             : }
     148             : 
     149             : /// scanFunction - Do the initial scan of the function, building up
     150             : /// information about each block.
     151        9771 : void AArch64BranchRelaxation::scanFunction() {
     152       19542 :   BlockInfo.clear();
     153       19542 :   BlockInfo.resize(MF->getNumBlockIDs());
     154             : 
     155             :   // First thing, compute the size of all basic blocks, and see if the function
     156             :   // has any inline assembly in it. If so, we have to be conservative about
     157             :   // alignment assumptions, as we don't know for sure the size of any
     158             :   // instructions in the inline assembly.
     159       40817 :   for (MachineBasicBlock &MBB : *MF)
     160       11504 :     computeBlockSize(MBB);
     161             : 
     162             :   // Compute block offsets and known bits.
     163       29313 :   adjustBlockOffsets(*MF->begin());
     164        9771 : }
     165             : 
     166             : /// computeBlockSize - Compute the size for MBB.
     167             : /// This function updates BlockInfo directly.
     168       11512 : void AArch64BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) {
     169       11512 :   unsigned Size = 0;
     170      158664 :   for (const MachineInstr &MI : MBB)
     171       56308 :     Size += TII->getInstSizeInBytes(MI);
     172       23024 :   BlockInfo[MBB.getNumber()].Size = Size;
     173       11512 : }
     174             : 
     175             : /// getInstrOffset - Return the current offset of the specified machine
     176             : /// instruction from the start of the function.  This offset changes as stuff is
     177             : /// moved around inside the function.
     178         891 : unsigned AArch64BranchRelaxation::getInstrOffset(const MachineInstr &MI) const {
     179         891 :   const MachineBasicBlock *MBB = MI.getParent();
     180             : 
     181             :   // The offset is composed of two things: the sum of the sizes of all MBB's
     182             :   // before this instruction's block, and the offset from the start of the block
     183             :   // it is in.
     184        1782 :   unsigned Offset = BlockInfo[MBB->getNumber()].Offset;
     185             : 
     186             :   // Sum instructions before MI in MBB.
     187        4690 :   for (MachineBasicBlock::const_iterator I = MBB->begin(); &*I != &MI; ++I) {
     188             :     assert(I != MBB->end() && "Didn't find MI in its own basic block?");
     189        2908 :     Offset += TII->getInstSizeInBytes(*I);
     190             :   }
     191             : 
     192         891 :   return Offset;
     193             : }
     194             : 
     195        9784 : void AArch64BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
     196        9784 :   unsigned PrevNum = Start.getNumber();
     197       50694 :   for (auto &MBB : make_range(MachineFunction::iterator(Start), MF->end())) {
     198       11558 :     unsigned Num = MBB.getNumber();
     199       11558 :     if (!Num) // block zero is never changed from offset zero.
     200             :       continue;
     201             :     // Get the offset and known bits at the end of the layout predecessor.
     202             :     // Include the alignment of the current block.
     203        1778 :     unsigned LogAlign = MBB.getAlignment();
     204        7112 :     BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(LogAlign);
     205        1778 :     PrevNum = Num;
     206             :   }
     207        9784 : }
     208             : 
     209             : /// Split the basic block containing MI into two blocks, which are joined by
     210             : /// an unconditional branch.  Update data structures and renumber blocks to
     211             : /// account for this change and returns the newly created block.
     212             : /// NOTE: Successor list of the original BB is out of date after this function,
     213             : /// and must be updated by the caller! Other transforms follow using this
     214             : /// utility function, so no point updating now rather than waiting.
     215             : MachineBasicBlock *
     216           4 : AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI) {
     217           4 :   MachineBasicBlock *OrigBB = MI.getParent();
     218             : 
     219             :   // Create a new MBB for the code after the OrigBB.
     220             :   MachineBasicBlock *NewBB =
     221           4 :       MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
     222          16 :   MF->insert(++OrigBB->getIterator(), NewBB);
     223             : 
     224             :   // Splice the instructions starting with MI over to NewBB.
     225          20 :   NewBB->splice(NewBB->end(), OrigBB, MI.getIterator(), OrigBB->end());
     226             : 
     227             :   // Add an unconditional branch from OrigBB to NewBB.
     228             :   // Note the new unconditional branch is not being recorded.
     229             :   // There doesn't seem to be meaningful DebugInfo available; this doesn't
     230             :   // correspond to anything in the source.
     231           8 :   insertUnconditionalBranch(*OrigBB, *NewBB, DebugLoc());
     232             : 
     233             :   // Insert an entry into BlockInfo to align it properly with the block numbers.
     234           8 :   BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
     235             : 
     236             :   // Figure out how large the OrigBB is.  As the first half of the original
     237             :   // block, it cannot contain a tablejump.  The size includes
     238             :   // the new jump we added.  (It should be possible to do this without
     239             :   // recounting everything, but it's very confusing, and this is rarely
     240             :   // executed.)
     241           4 :   computeBlockSize(*OrigBB);
     242             : 
     243             :   // Figure out how large the NewMBB is.  As the second half of the original
     244             :   // block, it may contain a tablejump.
     245           4 :   computeBlockSize(*NewBB);
     246             : 
     247             :   // All BBOffsets following these blocks must be modified.
     248           4 :   adjustBlockOffsets(*OrigBB);
     249             : 
     250           4 :   ++NumSplit;
     251             : 
     252           4 :   return NewBB;
     253             : }
     254             : 
     255             : /// isBlockInRange - Returns true if the distance between specific MI and
     256             : /// specific BB can fit in MI's displacement field.
     257         891 : bool AArch64BranchRelaxation::isBlockInRange(
     258             :   const MachineInstr &MI, const MachineBasicBlock &DestBB) const {
     259         891 :   unsigned BrOffset = getInstrOffset(MI);
     260        1782 :   unsigned DestOffset = BlockInfo[DestBB.getNumber()].Offset;
     261             : 
     262        1782 :   if (TII->isBranchInRange(MI.getOpcode(), BrOffset, DestOffset))
     263             :     return true;
     264             : 
     265             :   DEBUG(
     266             :     dbgs() << "Out of range branch to destination BB#" << DestBB.getNumber()
     267             :            << " from BB#" << MI.getParent()->getNumber()
     268             :            << " to " << DestOffset
     269             :            << " offset " << static_cast<int>(DestOffset - BrOffset)
     270             :            << '\t' << MI
     271             :   );
     272             : 
     273          10 :   return false;
     274             : }
     275             : 
     276         900 : static MachineBasicBlock *getDestBlock(const MachineInstr &MI) {
     277        1800 :   switch (MI.getOpcode()) {
     278             :   default:
     279           0 :     llvm_unreachable("unexpected opcode!");
     280             :   case AArch64::B:
     281           0 :     return MI.getOperand(0).getMBB();
     282             :   case AArch64::TBZW:
     283             :   case AArch64::TBNZW:
     284             :   case AArch64::TBZX:
     285             :   case AArch64::TBNZX:
     286         161 :     return MI.getOperand(2).getMBB();
     287             :   case AArch64::CBZW:
     288             :   case AArch64::CBNZW:
     289             :   case AArch64::CBZX:
     290             :   case AArch64::CBNZX:
     291             :   case AArch64::Bcc:
     292         739 :     return MI.getOperand(1).getMBB();
     293             :   }
     294             : }
     295             : 
     296           9 : static unsigned getOppositeConditionOpcode(unsigned Opc) {
     297           9 :   switch (Opc) {
     298             :   default:
     299           0 :     llvm_unreachable("unexpected opcode!");
     300             :   case AArch64::TBNZW:   return AArch64::TBZW;
     301           0 :   case AArch64::TBNZX:   return AArch64::TBZX;
     302           0 :   case AArch64::TBZW:    return AArch64::TBNZW;
     303           0 :   case AArch64::TBZX:    return AArch64::TBNZX;
     304           1 :   case AArch64::CBNZW:   return AArch64::CBZW;
     305           0 :   case AArch64::CBNZX:   return AArch64::CBZX;
     306           0 :   case AArch64::CBZW:    return AArch64::CBNZW;
     307           0 :   case AArch64::CBZX:    return AArch64::CBNZX;
     308           6 :   case AArch64::Bcc:     return AArch64::Bcc; // Condition is an operand for Bcc.
     309             :   }
     310             : }
     311             : 
     312             : static inline void invertBccCondition(MachineInstr &MI) {
     313             :   assert(MI.getOpcode() == AArch64::Bcc && "Unexpected opcode!");
     314           6 :   MachineOperand &CCOp = MI.getOperand(0);
     315             : 
     316           6 :   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(CCOp.getImm());
     317          12 :   CCOp.setImm(AArch64CC::getInvertedCondCode(CC));
     318             : }
     319             : 
     320             : /// Insert a conditional branch at the end of \p MBB to \p NewDestBB, using the
     321             : /// inverse condition of branch \p OldBr.
     322             : /// \returns The number of bytes added to the block.
     323           9 : unsigned AArch64BranchRelaxation::insertInvertedConditionalBranch(
     324             :   MachineBasicBlock &SrcMBB,
     325             :   MachineBasicBlock::iterator InsPt,
     326             :   const DebugLoc &DL,
     327             :   const MachineInstr &OldBr,
     328             :   MachineBasicBlock &NewDestBB) const {
     329          18 :   unsigned OppositeCondOpc = getOppositeConditionOpcode(OldBr.getOpcode());
     330             : 
     331             :   MachineInstrBuilder MIB =
     332          18 :     BuildMI(SrcMBB, InsPt, DL, TII->get(OppositeCondOpc))
     333          18 :     .addOperand(OldBr.getOperand(0));
     334             : 
     335          18 :   unsigned Opc = OldBr.getOpcode();
     336             : 
     337           9 :   if (Opc == AArch64::TBZW || Opc == AArch64::TBNZW ||
     338           7 :       Opc == AArch64::TBZX || Opc == AArch64::TBNZX)
     339           4 :     MIB.addOperand(OldBr.getOperand(1));
     340             : 
     341          18 :   if (OldBr.getOpcode() == AArch64::Bcc)
     342           6 :     invertBccCondition(*MIB);
     343             : 
     344           9 :   MIB.addMBB(&NewDestBB);
     345             : 
     346           9 :   return TII->getInstSizeInBytes(*MIB);
     347             : }
     348             : 
     349             : /// Insert an unconditional branch at the end of \p MBB to \p DestBB.
     350             : /// \returns the number of bytes emitted.
     351          13 : unsigned AArch64BranchRelaxation::insertUnconditionalBranch(
     352             :   MachineBasicBlock &MBB,
     353             :   MachineBasicBlock &DestBB,
     354             :   const DebugLoc &DL) const {
     355          39 :   MachineInstr *MI = BuildMI(&MBB, DL, TII->get(AArch64::B))
     356          13 :     .addMBB(&DestBB);
     357             : 
     358          13 :   return TII->getInstSizeInBytes(*MI);
     359             : }
     360             : 
     361             : static void changeBranchDestBlock(MachineInstr &MI,
     362             :                                   MachineBasicBlock &NewDestBB) {
     363           0 :   unsigned OpNum = 0;
     364           0 :   unsigned Opc = MI.getOpcode();
     365             : 
     366           0 :   if (Opc != AArch64::B) {
     367           0 :     OpNum = (Opc == AArch64::TBZW ||
     368           0 :              Opc == AArch64::TBNZW ||
     369           0 :              Opc == AArch64::TBZX ||
     370           0 :              Opc == AArch64::TBNZX) ? 2 : 1;
     371             :   }
     372             : 
     373           0 :   MI.getOperand(OpNum).setMBB(&NewDestBB);
     374             : }
     375             : 
     376             : /// fixupConditionalBranch - Fix up a conditional branch whose destination is
     377             : /// too far away to fit in its displacement field. It is converted to an inverse
     378             : /// conditional branch + an unconditional branch to the destination.
     379           9 : bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
     380           9 :   MachineBasicBlock *DestBB = getDestBlock(MI);
     381             : 
     382             :   // Add an unconditional branch to the destination and invert the branch
     383             :   // condition to jump over it:
     384             :   // tbz L1
     385             :   // =>
     386             :   // tbnz L2
     387             :   // b   L1
     388             :   // L2:
     389             : 
     390             :   // If the branch is at the end of its MBB and that has a fall-through block,
     391             :   // direct the updated conditional branch to the fall-through block. Otherwise,
     392             :   // split the MBB before the next instruction.
     393           9 :   MachineBasicBlock *MBB = MI.getParent();
     394           9 :   MachineInstr *BMI = &MBB->back();
     395           9 :   bool NeedSplit = (BMI != &MI) || !hasFallthrough(*MBB);
     396             : 
     397           9 :   if (BMI != &MI) {
     398          12 :     if (std::next(MachineBasicBlock::iterator(MI)) ==
     399          12 :             std::prev(MBB->getLastNonDebugInstr()) &&
     400           0 :         BMI->isUnconditionalBranch()) {
     401             :       // Last MI in the BB is an unconditional branch. We can simply invert the
     402             :       // condition and swap destinations:
     403             :       // beq L1
     404             :       // b   L2
     405             :       // =>
     406             :       // bne L2
     407             :       // b   L1
     408           0 :       MachineBasicBlock *NewDest = getDestBlock(*BMI);
     409           0 :       if (isBlockInRange(MI, *NewDest)) {
     410             :         DEBUG(dbgs() << "  Invert condition and swap its destination with "
     411             :                      << *BMI);
     412           0 :         changeBranchDestBlock(*BMI, *DestBB);
     413             : 
     414             :         int NewSize =
     415           0 :           insertInvertedConditionalBranch(*MBB, MI.getIterator(),
     416           0 :                                           MI.getDebugLoc(), MI, *NewDest);
     417           0 :         int OldSize = TII->getInstSizeInBytes(MI);
     418           0 :         BlockInfo[MBB->getNumber()].Size += (NewSize - OldSize);
     419           0 :         MI.eraseFromParent();
     420           0 :         return true;
     421             :       }
     422             :     }
     423             :   }
     424             : 
     425           9 :   if (NeedSplit) {
     426             :     // Analyze the branch so we know how to update the successor lists.
     427           3 :     MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
     428           6 :     SmallVector<MachineOperand, 2> Cond;
     429           3 :     bool Fail = TII->analyzeBranch(*MBB, TBB, FBB, Cond, false);
     430             :     assert(!Fail && "branches to relax should be analyzable");
     431             :     (void)Fail;
     432             : 
     433           3 :     MachineBasicBlock *NewBB = splitBlockBeforeInstr(MI);
     434             :     // No need for the branch to the next block. We're adding an unconditional
     435             :     // branch to the destination.
     436           3 :     int delta = TII->getInstSizeInBytes(MBB->back());
     437           6 :     BlockInfo[MBB->getNumber()].Size -= delta;
     438           3 :     MBB->back().eraseFromParent();
     439             :     // BlockInfo[SplitBB].Offset is wrong temporarily, fixed below
     440             : 
     441             :     // Update the successor lists according to the transformation to follow.
     442             :     // Do it here since if there's no split, no update is needed.
     443           3 :     MBB->replaceSuccessor(FBB, NewBB);
     444           3 :     NewBB->addSuccessor(FBB);
     445             :   }
     446             : 
     447          27 :   MachineBasicBlock &NextBB = *std::next(MachineFunction::iterator(MBB));
     448             : 
     449             :   DEBUG(dbgs() << "  Insert B to BB#" << DestBB->getNumber()
     450             :                << ", invert condition and change dest. to BB#"
     451             :                << NextBB.getNumber() << '\n');
     452             : 
     453          18 :   unsigned &MBBSize = BlockInfo[MBB->getNumber()].Size;
     454             : 
     455             :   // Insert a new conditional branch and a new unconditional branch.
     456          27 :   MBBSize += insertInvertedConditionalBranch(*MBB, MBB->end(),
     457           9 :                                              MI.getDebugLoc(), MI, NextBB);
     458             : 
     459           9 :   MBBSize += insertUnconditionalBranch(*MBB, *DestBB, MI.getDebugLoc());
     460             : 
     461             :   // Remove the old conditional branch.  It may or may not still be in MBB.
     462           9 :   MBBSize -= TII->getInstSizeInBytes(MI);
     463           9 :   MI.eraseFromParent();
     464             : 
     465             :   // Finally, keep the block offsets up to date.
     466           9 :   adjustBlockOffsets(*MBB);
     467           9 :   return true;
     468             : }
     469             : 
     470        9778 : bool AArch64BranchRelaxation::relaxBranchInstructions() {
     471        9778 :   bool Changed = false;
     472             :   // Relaxing branches involves creating new basic blocks, so re-eval
     473             :   // end() for termination.
     474       40872 :   for (MachineFunction::iterator I = MF->begin(); I != MF->end(); ++I) {
     475       11538 :     MachineBasicBlock &MBB = *I;
     476       11538 :     MachineBasicBlock::iterator J = MBB.getFirstTerminator();
     477       23076 :     if (J == MBB.end())
     478         523 :       continue;
     479             : 
     480       11015 :     MachineBasicBlock::iterator Next;
     481       44234 :     for (MachineBasicBlock::iterator J = MBB.getFirstTerminator();
     482       33219 :          J != MBB.end(); J = Next) {
     483       11102 :       Next = std::next(J);
     484       11102 :       MachineInstr &MI = *J;
     485             : 
     486       11102 :       if (MI.isConditionalBranch()) {
     487         891 :         MachineBasicBlock *DestBB = getDestBlock(MI);
     488         891 :         if (!isBlockInRange(MI, *DestBB)) {
     489          34 :           if (Next != MBB.end() && Next->isConditionalBranch()) {
     490             :             // If there are multiple conditional branches, this isn't an
     491             :             // analyzable block. Split later terminators into a new block so
     492             :             // each one will be analyzable.
     493             : 
     494           1 :             MachineBasicBlock *NewBB = splitBlockBeforeInstr(*Next);
     495           1 :             NewBB->transferSuccessors(&MBB);
     496           1 :             MBB.addSuccessor(NewBB);
     497           1 :             MBB.addSuccessor(DestBB);
     498             : 
     499             :             // Cleanup potential unconditional branch to successor block.
     500           1 :             NewBB->updateTerminator();
     501           1 :             MBB.updateTerminator();
     502             :           } else {
     503           9 :             fixupConditionalBranch(MI);
     504             :             ++NumConditionalRelaxed;
     505             :           }
     506             : 
     507          10 :           Changed = true;
     508             : 
     509             :           // This may have modified all of the terminators, so start over.
     510          10 :           Next = MBB.getFirstTerminator();
     511             :         }
     512             : 
     513             :       }
     514             :     }
     515             :   }
     516             : 
     517        9778 :   return Changed;
     518             : }
     519             : 
     520        9771 : bool AArch64BranchRelaxation::runOnMachineFunction(MachineFunction &mf) {
     521        9771 :   MF = &mf;
     522             : 
     523             :   DEBUG(dbgs() << "***** AArch64BranchRelaxation *****\n");
     524             : 
     525       19542 :   TII = MF->getSubtarget<AArch64Subtarget>().getInstrInfo();
     526             : 
     527             :   // Renumber all of the machine basic blocks in the function, guaranteeing that
     528             :   // the numbers agree with the position of the block in the function.
     529        9771 :   MF->RenumberBlocks();
     530             : 
     531             :   // Do the initial scan of the function, building up information about the
     532             :   // sizes of each block.
     533        9771 :   scanFunction();
     534             : 
     535             :   DEBUG(dbgs() << "  Basic blocks before relaxation\n"; dumpBBs(););
     536             : 
     537        9771 :   bool MadeChange = false;
     538        9778 :   while (relaxBranchInstructions())
     539             :     MadeChange = true;
     540             : 
     541             :   // After a while, this might be made debug-only, but it is not expensive.
     542        9771 :   verify();
     543             : 
     544             :   DEBUG(dbgs() << "  Basic blocks after relaxation\n\n"; dumpBBs());
     545             : 
     546       19542 :   BlockInfo.clear();
     547             : 
     548        9771 :   return MadeChange;
     549             : }
     550             : 
     551             : /// Returns an instance of the AArch64 Branch Relaxation pass.
     552         821 : FunctionPass *llvm::createAArch64BranchRelaxation() {
     553         821 :   return new AArch64BranchRelaxation();
     554             : }

Generated by: LCOV version 1.12