1 //===-- LanaiDelaySlotFiller.cpp - Lanai 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 #include "Lanai.h" 15 #include "LanaiTargetMachine.h" 16 #include "llvm/ADT/SmallSet.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/CodeGen/MachineFunctionPass.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/TargetInstrInfo.h" 21 #include "llvm/Support/CommandLine.h" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "delay-slot-filler" 26 27 STATISTIC(FilledSlots, "Number of delay slots filled"); 28 29 static cl::opt<bool> 30 NopDelaySlotFiller("lanai-nop-delay-filler", cl::init(false), 31 cl::desc("Fill Lanai delay slots with NOPs."), 32 cl::Hidden); 33 34 namespace { 35 struct Filler : public MachineFunctionPass { 36 // Target machine description which we query for reg. names, data 37 // layout, etc. 38 const TargetInstrInfo *TII; 39 const TargetRegisterInfo *TRI; 40 MachineBasicBlock::instr_iterator LastFiller; 41 42 static char ID; 43 explicit Filler() : MachineFunctionPass(ID) {} 44 45 StringRef getPassName() const override { return "Lanai Delay Slot Filler"; } 46 47 bool runOnMachineBasicBlock(MachineBasicBlock &MBB); 48 49 bool runOnMachineFunction(MachineFunction &MF) override { 50 const LanaiSubtarget &Subtarget = MF.getSubtarget<LanaiSubtarget>(); 51 TII = Subtarget.getInstrInfo(); 52 TRI = Subtarget.getRegisterInfo(); 53 54 bool Changed = false; 55 for (MachineFunction::iterator FI = MF.begin(), FE = MF.end(); FI != FE; 56 ++FI) 57 Changed |= runOnMachineBasicBlock(*FI); 58 return Changed; 59 } 60 61 MachineFunctionProperties getRequiredProperties() const override { 62 return MachineFunctionProperties().set( 63 MachineFunctionProperties::Property::NoVRegs); 64 } 65 66 void insertDefsUses(MachineBasicBlock::instr_iterator MI, 67 SmallSet<unsigned, 32> &RegDefs, 68 SmallSet<unsigned, 32> &RegUses); 69 70 bool isRegInSet(SmallSet<unsigned, 32> &RegSet, unsigned Reg); 71 72 bool delayHasHazard(MachineBasicBlock::instr_iterator MI, bool &SawLoad, 73 bool &SawStore, SmallSet<unsigned, 32> &RegDefs, 74 SmallSet<unsigned, 32> &RegUses); 75 76 bool findDelayInstr(MachineBasicBlock &MBB, 77 MachineBasicBlock::instr_iterator Slot, 78 MachineBasicBlock::instr_iterator &Filler); 79 }; 80 char Filler::ID = 0; 81 } // end of anonymous namespace 82 83 // createLanaiDelaySlotFillerPass - Returns a pass that fills in delay 84 // slots in Lanai MachineFunctions 85 FunctionPass * 86 llvm::createLanaiDelaySlotFillerPass(const LanaiTargetMachine & /*tm*/) { 87 return new Filler(); 88 } 89 90 // runOnMachineBasicBlock - Fill in delay slots for the given basic block. 91 // There is one or two delay slot per delayed instruction. 92 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { 93 bool Changed = false; 94 LastFiller = MBB.instr_end(); 95 96 for (MachineBasicBlock::instr_iterator I = MBB.instr_begin(); 97 I != MBB.instr_end(); ++I) { 98 if (I->getDesc().hasDelaySlot()) { 99 MachineBasicBlock::instr_iterator InstrWithSlot = I; 100 MachineBasicBlock::instr_iterator J = I; 101 102 // Treat RET specially as it is only instruction with 2 delay slots 103 // generated while all others generated have 1 delay slot. 104 if (I->getOpcode() == Lanai::RET) { 105 // RET is generated as part of epilogue generation and hence we know 106 // what the two instructions preceding it are and that it is safe to 107 // insert RET above them. 108 MachineBasicBlock::reverse_instr_iterator RI = ++I.getReverse(); 109 assert(RI->getOpcode() == Lanai::LDW_RI && RI->getOperand(0).isReg() && 110 RI->getOperand(0).getReg() == Lanai::FP && 111 RI->getOperand(1).isReg() && 112 RI->getOperand(1).getReg() == Lanai::FP && 113 RI->getOperand(2).isImm() && RI->getOperand(2).getImm() == -8); 114 ++RI; 115 assert(RI->getOpcode() == Lanai::ADD_I_LO && 116 RI->getOperand(0).isReg() && 117 RI->getOperand(0).getReg() == Lanai::SP && 118 RI->getOperand(1).isReg() && 119 RI->getOperand(1).getReg() == Lanai::FP); 120 MachineBasicBlock::instr_iterator FI = RI.getReverse(); 121 MBB.splice(std::next(I), &MBB, FI, I); 122 FilledSlots += 2; 123 } else { 124 if (!NopDelaySlotFiller && findDelayInstr(MBB, I, J)) { 125 MBB.splice(std::next(I), &MBB, J); 126 } else { 127 BuildMI(MBB, std::next(I), DebugLoc(), TII->get(Lanai::NOP)); 128 } 129 ++FilledSlots; 130 } 131 132 Changed = true; 133 // Record the filler instruction that filled the delay slot. 134 // The instruction after it will be visited in the next iteration. 135 LastFiller = ++I; 136 137 // Bundle the delay slot filler to InstrWithSlot so that the machine 138 // verifier doesn't expect this instruction to be a terminator. 139 MIBundleBuilder(MBB, InstrWithSlot, std::next(LastFiller)); 140 } 141 } 142 return Changed; 143 } 144 145 bool Filler::findDelayInstr(MachineBasicBlock &MBB, 146 MachineBasicBlock::instr_iterator Slot, 147 MachineBasicBlock::instr_iterator &Filler) { 148 SmallSet<unsigned, 32> RegDefs; 149 SmallSet<unsigned, 32> RegUses; 150 151 insertDefsUses(Slot, RegDefs, RegUses); 152 153 bool SawLoad = false; 154 bool SawStore = false; 155 156 for (MachineBasicBlock::reverse_instr_iterator I = ++Slot.getReverse(); 157 I != MBB.instr_rend(); ++I) { 158 // skip debug value 159 if (I->isDebugInstr()) 160 continue; 161 162 // Convert to forward iterator. 163 MachineBasicBlock::instr_iterator FI = I.getReverse(); 164 165 if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isLabel() || 166 FI == LastFiller || I->isPseudo()) 167 break; 168 169 if (delayHasHazard(FI, SawLoad, SawStore, RegDefs, RegUses)) { 170 insertDefsUses(FI, RegDefs, RegUses); 171 continue; 172 } 173 Filler = FI; 174 return true; 175 } 176 return false; 177 } 178 179 bool Filler::delayHasHazard(MachineBasicBlock::instr_iterator MI, bool &SawLoad, 180 bool &SawStore, SmallSet<unsigned, 32> &RegDefs, 181 SmallSet<unsigned, 32> &RegUses) { 182 if (MI->isImplicitDef() || MI->isKill()) 183 return true; 184 185 // Loads or stores cannot be moved past a store to the delay slot 186 // and stores cannot be moved past a load. 187 if (MI->mayLoad()) { 188 if (SawStore) 189 return true; 190 SawLoad = true; 191 } 192 193 if (MI->mayStore()) { 194 if (SawStore) 195 return true; 196 SawStore = true; 197 if (SawLoad) 198 return true; 199 } 200 201 assert((!MI->isCall() && !MI->isReturn()) && 202 "Cannot put calls or returns in delay slot."); 203 204 for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 205 const MachineOperand &MO = MI->getOperand(I); 206 unsigned Reg; 207 208 if (!MO.isReg() || !(Reg = MO.getReg())) 209 continue; // skip 210 211 if (MO.isDef()) { 212 // check whether Reg is defined or used before delay slot. 213 if (isRegInSet(RegDefs, Reg) || isRegInSet(RegUses, Reg)) 214 return true; 215 } 216 if (MO.isUse()) { 217 // check whether Reg is defined before delay slot. 218 if (isRegInSet(RegDefs, Reg)) 219 return true; 220 } 221 } 222 return false; 223 } 224 225 // Insert Defs and Uses of MI into the sets RegDefs and RegUses. 226 void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI, 227 SmallSet<unsigned, 32> &RegDefs, 228 SmallSet<unsigned, 32> &RegUses) { 229 // If MI is a call or return, just examine the explicit non-variadic operands. 230 MCInstrDesc MCID = MI->getDesc(); 231 unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands() 232 : MI->getNumOperands(); 233 for (unsigned I = 0; I != E; ++I) { 234 const MachineOperand &MO = MI->getOperand(I); 235 unsigned Reg; 236 237 if (!MO.isReg() || !(Reg = MO.getReg())) 238 continue; 239 240 if (MO.isDef()) 241 RegDefs.insert(Reg); 242 else if (MO.isUse()) 243 RegUses.insert(Reg); 244 } 245 246 // Call & return instructions defines SP implicitly. Implicit defines are not 247 // included in the RegDefs set of calls but instructions modifying SP cannot 248 // be inserted in the delay slot of a call/return as these instructions are 249 // expanded to multiple instructions with SP modified before the branch that 250 // has the delay slot. 251 if (MI->isCall() || MI->isReturn()) 252 RegDefs.insert(Lanai::SP); 253 } 254 255 // Returns true if the Reg or its alias is in the RegSet. 256 bool Filler::isRegInSet(SmallSet<unsigned, 32> &RegSet, unsigned Reg) { 257 // Check Reg and all aliased Registers. 258 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) 259 if (RegSet.count(*AI)) 260 return true; 261 return false; 262 } 263