LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PPCBranchSelector.cpp
Go to the documentation of this file.
1 //===-- PPCBranchSelector.cpp - Emit long conditional branches ------------===//
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 // This file contains a pass that scans a machine function to determine which
11 // conditional branches need more than 16 bits of displacement to reach their
12 // target basic block. It does this in two passes; a calculation of basic block
13 // positions pass, and a branch pseudo op to machine branch opcode pass. This
14 // pass should be run last, just before the assembly printer.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #define DEBUG_TYPE "ppc-branch-select"
19 #include "PPC.h"
21 #include "PPCInstrBuilder.h"
22 #include "PPCInstrInfo.h"
23 #include "llvm/ADT/Statistic.h"
27 using namespace llvm;
28 
29 STATISTIC(NumExpanded, "Number of branches expanded to long format");
30 
31 namespace llvm {
33 }
34 
35 namespace {
36  struct PPCBSel : public MachineFunctionPass {
37  static char ID;
38  PPCBSel() : MachineFunctionPass(ID) {
40  }
41 
42  /// BlockSizes - The sizes of the basic blocks in the function.
43  std::vector<unsigned> BlockSizes;
44 
45  virtual bool runOnMachineFunction(MachineFunction &Fn);
46 
47  virtual const char *getPassName() const {
48  return "PowerPC Branch Selector";
49  }
50  };
51  char PPCBSel::ID = 0;
52 }
53 
54 INITIALIZE_PASS(PPCBSel, "ppc-branch-select", "PowerPC Branch Selector",
55  false, false)
56 
57 /// createPPCBranchSelectionPass - returns an instance of the Branch Selection
58 /// Pass
59 ///
61  return new PPCBSel();
62 }
63 
64 bool PPCBSel::runOnMachineFunction(MachineFunction &Fn) {
65  const PPCInstrInfo *TII =
66  static_cast<const PPCInstrInfo*>(Fn.getTarget().getInstrInfo());
67  // Give the blocks of the function a dense, in-order, numbering.
68  Fn.RenumberBlocks();
69  BlockSizes.resize(Fn.getNumBlockIDs());
70 
71  // Measure each MBB and compute a size for the entire function.
72  unsigned FuncSize = 0;
73  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
74  ++MFI) {
75  MachineBasicBlock *MBB = MFI;
76 
77  unsigned BlockSize = 0;
78  for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
79  MBBI != EE; ++MBBI)
80  BlockSize += TII->GetInstSizeInBytes(MBBI);
81 
82  BlockSizes[MBB->getNumber()] = BlockSize;
83  FuncSize += BlockSize;
84  }
85 
86  // If the entire function is smaller than the displacement of a branch field,
87  // we know we don't need to shrink any branches in this function. This is a
88  // common case.
89  if (FuncSize < (1 << 15)) {
90  BlockSizes.clear();
91  return false;
92  }
93 
94  // For each conditional branch, if the offset to its destination is larger
95  // than the offset field allows, transform it into a long branch sequence
96  // like this:
97  // short branch:
98  // bCC MBB
99  // long branch:
100  // b!CC $PC+8
101  // b MBB
102  //
103  bool MadeChange = true;
104  bool EverMadeChange = false;
105  while (MadeChange) {
106  // Iteratively expand branches until we reach a fixed point.
107  MadeChange = false;
108 
109  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
110  ++MFI) {
111  MachineBasicBlock &MBB = *MFI;
112  unsigned MBBStartOffset = 0;
113  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
114  I != E; ++I) {
115  MachineBasicBlock *Dest = 0;
116  if (I->getOpcode() == PPC::BCC && !I->getOperand(2).isImm())
117  Dest = I->getOperand(2).getMBB();
118  else if ((I->getOpcode() == PPC::BDNZ8 || I->getOpcode() == PPC::BDNZ ||
119  I->getOpcode() == PPC::BDZ8 || I->getOpcode() == PPC::BDZ) &&
120  !I->getOperand(0).isImm())
121  Dest = I->getOperand(0).getMBB();
122 
123  if (!Dest) {
124  MBBStartOffset += TII->GetInstSizeInBytes(I);
125  continue;
126  }
127 
128  // Determine the offset from the current branch to the destination
129  // block.
130  int BranchSize;
131  if (Dest->getNumber() <= MBB.getNumber()) {
132  // If this is a backwards branch, the delta is the offset from the
133  // start of this block to this branch, plus the sizes of all blocks
134  // from this block to the dest.
135  BranchSize = MBBStartOffset;
136 
137  for (unsigned i = Dest->getNumber(), e = MBB.getNumber(); i != e; ++i)
138  BranchSize += BlockSizes[i];
139  } else {
140  // Otherwise, add the size of the blocks between this block and the
141  // dest to the number of bytes left in this block.
142  BranchSize = -MBBStartOffset;
143 
144  for (unsigned i = MBB.getNumber(), e = Dest->getNumber(); i != e; ++i)
145  BranchSize += BlockSizes[i];
146  }
147 
148  // If this branch is in range, ignore it.
149  if (isInt<16>(BranchSize)) {
150  MBBStartOffset += 4;
151  continue;
152  }
153 
154  // Otherwise, we have to expand it to a long branch.
155  MachineInstr *OldBranch = I;
156  DebugLoc dl = OldBranch->getDebugLoc();
157 
158  if (I->getOpcode() == PPC::BCC) {
159  // The BCC operands are:
160  // 0. PPC branch predicate
161  // 1. CR register
162  // 2. Target MBB
163  PPC::Predicate Pred = (PPC::Predicate)I->getOperand(0).getImm();
164  unsigned CRReg = I->getOperand(1).getReg();
165 
166  // Jump over the uncond branch inst (i.e. $PC+8) on opposite condition.
167  BuildMI(MBB, I, dl, TII->get(PPC::BCC))
168  .addImm(PPC::InvertPredicate(Pred)).addReg(CRReg).addImm(2);
169  } else if (I->getOpcode() == PPC::BDNZ) {
170  BuildMI(MBB, I, dl, TII->get(PPC::BDZ)).addImm(2);
171  } else if (I->getOpcode() == PPC::BDNZ8) {
172  BuildMI(MBB, I, dl, TII->get(PPC::BDZ8)).addImm(2);
173  } else if (I->getOpcode() == PPC::BDZ) {
174  BuildMI(MBB, I, dl, TII->get(PPC::BDNZ)).addImm(2);
175  } else if (I->getOpcode() == PPC::BDZ8) {
176  BuildMI(MBB, I, dl, TII->get(PPC::BDNZ8)).addImm(2);
177  } else {
178  llvm_unreachable("Unhandled branch type!");
179  }
180 
181  // Uncond branch to the real destination.
182  I = BuildMI(MBB, I, dl, TII->get(PPC::B)).addMBB(Dest);
183 
184  // Remove the old branch from the function.
185  OldBranch->eraseFromParent();
186 
187  // Remember that this instruction is 8-bytes, increase the size of the
188  // block by 4, remember to iterate.
189  BlockSizes[MBB.getNumber()] += 4;
190  MBBStartOffset += 8;
191  ++NumExpanded;
192  MadeChange = true;
193  }
194  }
195  EverMadeChange |= MadeChange;
196  }
197 
198  BlockSizes.clear();
199  return true;
200 }
201 
static PassRegistry * getPassRegistry()
unsigned getNumBlockIDs() const
const HexagonInstrInfo * TII
void initializePPCBSelPass(PassRegistry &)
#define llvm_unreachable(msg)
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
const MachineInstrBuilder & addImm(int64_t Val) const
void RenumberBlocks(MachineBasicBlock *MBBFrom=0)
FunctionPass * createPPCBranchSelectionPass()
bundle_iterator< MachineInstr, instr_iterator > iterator
INITIALIZE_PASS(PPCBSel,"ppc-branch-select","PowerPC Branch Selector", false, false) FunctionPass *llvm
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
STATISTIC(NumExpanded,"Number of branches expanded to long format")
virtual const TargetInstrInfo * getInstrInfo() const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:27
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:272
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const
BasicBlockListType::iterator iterator
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244