LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MipsLongBranch.cpp
Go to the documentation of this file.
1 //===-- MipsLongBranch.cpp - Emit long 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 pass expands a branch or jump instruction into a long branch if its
11 // offset is too large to fit into its immediate field.
12 //
13 // FIXME:
14 // 1. Fix pc-region jump instructions which cross 256MB segment boundaries.
15 // 2. If program has inline assembly statements whose size cannot be
16 // determined accurately, load branch target addresses from the GOT.
17 //===----------------------------------------------------------------------===//
18 
19 #define DEBUG_TYPE "mips-long-branch"
20 
21 #include "Mips.h"
23 #include "MipsTargetMachine.h"
24 #include "llvm/ADT/Statistic.h"
27 #include "llvm/IR/Function.h"
33 
34 using namespace llvm;
35 
36 STATISTIC(LongBranches, "Number of long branches.");
37 
39  "skip-mips-long-branch",
40  cl::init(false),
41  cl::desc("MIPS: Skip long branch pass."),
42  cl::Hidden);
43 
45  "force-mips-long-branch",
46  cl::init(false),
47  cl::desc("MIPS: Expand all branches to long format."),
48  cl::Hidden);
49 
50 namespace {
51  typedef MachineBasicBlock::iterator Iter;
52  typedef MachineBasicBlock::reverse_iterator ReverseIter;
53 
54  struct MBBInfo {
55  uint64_t Size, Address;
56  bool HasLongBranch;
57  MachineInstr *Br;
58 
59  MBBInfo() : Size(0), HasLongBranch(false), Br(0) {}
60  };
61 
62  class MipsLongBranch : public MachineFunctionPass {
63 
64  public:
65  static char ID;
66  MipsLongBranch(TargetMachine &tm)
67  : MachineFunctionPass(ID), TM(tm),
68  IsPIC(TM.getRelocationModel() == Reloc::PIC_),
69  ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()),
70  LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {}
71 
72  virtual const char *getPassName() const {
73  return "Mips Long Branch";
74  }
75 
76  bool runOnMachineFunction(MachineFunction &F);
77 
78  private:
79  void splitMBB(MachineBasicBlock *MBB);
80  void initMBBInfo();
81  int64_t computeOffset(const MachineInstr *Br);
82  void replaceBranch(MachineBasicBlock &MBB, Iter Br, DebugLoc DL,
83  MachineBasicBlock *MBBOpnd);
84  void expandToLongBranch(MBBInfo &Info);
85 
86  const TargetMachine &TM;
87  MachineFunction *MF;
88  SmallVector<MBBInfo, 16> MBBInfos;
89  bool IsPIC;
90  unsigned ABI;
91  unsigned LongBranchSeqSize;
92  };
93 
94  char MipsLongBranch::ID = 0;
95 } // end of anonymous namespace
96 
97 /// createMipsLongBranchPass - Returns a pass that converts branches to long
98 /// branches.
100  return new MipsLongBranch(tm);
101 }
102 
103 /// Iterate over list of Br's operands and search for a MachineBasicBlock
104 /// operand.
106  for (unsigned I = 0, E = Br.getDesc().getNumOperands(); I < E; ++I) {
107  const MachineOperand &MO = Br.getOperand(I);
108 
109  if (MO.isMBB())
110  return MO.getMBB();
111  }
112 
113  assert(false && "This instruction does not have an MBB operand.");
114  return 0;
115 }
116 
117 // Traverse the list of instructions backwards until a non-debug instruction is
118 // found or it reaches E.
119 static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E) {
120  for (; B != E; ++B)
121  if (!B->isDebugValue())
122  return B;
123 
124  return E;
125 }
126 
127 // Split MBB if it has two direct jumps/branches.
128 void MipsLongBranch::splitMBB(MachineBasicBlock *MBB) {
129  ReverseIter End = MBB->rend();
130  ReverseIter LastBr = getNonDebugInstr(MBB->rbegin(), End);
131 
132  // Return if MBB has no branch instructions.
133  if ((LastBr == End) ||
134  (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch()))
135  return;
136 
137  ReverseIter FirstBr = getNonDebugInstr(llvm::next(LastBr), End);
138 
139  // MBB has only one branch instruction if FirstBr is not a branch
140  // instruction.
141  if ((FirstBr == End) ||
142  (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch()))
143  return;
144 
145  assert(!FirstBr->isIndirectBranch() && "Unexpected indirect branch found.");
146 
147  // Create a new MBB. Move instructions in MBB to the newly created MBB.
148  MachineBasicBlock *NewMBB =
149  MF->CreateMachineBasicBlock(MBB->getBasicBlock());
150 
151  // Insert NewMBB and fix control flow.
152  MachineBasicBlock *Tgt = getTargetMBB(*FirstBr);
153  NewMBB->transferSuccessors(MBB);
154  NewMBB->removeSuccessor(Tgt);
155  MBB->addSuccessor(NewMBB);
156  MBB->addSuccessor(Tgt);
157  MF->insert(llvm::next(MachineFunction::iterator(MBB)), NewMBB);
158 
159  NewMBB->splice(NewMBB->end(), MBB, (++LastBr).base(), MBB->end());
160 }
161 
162 // Fill MBBInfos.
163 void MipsLongBranch::initMBBInfo() {
164  // Split the MBBs if they have two branches. Each basic block should have at
165  // most one branch after this loop is executed.
166  for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E;)
167  splitMBB(I++);
168 
169  MF->RenumberBlocks();
170  MBBInfos.clear();
171  MBBInfos.resize(MF->size());
172 
173  const MipsInstrInfo *TII =
174  static_cast<const MipsInstrInfo*>(TM.getInstrInfo());
175  for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) {
176  MachineBasicBlock *MBB = MF->getBlockNumbered(I);
177 
178  // Compute size of MBB.
180  MI != MBB->instr_end(); ++MI)
181  MBBInfos[I].Size += TII->GetInstSizeInBytes(&*MI);
182 
183  // Search for MBB's branch instruction.
184  ReverseIter End = MBB->rend();
185  ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End);
186 
187  if ((Br != End) && !Br->isIndirectBranch() &&
188  (Br->isConditionalBranch() ||
189  (Br->isUnconditionalBranch() &&
190  TM.getRelocationModel() == Reloc::PIC_)))
191  MBBInfos[I].Br = (++Br).base();
192  }
193 }
194 
195 // Compute offset of branch in number of bytes.
196 int64_t MipsLongBranch::computeOffset(const MachineInstr *Br) {
197  int64_t Offset = 0;
198  int ThisMBB = Br->getParent()->getNumber();
199  int TargetMBB = getTargetMBB(*Br)->getNumber();
200 
201  // Compute offset of a forward branch.
202  if (ThisMBB < TargetMBB) {
203  for (int N = ThisMBB + 1; N < TargetMBB; ++N)
204  Offset += MBBInfos[N].Size;
205 
206  return Offset + 4;
207  }
208 
209  // Compute offset of a backward branch.
210  for (int N = ThisMBB; N >= TargetMBB; --N)
211  Offset += MBBInfos[N].Size;
212 
213  return -Offset + 4;
214 }
215 
216 // Replace Br with a branch which has the opposite condition code and a
217 // MachineBasicBlock operand MBBOpnd.
218 void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br,
219  DebugLoc DL, MachineBasicBlock *MBBOpnd) {
220  const MipsInstrInfo *TII =
221  static_cast<const MipsInstrInfo*>(TM.getInstrInfo());
222  unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode());
223  const MCInstrDesc &NewDesc = TII->get(NewOpc);
224 
225  MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc);
226 
227  for (unsigned I = 0, E = Br->getDesc().getNumOperands(); I < E; ++I) {
228  MachineOperand &MO = Br->getOperand(I);
229 
230  if (!MO.isReg()) {
231  assert(MO.isMBB() && "MBB operand expected.");
232  break;
233  }
234 
235  MIB.addReg(MO.getReg());
236  }
237 
238  MIB.addMBB(MBBOpnd);
239 
240  // Bundle the instruction in the delay slot to the newly created branch
241  // and erase the original branch.
242  assert(Br->isBundledWithSucc());
244  MIBundleBuilder(&*MIB).append((++II)->removeFromBundle());
245  Br->eraseFromParent();
246 }
247 
248 // Expand branch instructions to long branches.
249 void MipsLongBranch::expandToLongBranch(MBBInfo &I) {
251  MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br);
252  DebugLoc DL = I.Br->getDebugLoc();
253  const BasicBlock *BB = MBB->getBasicBlock();
255  MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB);
256 
257  const MipsInstrInfo *TII =
258  static_cast<const MipsInstrInfo*>(TM.getInstrInfo());
259 
260  MF->insert(FallThroughMBB, LongBrMBB);
261  MBB->removeSuccessor(TgtMBB);
262  MBB->addSuccessor(LongBrMBB);
263 
264  if (IsPIC) {
265  MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB);
266  MF->insert(FallThroughMBB, BalTgtMBB);
267  LongBrMBB->addSuccessor(BalTgtMBB);
268  BalTgtMBB->addSuccessor(TgtMBB);
269 
270  int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address;
271  unsigned BalTgtMBBSize = 5;
272  int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4);
273  int64_t Lo = SignExtend64<16>(Offset & 0xffff);
274  int64_t Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff);
275 
276  if (ABI != MipsSubtarget::N64) {
277  // $longbr:
278  // addiu $sp, $sp, -8
279  // sw $ra, 0($sp)
280  // bal $baltgt
281  // lui $at, %hi($tgt - $baltgt)
282  // $baltgt:
283  // addiu $at, $at, %lo($tgt - $baltgt)
284  // addu $at, $ra, $at
285  // lw $ra, 0($sp)
286  // jr $at
287  // addiu $sp, $sp, 8
288  // $fallthrough:
289  //
290 
291  Pos = LongBrMBB->begin();
292 
293  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)
294  .addReg(Mips::SP).addImm(-8);
295  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA)
296  .addReg(Mips::SP).addImm(0);
297 
298  MIBundleBuilder(*LongBrMBB, Pos)
299  .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB))
300  .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi));
301 
302  Pos = BalTgtMBB->begin();
303 
304  BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT)
305  .addReg(Mips::AT).addImm(Lo);
306  BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)
307  .addReg(Mips::RA).addReg(Mips::AT);
308  BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)
309  .addReg(Mips::SP).addImm(0);
310 
311  MIBundleBuilder(*BalTgtMBB, Pos)
312  .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT))
313  .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP)
314  .addReg(Mips::SP).addImm(8));
315  } else {
316  // $longbr:
317  // daddiu $sp, $sp, -16
318  // sd $ra, 0($sp)
319  // lui64 $at, %highest($tgt - $baltgt)
320  // daddiu $at, $at, %higher($tgt - $baltgt)
321  // dsll $at, $at, 16
322  // daddiu $at, $at, %hi($tgt - $baltgt)
323  // bal $baltgt
324  // dsll $at, $at, 16
325  // $baltgt:
326  // daddiu $at, $at, %lo($tgt - $baltgt)
327  // daddu $at, $ra, $at
328  // ld $ra, 0($sp)
329  // jr64 $at
330  // daddiu $sp, $sp, 16
331  // $fallthrough:
332  //
333 
334  int64_t Higher = SignExtend64<16>(((Offset + 0x80008000) >> 32) & 0xffff);
335  int64_t Highest =
336  SignExtend64<16>(((Offset + 0x800080008000LL) >> 48) & 0xffff);
337 
338  Pos = LongBrMBB->begin();
339 
340  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)
341  .addReg(Mips::SP_64).addImm(-16);
342  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64)
343  .addReg(Mips::SP_64).addImm(0);
344  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LUi64), Mips::AT_64)
345  .addImm(Highest);
346  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64)
347  .addReg(Mips::AT_64).addImm(Higher);
348  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)
349  .addReg(Mips::AT_64).addImm(16);
350  BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64)
351  .addReg(Mips::AT_64).addImm(Hi);
352 
353  MIBundleBuilder(*LongBrMBB, Pos)
354  .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB))
355  .append(BuildMI(*MF, DL, TII->get(Mips::DSLL), Mips::AT_64)
356  .addReg(Mips::AT_64).addImm(16));
357 
358  Pos = BalTgtMBB->begin();
359 
360  BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64)
361  .addReg(Mips::AT_64).addImm(Lo);
362  BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)
363  .addReg(Mips::RA_64).addReg(Mips::AT_64);
364  BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)
365  .addReg(Mips::SP_64).addImm(0);
366 
367  MIBundleBuilder(*BalTgtMBB, Pos)
368  .append(BuildMI(*MF, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64))
369  .append(BuildMI(*MF, DL, TII->get(Mips::DADDiu), Mips::SP_64)
370  .addReg(Mips::SP_64).addImm(16));
371  }
372 
373  assert(BalTgtMBBSize == BalTgtMBB->size());
374  assert(LongBrMBB->size() + BalTgtMBBSize == LongBranchSeqSize);
375  } else {
376  // $longbr:
377  // j $tgt
378  // nop
379  // $fallthrough:
380  //
381  Pos = LongBrMBB->begin();
382  LongBrMBB->addSuccessor(TgtMBB);
383  MIBundleBuilder(*LongBrMBB, Pos)
384  .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB))
385  .append(BuildMI(*MF, DL, TII->get(Mips::NOP)));
386 
387  assert(LongBrMBB->size() == LongBranchSeqSize);
388  }
389 
390  if (I.Br->isUnconditionalBranch()) {
391  // Change branch destination.
392  assert(I.Br->getDesc().getNumOperands() == 1);
393  I.Br->RemoveOperand(0);
394  I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB));
395  } else
396  // Change branch destination and reverse condition.
397  replaceBranch(*MBB, I.Br, DL, FallThroughMBB);
398 }
399 
400 static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) {
401  MachineBasicBlock &MBB = F.front();
403  DebugLoc DL = MBB.findDebugLoc(MBB.begin());
404  BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0)
405  .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI);
406  BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0)
407  .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO);
408  MBB.removeLiveIn(Mips::V0);
409 }
410 
411 bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) {
412  const MipsInstrInfo *TII =
413  static_cast<const MipsInstrInfo*>(TM.getInstrInfo());
414 
415  if (TM.getSubtarget<MipsSubtarget>().inMips16Mode())
416  return false;
417  if ((TM.getRelocationModel() == Reloc::PIC_) &&
418  TM.getSubtarget<MipsSubtarget>().isABI_O32() &&
419  F.getInfo<MipsFunctionInfo>()->globalBaseRegSet())
420  emitGPDisp(F, TII);
421 
422  if (SkipLongBranch)
423  return true;
424 
425  MF = &F;
426  initMBBInfo();
427 
428  SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end();
429  bool EverMadeChange = false, MadeChange = true;
430 
431  while (MadeChange) {
432  MadeChange = false;
433 
434  for (I = MBBInfos.begin(); I != E; ++I) {
435  // Skip if this MBB doesn't have a branch or the branch has already been
436  // converted to a long branch.
437  if (!I->Br || I->HasLongBranch)
438  continue;
439 
440  // Check if offset fits into 16-bit immediate field of branches.
441  if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4))
442  continue;
443 
444  I->HasLongBranch = true;
445  I->Size += LongBranchSeqSize * 4;
446  ++LongBranches;
447  EverMadeChange = MadeChange = true;
448  }
449  }
450 
451  if (!EverMadeChange)
452  return true;
453 
454  // Compute basic block addresses.
455  if (TM.getRelocationModel() == Reloc::PIC_) {
456  uint64_t Address = 0;
457 
458  for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I)
459  I->Address = Address;
460  }
461 
462  // Do the expansion.
463  for (I = MBBInfos.begin(); I != E; ++I)
464  if (I->HasLongBranch)
465  expandToLongBranch(*I);
466 
467  MF->RenumberBlocks();
468 
469  return true;
470 }
instr_iterator instr_begin()
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
void removeLiveIn(unsigned Reg)
const MCInstrDesc & getDesc() const
Definition: MachineInstr.h:257
F(f)
virtual unsigned getOppositeBranchOpc(unsigned Opc) const =0
Instructions::iterator instr_iterator
static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII)
bool isABI_O32() const
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:372
const HexagonInstrInfo * TII
bool isReg() const
isReg - Tests if this is a MO_Register operand.
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
#define false
Definition: ConvertUTF.c:64
const MachineInstrBuilder & addImm(int64_t Val) const
const MachineBasicBlock & front() const
reverse_iterator rend()
reverse_iterator rbegin()
const BasicBlock * getBasicBlock() const
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:314
LLVM Basic Block Representation.
Definition: BasicBlock.h:72
FunctionPass * createMipsLongBranchPass(MipsTargetMachine &TM)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
static cl::opt< bool > SkipLongBranch("skip-mips-long-branch", cl::init(false), cl::desc("MIPS: Skip long branch pass."), cl::Hidden)
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
STATISTIC(LongBranches,"Number of long branches.")
bool inMips16Mode() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
void removeSuccessor(MachineBasicBlock *succ)
static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E)
DebugLoc findDebugLoc(instr_iterator MBBI)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0)
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
static cl::opt< bool > ForceLongBranch("force-mips-long-branch", cl::init(false), cl::desc("MIPS: Expand all branches to long format."), cl::Hidden)
instr_iterator insert(instr_iterator I, MachineInstr *M)
bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:272
unsigned getReg() const
getReg - Returns the register number.
MIBundleBuilder & append(MachineInstr *MI)
std::reverse_iterator< iterator > reverse_iterator
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
Definition: MCInstrDesc.h:190
BasicBlockListType::iterator iterator
unsigned GetInstSizeInBytes(const MachineInstr *MI) const
Return the number of bytes of code the specified instruction may be.
static MachineBasicBlock * getTargetMBB(const MachineInstr &Br)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)