10b57cec5SDimitry Andric //===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h" 100b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h" 110b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 120b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 140b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 150b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 18480093f4SDimitry Andric #include "llvm/InitializePasses.h" 1981ad6265SDimitry Andric #include "llvm/Pass.h" 2081ad6265SDimitry Andric #include "llvm/PassRegistry.h" 210b57cec5SDimitry Andric #include <utility> 220b57cec5SDimitry Andric using namespace llvm; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace { 250b57cec5SDimitry Andric class UnpackMachineBundles : public MachineFunctionPass { 260b57cec5SDimitry Andric public: 270b57cec5SDimitry Andric static char ID; // Pass identification 280b57cec5SDimitry Andric UnpackMachineBundles( 290b57cec5SDimitry Andric std::function<bool(const MachineFunction &)> Ftor = nullptr) 300b57cec5SDimitry Andric : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) { 310b57cec5SDimitry Andric initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry()); 320b57cec5SDimitry Andric } 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric private: 370b57cec5SDimitry Andric std::function<bool(const MachineFunction &)> PredicateFtor; 380b57cec5SDimitry Andric }; 390b57cec5SDimitry Andric } // end anonymous namespace 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric char UnpackMachineBundles::ID = 0; 420b57cec5SDimitry Andric char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID; 430b57cec5SDimitry Andric INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles", 440b57cec5SDimitry Andric "Unpack machine instruction bundles", false, false) 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { 470b57cec5SDimitry Andric if (PredicateFtor && !PredicateFtor(MF)) 480b57cec5SDimitry Andric return false; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric bool Changed = false; 51fe6060f1SDimitry Andric for (MachineBasicBlock &MBB : MF) { 52fe6060f1SDimitry Andric for (MachineBasicBlock::instr_iterator MII = MBB.instr_begin(), 53fe6060f1SDimitry Andric MIE = MBB.instr_end(); MII != MIE; ) { 540b57cec5SDimitry Andric MachineInstr *MI = &*MII; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric // Remove BUNDLE instruction and the InsideBundle flags from bundled 570b57cec5SDimitry Andric // instructions. 580b57cec5SDimitry Andric if (MI->isBundle()) { 590b57cec5SDimitry Andric while (++MII != MIE && MII->isBundledWithPred()) { 600b57cec5SDimitry Andric MII->unbundleFromPred(); 6106c3fb27SDimitry Andric for (MachineOperand &MO : MII->operands()) { 620b57cec5SDimitry Andric if (MO.isReg() && MO.isInternalRead()) 630b57cec5SDimitry Andric MO.setIsInternalRead(false); 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric MI->eraseFromParent(); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric Changed = true; 690b57cec5SDimitry Andric continue; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric ++MII; 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric return Changed; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric FunctionPass * 800b57cec5SDimitry Andric llvm::createUnpackMachineBundles( 810b57cec5SDimitry Andric std::function<bool(const MachineFunction &)> Ftor) { 820b57cec5SDimitry Andric return new UnpackMachineBundles(std::move(Ftor)); 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric namespace { 860b57cec5SDimitry Andric class FinalizeMachineBundles : public MachineFunctionPass { 870b57cec5SDimitry Andric public: 880b57cec5SDimitry Andric static char ID; // Pass identification 890b57cec5SDimitry Andric FinalizeMachineBundles() : MachineFunctionPass(ID) { 900b57cec5SDimitry Andric initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry()); 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 940b57cec5SDimitry Andric }; 950b57cec5SDimitry Andric } // end anonymous namespace 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric char FinalizeMachineBundles::ID = 0; 980b57cec5SDimitry Andric char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID; 990b57cec5SDimitry Andric INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles", 1000b57cec5SDimitry Andric "Finalize machine instruction bundles", false, false) 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) { 1030b57cec5SDimitry Andric return llvm::finalizeBundles(MF); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric /// Return the first found DebugLoc that has a DILocation, given a range of 1070b57cec5SDimitry Andric /// instructions. The search range is from FirstMI to LastMI (exclusive). If no 1080b57cec5SDimitry Andric /// DILocation is found, then an empty location is returned. 1090b57cec5SDimitry Andric static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, 1100b57cec5SDimitry Andric MachineBasicBlock::instr_iterator LastMI) { 1110b57cec5SDimitry Andric for (auto MII = FirstMI; MII != LastMI; ++MII) 11281ad6265SDimitry Andric if (MII->getDebugLoc()) 1130b57cec5SDimitry Andric return MII->getDebugLoc(); 1140b57cec5SDimitry Andric return DebugLoc(); 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric /// finalizeBundle - Finalize a machine instruction bundle which includes 1180b57cec5SDimitry Andric /// a sequence of instructions starting from FirstMI to LastMI (exclusive). 1190b57cec5SDimitry Andric /// This routine adds a BUNDLE instruction to represent the bundle, it adds 1200b57cec5SDimitry Andric /// IsInternalRead markers to MachineOperands which are defined inside the 1210b57cec5SDimitry Andric /// bundle, and it copies externally visible defs and uses to the BUNDLE 1220b57cec5SDimitry Andric /// instruction. 1230b57cec5SDimitry Andric void llvm::finalizeBundle(MachineBasicBlock &MBB, 1240b57cec5SDimitry Andric MachineBasicBlock::instr_iterator FirstMI, 1250b57cec5SDimitry Andric MachineBasicBlock::instr_iterator LastMI) { 1260b57cec5SDimitry Andric assert(FirstMI != LastMI && "Empty bundle?"); 1270b57cec5SDimitry Andric MIBundleBuilder Bundle(MBB, FirstMI, LastMI); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric MachineFunction &MF = *MBB.getParent(); 1300b57cec5SDimitry Andric const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 1310b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric MachineInstrBuilder MIB = 1340b57cec5SDimitry Andric BuildMI(MF, getDebugLoc(FirstMI, LastMI), TII->get(TargetOpcode::BUNDLE)); 1350b57cec5SDimitry Andric Bundle.prepend(MIB); 1360b57cec5SDimitry Andric 1375ffd83dbSDimitry Andric SmallVector<Register, 32> LocalDefs; 1385ffd83dbSDimitry Andric SmallSet<Register, 32> LocalDefSet; 1395ffd83dbSDimitry Andric SmallSet<Register, 8> DeadDefSet; 1405ffd83dbSDimitry Andric SmallSet<Register, 16> KilledDefSet; 1415ffd83dbSDimitry Andric SmallVector<Register, 8> ExternUses; 1425ffd83dbSDimitry Andric SmallSet<Register, 8> ExternUseSet; 1435ffd83dbSDimitry Andric SmallSet<Register, 8> KilledUseSet; 1445ffd83dbSDimitry Andric SmallSet<Register, 8> UndefUseSet; 1450b57cec5SDimitry Andric SmallVector<MachineOperand*, 4> Defs; 1460b57cec5SDimitry Andric for (auto MII = FirstMI; MII != LastMI; ++MII) { 14704eeddc0SDimitry Andric // Debug instructions have no effects to track. 14804eeddc0SDimitry Andric if (MII->isDebugInstr()) 14904eeddc0SDimitry Andric continue; 15004eeddc0SDimitry Andric 15106c3fb27SDimitry Andric for (MachineOperand &MO : MII->operands()) { 1520b57cec5SDimitry Andric if (!MO.isReg()) 1530b57cec5SDimitry Andric continue; 1540b57cec5SDimitry Andric if (MO.isDef()) { 1550b57cec5SDimitry Andric Defs.push_back(&MO); 1560b57cec5SDimitry Andric continue; 1570b57cec5SDimitry Andric } 1580b57cec5SDimitry Andric 1598bcb0991SDimitry Andric Register Reg = MO.getReg(); 1600b57cec5SDimitry Andric if (!Reg) 1610b57cec5SDimitry Andric continue; 1628bcb0991SDimitry Andric 1630b57cec5SDimitry Andric if (LocalDefSet.count(Reg)) { 1640b57cec5SDimitry Andric MO.setIsInternalRead(); 1650b57cec5SDimitry Andric if (MO.isKill()) 1660b57cec5SDimitry Andric // Internal def is now killed. 1670b57cec5SDimitry Andric KilledDefSet.insert(Reg); 1680b57cec5SDimitry Andric } else { 1690b57cec5SDimitry Andric if (ExternUseSet.insert(Reg).second) { 1700b57cec5SDimitry Andric ExternUses.push_back(Reg); 1710b57cec5SDimitry Andric if (MO.isUndef()) 1720b57cec5SDimitry Andric UndefUseSet.insert(Reg); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric if (MO.isKill()) 1750b57cec5SDimitry Andric // External def is now killed. 1760b57cec5SDimitry Andric KilledUseSet.insert(Reg); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 180*0fca6ea1SDimitry Andric for (MachineOperand *MO : Defs) { 181*0fca6ea1SDimitry Andric Register Reg = MO->getReg(); 1820b57cec5SDimitry Andric if (!Reg) 1830b57cec5SDimitry Andric continue; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric if (LocalDefSet.insert(Reg).second) { 1860b57cec5SDimitry Andric LocalDefs.push_back(Reg); 187*0fca6ea1SDimitry Andric if (MO->isDead()) { 1880b57cec5SDimitry Andric DeadDefSet.insert(Reg); 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric } else { 1910b57cec5SDimitry Andric // Re-defined inside the bundle, it's no longer killed. 1920b57cec5SDimitry Andric KilledDefSet.erase(Reg); 193*0fca6ea1SDimitry Andric if (!MO->isDead()) 1940b57cec5SDimitry Andric // Previously defined but dead. 1950b57cec5SDimitry Andric DeadDefSet.erase(Reg); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 198*0fca6ea1SDimitry Andric if (!MO->isDead() && Reg.isPhysical()) { 19906c3fb27SDimitry Andric for (MCPhysReg SubReg : TRI->subregs(Reg)) { 2000b57cec5SDimitry Andric if (LocalDefSet.insert(SubReg).second) 2010b57cec5SDimitry Andric LocalDefs.push_back(SubReg); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric Defs.clear(); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2095ffd83dbSDimitry Andric SmallSet<Register, 32> Added; 210cb14a3feSDimitry Andric for (Register Reg : LocalDefs) { 2110b57cec5SDimitry Andric if (Added.insert(Reg).second) { 2120b57cec5SDimitry Andric // If it's not live beyond end of the bundle, mark it dead. 2130b57cec5SDimitry Andric bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg); 2140b57cec5SDimitry Andric MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) | 2150b57cec5SDimitry Andric getImplRegState(true)); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric 219cb14a3feSDimitry Andric for (Register Reg : ExternUses) { 2200b57cec5SDimitry Andric bool isKill = KilledUseSet.count(Reg); 2210b57cec5SDimitry Andric bool isUndef = UndefUseSet.count(Reg); 2220b57cec5SDimitry Andric MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) | 2230b57cec5SDimitry Andric getImplRegState(true)); 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions got 2270b57cec5SDimitry Andric // the property, then also set it on the bundle. 2280b57cec5SDimitry Andric for (auto MII = FirstMI; MII != LastMI; ++MII) { 2290b57cec5SDimitry Andric if (MII->getFlag(MachineInstr::FrameSetup)) 2300b57cec5SDimitry Andric MIB.setMIFlag(MachineInstr::FrameSetup); 2310b57cec5SDimitry Andric if (MII->getFlag(MachineInstr::FrameDestroy)) 2320b57cec5SDimitry Andric MIB.setMIFlag(MachineInstr::FrameDestroy); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric /// finalizeBundle - Same functionality as the previous finalizeBundle except 2370b57cec5SDimitry Andric /// the last instruction in the bundle is not provided as an input. This is 2380b57cec5SDimitry Andric /// used in cases where bundles are pre-determined by marking instructions 2390b57cec5SDimitry Andric /// with 'InsideBundle' marker. It returns the MBB instruction iterator that 2400b57cec5SDimitry Andric /// points to the end of the bundle. 2410b57cec5SDimitry Andric MachineBasicBlock::instr_iterator 2420b57cec5SDimitry Andric llvm::finalizeBundle(MachineBasicBlock &MBB, 2430b57cec5SDimitry Andric MachineBasicBlock::instr_iterator FirstMI) { 2440b57cec5SDimitry Andric MachineBasicBlock::instr_iterator E = MBB.instr_end(); 2450b57cec5SDimitry Andric MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI); 2460b57cec5SDimitry Andric while (LastMI != E && LastMI->isInsideBundle()) 2470b57cec5SDimitry Andric ++LastMI; 2480b57cec5SDimitry Andric finalizeBundle(MBB, FirstMI, LastMI); 2490b57cec5SDimitry Andric return LastMI; 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric /// finalizeBundles - Finalize instruction bundles in the specified 2530b57cec5SDimitry Andric /// MachineFunction. Return true if any bundles are finalized. 2540b57cec5SDimitry Andric bool llvm::finalizeBundles(MachineFunction &MF) { 2550b57cec5SDimitry Andric bool Changed = false; 256fe6060f1SDimitry Andric for (MachineBasicBlock &MBB : MF) { 2570b57cec5SDimitry Andric MachineBasicBlock::instr_iterator MII = MBB.instr_begin(); 2580b57cec5SDimitry Andric MachineBasicBlock::instr_iterator MIE = MBB.instr_end(); 2590b57cec5SDimitry Andric if (MII == MIE) 2600b57cec5SDimitry Andric continue; 2610b57cec5SDimitry Andric assert(!MII->isInsideBundle() && 2620b57cec5SDimitry Andric "First instr cannot be inside bundle before finalization!"); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric for (++MII; MII != MIE; ) { 2650b57cec5SDimitry Andric if (!MII->isInsideBundle()) 2660b57cec5SDimitry Andric ++MII; 2670b57cec5SDimitry Andric else { 2680b57cec5SDimitry Andric MII = finalizeBundle(MBB, std::prev(MII)); 2690b57cec5SDimitry Andric Changed = true; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric return Changed; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 277480093f4SDimitry Andric VirtRegInfo llvm::AnalyzeVirtRegInBundle( 2785ffd83dbSDimitry Andric MachineInstr &MI, Register Reg, 2790b57cec5SDimitry Andric SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops) { 2800b57cec5SDimitry Andric VirtRegInfo RI = {false, false, false}; 281480093f4SDimitry Andric for (MIBundleOperands O(MI); O.isValid(); ++O) { 282480093f4SDimitry Andric MachineOperand &MO = *O; 2830b57cec5SDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 2840b57cec5SDimitry Andric continue; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric // Remember each (MI, OpNo) that refers to Reg. 2870b57cec5SDimitry Andric if (Ops) 288480093f4SDimitry Andric Ops->push_back(std::make_pair(MO.getParent(), O.getOperandNo())); 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric // Both defs and uses can read virtual registers. 2910b57cec5SDimitry Andric if (MO.readsReg()) { 2920b57cec5SDimitry Andric RI.Reads = true; 2930b57cec5SDimitry Andric if (MO.isDef()) 2940b57cec5SDimitry Andric RI.Tied = true; 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric // Only defs can write. 2980b57cec5SDimitry Andric if (MO.isDef()) 2990b57cec5SDimitry Andric RI.Writes = true; 300480093f4SDimitry Andric else if (!RI.Tied && 301480093f4SDimitry Andric MO.getParent()->isRegTiedToDefOperand(O.getOperandNo())) 3020b57cec5SDimitry Andric RI.Tied = true; 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric return RI; 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 30706c3fb27SDimitry Andric std::pair<LaneBitmask, LaneBitmask> 30806c3fb27SDimitry Andric llvm::AnalyzeVirtRegLanesInBundle(const MachineInstr &MI, Register Reg, 30906c3fb27SDimitry Andric const MachineRegisterInfo &MRI, 31006c3fb27SDimitry Andric const TargetRegisterInfo &TRI) { 31106c3fb27SDimitry Andric 31206c3fb27SDimitry Andric LaneBitmask UseMask, DefMask; 31306c3fb27SDimitry Andric 314*0fca6ea1SDimitry Andric for (const MachineOperand &MO : const_mi_bundle_ops(MI)) { 31506c3fb27SDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 31606c3fb27SDimitry Andric continue; 31706c3fb27SDimitry Andric 31806c3fb27SDimitry Andric unsigned SubReg = MO.getSubReg(); 31906c3fb27SDimitry Andric if (SubReg == 0 && MO.isUse() && !MO.isUndef()) 32006c3fb27SDimitry Andric UseMask |= MRI.getMaxLaneMaskForVReg(Reg); 32106c3fb27SDimitry Andric 32206c3fb27SDimitry Andric LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(SubReg); 32306c3fb27SDimitry Andric if (MO.isDef()) { 32406c3fb27SDimitry Andric if (!MO.isUndef()) 32506c3fb27SDimitry Andric UseMask |= ~SubRegMask; 32606c3fb27SDimitry Andric DefMask |= SubRegMask; 32706c3fb27SDimitry Andric } else if (!MO.isUndef()) 32806c3fb27SDimitry Andric UseMask |= SubRegMask; 32906c3fb27SDimitry Andric } 33006c3fb27SDimitry Andric 33106c3fb27SDimitry Andric return {UseMask, DefMask}; 33206c3fb27SDimitry Andric } 33306c3fb27SDimitry Andric 3345ffd83dbSDimitry Andric PhysRegInfo llvm::AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg, 3350b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 3360b57cec5SDimitry Andric bool AllDefsDead = true; 3370b57cec5SDimitry Andric PhysRegInfo PRI = {false, false, false, false, false, false, false, false}; 3380b57cec5SDimitry Andric 3395ffd83dbSDimitry Andric assert(Reg.isPhysical() && "analyzePhysReg not given a physical register!"); 340*0fca6ea1SDimitry Andric for (const MachineOperand &MO : const_mi_bundle_ops(MI)) { 3410b57cec5SDimitry Andric if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) { 3420b57cec5SDimitry Andric PRI.Clobbered = true; 3430b57cec5SDimitry Andric continue; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric if (!MO.isReg()) 3470b57cec5SDimitry Andric continue; 3480b57cec5SDimitry Andric 3498bcb0991SDimitry Andric Register MOReg = MO.getReg(); 350bdd1243dSDimitry Andric if (!MOReg || !MOReg.isPhysical()) 3510b57cec5SDimitry Andric continue; 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric if (!TRI->regsOverlap(MOReg, Reg)) 3540b57cec5SDimitry Andric continue; 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric bool Covered = TRI->isSuperRegisterEq(Reg, MOReg); 3570b57cec5SDimitry Andric if (MO.readsReg()) { 3580b57cec5SDimitry Andric PRI.Read = true; 3590b57cec5SDimitry Andric if (Covered) { 3600b57cec5SDimitry Andric PRI.FullyRead = true; 3610b57cec5SDimitry Andric if (MO.isKill()) 3620b57cec5SDimitry Andric PRI.Killed = true; 3630b57cec5SDimitry Andric } 3640b57cec5SDimitry Andric } else if (MO.isDef()) { 3650b57cec5SDimitry Andric PRI.Defined = true; 3660b57cec5SDimitry Andric if (Covered) 3670b57cec5SDimitry Andric PRI.FullyDefined = true; 3680b57cec5SDimitry Andric if (!MO.isDead()) 3690b57cec5SDimitry Andric AllDefsDead = false; 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric } 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric if (AllDefsDead) { 3740b57cec5SDimitry Andric if (PRI.FullyDefined || PRI.Clobbered) 3750b57cec5SDimitry Andric PRI.DeadDef = true; 3760b57cec5SDimitry Andric else if (PRI.Defined) 3770b57cec5SDimitry Andric PRI.PartialDeadDef = true; 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric return PRI; 3810b57cec5SDimitry Andric } 382