]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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 | // | |
1a4d82fc | 13 | // FIXME: Fix pc-region jump instructions which cross 256MB segment boundaries. |
223e47cc LB |
14 | //===----------------------------------------------------------------------===// |
15 | ||
223e47cc | 16 | #include "Mips.h" |
223e47cc | 17 | #include "MCTargetDesc/MipsBaseInfo.h" |
1a4d82fc JJ |
18 | #include "MCTargetDesc/MipsMCNaCl.h" |
19 | #include "MipsMachineFunction.h" | |
970d7e83 | 20 | #include "MipsTargetMachine.h" |
223e47cc LB |
21 | #include "llvm/ADT/Statistic.h" |
22 | #include "llvm/CodeGen/MachineFunctionPass.h" | |
23 | #include "llvm/CodeGen/MachineInstrBuilder.h" | |
970d7e83 | 24 | #include "llvm/IR/Function.h" |
223e47cc LB |
25 | #include "llvm/Support/CommandLine.h" |
26 | #include "llvm/Support/MathExtras.h" | |
27 | #include "llvm/Target/TargetInstrInfo.h" | |
28 | #include "llvm/Target/TargetMachine.h" | |
29 | #include "llvm/Target/TargetRegisterInfo.h" | |
30 | ||
31 | using namespace llvm; | |
32 | ||
1a4d82fc JJ |
33 | #define DEBUG_TYPE "mips-long-branch" |
34 | ||
223e47cc LB |
35 | STATISTIC(LongBranches, "Number of long branches."); |
36 | ||
37 | static cl::opt<bool> SkipLongBranch( | |
38 | "skip-mips-long-branch", | |
39 | cl::init(false), | |
40 | cl::desc("MIPS: Skip long branch pass."), | |
41 | cl::Hidden); | |
42 | ||
43 | static cl::opt<bool> ForceLongBranch( | |
44 | "force-mips-long-branch", | |
45 | cl::init(false), | |
46 | cl::desc("MIPS: Expand all branches to long format."), | |
47 | cl::Hidden); | |
48 | ||
49 | namespace { | |
50 | typedef MachineBasicBlock::iterator Iter; | |
51 | typedef MachineBasicBlock::reverse_iterator ReverseIter; | |
52 | ||
53 | struct MBBInfo { | |
54 | uint64_t Size, Address; | |
55 | bool HasLongBranch; | |
56 | MachineInstr *Br; | |
57 | ||
1a4d82fc | 58 | MBBInfo() : Size(0), HasLongBranch(false), Br(nullptr) {} |
223e47cc LB |
59 | }; |
60 | ||
61 | class MipsLongBranch : public MachineFunctionPass { | |
62 | ||
63 | public: | |
64 | static char ID; | |
65 | MipsLongBranch(TargetMachine &tm) | |
66 | : MachineFunctionPass(ID), TM(tm), | |
223e47cc | 67 | IsPIC(TM.getRelocationModel() == Reloc::PIC_), |
85aaf69f SL |
68 | ABI(TM.getSubtarget<MipsSubtarget>().getABI()), |
69 | LongBranchSeqSize(!IsPIC ? 2 : (ABI.IsN64() ? 10 : | |
1a4d82fc | 70 | (!TM.getSubtarget<MipsSubtarget>().isTargetNaCl() ? 9 : 10))) {} |
223e47cc | 71 | |
1a4d82fc | 72 | const char *getPassName() const override { |
223e47cc LB |
73 | return "Mips Long Branch"; |
74 | } | |
75 | ||
1a4d82fc | 76 | bool runOnMachineFunction(MachineFunction &F) override; |
223e47cc LB |
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; | |
223e47cc LB |
87 | MachineFunction *MF; |
88 | SmallVector<MBBInfo, 16> MBBInfos; | |
89 | bool IsPIC; | |
85aaf69f | 90 | MipsABIInfo ABI; |
223e47cc LB |
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. | |
99 | FunctionPass *llvm::createMipsLongBranchPass(MipsTargetMachine &tm) { | |
100 | return new MipsLongBranch(tm); | |
101 | } | |
102 | ||
103 | /// Iterate over list of Br's operands and search for a MachineBasicBlock | |
104 | /// operand. | |
105 | static MachineBasicBlock *getTargetMBB(const MachineInstr &Br) { | |
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 | ||
85aaf69f | 113 | llvm_unreachable("This instruction does not have an MBB operand."); |
223e47cc LB |
114 | } |
115 | ||
116 | // Traverse the list of instructions backwards until a non-debug instruction is | |
117 | // found or it reaches E. | |
118 | static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E) { | |
119 | for (; B != E; ++B) | |
120 | if (!B->isDebugValue()) | |
121 | return B; | |
122 | ||
123 | return E; | |
124 | } | |
125 | ||
126 | // Split MBB if it has two direct jumps/branches. | |
127 | void MipsLongBranch::splitMBB(MachineBasicBlock *MBB) { | |
128 | ReverseIter End = MBB->rend(); | |
129 | ReverseIter LastBr = getNonDebugInstr(MBB->rbegin(), End); | |
130 | ||
131 | // Return if MBB has no branch instructions. | |
132 | if ((LastBr == End) || | |
133 | (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch())) | |
134 | return; | |
135 | ||
1a4d82fc | 136 | ReverseIter FirstBr = getNonDebugInstr(std::next(LastBr), End); |
223e47cc LB |
137 | |
138 | // MBB has only one branch instruction if FirstBr is not a branch | |
139 | // instruction. | |
140 | if ((FirstBr == End) || | |
141 | (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch())) | |
142 | return; | |
143 | ||
144 | assert(!FirstBr->isIndirectBranch() && "Unexpected indirect branch found."); | |
145 | ||
146 | // Create a new MBB. Move instructions in MBB to the newly created MBB. | |
147 | MachineBasicBlock *NewMBB = | |
148 | MF->CreateMachineBasicBlock(MBB->getBasicBlock()); | |
149 | ||
150 | // Insert NewMBB and fix control flow. | |
151 | MachineBasicBlock *Tgt = getTargetMBB(*FirstBr); | |
152 | NewMBB->transferSuccessors(MBB); | |
153 | NewMBB->removeSuccessor(Tgt); | |
154 | MBB->addSuccessor(NewMBB); | |
155 | MBB->addSuccessor(Tgt); | |
1a4d82fc | 156 | MF->insert(std::next(MachineFunction::iterator(MBB)), NewMBB); |
223e47cc LB |
157 | |
158 | NewMBB->splice(NewMBB->end(), MBB, (++LastBr).base(), MBB->end()); | |
159 | } | |
160 | ||
161 | // Fill MBBInfos. | |
162 | void MipsLongBranch::initMBBInfo() { | |
163 | // Split the MBBs if they have two branches. Each basic block should have at | |
164 | // most one branch after this loop is executed. | |
165 | for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E;) | |
166 | splitMBB(I++); | |
167 | ||
168 | MF->RenumberBlocks(); | |
169 | MBBInfos.clear(); | |
170 | MBBInfos.resize(MF->size()); | |
171 | ||
1a4d82fc JJ |
172 | const MipsInstrInfo *TII = |
173 | static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | |
223e47cc LB |
174 | for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) { |
175 | MachineBasicBlock *MBB = MF->getBlockNumbered(I); | |
176 | ||
177 | // Compute size of MBB. | |
178 | for (MachineBasicBlock::instr_iterator MI = MBB->instr_begin(); | |
179 | MI != MBB->instr_end(); ++MI) | |
180 | MBBInfos[I].Size += TII->GetInstSizeInBytes(&*MI); | |
181 | ||
182 | // Search for MBB's branch instruction. | |
183 | ReverseIter End = MBB->rend(); | |
184 | ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End); | |
185 | ||
186 | if ((Br != End) && !Br->isIndirectBranch() && | |
187 | (Br->isConditionalBranch() || | |
188 | (Br->isUnconditionalBranch() && | |
189 | TM.getRelocationModel() == Reloc::PIC_))) | |
190 | MBBInfos[I].Br = (++Br).base(); | |
191 | } | |
192 | } | |
193 | ||
194 | // Compute offset of branch in number of bytes. | |
195 | int64_t MipsLongBranch::computeOffset(const MachineInstr *Br) { | |
196 | int64_t Offset = 0; | |
197 | int ThisMBB = Br->getParent()->getNumber(); | |
198 | int TargetMBB = getTargetMBB(*Br)->getNumber(); | |
199 | ||
200 | // Compute offset of a forward branch. | |
201 | if (ThisMBB < TargetMBB) { | |
202 | for (int N = ThisMBB + 1; N < TargetMBB; ++N) | |
203 | Offset += MBBInfos[N].Size; | |
204 | ||
205 | return Offset + 4; | |
206 | } | |
207 | ||
208 | // Compute offset of a backward branch. | |
209 | for (int N = ThisMBB; N >= TargetMBB; --N) | |
210 | Offset += MBBInfos[N].Size; | |
211 | ||
212 | return -Offset + 4; | |
213 | } | |
214 | ||
215 | // Replace Br with a branch which has the opposite condition code and a | |
216 | // MachineBasicBlock operand MBBOpnd. | |
217 | void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br, | |
218 | DebugLoc DL, MachineBasicBlock *MBBOpnd) { | |
1a4d82fc JJ |
219 | const MipsInstrInfo *TII = |
220 | static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | |
221 | unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode()); | |
223e47cc LB |
222 | const MCInstrDesc &NewDesc = TII->get(NewOpc); |
223 | ||
224 | MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc); | |
225 | ||
226 | for (unsigned I = 0, E = Br->getDesc().getNumOperands(); I < E; ++I) { | |
227 | MachineOperand &MO = Br->getOperand(I); | |
228 | ||
229 | if (!MO.isReg()) { | |
230 | assert(MO.isMBB() && "MBB operand expected."); | |
231 | break; | |
232 | } | |
233 | ||
234 | MIB.addReg(MO.getReg()); | |
235 | } | |
236 | ||
237 | MIB.addMBB(MBBOpnd); | |
238 | ||
85aaf69f SL |
239 | if (Br->hasDelaySlot()) { |
240 | // Bundle the instruction in the delay slot to the newly created branch | |
241 | // and erase the original branch. | |
242 | assert(Br->isBundledWithSucc()); | |
243 | MachineBasicBlock::instr_iterator II(Br); | |
244 | MIBundleBuilder(&*MIB).append((++II)->removeFromBundle()); | |
245 | } | |
223e47cc LB |
246 | Br->eraseFromParent(); |
247 | } | |
248 | ||
249 | // Expand branch instructions to long branches. | |
85aaf69f SL |
250 | // TODO: This function has to be fixed for beqz16 and bnez16, because it |
251 | // currently assumes that all branches have 16-bit offsets, and will produce | |
252 | // wrong code if branches whose allowed offsets are [-128, -126, ..., 126] | |
253 | // are present. | |
223e47cc LB |
254 | void MipsLongBranch::expandToLongBranch(MBBInfo &I) { |
255 | MachineBasicBlock::iterator Pos; | |
256 | MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br); | |
257 | DebugLoc DL = I.Br->getDebugLoc(); | |
258 | const BasicBlock *BB = MBB->getBasicBlock(); | |
259 | MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB); | |
260 | MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB); | |
261 | ||
1a4d82fc JJ |
262 | const MipsInstrInfo *TII = |
263 | static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | |
264 | ||
223e47cc LB |
265 | MF->insert(FallThroughMBB, LongBrMBB); |
266 | MBB->removeSuccessor(TgtMBB); | |
267 | MBB->addSuccessor(LongBrMBB); | |
268 | ||
269 | if (IsPIC) { | |
270 | MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB); | |
271 | MF->insert(FallThroughMBB, BalTgtMBB); | |
272 | LongBrMBB->addSuccessor(BalTgtMBB); | |
273 | BalTgtMBB->addSuccessor(TgtMBB); | |
274 | ||
1a4d82fc JJ |
275 | // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal |
276 | // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an | |
277 | // pseudo-instruction wrapping BGEZAL). | |
278 | ||
279 | const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); | |
280 | unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR; | |
223e47cc | 281 | |
85aaf69f | 282 | if (!ABI.IsN64()) { |
223e47cc LB |
283 | // $longbr: |
284 | // addiu $sp, $sp, -8 | |
285 | // sw $ra, 0($sp) | |
223e47cc | 286 | // lui $at, %hi($tgt - $baltgt) |
1a4d82fc | 287 | // bal $baltgt |
223e47cc | 288 | // addiu $at, $at, %lo($tgt - $baltgt) |
1a4d82fc | 289 | // $baltgt: |
223e47cc LB |
290 | // addu $at, $ra, $at |
291 | // lw $ra, 0($sp) | |
292 | // jr $at | |
293 | // addiu $sp, $sp, 8 | |
294 | // $fallthrough: | |
295 | // | |
296 | ||
297 | Pos = LongBrMBB->begin(); | |
298 | ||
299 | BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) | |
300 | .addReg(Mips::SP).addImm(-8); | |
301 | BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) | |
302 | .addReg(Mips::SP).addImm(0); | |
970d7e83 | 303 | |
1a4d82fc JJ |
304 | // LUi and ADDiu instructions create 32-bit offset of the target basic |
305 | // block from the target of BAL instruction. We cannot use immediate | |
306 | // value for this offset because it cannot be determined accurately when | |
307 | // the program has inline assembly statements. We therefore use the | |
308 | // relocation expressions %hi($tgt-$baltgt) and %lo($tgt-$baltgt) which | |
309 | // are resolved during the fixup, so the values will always be correct. | |
310 | // | |
311 | // Since we cannot create %hi($tgt-$baltgt) and %lo($tgt-$baltgt) | |
312 | // expressions at this point (it is possible only at the MC layer), | |
313 | // we replace LUi and ADDiu with pseudo instructions | |
314 | // LONG_BRANCH_LUi and LONG_BRANCH_ADDiu, and add both basic | |
315 | // blocks as operands to these instructions. When lowering these pseudo | |
316 | // instructions to LUi and ADDiu in the MC layer, we will create | |
317 | // %hi($tgt-$baltgt) and %lo($tgt-$baltgt) expressions and add them as | |
318 | // operands to lowered instructions. | |
319 | ||
320 | BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT) | |
321 | .addMBB(TgtMBB).addMBB(BalTgtMBB); | |
970d7e83 | 322 | MIBundleBuilder(*LongBrMBB, Pos) |
1a4d82fc JJ |
323 | .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) |
324 | .append(BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT) | |
325 | .addReg(Mips::AT) | |
326 | .addMBB(TgtMBB) | |
327 | .addMBB(BalTgtMBB)); | |
223e47cc LB |
328 | |
329 | Pos = BalTgtMBB->begin(); | |
330 | ||
223e47cc LB |
331 | BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) |
332 | .addReg(Mips::RA).addReg(Mips::AT); | |
333 | BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) | |
334 | .addReg(Mips::SP).addImm(0); | |
970d7e83 | 335 | |
1a4d82fc JJ |
336 | if (!TM.getSubtarget<MipsSubtarget>().isTargetNaCl()) { |
337 | MIBundleBuilder(*BalTgtMBB, Pos) | |
338 | .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) | |
339 | .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) | |
340 | .addReg(Mips::SP).addImm(8)); | |
341 | } else { | |
342 | // In NaCl, modifying the sp is not allowed in branch delay slot. | |
343 | BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) | |
344 | .addReg(Mips::SP).addImm(8); | |
345 | ||
346 | MIBundleBuilder(*BalTgtMBB, Pos) | |
347 | .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) | |
348 | .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); | |
349 | ||
350 | // Bundle-align the target of indirect branch JR. | |
351 | TgtMBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); | |
352 | } | |
223e47cc LB |
353 | } else { |
354 | // $longbr: | |
355 | // daddiu $sp, $sp, -16 | |
356 | // sd $ra, 0($sp) | |
1a4d82fc | 357 | // daddiu $at, $zero, %hi($tgt - $baltgt) |
223e47cc | 358 | // dsll $at, $at, 16 |
223e47cc | 359 | // bal $baltgt |
223e47cc | 360 | // daddiu $at, $at, %lo($tgt - $baltgt) |
1a4d82fc | 361 | // $baltgt: |
223e47cc LB |
362 | // daddu $at, $ra, $at |
363 | // ld $ra, 0($sp) | |
364 | // jr64 $at | |
365 | // daddiu $sp, $sp, 16 | |
366 | // $fallthrough: | |
367 | // | |
368 | ||
1a4d82fc JJ |
369 | // We assume the branch is within-function, and that offset is within |
370 | // +/- 2GB. High 32 bits will therefore always be zero. | |
371 | ||
372 | // Note that this will work even if the offset is negative, because | |
373 | // of the +1 modification that's added in that case. For example, if the | |
374 | // offset is -1MB (0xFFFFFFFFFFF00000), the computation for %higher is | |
375 | // | |
376 | // 0xFFFFFFFFFFF00000 + 0x80008000 = 0x000000007FF08000 | |
377 | // | |
378 | // and the bits [47:32] are zero. For %highest | |
379 | // | |
380 | // 0xFFFFFFFFFFF00000 + 0x800080008000 = 0x000080007FF08000 | |
381 | // | |
382 | // and the bits [63:48] are zero. | |
223e47cc LB |
383 | |
384 | Pos = LongBrMBB->begin(); | |
385 | ||
386 | BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) | |
387 | .addReg(Mips::SP_64).addImm(-16); | |
388 | BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64) | |
389 | .addReg(Mips::SP_64).addImm(0); | |
1a4d82fc JJ |
390 | BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu), |
391 | Mips::AT_64).addReg(Mips::ZERO_64) | |
392 | .addMBB(TgtMBB, MipsII::MO_ABS_HI).addMBB(BalTgtMBB); | |
223e47cc LB |
393 | BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) |
394 | .addReg(Mips::AT_64).addImm(16); | |
970d7e83 LB |
395 | |
396 | MIBundleBuilder(*LongBrMBB, Pos) | |
1a4d82fc JJ |
397 | .append(BuildMI(*MF, DL, TII->get(BalOp)).addMBB(BalTgtMBB)) |
398 | .append( | |
399 | BuildMI(*MF, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64) | |
400 | .addReg(Mips::AT_64) | |
401 | .addMBB(TgtMBB, MipsII::MO_ABS_LO) | |
402 | .addMBB(BalTgtMBB)); | |
223e47cc LB |
403 | |
404 | Pos = BalTgtMBB->begin(); | |
405 | ||
223e47cc LB |
406 | BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64) |
407 | .addReg(Mips::RA_64).addReg(Mips::AT_64); | |
408 | BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64) | |
409 | .addReg(Mips::SP_64).addImm(0); | |
970d7e83 LB |
410 | |
411 | MIBundleBuilder(*BalTgtMBB, Pos) | |
412 | .append(BuildMI(*MF, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64)) | |
413 | .append(BuildMI(*MF, DL, TII->get(Mips::DADDiu), Mips::SP_64) | |
414 | .addReg(Mips::SP_64).addImm(16)); | |
223e47cc | 415 | } |
970d7e83 | 416 | |
1a4d82fc | 417 | assert(LongBrMBB->size() + BalTgtMBB->size() == LongBranchSeqSize); |
223e47cc LB |
418 | } else { |
419 | // $longbr: | |
420 | // j $tgt | |
421 | // nop | |
422 | // $fallthrough: | |
423 | // | |
424 | Pos = LongBrMBB->begin(); | |
425 | LongBrMBB->addSuccessor(TgtMBB); | |
970d7e83 LB |
426 | MIBundleBuilder(*LongBrMBB, Pos) |
427 | .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) | |
428 | .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); | |
429 | ||
430 | assert(LongBrMBB->size() == LongBranchSeqSize); | |
223e47cc LB |
431 | } |
432 | ||
433 | if (I.Br->isUnconditionalBranch()) { | |
434 | // Change branch destination. | |
435 | assert(I.Br->getDesc().getNumOperands() == 1); | |
436 | I.Br->RemoveOperand(0); | |
437 | I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB)); | |
438 | } else | |
439 | // Change branch destination and reverse condition. | |
440 | replaceBranch(*MBB, I.Br, DL, FallThroughMBB); | |
441 | } | |
442 | ||
443 | static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) { | |
444 | MachineBasicBlock &MBB = F.front(); | |
445 | MachineBasicBlock::iterator I = MBB.begin(); | |
446 | DebugLoc DL = MBB.findDebugLoc(MBB.begin()); | |
447 | BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0) | |
448 | .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); | |
449 | BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0) | |
450 | .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); | |
451 | MBB.removeLiveIn(Mips::V0); | |
452 | } | |
453 | ||
454 | bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { | |
1a4d82fc JJ |
455 | const MipsInstrInfo *TII = |
456 | static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | |
457 | ||
458 | const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>(); | |
459 | if (STI.inMips16Mode() || !STI.enableLongBranchPass()) | |
460 | return false; | |
223e47cc LB |
461 | if ((TM.getRelocationModel() == Reloc::PIC_) && |
462 | TM.getSubtarget<MipsSubtarget>().isABI_O32() && | |
463 | F.getInfo<MipsFunctionInfo>()->globalBaseRegSet()) | |
464 | emitGPDisp(F, TII); | |
465 | ||
466 | if (SkipLongBranch) | |
467 | return true; | |
468 | ||
469 | MF = &F; | |
470 | initMBBInfo(); | |
471 | ||
1a4d82fc | 472 | SmallVectorImpl<MBBInfo>::iterator I, E = MBBInfos.end(); |
223e47cc LB |
473 | bool EverMadeChange = false, MadeChange = true; |
474 | ||
475 | while (MadeChange) { | |
476 | MadeChange = false; | |
477 | ||
478 | for (I = MBBInfos.begin(); I != E; ++I) { | |
479 | // Skip if this MBB doesn't have a branch or the branch has already been | |
480 | // converted to a long branch. | |
481 | if (!I->Br || I->HasLongBranch) | |
482 | continue; | |
483 | ||
1a4d82fc JJ |
484 | int ShVal = TM.getSubtarget<MipsSubtarget>().inMicroMipsMode() ? 2 : 4; |
485 | int64_t Offset = computeOffset(I->Br) / ShVal; | |
486 | ||
487 | if (TM.getSubtarget<MipsSubtarget>().isTargetNaCl()) { | |
488 | // The offset calculation does not include sandboxing instructions | |
489 | // that will be added later in the MC layer. Since at this point we | |
490 | // don't know the exact amount of code that "sandboxing" will add, we | |
491 | // conservatively estimate that code will not grow more than 100%. | |
492 | Offset *= 2; | |
493 | } | |
494 | ||
223e47cc | 495 | // Check if offset fits into 16-bit immediate field of branches. |
1a4d82fc | 496 | if (!ForceLongBranch && isInt<16>(Offset)) |
223e47cc LB |
497 | continue; |
498 | ||
499 | I->HasLongBranch = true; | |
500 | I->Size += LongBranchSeqSize * 4; | |
501 | ++LongBranches; | |
502 | EverMadeChange = MadeChange = true; | |
503 | } | |
504 | } | |
505 | ||
506 | if (!EverMadeChange) | |
507 | return true; | |
508 | ||
509 | // Compute basic block addresses. | |
510 | if (TM.getRelocationModel() == Reloc::PIC_) { | |
223e47cc LB |
511 | uint64_t Address = 0; |
512 | ||
513 | for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) | |
514 | I->Address = Address; | |
515 | } | |
516 | ||
517 | // Do the expansion. | |
518 | for (I = MBBInfos.begin(); I != E; ++I) | |
519 | if (I->HasLongBranch) | |
520 | expandToLongBranch(*I); | |
521 | ||
522 | MF->RenumberBlocks(); | |
523 | ||
524 | return true; | |
525 | } |