blob: d62b166a10c7ea304aff90e62ca35796391ff544 [file] [log] [blame]
Akira Hatanaka90db35a2013-02-14 23:20:15 +00001//===-- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler ------------------===//
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +00007//
Akira Hatanaka4552c9a2011-04-15 21:51:11 +00008//===----------------------------------------------------------------------===//
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +00009//
Akira Hatanaka90db35a2013-02-14 23:20:15 +000010// Simple pass to fill delay slots with useful instructions.
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000011//
Akira Hatanaka4552c9a2011-04-15 21:51:11 +000012//===----------------------------------------------------------------------===//
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000013
14#define DEBUG_TYPE "delay-slot-filler"
15
16#include "Mips.h"
17#include "MipsTargetMachine.h"
Akira Hatanakacd7319d2013-02-14 23:40:57 +000018#include "llvm/ADT/BitVector.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000019#include "llvm/ADT/Statistic.h"
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000020#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
Akira Hatanakaa3defb02011-09-29 23:52:13 +000022#include "llvm/Support/CommandLine.h"
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000023#include "llvm/Target/TargetInstrInfo.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000024#include "llvm/Target/TargetMachine.h"
Akira Hatanakaa3defb02011-09-29 23:52:13 +000025#include "llvm/Target/TargetRegisterInfo.h"
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000026
27using namespace llvm;
28
29STATISTIC(FilledSlots, "Number of delay slots filled");
Akira Hatanaka98f4d4d2011-10-05 01:19:13 +000030STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"
Akira Hatanaka176965f2011-10-05 02:22:49 +000031 " are not NOP.");
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000032
Akira Hatanaka6522a9e2012-08-22 02:51:28 +000033static cl::opt<bool> DisableDelaySlotFiller(
34 "disable-mips-delay-filler",
Akira Hatanakaa3defb02011-09-29 23:52:13 +000035 cl::init(false),
Akira Hatanaka90db35a2013-02-14 23:20:15 +000036 cl::desc("Fill all delay slots with NOPs."),
Akira Hatanakaa3defb02011-09-29 23:52:13 +000037 cl::Hidden);
38
Akira Hatanakaf9c3f3b2012-05-14 23:59:17 +000039// This option can be used to silence complaints by machine verifier passes.
40static cl::opt<bool> SkipDelaySlotFiller(
41 "skip-mips-delay-filler",
42 cl::init(false),
43 cl::desc("Skip MIPS' delay slot filling pass."),
44 cl::Hidden);
45
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000046namespace {
Akira Hatanaka70cdcd52013-02-26 01:30:05 +000047 class RegDefsUses {
48 public:
49 RegDefsUses(TargetMachine &TM);
50 void init(const MachineInstr &MI);
51 bool update(const MachineInstr &MI, unsigned Begin, unsigned End);
52
53 private:
54 bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses, unsigned Reg,
55 bool IsDef) const;
56
57 /// Returns true if Reg or its alias is in RegSet.
58 bool isRegInSet(const BitVector &RegSet, unsigned Reg) const;
59
60 const TargetRegisterInfo &TRI;
61 BitVector Defs, Uses;
62 };
63
Akira Hatanaka5dd41c92013-02-07 21:32:32 +000064 class Filler : public MachineFunctionPass {
65 public:
Bruno Cardoso Lopes90c59542010-12-09 17:31:11 +000066 Filler(TargetMachine &tm)
Owen Anderson90c579d2010-08-06 18:33:48 +000067 : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000068
69 virtual const char *getPassName() const {
70 return "Mips Delay Slot Filler";
71 }
72
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000073 bool runOnMachineFunction(MachineFunction &F) {
Akira Hatanakaf9c3f3b2012-05-14 23:59:17 +000074 if (SkipDelaySlotFiller)
75 return false;
76
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +000077 bool Changed = false;
78 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
79 FI != FE; ++FI)
80 Changed |= runOnMachineBasicBlock(*FI);
81 return Changed;
82 }
83
Akira Hatanaka5dd41c92013-02-07 21:32:32 +000084 private:
Akira Hatanakaeba97c52013-02-14 23:11:24 +000085 typedef MachineBasicBlock::iterator Iter;
86 typedef MachineBasicBlock::reverse_iterator ReverseIter;
Akira Hatanaka5dd41c92013-02-07 21:32:32 +000087
88 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
89
Akira Hatanakacd7319d2013-02-14 23:40:57 +000090 /// This function checks if it is valid to move Candidate to the delay slot
91 /// and returns true if it isn't. It also updates load and store flags and
92 /// register defs and uses.
Akira Hatanaka90db35a2013-02-14 23:20:15 +000093 bool delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
Akira Hatanaka70cdcd52013-02-26 01:30:05 +000094 bool &SawStore, RegDefsUses &RegDU) const;
Akira Hatanakaa3defb02011-09-29 23:52:13 +000095
Akira Hatanaka90db35a2013-02-14 23:20:15 +000096 bool findDelayInstr(MachineBasicBlock &MBB, Iter slot, Iter &Filler) const;
Akira Hatanakaeba97c52013-02-14 23:11:24 +000097
98 bool terminateSearch(const MachineInstr &Candidate) const;
Akira Hatanakaa3defb02011-09-29 23:52:13 +000099
Akira Hatanaka5dd41c92013-02-07 21:32:32 +0000100 TargetMachine &TM;
101 const TargetInstrInfo *TII;
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000102
Akira Hatanaka5dd41c92013-02-07 21:32:32 +0000103 static char ID;
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +0000104 };
105 char Filler::ID = 0;
106} // end of anonymous namespace
107
Akira Hatanaka70cdcd52013-02-26 01:30:05 +0000108RegDefsUses::RegDefsUses(TargetMachine &TM)
109 : TRI(*TM.getRegisterInfo()), Defs(TRI.getNumRegs(), false),
110 Uses(TRI.getNumRegs(), false) {}
111
112void RegDefsUses::init(const MachineInstr &MI) {
113 // Add all register operands which are explicit and non-variadic.
114 update(MI, 0, MI.getDesc().getNumOperands());
115
116 // If MI is a call, add RA to Defs to prevent users of RA from going into
117 // delay slot.
118 if (MI.isCall())
119 Defs.set(Mips::RA);
120
121 // Add all implicit register operands of branch instructions except
122 // register AT.
123 if (MI.isBranch()) {
124 update(MI, MI.getDesc().getNumOperands(), MI.getNumOperands());
125 Defs.reset(Mips::AT);
126 }
127}
128
129bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {
130 BitVector NewDefs(TRI.getNumRegs()), NewUses(TRI.getNumRegs());
131 bool HasHazard = false;
132
133 for (unsigned I = Begin; I != End; ++I) {
134 const MachineOperand &MO = MI.getOperand(I);
135
136 if (MO.isReg() && MO.getReg())
137 HasHazard |= checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef());
138 }
139
140 Defs |= NewDefs;
141 Uses |= NewUses;
142
143 return HasHazard;
144}
145
146bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,
147 unsigned Reg, bool IsDef) const {
148 if (IsDef) {
149 NewDefs.set(Reg);
150 // check whether Reg has already been defined or used.
151 return (isRegInSet(Defs, Reg) || isRegInSet(Uses, Reg));
152 }
153
154 NewUses.set(Reg);
155 // check whether Reg has already been defined.
156 return isRegInSet(Defs, Reg);
157}
158
159bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const {
160 // Check Reg and all aliased Registers.
161 for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
162 if (RegSet.test(*AI))
163 return true;
164 return false;
165}
166
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +0000167/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000168/// We assume there is only one delay slot per delayed instruction.
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000169bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +0000170 bool Changed = false;
Akira Hatanaka53120e02011-10-05 01:30:09 +0000171
Akira Hatanakaeba97c52013-02-14 23:11:24 +0000172 for (Iter I = MBB.begin(); I != MBB.end(); ++I) {
Akira Hatanaka5dd41c92013-02-07 21:32:32 +0000173 if (!I->hasDelaySlot())
174 continue;
Akira Hatanaka6f818ab2011-10-05 01:23:39 +0000175
Akira Hatanaka5dd41c92013-02-07 21:32:32 +0000176 ++FilledSlots;
177 Changed = true;
Akira Hatanakaeba97c52013-02-14 23:11:24 +0000178 Iter D;
Akira Hatanaka6f818ab2011-10-05 01:23:39 +0000179
Akira Hatanaka5dd41c92013-02-07 21:32:32 +0000180 // Delay slot filling is disabled at -O0.
181 if (!DisableDelaySlotFiller && (TM.getOptLevel() != CodeGenOpt::None) &&
182 findDelayInstr(MBB, I, D)) {
183 MBB.splice(llvm::next(I), &MBB, D);
184 ++UsefulSlots;
185 } else
186 BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP));
Akira Hatanaka15841392012-06-13 23:25:52 +0000187
Akira Hatanakaeba97c52013-02-14 23:11:24 +0000188 // Bundle the delay slot filler to the instruction with the delay slot.
189 MIBundleBuilder(MBB, I, llvm::next(llvm::next(I)));
Akira Hatanaka5dd41c92013-02-07 21:32:32 +0000190 }
191
Bruno Cardoso Lopes9684a692007-08-18 01:50:47 +0000192 return Changed;
193}
194
195/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay
196/// slots in Mips MachineFunctions
197FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) {
198 return new Filler(tm);
199}
200
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000201bool Filler::findDelayInstr(MachineBasicBlock &MBB, Iter Slot,
202 Iter &Filler) const {
Akira Hatanaka70cdcd52013-02-26 01:30:05 +0000203 RegDefsUses RegDU(TM);
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000204
Akira Hatanaka70cdcd52013-02-26 01:30:05 +0000205 RegDU.init(*Slot);
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000206
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000207 bool SawLoad = false;
208 bool SawStore = false;
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000209
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000210 for (ReverseIter I(Slot); I != MBB.rend(); ++I) {
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000211 // skip debug value
212 if (I->isDebugValue())
213 continue;
214
Akira Hatanakaeba97c52013-02-14 23:11:24 +0000215 if (terminateSearch(*I))
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000216 break;
217
Akira Hatanaka70cdcd52013-02-26 01:30:05 +0000218 if (delayHasHazard(*I, SawLoad, SawStore, RegDU))
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000219 continue;
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000220
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000221 Filler = llvm::next(I).base();
Akira Hatanaka6f818ab2011-10-05 01:23:39 +0000222 return true;
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000223 }
Akira Hatanaka6f818ab2011-10-05 01:23:39 +0000224
225 return false;
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000226}
227
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000228bool Filler::delayHasHazard(const MachineInstr &Candidate, bool &SawLoad,
Akira Hatanaka70cdcd52013-02-26 01:30:05 +0000229 bool &SawStore, RegDefsUses &RegDU) const {
Akira Hatanakacd7319d2013-02-14 23:40:57 +0000230 bool HasHazard = (Candidate.isImplicitDef() || Candidate.isKill());
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000231
Akira Hatanakacfc3fb52011-10-05 01:09:37 +0000232 // Loads or stores cannot be moved past a store to the delay slot
Jia Liubb481f82012-02-28 07:46:26 +0000233 // and stores cannot be moved past a load.
Akira Hatanakad977aac2013-02-14 23:54:40 +0000234 if (Candidate.mayStore() || Candidate.hasOrderedMemoryRef()) {
Akira Hatanakacd7319d2013-02-14 23:40:57 +0000235 HasHazard |= SawStore | SawLoad;
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000236 SawStore = true;
Akira Hatanakacd7319d2013-02-14 23:40:57 +0000237 } else if (Candidate.mayLoad()) {
238 HasHazard |= SawStore;
239 SawLoad = true;
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000240 }
241
Akira Hatanaka90db35a2013-02-14 23:20:15 +0000242 assert((!Candidate.isCall() && !Candidate.isReturn()) &&
Akira Hatanaka42be2802011-10-05 18:17:49 +0000243 "Cannot put calls or returns in delay slot.");
Akira Hatanaka0c419a72011-10-05 02:18:58 +0000244
Akira Hatanaka70cdcd52013-02-26 01:30:05 +0000245 HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000246
Akira Hatanakacd7319d2013-02-14 23:40:57 +0000247 return HasHazard;
Akira Hatanakaa3defb02011-09-29 23:52:13 +0000248}
249
Akira Hatanakaeba97c52013-02-14 23:11:24 +0000250bool Filler::terminateSearch(const MachineInstr &Candidate) const {
251 return (Candidate.isTerminator() || Candidate.isCall() ||
252 Candidate.isLabel() || Candidate.isInlineAsm() ||
253 Candidate.hasUnmodeledSideEffects());
254}