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"
190b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
200b57cec5SDimitry Andric #include <utility>
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric namespace {
240b57cec5SDimitry Andric class UnpackMachineBundles : public MachineFunctionPass {
250b57cec5SDimitry Andric public:
260b57cec5SDimitry Andric static char ID; // Pass identification
UnpackMachineBundles(std::function<bool (const MachineFunction &)> Ftor=nullptr)270b57cec5SDimitry Andric UnpackMachineBundles(
280b57cec5SDimitry Andric std::function<bool(const MachineFunction &)> Ftor = nullptr)
290b57cec5SDimitry Andric : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
300b57cec5SDimitry Andric initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric private:
360b57cec5SDimitry Andric std::function<bool(const MachineFunction &)> PredicateFtor;
370b57cec5SDimitry Andric };
380b57cec5SDimitry Andric } // end anonymous namespace
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric char UnpackMachineBundles::ID = 0;
410b57cec5SDimitry Andric char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
420b57cec5SDimitry Andric INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",
430b57cec5SDimitry Andric "Unpack machine instruction bundles", false, false)
440b57cec5SDimitry Andric
runOnMachineFunction(MachineFunction & MF)450b57cec5SDimitry Andric bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
460b57cec5SDimitry Andric if (PredicateFtor && !PredicateFtor(MF))
470b57cec5SDimitry Andric return false;
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric bool Changed = false;
50*5f7ddb14SDimitry Andric for (MachineBasicBlock &MBB : MF) {
51*5f7ddb14SDimitry Andric for (MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),
52*5f7ddb14SDimitry Andric MIE = MBB.instr_end(); MII != MIE; ) {
530b57cec5SDimitry Andric MachineInstr *MI = &*MII;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric // Remove BUNDLE instruction and the InsideBundle flags from bundled
560b57cec5SDimitry Andric // instructions.
570b57cec5SDimitry Andric if (MI->isBundle()) {
580b57cec5SDimitry Andric while (++MII != MIE && MII->isBundledWithPred()) {
590b57cec5SDimitry Andric MII->unbundleFromPred();
600b57cec5SDimitry Andric for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
610b57cec5SDimitry Andric MachineOperand &MO = MII->getOperand(i);
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 *
createUnpackMachineBundles(std::function<bool (const MachineFunction &)> Ftor)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
FinalizeMachineBundles()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
runOnMachineFunction(MachineFunction & MF)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.
getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,MachineBasicBlock::instr_iterator LastMI)1090b57cec5SDimitry Andric static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,
1100b57cec5SDimitry Andric MachineBasicBlock::instr_iterator LastMI) {
1110b57cec5SDimitry Andric for (auto MII = FirstMI; MII != LastMI; ++MII)
1120b57cec5SDimitry Andric if (MII->getDebugLoc().get())
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.
finalizeBundle(MachineBasicBlock & MBB,MachineBasicBlock::instr_iterator FirstMI,MachineBasicBlock::instr_iterator LastMI)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) {
1470b57cec5SDimitry Andric for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
1480b57cec5SDimitry Andric MachineOperand &MO = MII->getOperand(i);
1490b57cec5SDimitry Andric if (!MO.isReg())
1500b57cec5SDimitry Andric continue;
1510b57cec5SDimitry Andric if (MO.isDef()) {
1520b57cec5SDimitry Andric Defs.push_back(&MO);
1530b57cec5SDimitry Andric continue;
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric
1568bcb0991SDimitry Andric Register Reg = MO.getReg();
1570b57cec5SDimitry Andric if (!Reg)
1580b57cec5SDimitry Andric continue;
1598bcb0991SDimitry Andric
1600b57cec5SDimitry Andric if (LocalDefSet.count(Reg)) {
1610b57cec5SDimitry Andric MO.setIsInternalRead();
1620b57cec5SDimitry Andric if (MO.isKill())
1630b57cec5SDimitry Andric // Internal def is now killed.
1640b57cec5SDimitry Andric KilledDefSet.insert(Reg);
1650b57cec5SDimitry Andric } else {
1660b57cec5SDimitry Andric if (ExternUseSet.insert(Reg).second) {
1670b57cec5SDimitry Andric ExternUses.push_back(Reg);
1680b57cec5SDimitry Andric if (MO.isUndef())
1690b57cec5SDimitry Andric UndefUseSet.insert(Reg);
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric if (MO.isKill())
1720b57cec5SDimitry Andric // External def is now killed.
1730b57cec5SDimitry Andric KilledUseSet.insert(Reg);
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
1780b57cec5SDimitry Andric MachineOperand &MO = *Defs[i];
1798bcb0991SDimitry Andric Register Reg = MO.getReg();
1800b57cec5SDimitry Andric if (!Reg)
1810b57cec5SDimitry Andric continue;
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andric if (LocalDefSet.insert(Reg).second) {
1840b57cec5SDimitry Andric LocalDefs.push_back(Reg);
1850b57cec5SDimitry Andric if (MO.isDead()) {
1860b57cec5SDimitry Andric DeadDefSet.insert(Reg);
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric } else {
1890b57cec5SDimitry Andric // Re-defined inside the bundle, it's no longer killed.
1900b57cec5SDimitry Andric KilledDefSet.erase(Reg);
1910b57cec5SDimitry Andric if (!MO.isDead())
1920b57cec5SDimitry Andric // Previously defined but dead.
1930b57cec5SDimitry Andric DeadDefSet.erase(Reg);
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric
1968bcb0991SDimitry Andric if (!MO.isDead() && Register::isPhysicalRegister(Reg)) {
1970b57cec5SDimitry Andric for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
1980b57cec5SDimitry Andric unsigned SubReg = *SubRegs;
1990b57cec5SDimitry Andric if (LocalDefSet.insert(SubReg).second)
2000b57cec5SDimitry Andric LocalDefs.push_back(SubReg);
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric
2050b57cec5SDimitry Andric Defs.clear();
2060b57cec5SDimitry Andric }
2070b57cec5SDimitry Andric
2085ffd83dbSDimitry Andric SmallSet<Register, 32> Added;
2090b57cec5SDimitry Andric for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
2105ffd83dbSDimitry Andric Register Reg = LocalDefs[i];
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
2190b57cec5SDimitry Andric for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) {
2205ffd83dbSDimitry Andric Register Reg = ExternUses[i];
2210b57cec5SDimitry Andric bool isKill = KilledUseSet.count(Reg);
2220b57cec5SDimitry Andric bool isUndef = UndefUseSet.count(Reg);
2230b57cec5SDimitry Andric MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
2240b57cec5SDimitry Andric getImplRegState(true));
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions got
2280b57cec5SDimitry Andric // the property, then also set it on the bundle.
2290b57cec5SDimitry Andric for (auto MII = FirstMI; MII != LastMI; ++MII) {
2300b57cec5SDimitry Andric if (MII->getFlag(MachineInstr::FrameSetup))
2310b57cec5SDimitry Andric MIB.setMIFlag(MachineInstr::FrameSetup);
2320b57cec5SDimitry Andric if (MII->getFlag(MachineInstr::FrameDestroy))
2330b57cec5SDimitry Andric MIB.setMIFlag(MachineInstr::FrameDestroy);
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andric /// finalizeBundle - Same functionality as the previous finalizeBundle except
2380b57cec5SDimitry Andric /// the last instruction in the bundle is not provided as an input. This is
2390b57cec5SDimitry Andric /// used in cases where bundles are pre-determined by marking instructions
2400b57cec5SDimitry Andric /// with 'InsideBundle' marker. It returns the MBB instruction iterator that
2410b57cec5SDimitry Andric /// points to the end of the bundle.
2420b57cec5SDimitry Andric MachineBasicBlock::instr_iterator
finalizeBundle(MachineBasicBlock & MBB,MachineBasicBlock::instr_iterator FirstMI)2430b57cec5SDimitry Andric llvm::finalizeBundle(MachineBasicBlock &MBB,
2440b57cec5SDimitry Andric MachineBasicBlock::instr_iterator FirstMI) {
2450b57cec5SDimitry Andric MachineBasicBlock::instr_iterator E = MBB.instr_end();
2460b57cec5SDimitry Andric MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
2470b57cec5SDimitry Andric while (LastMI != E && LastMI->isInsideBundle())
2480b57cec5SDimitry Andric ++LastMI;
2490b57cec5SDimitry Andric finalizeBundle(MBB, FirstMI, LastMI);
2500b57cec5SDimitry Andric return LastMI;
2510b57cec5SDimitry Andric }
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric /// finalizeBundles - Finalize instruction bundles in the specified
2540b57cec5SDimitry Andric /// MachineFunction. Return true if any bundles are finalized.
finalizeBundles(MachineFunction & MF)2550b57cec5SDimitry Andric bool llvm::finalizeBundles(MachineFunction &MF) {
2560b57cec5SDimitry Andric bool Changed = false;
257*5f7ddb14SDimitry Andric for (MachineBasicBlock &MBB : MF) {
2580b57cec5SDimitry Andric MachineBasicBlock::instr_iterator MII = MBB.instr_begin();
2590b57cec5SDimitry Andric MachineBasicBlock::instr_iterator MIE = MBB.instr_end();
2600b57cec5SDimitry Andric if (MII == MIE)
2610b57cec5SDimitry Andric continue;
2620b57cec5SDimitry Andric assert(!MII->isInsideBundle() &&
2630b57cec5SDimitry Andric "First instr cannot be inside bundle before finalization!");
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric for (++MII; MII != MIE; ) {
2660b57cec5SDimitry Andric if (!MII->isInsideBundle())
2670b57cec5SDimitry Andric ++MII;
2680b57cec5SDimitry Andric else {
2690b57cec5SDimitry Andric MII = finalizeBundle(MBB, std::prev(MII));
2700b57cec5SDimitry Andric Changed = true;
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric return Changed;
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric
AnalyzeVirtRegInBundle(MachineInstr & MI,Register Reg,SmallVectorImpl<std::pair<MachineInstr *,unsigned>> * Ops)278480093f4SDimitry Andric VirtRegInfo llvm::AnalyzeVirtRegInBundle(
2795ffd83dbSDimitry Andric MachineInstr &MI, Register Reg,
2800b57cec5SDimitry Andric SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops) {
2810b57cec5SDimitry Andric VirtRegInfo RI = {false, false, false};
282480093f4SDimitry Andric for (MIBundleOperands O(MI); O.isValid(); ++O) {
283480093f4SDimitry Andric MachineOperand &MO = *O;
2840b57cec5SDimitry Andric if (!MO.isReg() || MO.getReg() != Reg)
2850b57cec5SDimitry Andric continue;
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric // Remember each (MI, OpNo) that refers to Reg.
2880b57cec5SDimitry Andric if (Ops)
289480093f4SDimitry Andric Ops->push_back(std::make_pair(MO.getParent(), O.getOperandNo()));
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric // Both defs and uses can read virtual registers.
2920b57cec5SDimitry Andric if (MO.readsReg()) {
2930b57cec5SDimitry Andric RI.Reads = true;
2940b57cec5SDimitry Andric if (MO.isDef())
2950b57cec5SDimitry Andric RI.Tied = true;
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andric // Only defs can write.
2990b57cec5SDimitry Andric if (MO.isDef())
3000b57cec5SDimitry Andric RI.Writes = true;
301480093f4SDimitry Andric else if (!RI.Tied &&
302480093f4SDimitry Andric MO.getParent()->isRegTiedToDefOperand(O.getOperandNo()))
3030b57cec5SDimitry Andric RI.Tied = true;
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric return RI;
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric
AnalyzePhysRegInBundle(const MachineInstr & MI,Register Reg,const TargetRegisterInfo * TRI)3085ffd83dbSDimitry Andric PhysRegInfo llvm::AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,
3090b57cec5SDimitry Andric const TargetRegisterInfo *TRI) {
3100b57cec5SDimitry Andric bool AllDefsDead = true;
3110b57cec5SDimitry Andric PhysRegInfo PRI = {false, false, false, false, false, false, false, false};
3120b57cec5SDimitry Andric
3135ffd83dbSDimitry Andric assert(Reg.isPhysical() && "analyzePhysReg not given a physical register!");
314480093f4SDimitry Andric for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
315480093f4SDimitry Andric const MachineOperand &MO = *O;
3160b57cec5SDimitry Andric
3170b57cec5SDimitry Andric if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) {
3180b57cec5SDimitry Andric PRI.Clobbered = true;
3190b57cec5SDimitry Andric continue;
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andric if (!MO.isReg())
3230b57cec5SDimitry Andric continue;
3240b57cec5SDimitry Andric
3258bcb0991SDimitry Andric Register MOReg = MO.getReg();
3268bcb0991SDimitry Andric if (!MOReg || !Register::isPhysicalRegister(MOReg))
3270b57cec5SDimitry Andric continue;
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andric if (!TRI->regsOverlap(MOReg, Reg))
3300b57cec5SDimitry Andric continue;
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);
3330b57cec5SDimitry Andric if (MO.readsReg()) {
3340b57cec5SDimitry Andric PRI.Read = true;
3350b57cec5SDimitry Andric if (Covered) {
3360b57cec5SDimitry Andric PRI.FullyRead = true;
3370b57cec5SDimitry Andric if (MO.isKill())
3380b57cec5SDimitry Andric PRI.Killed = true;
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric } else if (MO.isDef()) {
3410b57cec5SDimitry Andric PRI.Defined = true;
3420b57cec5SDimitry Andric if (Covered)
3430b57cec5SDimitry Andric PRI.FullyDefined = true;
3440b57cec5SDimitry Andric if (!MO.isDead())
3450b57cec5SDimitry Andric AllDefsDead = false;
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric }
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric if (AllDefsDead) {
3500b57cec5SDimitry Andric if (PRI.FullyDefined || PRI.Clobbered)
3510b57cec5SDimitry Andric PRI.DeadDef = true;
3520b57cec5SDimitry Andric else if (PRI.Defined)
3530b57cec5SDimitry Andric PRI.PartialDeadDef = true;
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andric return PRI;
3570b57cec5SDimitry Andric }
358