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