xref: /aosp_15_r20/external/llvm/lib/CodeGen/MachineInstrBundle.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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