0d6b00915f5cf1049c335a3464ede32715b5b421
[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     /// This function searches range [Begin, End) for an instruction that can be
133     /// moved to the delay slot. Returns true on success.
134     template<typename IterTy>
135     bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
136                      RegDefsUses &RegDU, MemDefsUses &MemDU, IterTy &Filler) const;
137
138     bool searchBackward(MachineBasicBlock &MBB, Iter Slot, Iter &Filler) const;
139
140     bool terminateSearch(const MachineInstr &Candidate) const;
141
142     TargetMachine &TM;
143     const TargetInstrInfo *TII;
144
145     static char ID;
146   };
147   char Filler::ID = 0;
148 } // end of anonymous namespace
149
150 RegDefsUses::RegDefsUses(TargetMachine &TM)
151   : TRI(*TM.getRegisterInfo()), Defs(TRI.getNumRegs(), false),
152     Uses(TRI.getNumRegs(), false) {}
153
154 void RegDefsUses::init(const MachineInstr &MI) {
155   // Add all register operands which are explicit and non-variadic.
156   update(MI, 0, MI.getDesc().getNumOperands());
157
158   // If MI is a call, add RA to Defs to prevent users of RA from going into
159   // delay slot.
160   if (MI.isCall())
161     Defs.set(Mips::RA);
162
163   // Add all implicit register operands of branch instructions except
164   // register AT.
165   if (MI.isBranch()) {
166     update(MI, MI.getDesc().getNumOperands(), MI.getNumOperands());
167     Defs.reset(Mips::AT);
168   }
169 }
170
171 bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {
172   BitVector NewDefs(TRI.getNumRegs()), NewUses(TRI.getNumRegs());
173   bool HasHazard = false;
174
175   for (unsigned I = Begin; I != End; ++I) {
176     const MachineOperand &MO = MI.getOperand(I);
177
178     if (MO.isReg() && MO.getReg())
179       HasHazard |= checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef());
180   }
181
182   Defs |= NewDefs;
183   Uses |= NewUses;
184
185   return HasHazard;
186 }
187
188 bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
189                                    unsigned Reg, bool IsDef) const {
190   if (IsDef) {
191     NewDefs.set(Reg);
192     // check whether Reg has already been defined or used.
193     return (isRegInSet(Defs, Reg) || isRegInSet(Uses, Reg));
194   }
195
196   NewUses.set(Reg);
197   // check whether Reg has already been defined.
198   return isRegInSet(Defs, Reg);
199 }
200
201 bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const {
202   // Check Reg and all aliased Registers.
203   for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
204     if (RegSet.test(*AI))
205       return true;
206   return false;
207 }
208
209 MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_)
210   : MFI(MFI_), SeenLoad(false), SeenStore(false), SeenNoObjLoad(false),
211     SeenNoObjStore(false),  ForbidMemInstr(false) {}
212
213 bool MemDefsUses::hasHazard(const MachineInstr &MI) {
214   if (!MI.mayStore() && !MI.mayLoad())
215     return false;
216
217   if (ForbidMemInstr)
218     return true;
219
220   bool OrigSeenLoad = SeenLoad, OrigSeenStore = SeenStore;
221
222   SeenLoad |= MI.mayLoad();
223   SeenStore |= MI.mayStore();
224
225   // If MI is an ordered or volatile memory reference, disallow moving
226   // subsequent loads and stores to delay slot.
227   if (MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {
228     ForbidMemInstr = true;
229     return true;
230   }
231
232   bool HasHazard = false;
233   SmallVector<const Value *, 4> Objs;
234
235   // Check underlying object list.
236   if (getUnderlyingObjects(MI, Objs)) {
237     for (SmallVector<const Value *, 4>::const_iterator I = Objs.begin();
238          I != Objs.end(); ++I)
239       HasHazard |= updateDefsUses(*I, MI.mayStore());
240
241     return HasHazard;
242   }
243
244   // No underlying objects found.
245   HasHazard = MI.mayStore() && (OrigSeenLoad || OrigSeenStore);
246   HasHazard |= MI.mayLoad() || OrigSeenStore;
247
248   SeenNoObjLoad |= MI.mayLoad();
249   SeenNoObjStore |= MI.mayStore();
250
251   return HasHazard;
252 }
253
254 bool MemDefsUses::updateDefsUses(const Value *V, bool MayStore) {
255   if (MayStore)
256     return !Defs.insert(V) || Uses.count(V) || SeenNoObjStore || SeenNoObjLoad;
257
258   Uses.insert(V);
259   return Defs.count(V) || SeenNoObjStore;
260 }
261
262 bool MemDefsUses::
263 getUnderlyingObjects(const MachineInstr &MI,
264                      SmallVectorImpl<const Value *> &Objects) const {
265   if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getValue())
266     return false;
267
268   const Value *V = (*MI.memoperands_begin())->getValue();
269
270   SmallVector<Value *, 4> Objs;
271   GetUnderlyingObjects(const_cast<Value *>(V), Objs);
272
273   for (SmallVector<Value*, 4>::iterator I = Objs.begin(), E = Objs.end();
274        I != E; ++I) {
275     if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(*I)) {
276       if (PSV->isAliased(MFI))
277         return false;
278     } else if (!isIdentifiedObject(V))
279       return false;
280
281     Objects.push_back(*I);
282   }
283
284   return true;
285 }
286
287 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
288 /// We assume there is only one delay slot per delayed instruction.
289 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
290   bool Changed = false;
291
292   for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
293     if (!I->hasDelaySlot())
294       continue;
295
296     ++FilledSlots;
297     Changed = true;
298     Iter D;
299
300     // Delay slot filling is disabled at -O0.
301     if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None) &&
302         searchBackward(MBB, I, D)) {
303       MBB.splice(llvm::next(I), &MBB, D);
304       ++UsefulSlots;
305     } else
306       BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
307
308     // Bundle the delay slot filler to the instruction with the delay slot.
309     MIBundleBuilder(MBB, I, llvm::next(llvm::next(I)));
310   }
311
312   return Changed;
313 }
314
315 /// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
316 /// slots in Mips MachineFunctions
317 FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) {
318   return new Filler(tm);
319 }
320
321 template<typename IterTy>
322 bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,
323                          RegDefsUses &RegDU, MemDefsUses &MemDU,
324                          IterTy &Filler) const {
325   for (IterTy I = Begin; I != End; ++I) {
326     // skip debug value
327     if (I->isDebugValue())
328       continue;
329
330     if (terminateSearch(*I))
331       break;
332
333     assert((!I->isCall() && !I->isReturn() && !I->isBranch()) &&
334            "Cannot put calls, returns or branches in delay slot.");
335
336     if (delayHasHazard(*I, RegDU, MemDU))
337       continue;
338
339     Filler = I;
340     return true;
341   }
342
343   return false;
344 }
345
346 bool Filler::searchBackward(MachineBasicBlock &MBB, Iter Slot,
347                             Iter &Filler) const {
348   RegDefsUses RegDU(TM);
349   MemDefsUses MemDU(MBB.getParent()->getFrameInfo());
350   ReverseIter FillerReverse;
351
352   RegDU.init(*Slot);
353
354   if (searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU,
355                   FillerReverse)) {
356     Filler = llvm::next(FillerReverse).base();
357     return true;
358   }
359
360   return false;
361 }
362
363 bool Filler::delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU,
364                             MemDefsUses &MemDU) const {
365   bool HasHazard = (Candidate.isImplicitDef() || Candidate.isKill());
366
367   HasHazard |= MemDU.hasHazard(Candidate);
368   HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
369
370   return HasHazard;
371 }
372
373 bool Filler::terminateSearch(const MachineInstr &Candidate) const {
374   return (Candidate.isTerminator() || Candidate.isCall() ||
375           Candidate.isLabel() || Candidate.isInlineAsm() ||
376           Candidate.hasUnmodeledSideEffects());
377 }