AArch64BranchRelaxation.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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"
24using namespace llvm;
25
26#define DEBUG_TYPE "aarch64-branch-relax"
27
28static cl::opt<bool>
29BranchRelaxation("aarch64-branch-relax", cl::Hidden, cl::init(true),
30                 cl::desc("Relax out of range conditional branches"));
31
32static cl::opt<unsigned>
33TBZDisplacementBits("aarch64-tbz-offset-bits", cl::Hidden, cl::init(14),
34                    cl::desc("Restrict range of TB[N]Z instructions (DEBUG)"));
35
36static cl::opt<unsigned>
37CBZDisplacementBits("aarch64-cbz-offset-bits", cl::Hidden, cl::init(19),
38                    cl::desc("Restrict range of CB[N]Z instructions (DEBUG)"));
39
40static cl::opt<unsigned>
41BCCDisplacementBits("aarch64-bcc-offset-bits", cl::Hidden, cl::init(19),
42                    cl::desc("Restrict range of Bcc instructions (DEBUG)"));
43
44STATISTIC(NumSplit, "Number of basic blocks split");
45STATISTIC(NumRelaxed, "Number of conditional branches relaxed");
46
47namespace {
48class 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
65    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.
70    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
93public:
94  static char ID;
95  AArch64BranchRelaxation() : MachineFunctionPass(ID) {}
96
97  bool runOnMachineFunction(MachineFunction &MF) override;
98
99  const char *getPassName() const override {
100    return "AArch64 branch relaxation pass";
101  }
102};
103char AArch64BranchRelaxation::ID = 0;
104}
105
106/// verify - check BBOffsets, BBSizes, alignment of islands
107void 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
121void 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.
131static 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.
148void 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.
165void 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.
175unsigned 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
191void 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.
211MachineBasicBlock *
212AArch64BranchRelaxation::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.
255bool 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
274static 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
291static MachineBasicBlock *getDestBlock(MachineInstr *MI) {
292  switch (MI->getOpcode()) {
293  default:
294    assert(0 && "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
309static unsigned getOppositeConditionOpcode(unsigned Opc) {
310  switch (Opc) {
311  default:
312    assert(0 && "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
325static unsigned getBranchDisplacementBits(unsigned Opc) {
326  switch (Opc) {
327  default:
328    assert(0 && "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
344static 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.
354bool 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
452bool 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
469bool 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.
508FunctionPass *llvm::createAArch64BranchRelaxation() {
509  return new AArch64BranchRelaxation();
510}
511