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