LLVM API Documentation
00001 //===-- MipsLongBranch.cpp - Emit long branches ---------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass expands a branch or jump instruction into a long branch if its 00011 // offset is too large to fit into its immediate field. 00012 // 00013 // FIXME: 00014 // 1. Fix pc-region jump instructions which cross 256MB segment boundaries. 00015 // 2. If program has inline assembly statements whose size cannot be 00016 // determined accurately, load branch target addresses from the GOT. 00017 //===----------------------------------------------------------------------===// 00018 00019 #define DEBUG_TYPE "mips-long-branch" 00020 00021 #include "Mips.h" 00022 #include "MCTargetDesc/MipsBaseInfo.h" 00023 #include "MipsTargetMachine.h" 00024 #include "llvm/ADT/Statistic.h" 00025 #include "llvm/CodeGen/MachineFunctionPass.h" 00026 #include "llvm/CodeGen/MachineInstrBuilder.h" 00027 #include "llvm/IR/Function.h" 00028 #include "llvm/Support/CommandLine.h" 00029 #include "llvm/Support/MathExtras.h" 00030 #include "llvm/Target/TargetInstrInfo.h" 00031 #include "llvm/Target/TargetMachine.h" 00032 #include "llvm/Target/TargetRegisterInfo.h" 00033 00034 using namespace llvm; 00035 00036 STATISTIC(LongBranches, "Number of long branches."); 00037 00038 static cl::opt<bool> SkipLongBranch( 00039 "skip-mips-long-branch", 00040 cl::init(false), 00041 cl::desc("MIPS: Skip long branch pass."), 00042 cl::Hidden); 00043 00044 static cl::opt<bool> ForceLongBranch( 00045 "force-mips-long-branch", 00046 cl::init(false), 00047 cl::desc("MIPS: Expand all branches to long format."), 00048 cl::Hidden); 00049 00050 namespace { 00051 typedef MachineBasicBlock::iterator Iter; 00052 typedef MachineBasicBlock::reverse_iterator ReverseIter; 00053 00054 struct MBBInfo { 00055 uint64_t Size, Address; 00056 bool HasLongBranch; 00057 MachineInstr *Br; 00058 00059 MBBInfo() : Size(0), HasLongBranch(false), Br(0) {} 00060 }; 00061 00062 class MipsLongBranch : public MachineFunctionPass { 00063 00064 public: 00065 static char ID; 00066 MipsLongBranch(TargetMachine &tm) 00067 : MachineFunctionPass(ID), TM(tm), 00068 TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), 00069 IsPIC(TM.getRelocationModel() == Reloc::PIC_), 00070 ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), 00071 LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {} 00072 00073 virtual const char *getPassName() const { 00074 return "Mips Long Branch"; 00075 } 00076 00077 bool runOnMachineFunction(MachineFunction &F); 00078 00079 private: 00080 void splitMBB(MachineBasicBlock *MBB); 00081 void initMBBInfo(); 00082 int64_t computeOffset(const MachineInstr *Br); 00083 void replaceBranch(MachineBasicBlock &MBB, Iter Br, DebugLoc DL, 00084 MachineBasicBlock *MBBOpnd); 00085 void expandToLongBranch(MBBInfo &Info); 00086 00087 const TargetMachine &TM; 00088 const MipsInstrInfo *TII; 00089 MachineFunction *MF; 00090 SmallVector<MBBInfo, 16> MBBInfos; 00091 bool IsPIC; 00092 unsigned ABI; 00093 unsigned LongBranchSeqSize; 00094 }; 00095 00096 char MipsLongBranch::ID = 0; 00097 } // end of anonymous namespace 00098 00099 /// createMipsLongBranchPass - Returns a pass that converts branches to long 00100 /// branches. 00101 FunctionPass *llvm::createMipsLongBranchPass(MipsTargetMachine &tm) { 00102 return new MipsLongBranch(tm); 00103 } 00104 00105 /// Iterate over list of Br's operands and search for a MachineBasicBlock 00106 /// operand. 00107 static MachineBasicBlock *getTargetMBB(const MachineInstr &Br) { 00108 for (unsigned I = 0, E = Br.getDesc().getNumOperands(); I < E; ++I) { 00109 const MachineOperand &MO = Br.getOperand(I); 00110 00111 if (MO.isMBB()) 00112 return MO.getMBB(); 00113 } 00114 00115 assert(false && "This instruction does not have an MBB operand."); 00116 return 0; 00117 } 00118 00119 // Traverse the list of instructions backwards until a non-debug instruction is 00120 // found or it reaches E. 00121 static ReverseIter getNonDebugInstr(ReverseIter B, ReverseIter E) { 00122 for (; B != E; ++B) 00123 if (!B->isDebugValue()) 00124 return B; 00125 00126 return E; 00127 } 00128 00129 // Split MBB if it has two direct jumps/branches. 00130 void MipsLongBranch::splitMBB(MachineBasicBlock *MBB) { 00131 ReverseIter End = MBB->rend(); 00132 ReverseIter LastBr = getNonDebugInstr(MBB->rbegin(), End); 00133 00134 // Return if MBB has no branch instructions. 00135 if ((LastBr == End) || 00136 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch())) 00137 return; 00138 00139 ReverseIter FirstBr = getNonDebugInstr(llvm::next(LastBr), End); 00140 00141 // MBB has only one branch instruction if FirstBr is not a branch 00142 // instruction. 00143 if ((FirstBr == End) || 00144 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch())) 00145 return; 00146 00147 assert(!FirstBr->isIndirectBranch() && "Unexpected indirect branch found."); 00148 00149 // Create a new MBB. Move instructions in MBB to the newly created MBB. 00150 MachineBasicBlock *NewMBB = 00151 MF->CreateMachineBasicBlock(MBB->getBasicBlock()); 00152 00153 // Insert NewMBB and fix control flow. 00154 MachineBasicBlock *Tgt = getTargetMBB(*FirstBr); 00155 NewMBB->transferSuccessors(MBB); 00156 NewMBB->removeSuccessor(Tgt); 00157 MBB->addSuccessor(NewMBB); 00158 MBB->addSuccessor(Tgt); 00159 MF->insert(llvm::next(MachineFunction::iterator(MBB)), NewMBB); 00160 00161 NewMBB->splice(NewMBB->end(), MBB, (++LastBr).base(), MBB->end()); 00162 } 00163 00164 // Fill MBBInfos. 00165 void MipsLongBranch::initMBBInfo() { 00166 // Split the MBBs if they have two branches. Each basic block should have at 00167 // most one branch after this loop is executed. 00168 for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E;) 00169 splitMBB(I++); 00170 00171 MF->RenumberBlocks(); 00172 MBBInfos.clear(); 00173 MBBInfos.resize(MF->size()); 00174 00175 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) { 00176 MachineBasicBlock *MBB = MF->getBlockNumbered(I); 00177 00178 // Compute size of MBB. 00179 for (MachineBasicBlock::instr_iterator MI = MBB->instr_begin(); 00180 MI != MBB->instr_end(); ++MI) 00181 MBBInfos[I].Size += TII->GetInstSizeInBytes(&*MI); 00182 00183 // Search for MBB's branch instruction. 00184 ReverseIter End = MBB->rend(); 00185 ReverseIter Br = getNonDebugInstr(MBB->rbegin(), End); 00186 00187 if ((Br != End) && !Br->isIndirectBranch() && 00188 (Br->isConditionalBranch() || 00189 (Br->isUnconditionalBranch() && 00190 TM.getRelocationModel() == Reloc::PIC_))) 00191 MBBInfos[I].Br = (++Br).base(); 00192 } 00193 } 00194 00195 // Compute offset of branch in number of bytes. 00196 int64_t MipsLongBranch::computeOffset(const MachineInstr *Br) { 00197 int64_t Offset = 0; 00198 int ThisMBB = Br->getParent()->getNumber(); 00199 int TargetMBB = getTargetMBB(*Br)->getNumber(); 00200 00201 // Compute offset of a forward branch. 00202 if (ThisMBB < TargetMBB) { 00203 for (int N = ThisMBB + 1; N < TargetMBB; ++N) 00204 Offset += MBBInfos[N].Size; 00205 00206 return Offset + 4; 00207 } 00208 00209 // Compute offset of a backward branch. 00210 for (int N = ThisMBB; N >= TargetMBB; --N) 00211 Offset += MBBInfos[N].Size; 00212 00213 return -Offset + 4; 00214 } 00215 00216 // Replace Br with a branch which has the opposite condition code and a 00217 // MachineBasicBlock operand MBBOpnd. 00218 void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br, 00219 DebugLoc DL, MachineBasicBlock *MBBOpnd) { 00220 unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode()); 00221 const MCInstrDesc &NewDesc = TII->get(NewOpc); 00222 00223 MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc); 00224 00225 for (unsigned I = 0, E = Br->getDesc().getNumOperands(); I < E; ++I) { 00226 MachineOperand &MO = Br->getOperand(I); 00227 00228 if (!MO.isReg()) { 00229 assert(MO.isMBB() && "MBB operand expected."); 00230 break; 00231 } 00232 00233 MIB.addReg(MO.getReg()); 00234 } 00235 00236 MIB.addMBB(MBBOpnd); 00237 00238 Br->eraseFromParent(); 00239 } 00240 00241 // Expand branch instructions to long branches. 00242 void MipsLongBranch::expandToLongBranch(MBBInfo &I) { 00243 MachineBasicBlock::iterator Pos; 00244 MachineBasicBlock *MBB = I.Br->getParent(), *TgtMBB = getTargetMBB(*I.Br); 00245 DebugLoc DL = I.Br->getDebugLoc(); 00246 const BasicBlock *BB = MBB->getBasicBlock(); 00247 MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB); 00248 MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB); 00249 00250 MF->insert(FallThroughMBB, LongBrMBB); 00251 MBB->removeSuccessor(TgtMBB); 00252 MBB->addSuccessor(LongBrMBB); 00253 00254 if (IsPIC) { 00255 MachineBasicBlock *BalTgtMBB = MF->CreateMachineBasicBlock(BB); 00256 MF->insert(FallThroughMBB, BalTgtMBB); 00257 LongBrMBB->addSuccessor(BalTgtMBB); 00258 BalTgtMBB->addSuccessor(TgtMBB); 00259 00260 int64_t TgtAddress = MBBInfos[TgtMBB->getNumber()].Address; 00261 unsigned BalTgtMBBSize = 5; 00262 int64_t Offset = TgtAddress - (I.Address + I.Size - BalTgtMBBSize * 4); 00263 int64_t Lo = SignExtend64<16>(Offset & 0xffff); 00264 int64_t Hi = SignExtend64<16>(((Offset + 0x8000) >> 16) & 0xffff); 00265 00266 if (ABI != MipsSubtarget::N64) { 00267 // $longbr: 00268 // addiu $sp, $sp, -8 00269 // sw $ra, 0($sp) 00270 // bal $baltgt 00271 // lui $at, %hi($tgt - $baltgt) 00272 // $baltgt: 00273 // addiu $at, $at, %lo($tgt - $baltgt) 00274 // addu $at, $ra, $at 00275 // lw $ra, 0($sp) 00276 // jr $at 00277 // addiu $sp, $sp, 8 00278 // $fallthrough: 00279 // 00280 00281 Pos = LongBrMBB->begin(); 00282 00283 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP) 00284 .addReg(Mips::SP).addImm(-8); 00285 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW)).addReg(Mips::RA) 00286 .addReg(Mips::SP).addImm(0); 00287 00288 MIBundleBuilder(*LongBrMBB, Pos) 00289 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) 00290 .append(BuildMI(*MF, DL, TII->get(Mips::LUi), Mips::AT).addImm(Hi)); 00291 00292 Pos = BalTgtMBB->begin(); 00293 00294 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::AT) 00295 .addReg(Mips::AT).addImm(Lo); 00296 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT) 00297 .addReg(Mips::RA).addReg(Mips::AT); 00298 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA) 00299 .addReg(Mips::SP).addImm(0); 00300 00301 MIBundleBuilder(*BalTgtMBB, Pos) 00302 .append(BuildMI(*MF, DL, TII->get(Mips::JR)).addReg(Mips::AT)) 00303 .append(BuildMI(*MF, DL, TII->get(Mips::ADDiu), Mips::SP) 00304 .addReg(Mips::SP).addImm(8)); 00305 } else { 00306 // $longbr: 00307 // daddiu $sp, $sp, -16 00308 // sd $ra, 0($sp) 00309 // lui64 $at, %highest($tgt - $baltgt) 00310 // daddiu $at, $at, %higher($tgt - $baltgt) 00311 // dsll $at, $at, 16 00312 // daddiu $at, $at, %hi($tgt - $baltgt) 00313 // bal $baltgt 00314 // dsll $at, $at, 16 00315 // $baltgt: 00316 // daddiu $at, $at, %lo($tgt - $baltgt) 00317 // daddu $at, $ra, $at 00318 // ld $ra, 0($sp) 00319 // jr64 $at 00320 // daddiu $sp, $sp, 16 00321 // $fallthrough: 00322 // 00323 00324 int64_t Higher = SignExtend64<16>(((Offset + 0x80008000) >> 32) & 0xffff); 00325 int64_t Highest = 00326 SignExtend64<16>(((Offset + 0x800080008000LL) >> 48) & 0xffff); 00327 00328 Pos = LongBrMBB->begin(); 00329 00330 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64) 00331 .addReg(Mips::SP_64).addImm(-16); 00332 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD)).addReg(Mips::RA_64) 00333 .addReg(Mips::SP_64).addImm(0); 00334 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LUi64), Mips::AT_64) 00335 .addImm(Highest); 00336 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64) 00337 .addReg(Mips::AT_64).addImm(Higher); 00338 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64) 00339 .addReg(Mips::AT_64).addImm(16); 00340 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64) 00341 .addReg(Mips::AT_64).addImm(Hi); 00342 00343 MIBundleBuilder(*LongBrMBB, Pos) 00344 .append(BuildMI(*MF, DL, TII->get(Mips::BAL_BR)).addMBB(BalTgtMBB)) 00345 .append(BuildMI(*MF, DL, TII->get(Mips::DSLL), Mips::AT_64) 00346 .addReg(Mips::AT_64).addImm(16)); 00347 00348 Pos = BalTgtMBB->begin(); 00349 00350 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::AT_64) 00351 .addReg(Mips::AT_64).addImm(Lo); 00352 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64) 00353 .addReg(Mips::RA_64).addReg(Mips::AT_64); 00354 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64) 00355 .addReg(Mips::SP_64).addImm(0); 00356 00357 MIBundleBuilder(*BalTgtMBB, Pos) 00358 .append(BuildMI(*MF, DL, TII->get(Mips::JR64)).addReg(Mips::AT_64)) 00359 .append(BuildMI(*MF, DL, TII->get(Mips::DADDiu), Mips::SP_64) 00360 .addReg(Mips::SP_64).addImm(16)); 00361 } 00362 00363 assert(BalTgtMBBSize == BalTgtMBB->size()); 00364 assert(LongBrMBB->size() + BalTgtMBBSize == LongBranchSeqSize); 00365 } else { 00366 // $longbr: 00367 // j $tgt 00368 // nop 00369 // $fallthrough: 00370 // 00371 Pos = LongBrMBB->begin(); 00372 LongBrMBB->addSuccessor(TgtMBB); 00373 MIBundleBuilder(*LongBrMBB, Pos) 00374 .append(BuildMI(*MF, DL, TII->get(Mips::J)).addMBB(TgtMBB)) 00375 .append(BuildMI(*MF, DL, TII->get(Mips::NOP))); 00376 00377 assert(LongBrMBB->size() == LongBranchSeqSize); 00378 } 00379 00380 if (I.Br->isUnconditionalBranch()) { 00381 // Change branch destination. 00382 assert(I.Br->getDesc().getNumOperands() == 1); 00383 I.Br->RemoveOperand(0); 00384 I.Br->addOperand(MachineOperand::CreateMBB(LongBrMBB)); 00385 } else 00386 // Change branch destination and reverse condition. 00387 replaceBranch(*MBB, I.Br, DL, FallThroughMBB); 00388 } 00389 00390 static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) { 00391 MachineBasicBlock &MBB = F.front(); 00392 MachineBasicBlock::iterator I = MBB.begin(); 00393 DebugLoc DL = MBB.findDebugLoc(MBB.begin()); 00394 BuildMI(MBB, I, DL, TII->get(Mips::LUi), Mips::V0) 00395 .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); 00396 BuildMI(MBB, I, DL, TII->get(Mips::ADDiu), Mips::V0) 00397 .addReg(Mips::V0).addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); 00398 MBB.removeLiveIn(Mips::V0); 00399 } 00400 00401 bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { 00402 if (TM.getSubtarget<MipsSubtarget>().inMips16Mode()) 00403 return false; 00404 if ((TM.getRelocationModel() == Reloc::PIC_) && 00405 TM.getSubtarget<MipsSubtarget>().isABI_O32() && 00406 F.getInfo<MipsFunctionInfo>()->globalBaseRegSet()) 00407 emitGPDisp(F, TII); 00408 00409 if (SkipLongBranch) 00410 return true; 00411 00412 MF = &F; 00413 initMBBInfo(); 00414 00415 SmallVector<MBBInfo, 16>::iterator I, E = MBBInfos.end(); 00416 bool EverMadeChange = false, MadeChange = true; 00417 00418 while (MadeChange) { 00419 MadeChange = false; 00420 00421 for (I = MBBInfos.begin(); I != E; ++I) { 00422 // Skip if this MBB doesn't have a branch or the branch has already been 00423 // converted to a long branch. 00424 if (!I->Br || I->HasLongBranch) 00425 continue; 00426 00427 // Check if offset fits into 16-bit immediate field of branches. 00428 if (!ForceLongBranch && isInt<16>(computeOffset(I->Br) / 4)) 00429 continue; 00430 00431 I->HasLongBranch = true; 00432 I->Size += LongBranchSeqSize * 4; 00433 ++LongBranches; 00434 EverMadeChange = MadeChange = true; 00435 } 00436 } 00437 00438 if (!EverMadeChange) 00439 return true; 00440 00441 // Compute basic block addresses. 00442 if (TM.getRelocationModel() == Reloc::PIC_) { 00443 uint64_t Address = 0; 00444 00445 for (I = MBBInfos.begin(); I != E; Address += I->Size, ++I) 00446 I->Address = Address; 00447 } 00448 00449 // Do the expansion. 00450 for (I = MBBInfos.begin(); I != E; ++I) 00451 if (I->HasLongBranch) 00452 expandToLongBranch(*I); 00453 00454 MF->RenumberBlocks(); 00455 00456 return true; 00457 }