1 //===-- DelaySlotFiller.cpp - Mips Delay Slot Filler ----------------------===// 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 // Simple pass to fills delay slots with useful instructions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "delay-slot-filler" 15 16 #include "Mips.h" 17 #include "MipsTargetMachine.h" 18 #include "llvm/ADT/SmallSet.h" 19 #include "llvm/ADT/Statistic.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 #include "llvm/Support/CommandLine.h" 23 #include "llvm/Target/TargetInstrInfo.h" 24 #include "llvm/Target/TargetMachine.h" 25 #include "llvm/Target/TargetRegisterInfo.h" 26 27 using namespace llvm; 28 29 STATISTIC(FilledSlots, "Number of delay slots filled"); 30 STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that" 31 " are not NOP."); 32 33 static cl::opt<bool> DisableDelaySlotFiller( 34 "disable-mips-delay-filler", 35 cl::init(false), 36 cl::desc("Disable the delay slot filler, which attempts to fill the Mips" 37 "delay slots with useful instructions."), 38 cl::Hidden); 39 40 // This option can be used to silence complaints by machine verifier passes. 41 static cl::opt<bool> SkipDelaySlotFiller( 42 "skip-mips-delay-filler", 43 cl::init(false), 44 cl::desc("Skip MIPS' delay slot filling pass."), 45 cl::Hidden); 46 47 namespace { 48 class Filler : public MachineFunctionPass { 49 public: 50 Filler(TargetMachine &tm) 51 : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { } 52 53 virtual const char *getPassName() const { 54 return "Mips Delay Slot Filler"; 55 } 56 57 bool runOnMachineFunction(MachineFunction &F) { 58 if (SkipDelaySlotFiller) 59 return false; 60 61 bool Changed = false; 62 for (MachineFunction::iterator FI = F.begin(), FE = F.end(); 63 FI != FE; ++FI) 64 Changed |= runOnMachineBasicBlock(*FI); 65 return Changed; 66 } 67 68 private: 69 typedef MachineBasicBlock::instr_iterator InstrIter; 70 typedef MachineBasicBlock::reverse_instr_iterator ReverseInstrIter; 71 72 bool runOnMachineBasicBlock(MachineBasicBlock &MBB); 73 74 bool isDelayFiller(MachineBasicBlock &MBB, 75 InstrIter candidate); 76 77 void insertCallUses(InstrIter MI, 78 SmallSet<unsigned, 32> &RegDefs, 79 SmallSet<unsigned, 32> &RegUses); 80 81 void insertDefsUses(InstrIter MI, 82 SmallSet<unsigned, 32> &RegDefs, 83 SmallSet<unsigned, 32> &RegUses); 84 85 bool IsRegInSet(SmallSet<unsigned, 32> &RegSet, 86 unsigned Reg); 87 88 bool delayHasHazard(InstrIter candidate, 89 bool &sawLoad, bool &sawStore, 90 SmallSet<unsigned, 32> &RegDefs, 91 SmallSet<unsigned, 32> &RegUses); 92 93 bool 94 findDelayInstr(MachineBasicBlock &MBB, InstrIter slot, 95 InstrIter &Filler); 96 97 TargetMachine &TM; 98 const TargetInstrInfo *TII; 99 InstrIter LastFiller; 100 101 static char ID; 102 }; 103 char Filler::ID = 0; 104 } // end of anonymous namespace 105 106 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block. 107 /// We assume there is only one delay slot per delayed instruction. 108 bool Filler:: 109 runOnMachineBasicBlock(MachineBasicBlock &MBB) { 110 bool Changed = false; 111 LastFiller = MBB.instr_end(); 112 113 for (InstrIter I = MBB.instr_begin(); I != MBB.instr_end(); ++I) { 114 if (!I->hasDelaySlot()) 115 continue; 116 117 ++FilledSlots; 118 Changed = true; 119 InstrIter InstrWithSlot = I; 120 InstrIter D; 121 122 // Delay slot filling is disabled at -O0. 123 if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None) && 124 findDelayInstr(MBB, I, D)) { 125 MBB.splice(llvm::next(I), &MBB, D); 126 ++UsefulSlots; 127 } else 128 BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); 129 130 // Record the filler instruction that filled the delay slot. 131 // The instruction after it will be visited in the next iteration. 132 LastFiller = ++I; 133 134 // Bundle the delay slot filler to InstrWithSlot so that the machine 135 // verifier doesn't expect this instruction to be a terminator. 136 MIBundleBuilder(MBB, InstrWithSlot, llvm::next(LastFiller)); 137 } 138 139 return Changed; 140 } 141 142 /// createMipsDelaySlotFillerPass - Returns a pass that fills in delay 143 /// slots in Mips MachineFunctions 144 FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) { 145 return new Filler(tm); 146 } 147 148 bool Filler::findDelayInstr(MachineBasicBlock &MBB, 149 InstrIter slot, 150 InstrIter &Filler) { 151 SmallSet<unsigned, 32> RegDefs; 152 SmallSet<unsigned, 32> RegUses; 153 154 insertDefsUses(slot, RegDefs, RegUses); 155 156 bool sawLoad = false; 157 bool sawStore = false; 158 159 for (ReverseInstrIter I(slot); I != MBB.instr_rend(); ++I) { 160 // skip debug value 161 if (I->isDebugValue()) 162 continue; 163 164 // Convert to forward iterator. 165 InstrIter FI(llvm::next(I).base()); 166 167 if (I->hasUnmodeledSideEffects() 168 || I->isInlineAsm() 169 || I->isLabel() 170 || FI == LastFiller 171 || I->isPseudo() 172 // 173 // Should not allow: 174 // ERET, DERET or WAIT, PAUSE. Need to add these to instruction 175 // list. TBD. 176 ) 177 break; 178 179 if (delayHasHazard(FI, sawLoad, sawStore, RegDefs, RegUses)) { 180 insertDefsUses(FI, RegDefs, RegUses); 181 continue; 182 } 183 184 Filler = FI; 185 return true; 186 } 187 188 return false; 189 } 190 191 bool Filler::delayHasHazard(InstrIter candidate, 192 bool &sawLoad, bool &sawStore, 193 SmallSet<unsigned, 32> &RegDefs, 194 SmallSet<unsigned, 32> &RegUses) { 195 if (candidate->isImplicitDef() || candidate->isKill()) 196 return true; 197 198 // Loads or stores cannot be moved past a store to the delay slot 199 // and stores cannot be moved past a load. 200 if (candidate->mayLoad()) { 201 if (sawStore) 202 return true; 203 sawLoad = true; 204 } 205 206 if (candidate->mayStore()) { 207 if (sawStore) 208 return true; 209 sawStore = true; 210 if (sawLoad) 211 return true; 212 } 213 214 assert((!candidate->isCall() && !candidate->isReturn()) && 215 "Cannot put calls or returns in delay slot."); 216 217 for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) { 218 const MachineOperand &MO = candidate->getOperand(i); 219 unsigned Reg; 220 221 if (!MO.isReg() || !(Reg = MO.getReg())) 222 continue; // skip 223 224 if (MO.isDef()) { 225 // check whether Reg is defined or used before delay slot. 226 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg)) 227 return true; 228 } 229 if (MO.isUse()) { 230 // check whether Reg is defined before delay slot. 231 if (IsRegInSet(RegDefs, Reg)) 232 return true; 233 } 234 } 235 return false; 236 } 237 238 // Helper function for getting a MachineOperand's register number and adding it 239 // to RegDefs or RegUses. 240 static void insertDefUse(const MachineOperand &MO, 241 SmallSet<unsigned, 32> &RegDefs, 242 SmallSet<unsigned, 32> &RegUses, 243 unsigned ExcludedReg = 0) { 244 unsigned Reg; 245 246 if (!MO.isReg() || !(Reg = MO.getReg()) || (Reg == ExcludedReg)) 247 return; 248 249 if (MO.isDef()) 250 RegDefs.insert(Reg); 251 else if (MO.isUse()) 252 RegUses.insert(Reg); 253 } 254 255 // Insert Defs and Uses of MI into the sets RegDefs and RegUses. 256 void Filler::insertDefsUses(InstrIter MI, 257 SmallSet<unsigned, 32> &RegDefs, 258 SmallSet<unsigned, 32> &RegUses) { 259 unsigned I, E = MI->getDesc().getNumOperands(); 260 261 for (I = 0; I != E; ++I) 262 insertDefUse(MI->getOperand(I), RegDefs, RegUses); 263 264 // If MI is a call, add RA to RegDefs to prevent users of RA from going into 265 // delay slot. 266 if (MI->isCall()) { 267 RegDefs.insert(Mips::RA); 268 return; 269 } 270 271 // Return if MI is a return. 272 if (MI->isReturn()) 273 return; 274 275 // Examine the implicit operands. Exclude register AT which is in the list of 276 // clobbered registers of branch instructions. 277 E = MI->getNumOperands(); 278 for (; I != E; ++I) 279 insertDefUse(MI->getOperand(I), RegDefs, RegUses, Mips::AT); 280 } 281 282 //returns true if the Reg or its alias is in the RegSet. 283 bool Filler::IsRegInSet(SmallSet<unsigned, 32> &RegSet, unsigned Reg) { 284 // Check Reg and all aliased Registers. 285 for (MCRegAliasIterator AI(Reg, TM.getRegisterInfo(), true); 286 AI.isValid(); ++AI) 287 if (RegSet.count(*AI)) 288 return true; 289 return false; 290 } 291