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(); 61*fe013be4SDimitry 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 151*fe013be4SDimitry 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 1800b57cec5SDimitry Andric for (unsigned i = 0, e = Defs.size(); i != e; ++i) { 1810b57cec5SDimitry Andric MachineOperand &MO = *Defs[i]; 1828bcb0991SDimitry Andric Register Reg = MO.getReg(); 1830b57cec5SDimitry Andric if (!Reg) 1840b57cec5SDimitry Andric continue; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric if (LocalDefSet.insert(Reg).second) { 1870b57cec5SDimitry Andric LocalDefs.push_back(Reg); 1880b57cec5SDimitry Andric if (MO.isDead()) { 1890b57cec5SDimitry Andric DeadDefSet.insert(Reg); 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric } else { 1920b57cec5SDimitry Andric // Re-defined inside the bundle, it's no longer killed. 1930b57cec5SDimitry Andric KilledDefSet.erase(Reg); 1940b57cec5SDimitry Andric if (!MO.isDead()) 1950b57cec5SDimitry Andric // Previously defined but dead. 1960b57cec5SDimitry Andric DeadDefSet.erase(Reg); 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric 199bdd1243dSDimitry Andric if (!MO.isDead() && Reg.isPhysical()) { 200*fe013be4SDimitry Andric for (MCPhysReg SubReg : TRI->subregs(Reg)) { 2010b57cec5SDimitry Andric if (LocalDefSet.insert(SubReg).second) 2020b57cec5SDimitry Andric LocalDefs.push_back(SubReg); 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric Defs.clear(); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2105ffd83dbSDimitry Andric SmallSet<Register, 32> Added; 2110b57cec5SDimitry Andric for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) { 2125ffd83dbSDimitry Andric Register Reg = LocalDefs[i]; 2130b57cec5SDimitry Andric if (Added.insert(Reg).second) { 2140b57cec5SDimitry Andric // If it's not live beyond end of the bundle, mark it dead. 2150b57cec5SDimitry Andric bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg); 2160b57cec5SDimitry Andric MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) | 2170b57cec5SDimitry Andric getImplRegState(true)); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) { 2225ffd83dbSDimitry Andric Register Reg = ExternUses[i]; 2230b57cec5SDimitry Andric bool isKill = KilledUseSet.count(Reg); 2240b57cec5SDimitry Andric bool isUndef = UndefUseSet.count(Reg); 2250b57cec5SDimitry Andric MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) | 2260b57cec5SDimitry Andric getImplRegState(true)); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions got 2300b57cec5SDimitry Andric // the property, then also set it on the bundle. 2310b57cec5SDimitry Andric for (auto MII = FirstMI; MII != LastMI; ++MII) { 2320b57cec5SDimitry Andric if (MII->getFlag(MachineInstr::FrameSetup)) 2330b57cec5SDimitry Andric MIB.setMIFlag(MachineInstr::FrameSetup); 2340b57cec5SDimitry Andric if (MII->getFlag(MachineInstr::FrameDestroy)) 2350b57cec5SDimitry Andric MIB.setMIFlag(MachineInstr::FrameDestroy); 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric /// finalizeBundle - Same functionality as the previous finalizeBundle except 2400b57cec5SDimitry Andric /// the last instruction in the bundle is not provided as an input. This is 2410b57cec5SDimitry Andric /// used in cases where bundles are pre-determined by marking instructions 2420b57cec5SDimitry Andric /// with 'InsideBundle' marker. It returns the MBB instruction iterator that 2430b57cec5SDimitry Andric /// points to the end of the bundle. 2440b57cec5SDimitry Andric MachineBasicBlock::instr_iterator 2450b57cec5SDimitry Andric llvm::finalizeBundle(MachineBasicBlock &MBB, 2460b57cec5SDimitry Andric MachineBasicBlock::instr_iterator FirstMI) { 2470b57cec5SDimitry Andric MachineBasicBlock::instr_iterator E = MBB.instr_end(); 2480b57cec5SDimitry Andric MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI); 2490b57cec5SDimitry Andric while (LastMI != E && LastMI->isInsideBundle()) 2500b57cec5SDimitry Andric ++LastMI; 2510b57cec5SDimitry Andric finalizeBundle(MBB, FirstMI, LastMI); 2520b57cec5SDimitry Andric return LastMI; 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric /// finalizeBundles - Finalize instruction bundles in the specified 2560b57cec5SDimitry Andric /// MachineFunction. Return true if any bundles are finalized. 2570b57cec5SDimitry Andric bool llvm::finalizeBundles(MachineFunction &MF) { 2580b57cec5SDimitry Andric bool Changed = false; 259fe6060f1SDimitry Andric for (MachineBasicBlock &MBB : MF) { 2600b57cec5SDimitry Andric MachineBasicBlock::instr_iterator MII = MBB.instr_begin(); 2610b57cec5SDimitry Andric MachineBasicBlock::instr_iterator MIE = MBB.instr_end(); 2620b57cec5SDimitry Andric if (MII == MIE) 2630b57cec5SDimitry Andric continue; 2640b57cec5SDimitry Andric assert(!MII->isInsideBundle() && 2650b57cec5SDimitry Andric "First instr cannot be inside bundle before finalization!"); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric for (++MII; MII != MIE; ) { 2680b57cec5SDimitry Andric if (!MII->isInsideBundle()) 2690b57cec5SDimitry Andric ++MII; 2700b57cec5SDimitry Andric else { 2710b57cec5SDimitry Andric MII = finalizeBundle(MBB, std::prev(MII)); 2720b57cec5SDimitry Andric Changed = true; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric return Changed; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 280480093f4SDimitry Andric VirtRegInfo llvm::AnalyzeVirtRegInBundle( 2815ffd83dbSDimitry Andric MachineInstr &MI, Register Reg, 2820b57cec5SDimitry Andric SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops) { 2830b57cec5SDimitry Andric VirtRegInfo RI = {false, false, false}; 284480093f4SDimitry Andric for (MIBundleOperands O(MI); O.isValid(); ++O) { 285480093f4SDimitry Andric MachineOperand &MO = *O; 2860b57cec5SDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 2870b57cec5SDimitry Andric continue; 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric // Remember each (MI, OpNo) that refers to Reg. 2900b57cec5SDimitry Andric if (Ops) 291480093f4SDimitry Andric Ops->push_back(std::make_pair(MO.getParent(), O.getOperandNo())); 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric // Both defs and uses can read virtual registers. 2940b57cec5SDimitry Andric if (MO.readsReg()) { 2950b57cec5SDimitry Andric RI.Reads = true; 2960b57cec5SDimitry Andric if (MO.isDef()) 2970b57cec5SDimitry Andric RI.Tied = true; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric // Only defs can write. 3010b57cec5SDimitry Andric if (MO.isDef()) 3020b57cec5SDimitry Andric RI.Writes = true; 303480093f4SDimitry Andric else if (!RI.Tied && 304480093f4SDimitry Andric MO.getParent()->isRegTiedToDefOperand(O.getOperandNo())) 3050b57cec5SDimitry Andric RI.Tied = true; 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric return RI; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 310*fe013be4SDimitry Andric std::pair<LaneBitmask, LaneBitmask> 311*fe013be4SDimitry Andric llvm::AnalyzeVirtRegLanesInBundle(const MachineInstr &MI, Register Reg, 312*fe013be4SDimitry Andric const MachineRegisterInfo &MRI, 313*fe013be4SDimitry Andric const TargetRegisterInfo &TRI) { 314*fe013be4SDimitry Andric 315*fe013be4SDimitry Andric LaneBitmask UseMask, DefMask; 316*fe013be4SDimitry Andric 317*fe013be4SDimitry Andric for (ConstMIBundleOperands O(MI); O.isValid(); ++O) { 318*fe013be4SDimitry Andric const MachineOperand &MO = *O; 319*fe013be4SDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 320*fe013be4SDimitry Andric continue; 321*fe013be4SDimitry Andric 322*fe013be4SDimitry Andric unsigned SubReg = MO.getSubReg(); 323*fe013be4SDimitry Andric if (SubReg == 0 && MO.isUse() && !MO.isUndef()) 324*fe013be4SDimitry Andric UseMask |= MRI.getMaxLaneMaskForVReg(Reg); 325*fe013be4SDimitry Andric 326*fe013be4SDimitry Andric LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(SubReg); 327*fe013be4SDimitry Andric if (MO.isDef()) { 328*fe013be4SDimitry Andric if (!MO.isUndef()) 329*fe013be4SDimitry Andric UseMask |= ~SubRegMask; 330*fe013be4SDimitry Andric DefMask |= SubRegMask; 331*fe013be4SDimitry Andric } else if (!MO.isUndef()) 332*fe013be4SDimitry Andric UseMask |= SubRegMask; 333*fe013be4SDimitry Andric } 334*fe013be4SDimitry Andric 335*fe013be4SDimitry Andric return {UseMask, DefMask}; 336*fe013be4SDimitry Andric } 337*fe013be4SDimitry Andric 3385ffd83dbSDimitry Andric PhysRegInfo llvm::AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg, 3390b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 3400b57cec5SDimitry Andric bool AllDefsDead = true; 3410b57cec5SDimitry Andric PhysRegInfo PRI = {false, false, false, false, false, false, false, false}; 3420b57cec5SDimitry Andric 3435ffd83dbSDimitry Andric assert(Reg.isPhysical() && "analyzePhysReg not given a physical register!"); 344480093f4SDimitry Andric for (ConstMIBundleOperands O(MI); O.isValid(); ++O) { 345480093f4SDimitry Andric const MachineOperand &MO = *O; 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) { 3480b57cec5SDimitry Andric PRI.Clobbered = true; 3490b57cec5SDimitry Andric continue; 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric if (!MO.isReg()) 3530b57cec5SDimitry Andric continue; 3540b57cec5SDimitry Andric 3558bcb0991SDimitry Andric Register MOReg = MO.getReg(); 356bdd1243dSDimitry Andric if (!MOReg || !MOReg.isPhysical()) 3570b57cec5SDimitry Andric continue; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric if (!TRI->regsOverlap(MOReg, Reg)) 3600b57cec5SDimitry Andric continue; 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric bool Covered = TRI->isSuperRegisterEq(Reg, MOReg); 3630b57cec5SDimitry Andric if (MO.readsReg()) { 3640b57cec5SDimitry Andric PRI.Read = true; 3650b57cec5SDimitry Andric if (Covered) { 3660b57cec5SDimitry Andric PRI.FullyRead = true; 3670b57cec5SDimitry Andric if (MO.isKill()) 3680b57cec5SDimitry Andric PRI.Killed = true; 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric } else if (MO.isDef()) { 3710b57cec5SDimitry Andric PRI.Defined = true; 3720b57cec5SDimitry Andric if (Covered) 3730b57cec5SDimitry Andric PRI.FullyDefined = true; 3740b57cec5SDimitry Andric if (!MO.isDead()) 3750b57cec5SDimitry Andric AllDefsDead = false; 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric if (AllDefsDead) { 3800b57cec5SDimitry Andric if (PRI.FullyDefined || PRI.Clobbered) 3810b57cec5SDimitry Andric PRI.DeadDef = true; 3820b57cec5SDimitry Andric else if (PRI.Defined) 3830b57cec5SDimitry Andric PRI.PartialDeadDef = true; 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric return PRI; 3870b57cec5SDimitry Andric } 388