annotate lib/Target/Lanai/LanaiDelaySlotFiller.cpp @ 131:f476a9ba4795

http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
author mir3636
date Fri, 16 Feb 2018 21:02:11 +0900
parents 1172e4bd9c6f
children 3a76565eade5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
1 //===-- LanaiDelaySlotFiller.cpp - Lanai delay slot filler ----------------===//
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
2 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
3 // The LLVM Compiler Infrastructure
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
4 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
7 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
9 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
10 // Simple pass to fills delay slots with useful instructions.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
11 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
13
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
14 #include "Lanai.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
15 #include "LanaiTargetMachine.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
16 #include "llvm/ADT/SmallSet.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
17 #include "llvm/ADT/Statistic.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
18 #include "llvm/CodeGen/MachineFunctionPass.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
20 #include "llvm/Support/CommandLine.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
21 #include "llvm/Target/TargetInstrInfo.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
22
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
23 using namespace llvm;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
24
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
25 #define DEBUG_TYPE "delay-slot-filler"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
26
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
27 STATISTIC(FilledSlots, "Number of delay slots filled");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
28
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
29 static cl::opt<bool>
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
30 NopDelaySlotFiller("lanai-nop-delay-filler", cl::init(false),
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
31 cl::desc("Fill Lanai delay slots with NOPs."),
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
32 cl::Hidden);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
33
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
34 namespace {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
35 struct Filler : public MachineFunctionPass {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
36 // Target machine description which we query for reg. names, data
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
37 // layout, etc.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
38 const TargetInstrInfo *TII;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
39 const TargetRegisterInfo *TRI;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
40 MachineBasicBlock::instr_iterator LastFiller;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
41
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
42 static char ID;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
43 explicit Filler() : MachineFunctionPass(ID) {}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
44
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
45 StringRef getPassName() const override { return "Lanai Delay Slot Filler"; }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
46
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
47 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
48
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
49 bool runOnMachineFunction(MachineFunction &MF) override {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
50 const LanaiSubtarget &Subtarget = MF.getSubtarget<LanaiSubtarget>();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
51 TII = Subtarget.getInstrInfo();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
52 TRI = Subtarget.getRegisterInfo();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
53
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
54 bool Changed = false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
55 for (MachineFunction::iterator FI = MF.begin(), FE = MF.end(); FI != FE;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
56 ++FI)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
57 Changed |= runOnMachineBasicBlock(*FI);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
58 return Changed;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
59 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
60
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
61 MachineFunctionProperties getRequiredProperties() const override {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
62 return MachineFunctionProperties().set(
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
63 MachineFunctionProperties::Property::NoVRegs);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
64 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
65
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
66 void insertDefsUses(MachineBasicBlock::instr_iterator MI,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
67 SmallSet<unsigned, 32> &RegDefs,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
68 SmallSet<unsigned, 32> &RegUses);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
69
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
70 bool isRegInSet(SmallSet<unsigned, 32> &RegSet, unsigned Reg);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
71
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
72 bool delayHasHazard(MachineBasicBlock::instr_iterator MI, bool &SawLoad,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
73 bool &SawStore, SmallSet<unsigned, 32> &RegDefs,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
74 SmallSet<unsigned, 32> &RegUses);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
75
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
76 bool findDelayInstr(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
77 MachineBasicBlock::instr_iterator Slot,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
78 MachineBasicBlock::instr_iterator &Filler);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
79 };
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
80 char Filler::ID = 0;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
81 } // end of anonymous namespace
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
82
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
83 // createLanaiDelaySlotFillerPass - Returns a pass that fills in delay
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
84 // slots in Lanai MachineFunctions
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
85 FunctionPass *
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
86 llvm::createLanaiDelaySlotFillerPass(const LanaiTargetMachine & /*tm*/) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
87 return new Filler();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
88 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
89
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
90 // runOnMachineBasicBlock - Fill in delay slots for the given basic block.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
91 // There is one or two delay slot per delayed instruction.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
92 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
93 bool Changed = false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
94 LastFiller = MBB.instr_end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
95
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
96 for (MachineBasicBlock::instr_iterator I = MBB.instr_begin();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
97 I != MBB.instr_end(); ++I) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
98 if (I->getDesc().hasDelaySlot()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
99 MachineBasicBlock::instr_iterator InstrWithSlot = I;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
100 MachineBasicBlock::instr_iterator J = I;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
101
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
102 // Treat RET specially as it is only instruction with 2 delay slots
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
103 // generated while all others generated have 1 delay slot.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
104 if (I->getOpcode() == Lanai::RET) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
105 // RET is generated as part of epilogue generation and hence we know
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
106 // what the two instructions preceding it are and that it is safe to
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
107 // insert RET above them.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
108 MachineBasicBlock::reverse_instr_iterator RI = ++I.getReverse();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
109 assert(RI->getOpcode() == Lanai::LDW_RI && RI->getOperand(0).isReg() &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
110 RI->getOperand(0).getReg() == Lanai::FP &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
111 RI->getOperand(1).isReg() &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
112 RI->getOperand(1).getReg() == Lanai::FP &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
113 RI->getOperand(2).isImm() && RI->getOperand(2).getImm() == -8);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
114 ++RI;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
115 assert(RI->getOpcode() == Lanai::ADD_I_LO &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
116 RI->getOperand(0).isReg() &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
117 RI->getOperand(0).getReg() == Lanai::SP &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
118 RI->getOperand(1).isReg() &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
119 RI->getOperand(1).getReg() == Lanai::FP);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
120 MachineBasicBlock::instr_iterator FI = RI.getReverse();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
121 MBB.splice(std::next(I), &MBB, FI, I);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
122 FilledSlots += 2;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
123 } else {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
124 if (!NopDelaySlotFiller && findDelayInstr(MBB, I, J)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
125 MBB.splice(std::next(I), &MBB, J);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
126 } else {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
127 BuildMI(MBB, std::next(I), DebugLoc(), TII->get(Lanai::NOP));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
128 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
129 ++FilledSlots;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
130 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
131
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
132 Changed = true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
133 // Record the filler instruction that filled the delay slot.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
134 // The instruction after it will be visited in the next iteration.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
135 LastFiller = ++I;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
136
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
137 // Bundle the delay slot filler to InstrWithSlot so that the machine
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
138 // verifier doesn't expect this instruction to be a terminator.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
139 MIBundleBuilder(MBB, InstrWithSlot, std::next(LastFiller));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
140 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
141 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
142 return Changed;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
143 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
144
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
145 bool Filler::findDelayInstr(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
146 MachineBasicBlock::instr_iterator Slot,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
147 MachineBasicBlock::instr_iterator &Filler) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
148 SmallSet<unsigned, 32> RegDefs;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
149 SmallSet<unsigned, 32> RegUses;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
150
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
151 insertDefsUses(Slot, RegDefs, RegUses);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
152
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
153 bool SawLoad = false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
154 bool SawStore = false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
155
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
156 for (MachineBasicBlock::reverse_instr_iterator I = ++Slot.getReverse();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
157 I != MBB.instr_rend(); ++I) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
158 // skip debug value
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
159 if (I->isDebugValue())
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
160 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
161
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
162 // Convert to forward iterator.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
163 MachineBasicBlock::instr_iterator FI = I.getReverse();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
164
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
165 if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isLabel() ||
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
166 FI == LastFiller || I->isPseudo())
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
167 break;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
168
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
169 if (delayHasHazard(FI, SawLoad, SawStore, RegDefs, RegUses)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
170 insertDefsUses(FI, RegDefs, RegUses);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
171 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
172 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
173 Filler = FI;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
174 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
175 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
176 return false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
177 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
178
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
179 bool Filler::delayHasHazard(MachineBasicBlock::instr_iterator MI, bool &SawLoad,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
180 bool &SawStore, SmallSet<unsigned, 32> &RegDefs,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
181 SmallSet<unsigned, 32> &RegUses) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
182 if (MI->isImplicitDef() || MI->isKill())
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
183 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
184
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
185 // Loads or stores cannot be moved past a store to the delay slot
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
186 // and stores cannot be moved past a load.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
187 if (MI->mayLoad()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
188 if (SawStore)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
189 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
190 SawLoad = true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
191 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
192
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
193 if (MI->mayStore()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
194 if (SawStore)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
195 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
196 SawStore = true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
197 if (SawLoad)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
198 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
199 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
200
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
201 assert((!MI->isCall() && !MI->isReturn()) &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
202 "Cannot put calls or returns in delay slot.");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
203
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
204 for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
205 const MachineOperand &MO = MI->getOperand(I);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
206 unsigned Reg;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
207
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
208 if (!MO.isReg() || !(Reg = MO.getReg()))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
209 continue; // skip
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
210
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
211 if (MO.isDef()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
212 // check whether Reg is defined or used before delay slot.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
213 if (isRegInSet(RegDefs, Reg) || isRegInSet(RegUses, Reg))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
214 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
215 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
216 if (MO.isUse()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
217 // check whether Reg is defined before delay slot.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
218 if (isRegInSet(RegDefs, Reg))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
219 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
220 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
221 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
222 return false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
223 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
224
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
225 // Insert Defs and Uses of MI into the sets RegDefs and RegUses.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
226 void Filler::insertDefsUses(MachineBasicBlock::instr_iterator MI,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
227 SmallSet<unsigned, 32> &RegDefs,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
228 SmallSet<unsigned, 32> &RegUses) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
229 // If MI is a call or return, just examine the explicit non-variadic operands.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
230 MCInstrDesc MCID = MI->getDesc();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
231 unsigned E = MI->isCall() || MI->isReturn() ? MCID.getNumOperands()
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
232 : MI->getNumOperands();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
233 for (unsigned I = 0; I != E; ++I) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
234 const MachineOperand &MO = MI->getOperand(I);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
235 unsigned Reg;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
236
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
237 if (!MO.isReg() || !(Reg = MO.getReg()))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
238 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
239
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
240 if (MO.isDef())
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
241 RegDefs.insert(Reg);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
242 else if (MO.isUse())
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
243 RegUses.insert(Reg);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
244 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
245
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
246 // Call & return instructions defines SP implicitly. Implicit defines are not
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
247 // included in the RegDefs set of calls but instructions modifying SP cannot
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
248 // be inserted in the delay slot of a call/return as these instructions are
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
249 // expanded to multiple instructions with SP modified before the branch that
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
250 // has the delay slot.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
251 if (MI->isCall() || MI->isReturn())
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
252 RegDefs.insert(Lanai::SP);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
253 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
254
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
255 // Returns true if the Reg or its alias is in the RegSet.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
256 bool Filler::isRegInSet(SmallSet<unsigned, 32> &RegSet, unsigned Reg) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
257 // Check Reg and all aliased Registers.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
258 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
259 if (RegSet.count(*AI))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
260 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
261 return false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
262 }