1 //===-- AArch64BranchRelaxation.cpp - AArch64 branch relaxation -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
13 #include "AArch64InstrInfo.h"
14 #include "AArch64MachineFunctionInfo.h"
15 #include "AArch64Subtarget.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/Format.h"
24 #include "llvm/Support/raw_ostream.h"
27 #define DEBUG_TYPE "aarch64-branch-relax"
30 BranchRelaxation("aarch64-branch-relax", cl::Hidden, cl::init(true),
31 cl::desc("Relax out of range conditional branches"));
33 static cl::opt<unsigned>
34 TBZDisplacementBits("aarch64-tbz-offset-bits", cl::Hidden, cl::init(14),
35 cl::desc("Restrict range of TB[N]Z instructions (DEBUG)"));
37 static cl::opt<unsigned>
38 CBZDisplacementBits("aarch64-cbz-offset-bits", cl::Hidden, cl::init(19),
39 cl::desc("Restrict range of CB[N]Z instructions (DEBUG)"));
41 static cl::opt<unsigned>
42 BCCDisplacementBits("aarch64-bcc-offset-bits", cl::Hidden, cl::init(19),
43 cl::desc("Restrict range of Bcc instructions (DEBUG)"));
45 STATISTIC(NumSplit, "Number of basic blocks split");
46 STATISTIC(NumRelaxed, "Number of conditional branches relaxed");
49 class AArch64BranchRelaxation : public MachineFunctionPass {
50 /// BasicBlockInfo - Information about the offset and size of a single
52 struct BasicBlockInfo {
53 /// Offset - Distance from the beginning of the function to the beginning
54 /// of this basic block.
56 /// The offset is always aligned as required by the basic block.
59 /// Size - Size of the basic block in bytes. If the block contains
60 /// inline assembly, this is a worst case estimate.
62 /// The size does not include any alignment padding whether from the
63 /// beginning of the block, or from an aligned jump table at the end.
66 BasicBlockInfo() : Offset(0), Size(0) {}
68 /// Compute the offset immediately following this block. If LogAlign is
69 /// specified, return the offset the successor block will get if it has
71 unsigned postOffset(unsigned LogAlign = 0) const {
72 unsigned PO = Offset + Size;
73 unsigned Align = 1 << LogAlign;
74 return (PO + Align - 1) / Align * Align;
78 SmallVector<BasicBlockInfo, 16> BlockInfo;
81 const AArch64InstrInfo *TII;
83 bool relaxBranchInstructions();
85 MachineBasicBlock *splitBlockBeforeInstr(MachineInstr *MI);
86 void adjustBlockOffsets(MachineBasicBlock &MBB);
87 bool isBlockInRange(MachineInstr *MI, MachineBasicBlock *BB, unsigned Disp);
88 bool fixupConditionalBranch(MachineInstr *MI);
89 void computeBlockSize(const MachineBasicBlock &MBB);
90 unsigned getInstrOffset(MachineInstr *MI) const;
96 AArch64BranchRelaxation() : MachineFunctionPass(ID) {}
98 bool runOnMachineFunction(MachineFunction &MF) override;
100 const char *getPassName() const override {
101 return "AArch64 branch relaxation pass";
104 char AArch64BranchRelaxation::ID = 0;
107 /// verify - check BBOffsets, BBSizes, alignment of islands
108 void AArch64BranchRelaxation::verify() {
110 unsigned PrevNum = MF->begin()->getNumber();
111 for (MachineBasicBlock &MBB : *MF) {
112 unsigned Align = MBB.getAlignment();
113 unsigned Num = MBB.getNumber();
114 assert(BlockInfo[Num].Offset % (1u << Align) == 0);
115 assert(!Num || BlockInfo[PrevNum].postOffset() <= BlockInfo[Num].Offset);
121 /// print block size and offset information - debugging
122 void AArch64BranchRelaxation::dumpBBs() {
123 for (auto &MBB : *MF) {
124 const BasicBlockInfo &BBI = BlockInfo[MBB.getNumber()];
125 dbgs() << format("BB#%u\toffset=%08x\t", MBB.getNumber(), BBI.Offset)
126 << format("size=%#x\n", BBI.Size);
130 /// BBHasFallthrough - Return true if the specified basic block can fallthrough
131 /// into the block immediately after it.
132 static bool BBHasFallthrough(MachineBasicBlock *MBB) {
133 // Get the next machine basic block in the function.
134 MachineFunction::iterator MBBI = MBB;
135 // Can't fall off end of function.
136 MachineBasicBlock *NextBB = std::next(MBBI);
137 if (NextBB == MBB->getParent()->end())
140 for (MachineBasicBlock *S : MBB->successors())
147 /// scanFunction - Do the initial scan of the function, building up
148 /// information about each block.
149 void AArch64BranchRelaxation::scanFunction() {
151 BlockInfo.resize(MF->getNumBlockIDs());
153 // First thing, compute the size of all basic blocks, and see if the function
154 // has any inline assembly in it. If so, we have to be conservative about
155 // alignment assumptions, as we don't know for sure the size of any
156 // instructions in the inline assembly.
157 for (MachineBasicBlock &MBB : *MF)
158 computeBlockSize(MBB);
160 // Compute block offsets and known bits.
161 adjustBlockOffsets(*MF->begin());
164 /// computeBlockSize - Compute the size for MBB.
165 /// This function updates BlockInfo directly.
166 void AArch64BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) {
168 for (const MachineInstr &MI : MBB)
169 Size += TII->GetInstSizeInBytes(&MI);
170 BlockInfo[MBB.getNumber()].Size = Size;
173 /// getInstrOffset - Return the current offset of the specified machine
174 /// instruction from the start of the function. This offset changes as stuff is
175 /// moved around inside the function.
176 unsigned AArch64BranchRelaxation::getInstrOffset(MachineInstr *MI) const {
177 MachineBasicBlock *MBB = MI->getParent();
179 // The offset is composed of two things: the sum of the sizes of all MBB's
180 // before this instruction's block, and the offset from the start of the block
182 unsigned Offset = BlockInfo[MBB->getNumber()].Offset;
184 // Sum instructions before MI in MBB.
185 for (MachineBasicBlock::iterator I = MBB->begin(); &*I != MI; ++I) {
186 assert(I != MBB->end() && "Didn't find MI in its own basic block?");
187 Offset += TII->GetInstSizeInBytes(I);
192 void AArch64BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
193 unsigned PrevNum = Start.getNumber();
194 for (auto &MBB : make_range(MachineFunction::iterator(Start), MF->end())) {
195 unsigned Num = MBB.getNumber();
196 if (!Num) // block zero is never changed from offset zero.
198 // Get the offset and known bits at the end of the layout predecessor.
199 // Include the alignment of the current block.
200 unsigned LogAlign = MBB.getAlignment();
201 BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(LogAlign);
206 /// Split the basic block containing MI into two blocks, which are joined by
207 /// an unconditional branch. Update data structures and renumber blocks to
208 /// account for this change and returns the newly created block.
209 /// NOTE: Successor list of the original BB is out of date after this function,
210 /// and must be updated by the caller! Other transforms follow using this
211 /// utility function, so no point updating now rather than waiting.
213 AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr *MI) {
214 MachineBasicBlock *OrigBB = MI->getParent();
216 // Create a new MBB for the code after the OrigBB.
217 MachineBasicBlock *NewBB =
218 MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
219 MachineFunction::iterator MBBI = OrigBB;
221 MF->insert(MBBI, NewBB);
223 // Splice the instructions starting with MI over to NewBB.
224 NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());
226 // Add an unconditional branch from OrigBB to NewBB.
227 // Note the new unconditional branch is not being recorded.
228 // There doesn't seem to be meaningful DebugInfo available; this doesn't
229 // correspond to anything in the source.
230 BuildMI(OrigBB, DebugLoc(), TII->get(AArch64::B)).addMBB(NewBB);
232 // Insert an entry into BlockInfo to align it properly with the block numbers.
233 BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
235 // Figure out how large the OrigBB is. As the first half of the original
236 // block, it cannot contain a tablejump. The size includes
237 // the new jump we added. (It should be possible to do this without
238 // recounting everything, but it's very confusing, and this is rarely
240 computeBlockSize(*OrigBB);
242 // Figure out how large the NewMBB is. As the second half of the original
243 // block, it may contain a tablejump.
244 computeBlockSize(*NewBB);
246 // All BBOffsets following these blocks must be modified.
247 adjustBlockOffsets(*OrigBB);
254 /// isBlockInRange - Returns true if the distance between specific MI and
255 /// specific BB can fit in MI's displacement field.
256 bool AArch64BranchRelaxation::isBlockInRange(MachineInstr *MI,
257 MachineBasicBlock *DestBB,
259 unsigned MaxOffs = ((1 << (Bits - 1)) - 1) << 2;
260 unsigned BrOffset = getInstrOffset(MI);
261 unsigned DestOffset = BlockInfo[DestBB->getNumber()].Offset;
263 DEBUG(dbgs() << "Branch of destination BB#" << DestBB->getNumber()
264 << " from BB#" << MI->getParent()->getNumber()
265 << " max delta=" << MaxOffs << " from " << getInstrOffset(MI)
266 << " to " << DestOffset << " offset "
267 << int(DestOffset - BrOffset) << "\t" << *MI);
269 // Branch before the Dest.
270 if (BrOffset <= DestOffset)
271 return (DestOffset - BrOffset <= MaxOffs);
272 return (BrOffset - DestOffset <= MaxOffs);
275 static bool isConditionalBranch(unsigned Opc) {
292 static MachineBasicBlock *getDestBlock(MachineInstr *MI) {
293 switch (MI->getOpcode()) {
295 llvm_unreachable("unexpected opcode!");
300 return MI->getOperand(2).getMBB();
306 return MI->getOperand(1).getMBB();
310 static unsigned getOppositeConditionOpcode(unsigned Opc) {
313 llvm_unreachable("unexpected opcode!");
314 case AArch64::TBNZW: return AArch64::TBZW;
315 case AArch64::TBNZX: return AArch64::TBZX;
316 case AArch64::TBZW: return AArch64::TBNZW;
317 case AArch64::TBZX: return AArch64::TBNZX;
318 case AArch64::CBNZW: return AArch64::CBZW;
319 case AArch64::CBNZX: return AArch64::CBZX;
320 case AArch64::CBZW: return AArch64::CBNZW;
321 case AArch64::CBZX: return AArch64::CBNZX;
322 case AArch64::Bcc: return AArch64::Bcc; // Condition is an operand for Bcc.
326 static unsigned getBranchDisplacementBits(unsigned Opc) {
329 llvm_unreachable("unexpected opcode!");
334 return TBZDisplacementBits;
339 return CBZDisplacementBits;
341 return BCCDisplacementBits;
345 static inline void invertBccCondition(MachineInstr *MI) {
346 assert(MI->getOpcode() == AArch64::Bcc && "Unexpected opcode!");
347 AArch64CC::CondCode CC = (AArch64CC::CondCode)MI->getOperand(0).getImm();
348 CC = AArch64CC::getInvertedCondCode(CC);
349 MI->getOperand(0).setImm((int64_t)CC);
352 /// fixupConditionalBranch - Fix up a conditional branch whose destination is
353 /// too far away to fit in its displacement field. It is converted to an inverse
354 /// conditional branch + an unconditional branch to the destination.
355 bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr *MI) {
356 MachineBasicBlock *DestBB = getDestBlock(MI);
358 // Add an unconditional branch to the destination and invert the branch
359 // condition to jump over it:
366 // If the branch is at the end of its MBB and that has a fall-through block,
367 // direct the updated conditional branch to the fall-through block. Otherwise,
368 // split the MBB before the next instruction.
369 MachineBasicBlock *MBB = MI->getParent();
370 MachineInstr *BMI = &MBB->back();
371 bool NeedSplit = (BMI != MI) || !BBHasFallthrough(MBB);
374 if (std::next(MachineBasicBlock::iterator(MI)) ==
375 std::prev(MBB->getLastNonDebugInstr()) &&
376 BMI->getOpcode() == AArch64::B) {
377 // Last MI in the BB is an unconditional branch. Can we simply invert the
378 // condition and swap destinations:
384 MachineBasicBlock *NewDest = BMI->getOperand(0).getMBB();
385 if (isBlockInRange(MI, NewDest,
386 getBranchDisplacementBits(MI->getOpcode()))) {
387 DEBUG(dbgs() << " Invert condition and swap its destination with "
389 BMI->getOperand(0).setMBB(DestBB);
390 unsigned OpNum = (MI->getOpcode() == AArch64::TBZW ||
391 MI->getOpcode() == AArch64::TBNZW ||
392 MI->getOpcode() == AArch64::TBZX ||
393 MI->getOpcode() == AArch64::TBNZX)
396 MI->getOperand(OpNum).setMBB(NewDest);
397 MI->setDesc(TII->get(getOppositeConditionOpcode(MI->getOpcode())));
398 if (MI->getOpcode() == AArch64::Bcc)
399 invertBccCondition(MI);
406 // Analyze the branch so we know how to update the successor lists.
407 MachineBasicBlock *TBB, *FBB;
408 SmallVector<MachineOperand, 2> Cond;
409 TII->AnalyzeBranch(*MBB, TBB, FBB, Cond, false);
411 MachineBasicBlock *NewBB = splitBlockBeforeInstr(MI);
412 // No need for the branch to the next block. We're adding an unconditional
413 // branch to the destination.
414 int delta = TII->GetInstSizeInBytes(&MBB->back());
415 BlockInfo[MBB->getNumber()].Size -= delta;
416 MBB->back().eraseFromParent();
417 // BlockInfo[SplitBB].Offset is wrong temporarily, fixed below
419 // Update the successor lists according to the transformation to follow.
420 // Do it here since if there's no split, no update is needed.
421 MBB->replaceSuccessor(FBB, NewBB);
422 NewBB->addSuccessor(FBB);
424 MachineBasicBlock *NextBB = std::next(MachineFunction::iterator(MBB));
426 DEBUG(dbgs() << " Insert B to BB#" << DestBB->getNumber()
427 << ", invert condition and change dest. to BB#"
428 << NextBB->getNumber() << "\n");
430 // Insert a new conditional branch and a new unconditional branch.
431 MachineInstrBuilder MIB = BuildMI(
432 MBB, DebugLoc(), TII->get(getOppositeConditionOpcode(MI->getOpcode())))
433 .addOperand(MI->getOperand(0));
434 if (MI->getOpcode() == AArch64::TBZW || MI->getOpcode() == AArch64::TBNZW ||
435 MI->getOpcode() == AArch64::TBZX || MI->getOpcode() == AArch64::TBNZX)
436 MIB.addOperand(MI->getOperand(1));
437 if (MI->getOpcode() == AArch64::Bcc)
438 invertBccCondition(MIB);
440 BlockInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
441 BuildMI(MBB, DebugLoc(), TII->get(AArch64::B)).addMBB(DestBB);
442 BlockInfo[MBB->getNumber()].Size += TII->GetInstSizeInBytes(&MBB->back());
444 // Remove the old conditional branch. It may or may not still be in MBB.
445 BlockInfo[MI->getParent()->getNumber()].Size -= TII->GetInstSizeInBytes(MI);
446 MI->eraseFromParent();
448 // Finally, keep the block offsets up to date.
449 adjustBlockOffsets(*MBB);
453 bool AArch64BranchRelaxation::relaxBranchInstructions() {
454 bool Changed = false;
455 // Relaxing branches involves creating new basic blocks, so re-eval
456 // end() for termination.
457 for (auto &MBB : *MF) {
458 MachineInstr *MI = MBB.getFirstTerminator();
459 if (isConditionalBranch(MI->getOpcode()) &&
460 !isBlockInRange(MI, getDestBlock(MI),
461 getBranchDisplacementBits(MI->getOpcode()))) {
462 fixupConditionalBranch(MI);
470 bool AArch64BranchRelaxation::runOnMachineFunction(MachineFunction &mf) {
473 // If the pass is disabled, just bail early.
474 if (!BranchRelaxation)
477 DEBUG(dbgs() << "***** AArch64BranchRelaxation *****\n");
479 TII = (const AArch64InstrInfo *)MF->getTarget()
483 // Renumber all of the machine basic blocks in the function, guaranteeing that
484 // the numbers agree with the position of the block in the function.
485 MF->RenumberBlocks();
487 // Do the initial scan of the function, building up information about the
488 // sizes of each block.
491 DEBUG(dbgs() << " Basic blocks before relaxation\n");
494 bool MadeChange = false;
495 while (relaxBranchInstructions())
498 // After a while, this might be made debug-only, but it is not expensive.
501 DEBUG(dbgs() << " Basic blocks after relaxation\n");
502 DEBUG(dbgs() << '\n'; dumpBBs());
509 /// createAArch64BranchRelaxation - returns an instance of the constpool
511 FunctionPass *llvm::createAArch64BranchRelaxation() {
512 return new AArch64BranchRelaxation();