c5558eb9cff0da260e4c6558f4563561e8418f74
[oota-llvm.git] / lib / Target / Mips / MipsDelaySlotFiller.cpp
1 //===-- MipsDelaySlotFiller.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 fill 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/BitVector.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/Analysis/AliasAnalysis.h"
22 #include "llvm/Analysis/ValueTracking.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/PseudoSourceValue.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Target/TargetInstrInfo.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/Target/TargetRegisterInfo.h"
30
31 using namespace llvm;
32
33 STATISTIC(FilledSlots, "Number of delay slots filled");
34 STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"
35                        " are not NOP.");
36
37 static cl::opt<bool> DisableDelaySlotFiller(
38   "disable-mips-delay-filler",
39   cl::init(false),
40   cl::desc("Fill all delay slots with NOPs."),
41   cl::Hidden);
42
43 // This option can be used to silence complaints by machine verifier passes.
44 static cl::opt<bool> SkipDelaySlotFiller(
45   "skip-mips-delay-filler",
46   cl::init(false),
47   cl::desc("Skip MIPS' delay slot filling pass."),
48   cl::Hidden);
49
50 namespace {
51   class RegDefsUses {
52   public:
53     RegDefsUses(TargetMachine &TM);
54     void init(const MachineInstr &MI);
55     bool update(const MachineInstr &MI, unsigned Begin, unsigned End);
56
57   private:
58     bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses, unsigned Reg,
59                           bool IsDef) const;
60
61     /// Returns true if Reg or its alias is in RegSet.
62     bool isRegInSet(const BitVector &RegSet, unsigned Reg) const;
63
64     const TargetRegisterInfo &TRI;
65     BitVector Defs, Uses;
66   };
67
68   /// This class maintains memory dependence information.
69   class MemDefsUses {
70   public:
71     MemDefsUses(const MachineFrameInfo *MFI);
72
73     /// Return true if MI cannot be moved to delay slot.
74     bool hasHazard(const MachineInstr &MI);
75
76   private:
77     /// Update Defs and Uses. Return true if there exist dependences that
78     /// disqualify the delay slot candidate between V and values in Uses and Defs.
79     bool updateDefsUses(const Value *V, bool MayStore);
80
81     /// Get the list of underlying objects of MI's memory operand.
82     bool getUnderlyingObjects(const MachineInstr &MI,
83                               SmallVectorImpl<const Value *> &Objects) const;
84
85     const MachineFrameInfo *MFI;
86     SmallPtrSet<const Value*, 4> Uses, Defs;
87
88     /// Flags indicating whether loads or stores have been seen.
89     bool SeenLoad, SeenStore;
90
91     /// Flags indicating whether loads or stores with no underlying objects have
92     /// been seen.
93     bool SeenNoObjLoad, SeenNoObjStore;
94
95     /// Memory instructions are not allowed to move to delay slot if this flag
96     /// is true.
97     bool ForbidMemInstr;
98   };
99
100   class Filler : public MachineFunctionPass {
101   public:
102     Filler(TargetMachine &tm)
103       : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
104
105     virtual const char *getPassName() const {
106       return "Mips Delay Slot Filler";
107     }
108
109     bool runOnMachineFunction(MachineFunction &F) {
110       if (SkipDelaySlotFiller)
111         return false;
112
113       bool Changed = false;
114       for (MachineFunction::iterator FI = F.begin(), FE = F.end();
115            FI != FE; ++FI)
116         Changed |= runOnMachineBasicBlock(*FI);
117       return Changed;
118     }
119
120   private:
121     typedef MachineBasicBlock::iterator Iter;
122     typedef MachineBasicBlock::reverse_iterator ReverseIter;
123
124     bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
125
126     /// This function checks if it is valid to move Candidate to the delay slot
127     /// and returns true if it isn't. It also updates memory and register
128     /// dependence information.
129     bool delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU,
130                         MemDefsUses &MemDU) const;
131
132     bool findDelayInstr(MachineBasicBlock &MBB, Iter slot, Iter &Filler) const;
133
134     bool terminateSearch(const MachineInstr &Candidate) const;
135
136     TargetMachine &TM;
137     const TargetInstrInfo *TII;
138
139     static char ID;
140   };
141   char Filler::ID = 0;
142 } // end of anonymous namespace
143
144 RegDefsUses::RegDefsUses(TargetMachine &TM)
145   : TRI(*TM.getRegisterInfo()), Defs(TRI.getNumRegs(), false),
146     Uses(TRI.getNumRegs(), false) {}
147
148 void RegDefsUses::init(const MachineInstr &MI) {
149   // Add all register operands which are explicit and non-variadic.
150   update(MI, 0, MI.getDesc().getNumOperands());
151
152   // If MI is a call, add RA to Defs to prevent users of RA from going into
153   // delay slot.
154   if (MI.isCall())
155     Defs.set(Mips::RA);
156
157   // Add all implicit register operands of branch instructions except
158   // register AT.
159   if (MI.isBranch()) {
160     update(MI, MI.getDesc().getNumOperands(), MI.getNumOperands());
161     Defs.reset(Mips::AT);
162   }
163 }
164
165 bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {
166   BitVector NewDefs(TRI.getNumRegs()), NewUses(TRI.getNumRegs());
167   bool HasHazard = false;
168
169   for (unsigned I = Begin; I != End; ++I) {
170     const MachineOperand &MO = MI.getOperand(I);
171
172     if (MO.isReg() && MO.getReg())
173       HasHazard |= checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef());
174   }
175
176   Defs |= NewDefs;
177   Uses |= NewUses;
178
179   return HasHazard;
180 }
181
182 bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
183                                    unsigned Reg, bool IsDef) const {
184   if (IsDef) {
185     NewDefs.set(Reg);
186     // check whether Reg has already been defined or used.
187     return (isRegInSet(Defs, Reg) || isRegInSet(Uses, Reg));
188   }
189
190   NewUses.set(Reg);
191   // check whether Reg has already been defined.
192   return isRegInSet(Defs, Reg);
193 }
194
195 bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const {
196   // Check Reg and all aliased Registers.
197   for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
198     if (RegSet.test(*AI))
199       return true;
200   return false;
201 }
202
203 MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_)
204   : MFI(MFI_), SeenLoad(false), SeenStore(false), SeenNoObjLoad(false),
205     SeenNoObjStore(false),  ForbidMemInstr(false) {}
206
207 bool MemDefsUses::hasHazard(const MachineInstr &MI) {
208   if (!MI.mayStore() && !MI.mayLoad())
209     return false;
210
211   if (ForbidMemInstr)
212     return true;
213
214   bool OrigSeenLoad = SeenLoad, OrigSeenStore = SeenStore;
215
216   SeenLoad |= MI.mayLoad();
217   SeenStore |= MI.mayStore();
218
219   // If MI is an ordered or volatile memory reference, disallow moving
220   // subsequent loads and stores to delay slot.
221   if (MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {
222     ForbidMemInstr = true;
223     return true;
224   }
225
226   bool HasHazard = false;
227   SmallVector<const Value *, 4> Objs;
228
229   // Check underlying object list.
230   if (getUnderlyingObjects(MI, Objs)) {
231     for (SmallVector<const Value *, 4>::const_iterator I = Objs.begin();
232          I != Objs.end(); ++I)
233       HasHazard |= updateDefsUses(*I, MI.mayStore());
234
235     return HasHazard;
236   }
237
238   // No underlying objects found.
239   HasHazard = MI.mayStore() && (OrigSeenLoad || OrigSeenStore);
240   HasHazard |= MI.mayLoad() || OrigSeenStore;
241
242   SeenNoObjLoad |= MI.mayLoad();
243   SeenNoObjStore |= MI.mayStore();
244
245   return HasHazard;
246 }
247
248 bool MemDefsUses::updateDefsUses(const Value *V, bool MayStore) {
249   if (MayStore)
250     return !Defs.insert(V) || Uses.count(V) || SeenNoObjStore || SeenNoObjLoad;
251
252   Uses.insert(V);
253   return Defs.count(V) || SeenNoObjStore;
254 }
255
256 bool MemDefsUses::
257 getUnderlyingObjects(const MachineInstr &MI,
258                      SmallVectorImpl<const Value *> &Objects) const {
259   if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getValue())
260     return false;
261
262   const Value *V = (*MI.memoperands_begin())->getValue();
263
264   SmallVector<Value *, 4> Objs;
265   GetUnderlyingObjects(const_cast<Value *>(V), Objs);
266
267   for (SmallVector<Value*, 4>::iterator I = Objs.begin(), E = Objs.end();
268        I != E; ++I) {
269     if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(*I)) {
270       if (PSV->isAliased(MFI))
271         return false;
272     } else if (!isIdentifiedObject(V))
273       return false;
274
275     Objects.push_back(*I);
276   }
277
278   return true;
279 }
280
281 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
282 /// We assume there is only one delay slot per delayed instruction.
283 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
284   bool Changed = false;
285
286   for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
287     if (!I->hasDelaySlot())
288       continue;
289
290     ++FilledSlots;
291     Changed = true;
292     Iter D;
293
294     // Delay slot filling is disabled at -O0.
295     if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None) &&
296         findDelayInstr(MBB, I, D)) {
297       MBB.splice(llvm::next(I), &MBB, D);
298       ++UsefulSlots;
299     } else
300       BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
301
302     // Bundle the delay slot filler to the instruction with the delay slot.
303     MIBundleBuilder(MBB, I, llvm::next(llvm::next(I)));
304   }
305
306   return Changed;
307 }
308
309 /// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
310 /// slots in Mips MachineFunctions
311 FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) {
312   return new Filler(tm);
313 }
314
315 bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
316                             Iter &Filler) const {
317   RegDefsUses RegDU(TM);
318   MemDefsUses MemDU(MBB.getParent()->getFrameInfo());
319
320   RegDU.init(*Slot);
321
322   for (ReverseIter I(Slot); I != MBB.rend(); ++I) {
323     // skip debug value
324     if (I->isDebugValue())
325       continue;
326
327     if (terminateSearch(*I))
328       break;
329
330     assert((!I->isCall() && !I->isReturn() && !I->isBranch()) &&
331            "Cannot put calls, returns or branches in delay slot.");
332
333     if (delayHasHazard(*I, RegDU, MemDU))
334       continue;
335
336     Filler = llvm::next(I).base();
337     return true;
338   }
339
340   return false;
341 }
342
343 bool Filler::delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU,
344                             MemDefsUses &MemDU) const {
345   bool HasHazard = (Candidate.isImplicitDef() || Candidate.isKill());
346
347   HasHazard |= MemDU.hasHazard(Candidate);
348   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
349
350   return HasHazard;
351 }
352
353 bool Filler::terminateSearch(const MachineInstr &Candidate) const {
354   return (Candidate.isTerminator() || Candidate.isCall() ||
355           Candidate.isLabel() || Candidate.isInlineAsm() ||
356           Candidate.hasUnmodeledSideEffects());
357 }