Mercurial > hg > CbC > CbC_llvm
comparison lib/Target/Mips/MipsLongBranch.cpp @ 83:60c9769439b8 LLVM3.7
LLVM 3.7
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Feb 2015 14:55:36 +0900 |
parents | 54457678186b |
children | 7d135dc70f03 |
comparison
equal
deleted
inserted
replaced
78:af83660cff7b | 83:60c9769439b8 |
---|---|
61 class MipsLongBranch : public MachineFunctionPass { | 61 class MipsLongBranch : public MachineFunctionPass { |
62 | 62 |
63 public: | 63 public: |
64 static char ID; | 64 static char ID; |
65 MipsLongBranch(TargetMachine &tm) | 65 MipsLongBranch(TargetMachine &tm) |
66 : MachineFunctionPass(ID), TM(tm), | 66 : MachineFunctionPass(ID), TM(tm), |
67 IsPIC(TM.getRelocationModel() == Reloc::PIC_), | 67 IsPIC(TM.getRelocationModel() == Reloc::PIC_), |
68 ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), | 68 ABI(static_cast<const MipsTargetMachine &>(TM).getABI()) {} |
69 LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 10 : | |
70 (!TM.getSubtarget<MipsSubtarget>().isTargetNaCl() ? 9 : 10))) {} | |
71 | 69 |
72 const char *getPassName() const override { | 70 const char *getPassName() const override { |
73 return "Mips Long Branch"; | 71 return "Mips Long Branch"; |
74 } | 72 } |
75 | 73 |
85 | 83 |
86 const TargetMachine &TM; | 84 const TargetMachine &TM; |
87 MachineFunction *MF; | 85 MachineFunction *MF; |
88 SmallVector<MBBInfo, 16> MBBInfos; | 86 SmallVector<MBBInfo, 16> MBBInfos; |
89 bool IsPIC; | 87 bool IsPIC; |
90 unsigned ABI; | 88 MipsABIInfo ABI; |
91 unsigned LongBranchSeqSize; | 89 unsigned LongBranchSeqSize; |
92 }; | 90 }; |
93 | 91 |
94 char MipsLongBranch::ID = 0; | 92 char MipsLongBranch::ID = 0; |
95 } // end of anonymous namespace | 93 } // end of anonymous namespace |
108 | 106 |
109 if (MO.isMBB()) | 107 if (MO.isMBB()) |
110 return MO.getMBB(); | 108 return MO.getMBB(); |
111 } | 109 } |
112 | 110 |
113 assert(false && "This instruction does not have an MBB operand."); | 111 llvm_unreachable("This instruction does not have an MBB operand."); |
114 return nullptr; | |
115 } | 112 } |
116 | 113 |
117 // Traverse the list of instructions backwards until a non-debug instruction is | 114 // Traverse the list of instructions backwards until a non-debug instruction is |
118 // found or it reaches E. | 115 // found or it reaches E. |
119 static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E) { | 116 static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E) { |
169 MF->RenumberBlocks(); | 166 MF->RenumberBlocks(); |
170 MBBInfos.clear(); | 167 MBBInfos.clear(); |
171 MBBInfos.resize(MF->size()); | 168 MBBInfos.resize(MF->size()); |
172 | 169 |
173 const MipsInstrInfo *TII = | 170 const MipsInstrInfo *TII = |
174 static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | 171 static_cast<const MipsInstrInfo *>(MF->getSubtarget().getInstrInfo()); |
175 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) { | 172 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) { |
176 MachineBasicBlock *MBB = MF->getBlockNumbered(I); | 173 MachineBasicBlock *MBB = MF->getBlockNumbered(I); |
177 | 174 |
178 // Compute size of MBB. | 175 // Compute size of MBB. |
179 for (MachineBasicBlock::instr_iterator MI = MBB->instr_begin(); | 176 for (MachineBasicBlock::instr_iterator MI = MBB->instr_begin(); |
215 | 212 |
216 // Replace Br with a branch which has the opposite condition code and a | 213 // Replace Br with a branch which has the opposite condition code and a |
217 // MachineBasicBlock operand MBBOpnd. | 214 // MachineBasicBlock operand MBBOpnd. |
218 void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br, | 215 void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br, |
219 DebugLoc DL, MachineBasicBlock *MBBOpnd) { | 216 DebugLoc DL, MachineBasicBlock *MBBOpnd) { |
220 const MipsInstrInfo *TII = | 217 const MipsInstrInfo *TII = static_cast<const MipsInstrInfo *>( |
221 static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | 218 MBB.getParent()->getSubtarget().getInstrInfo()); |
222 unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode()); | 219 unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode()); |
223 const MCInstrDesc &NewDesc = TII->get(NewOpc); | 220 const MCInstrDesc &NewDesc = TII->get(NewOpc); |
224 | 221 |
225 MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc); | 222 MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc); |
226 | 223 |
235 MIB.addReg(MO.getReg()); | 232 MIB.addReg(MO.getReg()); |
236 } | 233 } |
237 | 234 |
238 MIB.addMBB(MBBOpnd); | 235 MIB.addMBB(MBBOpnd); |
239 | 236 |
240 // Bundle the instruction in the delay slot to the newly created branch | 237 if (Br->hasDelaySlot()) { |
241 // and erase the original branch. | 238 // Bundle the instruction in the delay slot to the newly created branch |
242 assert(Br->isBundledWithSucc()); | 239 // and erase the original branch. |
243 MachineBasicBlock::instr_iterator II(Br); | 240 assert(Br->isBundledWithSucc()); |
244 MIBundleBuilder(&*MIB).append((++II)->removeFromBundle()); | 241 MachineBasicBlock::instr_iterator II(Br); |
242 MIBundleBuilder(&*MIB).append((++II)->removeFromBundle()); | |
243 } | |
245 Br->eraseFromParent(); | 244 Br->eraseFromParent(); |
246 } | 245 } |
247 | 246 |
248 // Expand branch instructions to long branches. | 247 // Expand branch instructions to long branches. |
248 // TODO: This function has to be fixed for beqz16 and bnez16, because it | |
249 // currently assumes that all branches have 16-bit offsets, and will produce | |
250 // wrong code if branches whose allowed offsets are [-128, -126, ..., 126] | |
251 // are present. | |
249 void MipsLongBranch::expandToLongBranch(MBBInfo &I) { | 252 void MipsLongBranch::expandToLongBranch(MBBInfo &I) { |
250 MachineBasicBlock::iterator Pos; | 253 MachineBasicBlock::iterator Pos; |
251 MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br); | 254 MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br); |
252 DebugLoc DL = I.Br->getDebugLoc(); | 255 DebugLoc DL = I.Br->getDebugLoc(); |
253 const BasicBlock *BB = MBB->getBasicBlock(); | 256 const BasicBlock *BB = MBB->getBasicBlock(); |
254 MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB); | 257 MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB); |
255 MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB); | 258 MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB); |
256 | 259 const MipsSubtarget &Subtarget = |
260 static_cast<const MipsSubtarget &>(MF->getSubtarget()); | |
257 const MipsInstrInfo *TII = | 261 const MipsInstrInfo *TII = |
258 static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | 262 static_cast<const MipsInstrInfo *>(Subtarget.getInstrInfo()); |
259 | 263 |
260 MF->insert(FallThroughMBB, LongBrMBB); | 264 MF->insert(FallThroughMBB, LongBrMBB); |
261 MBB->removeSuccessor(TgtMBB); | 265 MBB->removeSuccessor(TgtMBB); |
262 MBB->addSuccessor(LongBrMBB); | 266 MBB->addSuccessor(LongBrMBB); |
263 | 267 |
268 BalTgtMBB->addSuccessor(TgtMBB); | 272 BalTgtMBB->addSuccessor(TgtMBB); |
269 | 273 |
270 // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal | 274 // We must select between the MIPS32r6/MIPS64r6 BAL (which is a normal |
271 // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an | 275 // instruction) and the pre-MIPS32r6/MIPS64r6 definition (which is an |
272 // pseudo-instruction wrapping BGEZAL). | 276 // pseudo-instruction wrapping BGEZAL). |
273 | |
274 const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); | |
275 unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR; | 277 unsigned BalOp = Subtarget.hasMips32r6() ? Mips::BAL : Mips::BAL_BR; |
276 | 278 |
277 if (ABI != MipsSubtarget::N64) { | 279 if (!ABI.IsN64()) { |
278 // $longbr: | 280 // $longbr: |
279 // addiu $sp, $sp, -8 | 281 // addiu $sp, $sp, -8 |
280 // sw $ra, 0($sp) | 282 // sw $ra, 0($sp) |
281 // lui $at, %hi($tgt - $baltgt) | 283 // lui $at, %hi($tgt - $baltgt) |
282 // bal $baltgt | 284 // bal $baltgt |
326 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) | 328 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) |
327 .addReg(Mips::RA).addReg(Mips::AT); | 329 .addReg(Mips::RA).addReg(Mips::AT); |
328 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) | 330 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) |
329 .addReg(Mips::SP).addImm(0); | 331 .addReg(Mips::SP).addImm(0); |
330 | 332 |
331 if (!TM.getSubtarget<MipsSubtarget>().isTargetNaCl()) { | 333 if (!Subtarget.isTargetNaCl()) { |
332 MIBundleBuilder(*BalTgtMBB, Pos) | 334 MIBundleBuilder(*BalTgtMBB, Pos) |
333 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) | 335 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) |
334 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) | 336 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) |
335 .addReg(Mips::SP).addImm(8)); | 337 .addReg(Mips::SP).addImm(8)); |
336 } else { | 338 } else { |
445 .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); | 447 .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); |
446 MBB.removeLiveIn(Mips::V0); | 448 MBB.removeLiveIn(Mips::V0); |
447 } | 449 } |
448 | 450 |
449 bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { | 451 bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { |
452 const MipsSubtarget &STI = | |
453 static_cast<const MipsSubtarget &>(F.getSubtarget()); | |
450 const MipsInstrInfo *TII = | 454 const MipsInstrInfo *TII = |
451 static_cast<const MipsInstrInfo *>(TM.getSubtargetImpl()->getInstrInfo()); | 455 static_cast<const MipsInstrInfo *>(STI.getInstrInfo()); |
452 | 456 LongBranchSeqSize = |
453 const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>(); | 457 !IsPIC ? 2 : (ABI.IsN64() ? 10 : (!STI.isTargetNaCl() ? 9 : 10)); |
458 | |
454 if (STI.inMips16Mode() || !STI.enableLongBranchPass()) | 459 if (STI.inMips16Mode() || !STI.enableLongBranchPass()) |
455 return false; | 460 return false; |
456 if ((TM.getRelocationModel() == Reloc::PIC_) && | 461 if ((TM.getRelocationModel() == Reloc::PIC_) && |
457 TM.getSubtarget<MipsSubtarget>().isABI_O32() && | 462 static_cast<const MipsTargetMachine &>(TM).getABI().IsO32() && |
458 F.getInfo<MipsFunctionInfo>()->globalBaseRegSet()) | 463 F.getInfo<MipsFunctionInfo>()->globalBaseRegSet()) |
459 emitGPDisp(F, TII); | 464 emitGPDisp(F, TII); |
460 | 465 |
461 if (SkipLongBranch) | 466 if (SkipLongBranch) |
462 return true; | 467 return true; |
474 // Skip if this MBB doesn't have a branch or the branch has already been | 479 // Skip if this MBB doesn't have a branch or the branch has already been |
475 // converted to a long branch. | 480 // converted to a long branch. |
476 if (!I->Br || I->HasLongBranch) | 481 if (!I->Br || I->HasLongBranch) |
477 continue; | 482 continue; |
478 | 483 |
479 int ShVal = TM.getSubtarget<MipsSubtarget>().inMicroMipsMode() ? 2 : 4; | 484 int ShVal = STI.inMicroMipsMode() ? 2 : 4; |
480 int64_t Offset = computeOffset(I->Br) / ShVal; | 485 int64_t Offset = computeOffset(I->Br) / ShVal; |
481 | 486 |
482 if (TM.getSubtarget<MipsSubtarget>().isTargetNaCl()) { | 487 if (STI.isTargetNaCl()) { |
483 // The offset calculation does not include sandboxing instructions | 488 // The offset calculation does not include sandboxing instructions |
484 // that will be added later in the MC layer. Since at this point we | 489 // that will be added later in the MC layer. Since at this point we |
485 // don't know the exact amount of code that "sandboxing" will add, we | 490 // don't know the exact amount of code that "sandboxing" will add, we |
486 // conservatively estimate that code will not grow more than 100%. | 491 // conservatively estimate that code will not grow more than 100%. |
487 Offset *= 2; | 492 Offset *= 2; |