1*9880d681SAndroid Build Coastguard Worker //===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBundle.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallSet.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include <utility>
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker namespace {
24*9880d681SAndroid Build Coastguard Worker class UnpackMachineBundles : public MachineFunctionPass {
25*9880d681SAndroid Build Coastguard Worker public:
26*9880d681SAndroid Build Coastguard Worker static char ID; // Pass identification
UnpackMachineBundles(std::function<bool (const Function &)> Ftor=nullptr)27*9880d681SAndroid Build Coastguard Worker UnpackMachineBundles(std::function<bool(const Function &)> Ftor = nullptr)
28*9880d681SAndroid Build Coastguard Worker : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
29*9880d681SAndroid Build Coastguard Worker initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker private:
35*9880d681SAndroid Build Coastguard Worker std::function<bool(const Function &)> PredicateFtor;
36*9880d681SAndroid Build Coastguard Worker };
37*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker char UnpackMachineBundles::ID = 0;
40*9880d681SAndroid Build Coastguard Worker char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
41*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",
42*9880d681SAndroid Build Coastguard Worker "Unpack machine instruction bundles", false, false)
43*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)44*9880d681SAndroid Build Coastguard Worker bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
45*9880d681SAndroid Build Coastguard Worker if (PredicateFtor && !PredicateFtor(*MF.getFunction()))
46*9880d681SAndroid Build Coastguard Worker return false;
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker bool Changed = false;
49*9880d681SAndroid Build Coastguard Worker for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
50*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = &*I;
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(),
53*9880d681SAndroid Build Coastguard Worker MIE = MBB->instr_end(); MII != MIE; ) {
54*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*MII;
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker // Remove BUNDLE instruction and the InsideBundle flags from bundled
57*9880d681SAndroid Build Coastguard Worker // instructions.
58*9880d681SAndroid Build Coastguard Worker if (MI->isBundle()) {
59*9880d681SAndroid Build Coastguard Worker while (++MII != MIE && MII->isBundledWithPred()) {
60*9880d681SAndroid Build Coastguard Worker MII->unbundleFromPred();
61*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
62*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = MII->getOperand(i);
63*9880d681SAndroid Build Coastguard Worker if (MO.isReg() && MO.isInternalRead())
64*9880d681SAndroid Build Coastguard Worker MO.setIsInternalRead(false);
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker MI->eraseFromParent();
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker Changed = true;
70*9880d681SAndroid Build Coastguard Worker continue;
71*9880d681SAndroid Build Coastguard Worker }
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker ++MII;
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker }
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker return Changed;
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker FunctionPass *
createUnpackMachineBundles(std::function<bool (const Function &)> Ftor)81*9880d681SAndroid Build Coastguard Worker llvm::createUnpackMachineBundles(std::function<bool(const Function &)> Ftor) {
82*9880d681SAndroid Build Coastguard Worker return new UnpackMachineBundles(std::move(Ftor));
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker namespace {
86*9880d681SAndroid Build Coastguard Worker class FinalizeMachineBundles : public MachineFunctionPass {
87*9880d681SAndroid Build Coastguard Worker public:
88*9880d681SAndroid Build Coastguard Worker static char ID; // Pass identification
FinalizeMachineBundles()89*9880d681SAndroid Build Coastguard Worker FinalizeMachineBundles() : MachineFunctionPass(ID) {
90*9880d681SAndroid Build Coastguard Worker initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry());
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
94*9880d681SAndroid Build Coastguard Worker };
95*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker char FinalizeMachineBundles::ID = 0;
98*9880d681SAndroid Build Coastguard Worker char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID;
99*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles",
100*9880d681SAndroid Build Coastguard Worker "Finalize machine instruction bundles", false, false)
101*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)102*9880d681SAndroid Build Coastguard Worker bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) {
103*9880d681SAndroid Build Coastguard Worker return llvm::finalizeBundles(MF);
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker /// finalizeBundle - Finalize a machine instruction bundle which includes
108*9880d681SAndroid Build Coastguard Worker /// a sequence of instructions starting from FirstMI to LastMI (exclusive).
109*9880d681SAndroid Build Coastguard Worker /// This routine adds a BUNDLE instruction to represent the bundle, it adds
110*9880d681SAndroid Build Coastguard Worker /// IsInternalRead markers to MachineOperands which are defined inside the
111*9880d681SAndroid Build Coastguard Worker /// bundle, and it copies externally visible defs and uses to the BUNDLE
112*9880d681SAndroid Build Coastguard Worker /// instruction.
finalizeBundle(MachineBasicBlock & MBB,MachineBasicBlock::instr_iterator FirstMI,MachineBasicBlock::instr_iterator LastMI)113*9880d681SAndroid Build Coastguard Worker void llvm::finalizeBundle(MachineBasicBlock &MBB,
114*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator FirstMI,
115*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator LastMI) {
116*9880d681SAndroid Build Coastguard Worker assert(FirstMI != LastMI && "Empty bundle?");
117*9880d681SAndroid Build Coastguard Worker MIBundleBuilder Bundle(MBB, FirstMI, LastMI);
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = *MBB.getParent();
120*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
121*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder MIB =
124*9880d681SAndroid Build Coastguard Worker BuildMI(MF, FirstMI->getDebugLoc(), TII->get(TargetOpcode::BUNDLE));
125*9880d681SAndroid Build Coastguard Worker Bundle.prepend(MIB);
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 32> LocalDefs;
128*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned, 32> LocalDefSet;
129*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned, 8> DeadDefSet;
130*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned, 16> KilledDefSet;
131*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 8> ExternUses;
132*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned, 8> ExternUseSet;
133*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned, 8> KilledUseSet;
134*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned, 8> UndefUseSet;
135*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand*, 4> Defs;
136*9880d681SAndroid Build Coastguard Worker for (; FirstMI != LastMI; ++FirstMI) {
137*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = FirstMI->getNumOperands(); i != e; ++i) {
138*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = FirstMI->getOperand(i);
139*9880d681SAndroid Build Coastguard Worker if (!MO.isReg())
140*9880d681SAndroid Build Coastguard Worker continue;
141*9880d681SAndroid Build Coastguard Worker if (MO.isDef()) {
142*9880d681SAndroid Build Coastguard Worker Defs.push_back(&MO);
143*9880d681SAndroid Build Coastguard Worker continue;
144*9880d681SAndroid Build Coastguard Worker }
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO.getReg();
147*9880d681SAndroid Build Coastguard Worker if (!Reg)
148*9880d681SAndroid Build Coastguard Worker continue;
149*9880d681SAndroid Build Coastguard Worker assert(TargetRegisterInfo::isPhysicalRegister(Reg));
150*9880d681SAndroid Build Coastguard Worker if (LocalDefSet.count(Reg)) {
151*9880d681SAndroid Build Coastguard Worker MO.setIsInternalRead();
152*9880d681SAndroid Build Coastguard Worker if (MO.isKill())
153*9880d681SAndroid Build Coastguard Worker // Internal def is now killed.
154*9880d681SAndroid Build Coastguard Worker KilledDefSet.insert(Reg);
155*9880d681SAndroid Build Coastguard Worker } else {
156*9880d681SAndroid Build Coastguard Worker if (ExternUseSet.insert(Reg).second) {
157*9880d681SAndroid Build Coastguard Worker ExternUses.push_back(Reg);
158*9880d681SAndroid Build Coastguard Worker if (MO.isUndef())
159*9880d681SAndroid Build Coastguard Worker UndefUseSet.insert(Reg);
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker if (MO.isKill())
162*9880d681SAndroid Build Coastguard Worker // External def is now killed.
163*9880d681SAndroid Build Coastguard Worker KilledUseSet.insert(Reg);
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
168*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = *Defs[i];
169*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO.getReg();
170*9880d681SAndroid Build Coastguard Worker if (!Reg)
171*9880d681SAndroid Build Coastguard Worker continue;
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker if (LocalDefSet.insert(Reg).second) {
174*9880d681SAndroid Build Coastguard Worker LocalDefs.push_back(Reg);
175*9880d681SAndroid Build Coastguard Worker if (MO.isDead()) {
176*9880d681SAndroid Build Coastguard Worker DeadDefSet.insert(Reg);
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker } else {
179*9880d681SAndroid Build Coastguard Worker // Re-defined inside the bundle, it's no longer killed.
180*9880d681SAndroid Build Coastguard Worker KilledDefSet.erase(Reg);
181*9880d681SAndroid Build Coastguard Worker if (!MO.isDead())
182*9880d681SAndroid Build Coastguard Worker // Previously defined but dead.
183*9880d681SAndroid Build Coastguard Worker DeadDefSet.erase(Reg);
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker if (!MO.isDead()) {
187*9880d681SAndroid Build Coastguard Worker for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
188*9880d681SAndroid Build Coastguard Worker unsigned SubReg = *SubRegs;
189*9880d681SAndroid Build Coastguard Worker if (LocalDefSet.insert(SubReg).second)
190*9880d681SAndroid Build Coastguard Worker LocalDefs.push_back(SubReg);
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker }
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker Defs.clear();
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned, 32> Added;
199*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
200*9880d681SAndroid Build Coastguard Worker unsigned Reg = LocalDefs[i];
201*9880d681SAndroid Build Coastguard Worker if (Added.insert(Reg).second) {
202*9880d681SAndroid Build Coastguard Worker // If it's not live beyond end of the bundle, mark it dead.
203*9880d681SAndroid Build Coastguard Worker bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg);
204*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) |
205*9880d681SAndroid Build Coastguard Worker getImplRegState(true));
206*9880d681SAndroid Build Coastguard Worker }
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker
209*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) {
210*9880d681SAndroid Build Coastguard Worker unsigned Reg = ExternUses[i];
211*9880d681SAndroid Build Coastguard Worker bool isKill = KilledUseSet.count(Reg);
212*9880d681SAndroid Build Coastguard Worker bool isUndef = UndefUseSet.count(Reg);
213*9880d681SAndroid Build Coastguard Worker MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
214*9880d681SAndroid Build Coastguard Worker getImplRegState(true));
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker }
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker /// finalizeBundle - Same functionality as the previous finalizeBundle except
219*9880d681SAndroid Build Coastguard Worker /// the last instruction in the bundle is not provided as an input. This is
220*9880d681SAndroid Build Coastguard Worker /// used in cases where bundles are pre-determined by marking instructions
221*9880d681SAndroid Build Coastguard Worker /// with 'InsideBundle' marker. It returns the MBB instruction iterator that
222*9880d681SAndroid Build Coastguard Worker /// points to the end of the bundle.
223*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator
finalizeBundle(MachineBasicBlock & MBB,MachineBasicBlock::instr_iterator FirstMI)224*9880d681SAndroid Build Coastguard Worker llvm::finalizeBundle(MachineBasicBlock &MBB,
225*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator FirstMI) {
226*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator E = MBB.instr_end();
227*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
228*9880d681SAndroid Build Coastguard Worker while (LastMI != E && LastMI->isInsideBundle())
229*9880d681SAndroid Build Coastguard Worker ++LastMI;
230*9880d681SAndroid Build Coastguard Worker finalizeBundle(MBB, FirstMI, LastMI);
231*9880d681SAndroid Build Coastguard Worker return LastMI;
232*9880d681SAndroid Build Coastguard Worker }
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard Worker /// finalizeBundles - Finalize instruction bundles in the specified
235*9880d681SAndroid Build Coastguard Worker /// MachineFunction. Return true if any bundles are finalized.
finalizeBundles(MachineFunction & MF)236*9880d681SAndroid Build Coastguard Worker bool llvm::finalizeBundles(MachineFunction &MF) {
237*9880d681SAndroid Build Coastguard Worker bool Changed = false;
238*9880d681SAndroid Build Coastguard Worker for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
239*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB = *I;
240*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator MII = MBB.instr_begin();
241*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::instr_iterator MIE = MBB.instr_end();
242*9880d681SAndroid Build Coastguard Worker if (MII == MIE)
243*9880d681SAndroid Build Coastguard Worker continue;
244*9880d681SAndroid Build Coastguard Worker assert(!MII->isInsideBundle() &&
245*9880d681SAndroid Build Coastguard Worker "First instr cannot be inside bundle before finalization!");
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker for (++MII; MII != MIE; ) {
248*9880d681SAndroid Build Coastguard Worker if (!MII->isInsideBundle())
249*9880d681SAndroid Build Coastguard Worker ++MII;
250*9880d681SAndroid Build Coastguard Worker else {
251*9880d681SAndroid Build Coastguard Worker MII = finalizeBundle(MBB, std::prev(MII));
252*9880d681SAndroid Build Coastguard Worker Changed = true;
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker return Changed;
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
261*9880d681SAndroid Build Coastguard Worker // MachineOperand iterator
262*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker MachineOperandIteratorBase::VirtRegInfo
analyzeVirtReg(unsigned Reg,SmallVectorImpl<std::pair<MachineInstr *,unsigned>> * Ops)265*9880d681SAndroid Build Coastguard Worker MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg,
266*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops) {
267*9880d681SAndroid Build Coastguard Worker VirtRegInfo RI = { false, false, false };
268*9880d681SAndroid Build Coastguard Worker for(; isValid(); ++*this) {
269*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = deref();
270*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || MO.getReg() != Reg)
271*9880d681SAndroid Build Coastguard Worker continue;
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Worker // Remember each (MI, OpNo) that refers to Reg.
274*9880d681SAndroid Build Coastguard Worker if (Ops)
275*9880d681SAndroid Build Coastguard Worker Ops->push_back(std::make_pair(MO.getParent(), getOperandNo()));
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker // Both defs and uses can read virtual registers.
278*9880d681SAndroid Build Coastguard Worker if (MO.readsReg()) {
279*9880d681SAndroid Build Coastguard Worker RI.Reads = true;
280*9880d681SAndroid Build Coastguard Worker if (MO.isDef())
281*9880d681SAndroid Build Coastguard Worker RI.Tied = true;
282*9880d681SAndroid Build Coastguard Worker }
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker // Only defs can write.
285*9880d681SAndroid Build Coastguard Worker if (MO.isDef())
286*9880d681SAndroid Build Coastguard Worker RI.Writes = true;
287*9880d681SAndroid Build Coastguard Worker else if (!RI.Tied && MO.getParent()->isRegTiedToDefOperand(getOperandNo()))
288*9880d681SAndroid Build Coastguard Worker RI.Tied = true;
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker return RI;
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker MachineOperandIteratorBase::PhysRegInfo
analyzePhysReg(unsigned Reg,const TargetRegisterInfo * TRI)294*9880d681SAndroid Build Coastguard Worker MachineOperandIteratorBase::analyzePhysReg(unsigned Reg,
295*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) {
296*9880d681SAndroid Build Coastguard Worker bool AllDefsDead = true;
297*9880d681SAndroid Build Coastguard Worker PhysRegInfo PRI = {false, false, false, false, false, false, false, false};
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
300*9880d681SAndroid Build Coastguard Worker "analyzePhysReg not given a physical register!");
301*9880d681SAndroid Build Coastguard Worker for (; isValid(); ++*this) {
302*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = deref();
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) {
305*9880d681SAndroid Build Coastguard Worker PRI.Clobbered = true;
306*9880d681SAndroid Build Coastguard Worker continue;
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker if (!MO.isReg())
310*9880d681SAndroid Build Coastguard Worker continue;
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Worker unsigned MOReg = MO.getReg();
313*9880d681SAndroid Build Coastguard Worker if (!MOReg || !TargetRegisterInfo::isPhysicalRegister(MOReg))
314*9880d681SAndroid Build Coastguard Worker continue;
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker if (!TRI->regsOverlap(MOReg, Reg))
317*9880d681SAndroid Build Coastguard Worker continue;
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);
320*9880d681SAndroid Build Coastguard Worker if (MO.readsReg()) {
321*9880d681SAndroid Build Coastguard Worker PRI.Read = true;
322*9880d681SAndroid Build Coastguard Worker if (Covered) {
323*9880d681SAndroid Build Coastguard Worker PRI.FullyRead = true;
324*9880d681SAndroid Build Coastguard Worker if (MO.isKill())
325*9880d681SAndroid Build Coastguard Worker PRI.Killed = true;
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker } else if (MO.isDef()) {
328*9880d681SAndroid Build Coastguard Worker PRI.Defined = true;
329*9880d681SAndroid Build Coastguard Worker if (Covered)
330*9880d681SAndroid Build Coastguard Worker PRI.FullyDefined = true;
331*9880d681SAndroid Build Coastguard Worker if (!MO.isDead())
332*9880d681SAndroid Build Coastguard Worker AllDefsDead = false;
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker }
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker if (AllDefsDead) {
337*9880d681SAndroid Build Coastguard Worker if (PRI.FullyDefined || PRI.Clobbered)
338*9880d681SAndroid Build Coastguard Worker PRI.DeadDef = true;
339*9880d681SAndroid Build Coastguard Worker else if (PRI.Defined)
340*9880d681SAndroid Build Coastguard Worker PRI.PartialDeadDef = true;
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker return PRI;
344*9880d681SAndroid Build Coastguard Worker }
345