1 //===-- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Simple pass to fill delay slots with useful instructions.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "delay-slot-filler"
17 #include "MipsTargetMachine.h"
18 #include "llvm/ADT/BitVector.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"
29 STATISTIC(FilledSlots, "Number of delay slots filled");
30 STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"
33 static cl::opt<bool> DisableDelaySlotFiller(
34 "disable-mips-delay-filler",
36 cl::desc("Fill all delay slots with NOPs."),
39 // This option can be used to silence complaints by machine verifier passes.
40 static cl::opt<bool> SkipDelaySlotFiller(
41 "skip-mips-delay-filler",
43 cl::desc("Skip MIPS' delay slot filling pass."),
47 class Filler : public MachineFunctionPass {
49 Filler(TargetMachine &tm)
50 : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
52 virtual const char *getPassName() const {
53 return "Mips Delay Slot Filler";
56 bool runOnMachineFunction(MachineFunction &F) {
57 if (SkipDelaySlotFiller)
61 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
63 Changed |= runOnMachineBasicBlock(*FI);
68 typedef MachineBasicBlock::iterator Iter;
69 typedef MachineBasicBlock::reverse_iterator ReverseIter;
71 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
73 /// Initialize RegDefs and RegUses.
74 void initRegDefsUses(const MachineInstr &MI, BitVector &RegDefs,
75 BitVector &RegUses) const;
77 bool isRegInSet(const BitVector &RegSet, unsigned Reg) const;
79 bool checkRegDefsUses(const BitVector &RegDefs, const BitVector &RegUses,
80 BitVector &NewDefs, BitVector &NewUses,
81 unsigned Reg, bool IsDef) const;
83 bool checkRegDefsUses(BitVector &RegDefs, BitVector &RegUses,
84 const MachineInstr &MI, unsigned Begin,
87 /// This function checks if it is valid to move Candidate to the delay slot
88 /// and returns true if it isn't. It also updates load and store flags and
89 /// register defs and uses.
90 bool delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
91 bool &SawStore, BitVector &RegDefs,
92 BitVector &RegUses) const;
94 bool findDelayInstr(MachineBasicBlock &MBB, Iter slot, Iter &Filler) const;
96 bool terminateSearch(const MachineInstr &Candidate) const;
99 const TargetInstrInfo *TII;
104 } // end of anonymous namespace
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::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
109 bool Changed = false;
111 for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
112 if (!I->hasDelaySlot())
119 // Delay slot filling is disabled at -O0.
120 if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None) &&
121 findDelayInstr(MBB, I, D)) {
122 MBB.splice(llvm::next(I), &MBB, D);
125 BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
127 // Bundle the delay slot filler to the instruction with the delay slot.
128 MIBundleBuilder(MBB, I, llvm::next(llvm::next(I)));
134 /// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
135 /// slots in Mips MachineFunctions
136 FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) {
137 return new Filler(tm);
140 bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
141 Iter &Filler) const {
142 unsigned NumRegs = TM.getRegisterInfo()->getNumRegs();
143 BitVector RegDefs(NumRegs), RegUses(NumRegs);
145 initRegDefsUses(*Slot, RegDefs, RegUses);
147 bool SawLoad = false;
148 bool SawStore = false;
150 for (ReverseIter I(Slot); I != MBB.rend(); ++I) {
152 if (I->isDebugValue())
155 if (terminateSearch(*I))
158 if (delayHasHazard(*I, SawLoad, SawStore, RegDefs, RegUses))
161 Filler = llvm::next(I).base();
168 bool Filler::checkRegDefsUses(const BitVector &RegDefs,
169 const BitVector &RegUses,
170 BitVector &NewDefs, BitVector &NewUses,
171 unsigned Reg, bool IsDef) const {
174 // check whether Reg has already been defined or used.
175 return (isRegInSet(RegDefs, Reg) || isRegInSet(RegUses, Reg));
179 // check whether Reg has already been defined.
180 return isRegInSet(RegDefs, Reg);
183 bool Filler::checkRegDefsUses(BitVector &RegDefs, BitVector &RegUses,
184 const MachineInstr &MI, unsigned Begin,
185 unsigned End) const {
186 unsigned NumRegs = TM.getRegisterInfo()->getNumRegs();
187 BitVector NewDefs(NumRegs), NewUses(NumRegs);
188 bool HasHazard = false;
190 for (unsigned I = Begin; I != End; ++I) {
191 const MachineOperand &MO = MI.getOperand(I);
193 if (MO.isReg() && MO.getReg())
194 HasHazard |= checkRegDefsUses(RegDefs, RegUses, NewDefs, NewUses,
195 MO.getReg(), MO.isDef());
204 bool Filler::delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
205 bool &SawStore, BitVector &RegDefs,
206 BitVector &RegUses) const {
207 bool HasHazard = (Candidate.isImplicitDef() || Candidate.isKill());
209 // Loads or stores cannot be moved past a store to the delay slot
210 // and stores cannot be moved past a load.
211 if (Candidate.mayStore() || Candidate.hasOrderedMemoryRef()) {
212 HasHazard |= SawStore | SawLoad;
214 } else if (Candidate.mayLoad()) {
215 HasHazard |= SawStore;
219 assert((!Candidate.isCall() && !Candidate.isReturn()) &&
220 "Cannot put calls or returns in delay slot.");
222 HasHazard |= checkRegDefsUses(RegDefs, RegUses, Candidate, 0,
223 Candidate.getNumOperands());
228 void Filler::initRegDefsUses(const MachineInstr &MI, BitVector &RegDefs,
229 BitVector &RegUses) const {
230 // Add all register operands which are explicit and non-variadic.
231 checkRegDefsUses(RegDefs, RegUses, MI, 0, MI.getDesc().getNumOperands());
233 // If MI is a call, add RA to RegDefs to prevent users of RA from going into
236 RegDefs.set(Mips::RA);
238 // Add all implicit register operands of branch instructions except
241 checkRegDefsUses(RegDefs, RegUses, MI, MI.getDesc().getNumOperands(),
242 MI.getNumOperands());
243 RegDefs.reset(Mips::AT);
247 //returns true if the Reg or its alias is in the RegSet.
248 bool Filler::isRegInSet(const BitVector &RegSet, unsigned Reg) const {
249 // Check Reg and all aliased Registers.
250 for (MCRegAliasIterator AI(Reg, TM.getRegisterInfo(), true);
252 if (RegSet.test(*AI))
257 bool Filler::terminateSearch(const MachineInstr &Candidate) const {
258 return (Candidate.isTerminator() || Candidate.isCall() ||
259 Candidate.isLabel() || Candidate.isInlineAsm() ||
260 Candidate.hasUnmodeledSideEffects());