[Sparc] Generate correct code for leaf functions with stack objects
[oota-llvm.git] / lib / Target / Sparc / DelaySlotFiller.cpp
1 //===-- DelaySlotFiller.cpp - SPARC 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 // This is a simple local pass that attempts to fill delay slots with useful
11 // instructions. If no instructions can be moved into the delay slot, then a
12 // NOP is placed.
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "delay-slot-filler"
16 #include "Sparc.h"
17 #include "llvm/ADT/SmallSet.h"
18 #include "llvm/ADT/Statistic.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Target/TargetInstrInfo.h"
23 #include "llvm/Target/TargetMachine.h"
24 #include "llvm/Target/TargetRegisterInfo.h"
25
26 using namespace llvm;
27
28 STATISTIC(FilledSlots, "Number of delay slots filled");
29
30 static cl::opt<bool> DisableDelaySlotFiller(
31   "disable-sparc-delay-filler",
32   cl::init(false),
33   cl::desc("Disable the Sparc delay slot filler."),
34   cl::Hidden);
35
36 namespace {
37   struct Filler : public MachineFunctionPass {
38     /// Target machine description which we query for reg. names, data
39     /// layout, etc.
40     ///
41     TargetMachine &TM;
42     const TargetInstrInfo *TII;
43
44     static char ID;
45     Filler(TargetMachine &tm) 
46       : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
47
48     virtual const char *getPassName() const {
49       return "SPARC Delay Slot Filler";
50     }
51
52     bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
53     bool runOnMachineFunction(MachineFunction &F) {
54       bool Changed = false;
55       for (MachineFunction::iterator FI = F.begin(), FE = F.end();
56            FI != FE; ++FI)
57         Changed |= runOnMachineBasicBlock(*FI);
58       return Changed;
59     }
60
61     bool isDelayFiller(MachineBasicBlock &MBB,
62                        MachineBasicBlock::iterator candidate);
63
64     void insertCallDefsUses(MachineBasicBlock::iterator MI,
65                             SmallSet<unsigned, 32>& RegDefs,
66                             SmallSet<unsigned, 32>& RegUses);
67
68     void insertDefsUses(MachineBasicBlock::iterator MI,
69                         SmallSet<unsigned, 32>& RegDefs,
70                         SmallSet<unsigned, 32>& RegUses);
71
72     bool IsRegInSet(SmallSet<unsigned, 32>& RegSet,
73                     unsigned Reg);
74
75     bool delayHasHazard(MachineBasicBlock::iterator candidate,
76                         bool &sawLoad, bool &sawStore,
77                         SmallSet<unsigned, 32> &RegDefs,
78                         SmallSet<unsigned, 32> &RegUses);
79
80     MachineBasicBlock::iterator
81     findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot);
82
83     bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize);
84
85   };
86   char Filler::ID = 0;
87 } // end of anonymous namespace
88
89 /// createSparcDelaySlotFillerPass - Returns a pass that fills in delay
90 /// slots in Sparc MachineFunctions
91 ///
92 FunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) {
93   return new Filler(tm);
94 }
95
96
97 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
98 /// We assume there is only one delay slot per delayed instruction.
99 ///
100 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
101   bool Changed = false;
102
103   for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
104     if (I->hasDelaySlot()) {
105       MachineBasicBlock::iterator D = MBB.end();
106       MachineBasicBlock::iterator J = I;
107
108       if (!DisableDelaySlotFiller)
109         D = findDelayInstr(MBB, I);
110
111       ++FilledSlots;
112       Changed = true;
113
114       if (D == MBB.end())
115         BuildMI(MBB, ++J, I->getDebugLoc(), TII->get(SP::NOP));
116       else
117         MBB.splice(++J, &MBB, D);
118       unsigned structSize = 0;
119       if (needsUnimp(I, structSize)) {
120         MachineBasicBlock::iterator J = I;
121         ++J; //skip the delay filler.
122         BuildMI(MBB, ++J, I->getDebugLoc(),
123                 TII->get(SP::UNIMP)).addImm(structSize);
124       }
125     }
126   return Changed;
127 }
128
129 MachineBasicBlock::iterator
130 Filler::findDelayInstr(MachineBasicBlock &MBB,
131                        MachineBasicBlock::iterator slot)
132 {
133   SmallSet<unsigned, 32> RegDefs;
134   SmallSet<unsigned, 32> RegUses;
135   bool sawLoad = false;
136   bool sawStore = false;
137
138   if (slot == MBB.begin())
139     return MBB.end();
140
141   if (slot->getOpcode() == SP::RET)
142     return MBB.end();
143
144   if (slot->getOpcode() == SP::RETL) {
145     MachineBasicBlock::iterator J = slot;
146     --J;
147
148     if (J->getOpcode() == SP::RESTORErr
149         || J->getOpcode() == SP::RESTOREri) {
150       //change retl to ret
151       slot->setDesc(TII->get(SP::RET));
152       return J;
153     }
154   }
155
156   //Call's delay filler can def some of call's uses.
157   if (slot->isCall())
158     insertCallDefsUses(slot, RegDefs, RegUses);
159   else
160     insertDefsUses(slot, RegDefs, RegUses);
161
162   bool done = false;
163
164   MachineBasicBlock::iterator I = slot;
165
166   while (!done) {
167     done = (I == MBB.begin());
168
169     if (!done)
170       --I;
171
172     // skip debug value
173     if (I->isDebugValue())
174       continue;
175
176
177     if (I->hasUnmodeledSideEffects()
178         || I->isInlineAsm()
179         || I->isLabel()
180         || I->hasDelaySlot()
181         || isDelayFiller(MBB, I))
182       break;
183
184     if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
185       insertDefsUses(I, RegDefs, RegUses);
186       continue;
187     }
188
189     return I;
190   }
191   return MBB.end();
192 }
193
194 bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate,
195                             bool &sawLoad,
196                             bool &sawStore,
197                             SmallSet<unsigned, 32> &RegDefs,
198                             SmallSet<unsigned, 32> &RegUses)
199 {
200
201   if (candidate->isImplicitDef() || candidate->isKill())
202     return true;
203
204   if (candidate->mayLoad()) {
205     sawLoad = true;
206     if (sawStore)
207       return true;
208   }
209
210   if (candidate->mayStore()) {
211     if (sawStore)
212       return true;
213     sawStore = true;
214     if (sawLoad)
215       return true;
216   }
217
218   for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
219     const MachineOperand &MO = candidate->getOperand(i);
220     if (!MO.isReg())
221       continue; // skip
222
223     unsigned Reg = MO.getReg();
224
225     if (MO.isDef()) {
226       //check whether Reg is defined or used before delay slot.
227       if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
228         return true;
229     }
230     if (MO.isUse()) {
231       //check whether Reg is defined before delay slot.
232       if (IsRegInSet(RegDefs, Reg))
233         return true;
234     }
235   }
236   return false;
237 }
238
239
240 void Filler::insertCallDefsUses(MachineBasicBlock::iterator MI,
241                                 SmallSet<unsigned, 32>& RegDefs,
242                                 SmallSet<unsigned, 32>& RegUses)
243 {
244   //Call defines o7, which is visible to the instruction in delay slot.
245   RegDefs.insert(SP::O7);
246
247   switch(MI->getOpcode()) {
248   default: llvm_unreachable("Unknown opcode.");
249   case SP::CALL: break;
250   case SP::JMPLrr:
251   case SP::JMPLri:
252     assert(MI->getNumOperands() >= 2);
253     const MachineOperand &Reg = MI->getOperand(0);
254     assert(Reg.isReg() && "JMPL first operand is not a register.");
255     assert(Reg.isUse() && "JMPL first operand is not a use.");
256     RegUses.insert(Reg.getReg());
257
258     const MachineOperand &RegOrImm = MI->getOperand(1);
259     if (RegOrImm.isImm())
260         break;
261     assert(RegOrImm.isReg() && "JMPLrr second operand is not a register.");
262     assert(RegOrImm.isUse() && "JMPLrr second operand is not a use.");
263     RegUses.insert(RegOrImm.getReg());
264     break;
265   }
266 }
267
268 //Insert Defs and Uses of MI into the sets RegDefs and RegUses.
269 void Filler::insertDefsUses(MachineBasicBlock::iterator MI,
270                             SmallSet<unsigned, 32>& RegDefs,
271                             SmallSet<unsigned, 32>& RegUses)
272 {
273   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
274     const MachineOperand &MO = MI->getOperand(i);
275     if (!MO.isReg())
276       continue;
277
278     unsigned Reg = MO.getReg();
279     if (Reg == 0)
280       continue;
281     if (MO.isDef())
282       RegDefs.insert(Reg);
283     if (MO.isUse()) {
284       //Implicit register uses of retl are return values and
285       //retl does not use them.
286       if (MO.isImplicit() && MI->getOpcode() == SP::RETL)
287         continue;
288       RegUses.insert(Reg);
289     }
290   }
291 }
292
293 //returns true if the Reg or its alias is in the RegSet.
294 bool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg)
295 {
296   // Check Reg and all aliased Registers.
297   for (MCRegAliasIterator AI(Reg, TM.getRegisterInfo(), true);
298        AI.isValid(); ++AI)
299     if (RegSet.count(*AI))
300       return true;
301   return false;
302 }
303
304 // return true if the candidate is a delay filler.
305 bool Filler::isDelayFiller(MachineBasicBlock &MBB,
306                            MachineBasicBlock::iterator candidate)
307 {
308   if (candidate == MBB.begin())
309     return false;
310   if (candidate->getOpcode() == SP::UNIMP)
311     return true;
312   --candidate;
313   return candidate->hasDelaySlot();
314 }
315
316 bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
317 {
318   if (!I->isCall())
319     return false;
320
321   unsigned structSizeOpNum = 0;
322   switch (I->getOpcode()) {
323   default: llvm_unreachable("Unknown call opcode.");
324   case SP::CALL: structSizeOpNum = 1; break;
325   case SP::JMPLrr:
326   case SP::JMPLri: structSizeOpNum = 2; break;
327   }
328
329   const MachineOperand &MO = I->getOperand(structSizeOpNum);
330   if (!MO.isImm())
331     return false;
332   StructSize = MO.getImm();
333   return true;
334 }