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