xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MachineInstrBundle.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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