LLVM API Documentation
00001 //===-- DelaySlotFiller.cpp - SPARC delay slot filler ---------------------===// 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 is a simple local pass that attempts to fill delay slots with useful 00011 // instructions. If no instructions can be moved into the delay slot, then a 00012 // NOP is placed. 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "Sparc.h" 00016 #include "SparcSubtarget.h" 00017 #include "llvm/ADT/SmallSet.h" 00018 #include "llvm/ADT/Statistic.h" 00019 #include "llvm/CodeGen/MachineFunctionPass.h" 00020 #include "llvm/CodeGen/MachineInstrBuilder.h" 00021 #include "llvm/CodeGen/MachineRegisterInfo.h" 00022 #include "llvm/Support/CommandLine.h" 00023 #include "llvm/Target/TargetInstrInfo.h" 00024 #include "llvm/Target/TargetMachine.h" 00025 #include "llvm/Target/TargetRegisterInfo.h" 00026 00027 using namespace llvm; 00028 00029 #define DEBUG_TYPE "delay-slot-filler" 00030 00031 STATISTIC(FilledSlots, "Number of delay slots filled"); 00032 00033 static cl::opt<bool> DisableDelaySlotFiller( 00034 "disable-sparc-delay-filler", 00035 cl::init(false), 00036 cl::desc("Disable the Sparc delay slot filler."), 00037 cl::Hidden); 00038 00039 namespace { 00040 struct Filler : public MachineFunctionPass { 00041 /// Target machine description which we query for reg. names, data 00042 /// layout, etc. 00043 /// 00044 TargetMachine &TM; 00045 const SparcSubtarget *Subtarget; 00046 00047 static char ID; 00048 Filler(TargetMachine &tm) 00049 : MachineFunctionPass(ID), TM(tm), 00050 Subtarget(&TM.getSubtarget<SparcSubtarget>()) { 00051 } 00052 00053 const char *getPassName() const override { 00054 return "SPARC Delay Slot Filler"; 00055 } 00056 00057 bool runOnMachineBasicBlock(MachineBasicBlock &MBB); 00058 bool runOnMachineFunction(MachineFunction &F) override { 00059 bool Changed = false; 00060 00061 // This pass invalidates liveness information when it reorders 00062 // instructions to fill delay slot. 00063 F.getRegInfo().invalidateLiveness(); 00064 00065 for (MachineFunction::iterator FI = F.begin(), FE = F.end(); 00066 FI != FE; ++FI) 00067 Changed |= runOnMachineBasicBlock(*FI); 00068 return Changed; 00069 } 00070 00071 void insertCallDefsUses(MachineBasicBlock::iterator MI, 00072 SmallSet<unsigned, 32>& RegDefs, 00073 SmallSet<unsigned, 32>& RegUses); 00074 00075 void insertDefsUses(MachineBasicBlock::iterator MI, 00076 SmallSet<unsigned, 32>& RegDefs, 00077 SmallSet<unsigned, 32>& RegUses); 00078 00079 bool IsRegInSet(SmallSet<unsigned, 32>& RegSet, 00080 unsigned Reg); 00081 00082 bool delayHasHazard(MachineBasicBlock::iterator candidate, 00083 bool &sawLoad, bool &sawStore, 00084 SmallSet<unsigned, 32> &RegDefs, 00085 SmallSet<unsigned, 32> &RegUses); 00086 00087 MachineBasicBlock::iterator 00088 findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot); 00089 00090 bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize); 00091 00092 bool tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB, 00093 MachineBasicBlock::iterator MBBI); 00094 00095 }; 00096 char Filler::ID = 0; 00097 } // end of anonymous namespace 00098 00099 /// createSparcDelaySlotFillerPass - Returns a pass that fills in delay 00100 /// slots in Sparc MachineFunctions 00101 /// 00102 FunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) { 00103 return new Filler(tm); 00104 } 00105 00106 00107 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block. 00108 /// We assume there is only one delay slot per delayed instruction. 00109 /// 00110 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { 00111 bool Changed = false; 00112 00113 const TargetInstrInfo *TII = TM.getSubtargetImpl()->getInstrInfo(); 00114 00115 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) { 00116 MachineBasicBlock::iterator MI = I; 00117 ++I; 00118 00119 // If MI is restore, try combining it with previous inst. 00120 if (!DisableDelaySlotFiller && 00121 (MI->getOpcode() == SP::RESTORErr 00122 || MI->getOpcode() == SP::RESTOREri)) { 00123 Changed |= tryCombineRestoreWithPrevInst(MBB, MI); 00124 continue; 00125 } 00126 00127 if (!Subtarget->isV9() && 00128 (MI->getOpcode() == SP::FCMPS || MI->getOpcode() == SP::FCMPD 00129 || MI->getOpcode() == SP::FCMPQ)) { 00130 BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP)); 00131 Changed = true; 00132 continue; 00133 } 00134 00135 // If MI has no delay slot, skip. 00136 if (!MI->hasDelaySlot()) 00137 continue; 00138 00139 MachineBasicBlock::iterator D = MBB.end(); 00140 00141 if (!DisableDelaySlotFiller) 00142 D = findDelayInstr(MBB, MI); 00143 00144 ++FilledSlots; 00145 Changed = true; 00146 00147 if (D == MBB.end()) 00148 BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP)); 00149 else 00150 MBB.splice(I, &MBB, D); 00151 00152 unsigned structSize = 0; 00153 if (needsUnimp(MI, structSize)) { 00154 MachineBasicBlock::iterator J = MI; 00155 ++J; // skip the delay filler. 00156 assert (J != MBB.end() && "MI needs a delay instruction."); 00157 BuildMI(MBB, ++J, MI->getDebugLoc(), 00158 TII->get(SP::UNIMP)).addImm(structSize); 00159 // Bundle the delay filler and unimp with the instruction. 00160 MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J); 00161 } else { 00162 MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I); 00163 } 00164 } 00165 return Changed; 00166 } 00167 00168 MachineBasicBlock::iterator 00169 Filler::findDelayInstr(MachineBasicBlock &MBB, 00170 MachineBasicBlock::iterator slot) 00171 { 00172 SmallSet<unsigned, 32> RegDefs; 00173 SmallSet<unsigned, 32> RegUses; 00174 bool sawLoad = false; 00175 bool sawStore = false; 00176 00177 if (slot == MBB.begin()) 00178 return MBB.end(); 00179 00180 if (slot->getOpcode() == SP::RET || slot->getOpcode() == SP::TLS_CALL) 00181 return MBB.end(); 00182 00183 if (slot->getOpcode() == SP::RETL) { 00184 MachineBasicBlock::iterator J = slot; 00185 --J; 00186 00187 if (J->getOpcode() == SP::RESTORErr 00188 || J->getOpcode() == SP::RESTOREri) { 00189 // change retl to ret. 00190 slot->setDesc(TM.getSubtargetImpl()->getInstrInfo()->get(SP::RET)); 00191 return J; 00192 } 00193 } 00194 00195 // Call's delay filler can def some of call's uses. 00196 if (slot->isCall()) 00197 insertCallDefsUses(slot, RegDefs, RegUses); 00198 else 00199 insertDefsUses(slot, RegDefs, RegUses); 00200 00201 bool done = false; 00202 00203 MachineBasicBlock::iterator I = slot; 00204 00205 while (!done) { 00206 done = (I == MBB.begin()); 00207 00208 if (!done) 00209 --I; 00210 00211 // skip debug value 00212 if (I->isDebugValue()) 00213 continue; 00214 00215 if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() || 00216 I->hasDelaySlot() || I->isBundledWithSucc()) 00217 break; 00218 00219 if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) { 00220 insertDefsUses(I, RegDefs, RegUses); 00221 continue; 00222 } 00223 00224 return I; 00225 } 00226 return MBB.end(); 00227 } 00228 00229 bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate, 00230 bool &sawLoad, 00231 bool &sawStore, 00232 SmallSet<unsigned, 32> &RegDefs, 00233 SmallSet<unsigned, 32> &RegUses) 00234 { 00235 00236 if (candidate->isImplicitDef() || candidate->isKill()) 00237 return true; 00238 00239 if (candidate->mayLoad()) { 00240 sawLoad = true; 00241 if (sawStore) 00242 return true; 00243 } 00244 00245 if (candidate->mayStore()) { 00246 if (sawStore) 00247 return true; 00248 sawStore = true; 00249 if (sawLoad) 00250 return true; 00251 } 00252 00253 for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) { 00254 const MachineOperand &MO = candidate->getOperand(i); 00255 if (!MO.isReg()) 00256 continue; // skip 00257 00258 unsigned Reg = MO.getReg(); 00259 00260 if (MO.isDef()) { 00261 // check whether Reg is defined or used before delay slot. 00262 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg)) 00263 return true; 00264 } 00265 if (MO.isUse()) { 00266 // check whether Reg is defined before delay slot. 00267 if (IsRegInSet(RegDefs, Reg)) 00268 return true; 00269 } 00270 } 00271 return false; 00272 } 00273 00274 00275 void Filler::insertCallDefsUses(MachineBasicBlock::iterator MI, 00276 SmallSet<unsigned, 32>& RegDefs, 00277 SmallSet<unsigned, 32>& RegUses) 00278 { 00279 // Call defines o7, which is visible to the instruction in delay slot. 00280 RegDefs.insert(SP::O7); 00281 00282 switch(MI->getOpcode()) { 00283 default: llvm_unreachable("Unknown opcode."); 00284 case SP::CALL: break; 00285 case SP::CALLrr: 00286 case SP::CALLri: 00287 assert(MI->getNumOperands() >= 2); 00288 const MachineOperand &Reg = MI->getOperand(0); 00289 assert(Reg.isReg() && "CALL first operand is not a register."); 00290 assert(Reg.isUse() && "CALL first operand is not a use."); 00291 RegUses.insert(Reg.getReg()); 00292 00293 const MachineOperand &RegOrImm = MI->getOperand(1); 00294 if (RegOrImm.isImm()) 00295 break; 00296 assert(RegOrImm.isReg() && "CALLrr second operand is not a register."); 00297 assert(RegOrImm.isUse() && "CALLrr second operand is not a use."); 00298 RegUses.insert(RegOrImm.getReg()); 00299 break; 00300 } 00301 } 00302 00303 // Insert Defs and Uses of MI into the sets RegDefs and RegUses. 00304 void Filler::insertDefsUses(MachineBasicBlock::iterator MI, 00305 SmallSet<unsigned, 32>& RegDefs, 00306 SmallSet<unsigned, 32>& RegUses) 00307 { 00308 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 00309 const MachineOperand &MO = MI->getOperand(i); 00310 if (!MO.isReg()) 00311 continue; 00312 00313 unsigned Reg = MO.getReg(); 00314 if (Reg == 0) 00315 continue; 00316 if (MO.isDef()) 00317 RegDefs.insert(Reg); 00318 if (MO.isUse()) { 00319 // Implicit register uses of retl are return values and 00320 // retl does not use them. 00321 if (MO.isImplicit() && MI->getOpcode() == SP::RETL) 00322 continue; 00323 RegUses.insert(Reg); 00324 } 00325 } 00326 } 00327 00328 // returns true if the Reg or its alias is in the RegSet. 00329 bool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg) 00330 { 00331 // Check Reg and all aliased Registers. 00332 for (MCRegAliasIterator AI(Reg, TM.getSubtargetImpl()->getRegisterInfo(), 00333 true); 00334 AI.isValid(); ++AI) 00335 if (RegSet.count(*AI)) 00336 return true; 00337 return false; 00338 } 00339 00340 bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize) 00341 { 00342 if (!I->isCall()) 00343 return false; 00344 00345 unsigned structSizeOpNum = 0; 00346 switch (I->getOpcode()) { 00347 default: llvm_unreachable("Unknown call opcode."); 00348 case SP::CALL: structSizeOpNum = 1; break; 00349 case SP::CALLrr: 00350 case SP::CALLri: structSizeOpNum = 2; break; 00351 case SP::TLS_CALL: return false; 00352 } 00353 00354 const MachineOperand &MO = I->getOperand(structSizeOpNum); 00355 if (!MO.isImm()) 00356 return false; 00357 StructSize = MO.getImm(); 00358 return true; 00359 } 00360 00361 static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI, 00362 MachineBasicBlock::iterator AddMI, 00363 const TargetInstrInfo *TII) 00364 { 00365 // Before: add <op0>, <op1>, %i[0-7] 00366 // restore %g0, %g0, %i[0-7] 00367 // 00368 // After : restore <op0>, <op1>, %o[0-7] 00369 00370 unsigned reg = AddMI->getOperand(0).getReg(); 00371 if (reg < SP::I0 || reg > SP::I7) 00372 return false; 00373 00374 // Erase RESTORE. 00375 RestoreMI->eraseFromParent(); 00376 00377 // Change ADD to RESTORE. 00378 AddMI->setDesc(TII->get((AddMI->getOpcode() == SP::ADDrr) 00379 ? SP::RESTORErr 00380 : SP::RESTOREri)); 00381 00382 // Map the destination register. 00383 AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); 00384 00385 return true; 00386 } 00387 00388 static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI, 00389 MachineBasicBlock::iterator OrMI, 00390 const TargetInstrInfo *TII) 00391 { 00392 // Before: or <op0>, <op1>, %i[0-7] 00393 // restore %g0, %g0, %i[0-7] 00394 // and <op0> or <op1> is zero, 00395 // 00396 // After : restore <op0>, <op1>, %o[0-7] 00397 00398 unsigned reg = OrMI->getOperand(0).getReg(); 00399 if (reg < SP::I0 || reg > SP::I7) 00400 return false; 00401 00402 // check whether it is a copy. 00403 if (OrMI->getOpcode() == SP::ORrr 00404 && OrMI->getOperand(1).getReg() != SP::G0 00405 && OrMI->getOperand(2).getReg() != SP::G0) 00406 return false; 00407 00408 if (OrMI->getOpcode() == SP::ORri 00409 && OrMI->getOperand(1).getReg() != SP::G0 00410 && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0)) 00411 return false; 00412 00413 // Erase RESTORE. 00414 RestoreMI->eraseFromParent(); 00415 00416 // Change OR to RESTORE. 00417 OrMI->setDesc(TII->get((OrMI->getOpcode() == SP::ORrr) 00418 ? SP::RESTORErr 00419 : SP::RESTOREri)); 00420 00421 // Map the destination register. 00422 OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); 00423 00424 return true; 00425 } 00426 00427 static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI, 00428 MachineBasicBlock::iterator SetHiMI, 00429 const TargetInstrInfo *TII) 00430 { 00431 // Before: sethi imm3, %i[0-7] 00432 // restore %g0, %g0, %g0 00433 // 00434 // After : restore %g0, (imm3<<10), %o[0-7] 00435 00436 unsigned reg = SetHiMI->getOperand(0).getReg(); 00437 if (reg < SP::I0 || reg > SP::I7) 00438 return false; 00439 00440 if (!SetHiMI->getOperand(1).isImm()) 00441 return false; 00442 00443 int64_t imm = SetHiMI->getOperand(1).getImm(); 00444 00445 // Is it a 3 bit immediate? 00446 if (!isInt<3>(imm)) 00447 return false; 00448 00449 // Make it a 13 bit immediate. 00450 imm = (imm << 10) & 0x1FFF; 00451 00452 assert(RestoreMI->getOpcode() == SP::RESTORErr); 00453 00454 RestoreMI->setDesc(TII->get(SP::RESTOREri)); 00455 00456 RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); 00457 RestoreMI->getOperand(1).setReg(SP::G0); 00458 RestoreMI->getOperand(2).ChangeToImmediate(imm); 00459 00460 00461 // Erase the original SETHI. 00462 SetHiMI->eraseFromParent(); 00463 00464 return true; 00465 } 00466 00467 bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB, 00468 MachineBasicBlock::iterator MBBI) 00469 { 00470 // No previous instruction. 00471 if (MBBI == MBB.begin()) 00472 return false; 00473 00474 // assert that MBBI is a "restore %g0, %g0, %g0". 00475 assert(MBBI->getOpcode() == SP::RESTORErr 00476 && MBBI->getOperand(0).getReg() == SP::G0 00477 && MBBI->getOperand(1).getReg() == SP::G0 00478 && MBBI->getOperand(2).getReg() == SP::G0); 00479 00480 MachineBasicBlock::iterator PrevInst = std::prev(MBBI); 00481 00482 // It cannot be combined with a bundled instruction. 00483 if (PrevInst->isBundledWithSucc()) 00484 return false; 00485 00486 const TargetInstrInfo *TII = TM.getSubtargetImpl()->getInstrInfo(); 00487 00488 switch (PrevInst->getOpcode()) { 00489 default: break; 00490 case SP::ADDrr: 00491 case SP::ADDri: return combineRestoreADD(MBBI, PrevInst, TII); break; 00492 case SP::ORrr: 00493 case SP::ORri: return combineRestoreOR(MBBI, PrevInst, TII); break; 00494 case SP::SETHIi: return combineRestoreSETHIi(MBBI, PrevInst, TII); break; 00495 } 00496 // It cannot combine with the previous instruction. 00497 return false; 00498 }