LLVM API Documentation

AArch64BranchRelaxation.cpp
Go to the documentation of this file.
00001 //===-- AArch64BranchRelaxation.cpp - AArch64 branch relaxation -----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //===----------------------------------------------------------------------===//
00011 
00012 #include "AArch64.h"
00013 #include "AArch64InstrInfo.h"
00014 #include "AArch64MachineFunctionInfo.h"
00015 #include "AArch64Subtarget.h"
00016 #include "llvm/ADT/SmallVector.h"
00017 #include "llvm/ADT/Statistic.h"
00018 #include "llvm/CodeGen/MachineFunctionPass.h"
00019 #include "llvm/CodeGen/MachineInstrBuilder.h"
00020 #include "llvm/Support/CommandLine.h"
00021 #include "llvm/Support/Debug.h"
00022 #include "llvm/Support/ErrorHandling.h"
00023 #include "llvm/Support/Format.h"
00024 #include "llvm/Support/raw_ostream.h"
00025 using namespace llvm;
00026 
00027 #define DEBUG_TYPE "aarch64-branch-relax"
00028 
00029 static cl::opt<bool>
00030 BranchRelaxation("aarch64-branch-relax", cl::Hidden, cl::init(true),
00031                  cl::desc("Relax out of range conditional branches"));
00032 
00033 static cl::opt<unsigned>
00034 TBZDisplacementBits("aarch64-tbz-offset-bits", cl::Hidden, cl::init(14),
00035                     cl::desc("Restrict range of TB[N]Z instructions (DEBUG)"));
00036 
00037 static cl::opt<unsigned>
00038 CBZDisplacementBits("aarch64-cbz-offset-bits", cl::Hidden, cl::init(19),
00039                     cl::desc("Restrict range of CB[N]Z instructions (DEBUG)"));
00040 
00041 static cl::opt<unsigned>
00042 BCCDisplacementBits("aarch64-bcc-offset-bits", cl::Hidden, cl::init(19),
00043                     cl::desc("Restrict range of Bcc instructions (DEBUG)"));
00044 
00045 STATISTIC(NumSplit, "Number of basic blocks split");
00046 STATISTIC(NumRelaxed, "Number of conditional branches relaxed");
00047 
00048 namespace {
00049 class AArch64BranchRelaxation : public MachineFunctionPass {
00050   /// BasicBlockInfo - Information about the offset and size of a single
00051   /// basic block.
00052   struct BasicBlockInfo {
00053     /// Offset - Distance from the beginning of the function to the beginning
00054     /// of this basic block.
00055     ///
00056     /// The offset is always aligned as required by the basic block.
00057     unsigned Offset;
00058 
00059     /// Size - Size of the basic block in bytes.  If the block contains
00060     /// inline assembly, this is a worst case estimate.
00061     ///
00062     /// The size does not include any alignment padding whether from the
00063     /// beginning of the block, or from an aligned jump table at the end.
00064     unsigned Size;
00065 
00066     BasicBlockInfo() : Offset(0), Size(0) {}
00067 
00068     /// Compute the offset immediately following this block.  If LogAlign is
00069     /// specified, return the offset the successor block will get if it has
00070     /// this alignment.
00071     unsigned postOffset(unsigned LogAlign = 0) const {
00072       unsigned PO = Offset + Size;
00073       unsigned Align = 1 << LogAlign;
00074       return (PO + Align - 1) / Align * Align;
00075     }
00076   };
00077 
00078   SmallVector<BasicBlockInfo, 16> BlockInfo;
00079 
00080   MachineFunction *MF;
00081   const AArch64InstrInfo *TII;
00082 
00083   bool relaxBranchInstructions();
00084   void scanFunction();
00085   MachineBasicBlock *splitBlockBeforeInstr(MachineInstr *MI);
00086   void adjustBlockOffsets(MachineBasicBlock &MBB);
00087   bool isBlockInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
00088   bool fixupConditionalBranch(MachineInstr *MI);
00089   void computeBlockSize(const MachineBasicBlock &MBB);
00090   unsigned getInstrOffset(MachineInstr *MI) const;
00091   void dumpBBs();
00092   void verify();
00093 
00094 public:
00095   static char ID;
00096   AArch64BranchRelaxation() : MachineFunctionPass(ID) {}
00097 
00098   bool runOnMachineFunction(MachineFunction &MF) override;
00099 
00100   const char *getPassName() const override {
00101     return "AArch64 branch relaxation pass";
00102   }
00103 };
00104 char AArch64BranchRelaxation::ID = 0;
00105 }
00106 
00107 /// verify - check BBOffsets, BBSizes, alignment of islands
00108 void AArch64BranchRelaxation::verify() {
00109 #ifndef NDEBUG
00110   unsigned PrevNum = MF->begin()->getNumber();
00111   for (MachineBasicBlock &MBB : *MF) {
00112     unsigned Align = MBB.getAlignment();
00113     unsigned Num = MBB.getNumber();
00114     assert(BlockInfo[Num].Offset % (1u << Align) == 0);
00115     assert(!Num || BlockInfo[PrevNum].postOffset() <= BlockInfo[Num].Offset);
00116     PrevNum = Num;
00117   }
00118 #endif
00119 }
00120 
00121 /// print block size and offset information - debugging
00122 void AArch64BranchRelaxation::dumpBBs() {
00123   for (auto &MBB : *MF) {
00124     const BasicBlockInfo &BBI = BlockInfo[MBB.getNumber()];
00125     dbgs() << format("BB#%u\toffset=%08x\t", MBB.getNumber(), BBI.Offset)
00126            << format("size=%#x\n", BBI.Size);
00127   }
00128 }
00129 
00130 /// BBHasFallthrough - Return true if the specified basic block can fallthrough
00131 /// into the block immediately after it.
00132 static bool BBHasFallthrough(MachineBasicBlock *MBB) {
00133   // Get the next machine basic block in the function.
00134   MachineFunction::iterator MBBI = MBB;
00135   // Can't fall off end of function.
00136   MachineBasicBlock *NextBB = std::next(MBBI);
00137   if (NextBB == MBB->getParent()->end())
00138     return false;
00139 
00140   for (MachineBasicBlock *S : MBB->successors())
00141     if (S == NextBB)
00142       return true;
00143 
00144   return false;
00145 }
00146 
00147 /// scanFunction - Do the initial scan of the function, building up
00148 /// information about each block.
00149 void AArch64BranchRelaxation::scanFunction() {
00150   BlockInfo.clear();
00151   BlockInfo.resize(MF->getNumBlockIDs());
00152 
00153   // First thing, compute the size of all basic blocks, and see if the function
00154   // has any inline assembly in it. If so, we have to be conservative about
00155   // alignment assumptions, as we don't know for sure the size of any
00156   // instructions in the inline assembly.
00157   for (MachineBasicBlock &MBB : *MF)
00158     computeBlockSize(MBB);
00159 
00160   // Compute block offsets and known bits.
00161   adjustBlockOffsets(*MF->begin());
00162 }
00163 
00164 /// computeBlockSize - Compute the size for MBB.
00165 /// This function updates BlockInfo directly.
00166 void AArch64BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) {
00167   unsigned Size = 0;
00168   for (const MachineInstr &MI : MBB)
00169     Size += TII->GetInstSizeInBytes(&MI);
00170   BlockInfo[MBB.getNumber()].Size = Size;
00171 }
00172 
00173 /// getInstrOffset - Return the current offset of the specified machine
00174 /// instruction from the start of the function.  This offset changes as stuff is
00175 /// moved around inside the function.
00176 unsigned AArch64BranchRelaxation::getInstrOffset(MachineInstr *MI) const {
00177   MachineBasicBlock *MBB = MI->getParent();
00178 
00179   // The offset is composed of two things: the sum of the sizes of all MBB's
00180   // before this instruction's block, and the offset from the start of the block
00181   // it is in.
00182   unsigned Offset = BlockInfo[MBB->getNumber()].Offset;
00183 
00184   // Sum instructions before MI in MBB.
00185   for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {
00186     assert(I != MBB->end() && "Didn't find MI in its own basic block?");
00187     Offset += TII->GetInstSizeInBytes(I);
00188   }
00189   return Offset;
00190 }
00191 
00192 void AArch64BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
00193   unsigned PrevNum = Start.getNumber();
00194   for (auto &MBB : make_range(MachineFunction::iterator(Start), MF->end())) {
00195     unsigned Num = MBB.getNumber();
00196     if (!Num) // block zero is never changed from offset zero.
00197       continue;
00198     // Get the offset and known bits at the end of the layout predecessor.
00199     // Include the alignment of the current block.
00200     unsigned LogAlign = MBB.getAlignment();
00201     BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(LogAlign);
00202     PrevNum = Num;
00203   }
00204 }
00205 
00206 /// Split the basic block containing MI into two blocks, which are joined by
00207 /// an unconditional branch.  Update data structures and renumber blocks to
00208 /// account for this change and returns the newly created block.
00209 /// NOTE: Successor list of the original BB is out of date after this function,
00210 /// and must be updated by the caller! Other transforms follow using this
00211 /// utility function, so no point updating now rather than waiting.
00212 MachineBasicBlock *
00213 AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr *MI) {
00214   MachineBasicBlock *OrigBB = MI->getParent();
00215 
00216   // Create a new MBB for the code after the OrigBB.
00217   MachineBasicBlock *NewBB =
00218       MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
00219   MachineFunction::iterator MBBI = OrigBB;
00220   ++MBBI;
00221   MF->insert(MBBI, NewBB);
00222 
00223   // Splice the instructions starting with MI over to NewBB.
00224   NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());
00225 
00226   // Add an unconditional branch from OrigBB to NewBB.
00227   // Note the new unconditional branch is not being recorded.
00228   // There doesn't seem to be meaningful DebugInfo available; this doesn't
00229   // correspond to anything in the source.
00230   BuildMI(OrigBB, DebugLoc(), TII->get(AArch64::B)).addMBB(NewBB);
00231 
00232   // Insert an entry into BlockInfo to align it properly with the block numbers.
00233   BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
00234 
00235   // Figure out how large the OrigBB is.  As the first half of the original
00236   // block, it cannot contain a tablejump.  The size includes
00237   // the new jump we added.  (It should be possible to do this without
00238   // recounting everything, but it's very confusing, and this is rarely
00239   // executed.)
00240   computeBlockSize(*OrigBB);
00241 
00242   // Figure out how large the NewMBB is.  As the second half of the original
00243   // block, it may contain a tablejump.
00244   computeBlockSize(*NewBB);
00245 
00246   // All BBOffsets following these blocks must be modified.
00247   adjustBlockOffsets(*OrigBB);
00248 
00249   ++NumSplit;
00250 
00251   return NewBB;
00252 }
00253 
00254 /// isBlockInRange - Returns true if the distance between specific MI and
00255 /// specific BB can fit in MI's displacement field.
00256 bool AArch64BranchRelaxation::isBlockInRange(MachineInstr *MI,
00257                                              MachineBasicBlock *DestBB,
00258                                              unsigned Bits) {
00259   unsigned MaxOffs = ((1 << (Bits - 1)) - 1) << 2;
00260   unsigned BrOffset = getInstrOffset(MI);
00261   unsigned DestOffset = BlockInfo[DestBB->getNumber()].Offset;
00262 
00263   DEBUG(dbgs() << "Branch of destination BB#" << DestBB->getNumber()
00264                << " from BB#" << MI->getParent()->getNumber()
00265                << " max delta=" << MaxOffs << " from " << getInstrOffset(MI)
00266                << " to " << DestOffset << " offset "
00267                << int(DestOffset - BrOffset) << "\t" << *MI);
00268 
00269   // Branch before the Dest.
00270   if (BrOffset <= DestOffset)
00271     return (DestOffset - BrOffset <= MaxOffs);
00272   return (BrOffset - DestOffset <= MaxOffs);
00273 }
00274 
00275 static bool isConditionalBranch(unsigned Opc) {
00276   switch (Opc) {
00277   default:
00278     return false;
00279   case AArch64::TBZW:
00280   case AArch64::TBNZW:
00281   case AArch64::TBZX:
00282   case AArch64::TBNZX:
00283   case AArch64::CBZW:
00284   case AArch64::CBNZW:
00285   case AArch64::CBZX:
00286   case AArch64::CBNZX:
00287   case AArch64::Bcc:
00288     return true;
00289   }
00290 }
00291 
00292 static MachineBasicBlock *getDestBlock(MachineInstr *MI) {
00293   switch (MI->getOpcode()) {
00294   default:
00295     llvm_unreachable("unexpected opcode!");
00296   case AArch64::TBZW:
00297   case AArch64::TBNZW:
00298   case AArch64::TBZX:
00299   case AArch64::TBNZX:
00300     return MI->getOperand(2).getMBB();
00301   case AArch64::CBZW:
00302   case AArch64::CBNZW:
00303   case AArch64::CBZX:
00304   case AArch64::CBNZX:
00305   case AArch64::Bcc:
00306     return MI->getOperand(1).getMBB();
00307   }
00308 }
00309 
00310 static unsigned getOppositeConditionOpcode(unsigned Opc) {
00311   switch (Opc) {
00312   default:
00313     llvm_unreachable("unexpected opcode!");
00314   case AArch64::TBNZW:   return AArch64::TBZW;
00315   case AArch64::TBNZX:   return AArch64::TBZX;
00316   case AArch64::TBZW:    return AArch64::TBNZW;
00317   case AArch64::TBZX:    return AArch64::TBNZX;
00318   case AArch64::CBNZW:   return AArch64::CBZW;
00319   case AArch64::CBNZX:   return AArch64::CBZX;
00320   case AArch64::CBZW:    return AArch64::CBNZW;
00321   case AArch64::CBZX:    return AArch64::CBNZX;
00322   case AArch64::Bcc:     return AArch64::Bcc; // Condition is an operand for Bcc.
00323   }
00324 }
00325 
00326 static unsigned getBranchDisplacementBits(unsigned Opc) {
00327   switch (Opc) {
00328   default:
00329     llvm_unreachable("unexpected opcode!");
00330   case AArch64::TBNZW:
00331   case AArch64::TBZW:
00332   case AArch64::TBNZX:
00333   case AArch64::TBZX:
00334     return TBZDisplacementBits;
00335   case AArch64::CBNZW:
00336   case AArch64::CBZW:
00337   case AArch64::CBNZX:
00338   case AArch64::CBZX:
00339     return CBZDisplacementBits;
00340   case AArch64::Bcc:
00341     return BCCDisplacementBits;
00342   }
00343 }
00344 
00345 static inline void invertBccCondition(MachineInstr *MI) {
00346   assert(MI->getOpcode() == AArch64::Bcc && "Unexpected opcode!");
00347   AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(0).getImm();
00348   CC = AArch64CC::getInvertedCondCode(CC);
00349   MI->getOperand(0).setImm((int64_t)CC);
00350 }
00351 
00352 /// fixupConditionalBranch - Fix up a conditional branch whose destination is
00353 /// too far away to fit in its displacement field. It is converted to an inverse
00354 /// conditional branch + an unconditional branch to the destination.
00355 bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr *MI) {
00356   MachineBasicBlock *DestBB = getDestBlock(MI);
00357 
00358   // Add an unconditional branch to the destination and invert the branch
00359   // condition to jump over it:
00360   // tbz L1
00361   // =>
00362   // tbnz L2
00363   // b   L1
00364   // L2:
00365 
00366   // If the branch is at the end of its MBB and that has a fall-through block,
00367   // direct the updated conditional branch to the fall-through block. Otherwise,
00368   // split the MBB before the next instruction.
00369   MachineBasicBlock *MBB = MI->getParent();
00370   MachineInstr *BMI = &MBB->back();
00371   bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);
00372 
00373   if (BMI != MI) {
00374     if (std::next(MachineBasicBlock::iterator(MI)) ==
00375             std::prev(MBB->getLastNonDebugInstr()) &&
00376         BMI->getOpcode() == AArch64::B) {
00377       // Last MI in the BB is an unconditional branch. Can we simply invert the
00378       // condition and swap destinations:
00379       // beq L1
00380       // b   L2
00381       // =>
00382       // bne L2
00383       // b   L1
00384       MachineBasicBlock *NewDest = BMI->getOperand(0).getMBB();
00385       if (isBlockInRange(MI, NewDest,
00386                          getBranchDisplacementBits(MI->getOpcode()))) {
00387         DEBUG(dbgs() << "  Invert condition and swap its destination with "
00388                      << *BMI);
00389         BMI->getOperand(0).setMBB(DestBB);
00390         unsigned OpNum = (MI->getOpcode() == AArch64::TBZW ||
00391                           MI->getOpcode() == AArch64::TBNZW ||
00392                           MI->getOpcode() == AArch64::TBZX ||
00393                           MI->getOpcode() == AArch64::TBNZX)
00394                              ? 2
00395                              : 1;
00396         MI->getOperand(OpNum).setMBB(NewDest);
00397         MI->setDesc(TII->get(getOppositeConditionOpcode(MI->getOpcode())));
00398         if (MI->getOpcode() == AArch64::Bcc)
00399           invertBccCondition(MI);
00400         return true;
00401       }
00402     }
00403   }
00404 
00405   if (NeedSplit) {
00406     // Analyze the branch so we know how to update the successor lists.
00407     MachineBasicBlock *TBB, *FBB;
00408     SmallVector<MachineOperand, 2> Cond;
00409     TII->AnalyzeBranch(*MBB, TBB, FBB, Cond, false);
00410 
00411     MachineBasicBlock *NewBB = splitBlockBeforeInstr(MI);
00412     // No need for the branch to the next block. We're adding an unconditional
00413     // branch to the destination.
00414     int delta = TII->GetInstSizeInBytes(&MBB->back());
00415     BlockInfo[MBB->getNumber()].Size -= delta;
00416     MBB->back().eraseFromParent();
00417     // BlockInfo[SplitBB].Offset is wrong temporarily, fixed below
00418 
00419     // Update the successor lists according to the transformation to follow.
00420     // Do it here since if there's no split, no update is needed.
00421     MBB->replaceSuccessor(FBB, NewBB);
00422     NewBB->addSuccessor(FBB);
00423   }
00424   MachineBasicBlock *NextBB = std::next(MachineFunction::iterator(MBB));
00425 
00426   DEBUG(dbgs() << "  Insert B to BB#" << DestBB->getNumber()
00427                << ", invert condition and change dest. to BB#"
00428                << NextBB->getNumber() << "\n");
00429 
00430   // Insert a new conditional branch and a new unconditional branch.
00431   MachineInstrBuilder MIB = BuildMI(
00432       MBB, DebugLoc(), TII->get(getOppositeConditionOpcode(MI->getOpcode())))
00433                                 .addOperand(MI->getOperand(0));
00434   if (MI->getOpcode() == AArch64::TBZW || MI->getOpcode() == AArch64::TBNZW ||
00435       MI->getOpcode() == AArch64::TBZX || MI->getOpcode() == AArch64::TBNZX)
00436     MIB.addOperand(MI->getOperand(1));
00437   if (MI->getOpcode() == AArch64::Bcc)
00438     invertBccCondition(MIB);
00439   MIB.addMBB(NextBB);
00440   BlockInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
00441   BuildMI(MBB, DebugLoc(), TII->get(AArch64::B)).addMBB(DestBB);
00442   BlockInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
00443 
00444   // Remove the old conditional branch.  It may or may not still be in MBB.
00445   BlockInfo[MI->getParent()->getNumber()].Size -= TII->GetInstSizeInBytes(MI);
00446   MI->eraseFromParent();
00447 
00448   // Finally, keep the block offsets up to date.
00449   adjustBlockOffsets(*MBB);
00450   return true;
00451 }
00452 
00453 bool AArch64BranchRelaxation::relaxBranchInstructions() {
00454   bool Changed = false;
00455   // Relaxing branches involves creating new basic blocks, so re-eval
00456   // end() for termination.
00457   for (auto &MBB : *MF) {
00458     MachineInstr *MI = MBB.getFirstTerminator();
00459     if (isConditionalBranch(MI->getOpcode()) &&
00460         !isBlockInRange(MI, getDestBlock(MI),
00461                         getBranchDisplacementBits(MI->getOpcode()))) {
00462       fixupConditionalBranch(MI);
00463       ++NumRelaxed;
00464       Changed = true;
00465     }
00466   }
00467   return Changed;
00468 }
00469 
00470 bool AArch64BranchRelaxation::runOnMachineFunction(MachineFunction &mf) {
00471   MF = &mf;
00472 
00473   // If the pass is disabled, just bail early.
00474   if (!BranchRelaxation)
00475     return false;
00476 
00477   DEBUG(dbgs() << "***** AArch64BranchRelaxation *****\n");
00478 
00479   TII = (const AArch64InstrInfo *)MF->getTarget()
00480             .getSubtargetImpl()
00481             ->getInstrInfo();
00482 
00483   // Renumber all of the machine basic blocks in the function, guaranteeing that
00484   // the numbers agree with the position of the block in the function.
00485   MF->RenumberBlocks();
00486 
00487   // Do the initial scan of the function, building up information about the
00488   // sizes of each block.
00489   scanFunction();
00490 
00491   DEBUG(dbgs() << "  Basic blocks before relaxation\n");
00492   DEBUG(dumpBBs());
00493 
00494   bool MadeChange = false;
00495   while (relaxBranchInstructions())
00496     MadeChange = true;
00497 
00498   // After a while, this might be made debug-only, but it is not expensive.
00499   verify();
00500 
00501   DEBUG(dbgs() << "  Basic blocks after relaxation\n");
00502   DEBUG(dbgs() << '\n'; dumpBBs());
00503 
00504   BlockInfo.clear();
00505 
00506   return MadeChange;
00507 }
00508 
00509 /// createAArch64BranchRelaxation - returns an instance of the constpool
00510 /// island pass.
00511 FunctionPass *llvm::createAArch64BranchRelaxation() {
00512   return new AArch64BranchRelaxation();
00513 }