[llvm] [AMDGPU] Create an AMDGPUIfConverter pass (PR #106415)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 28 09:16:45 PDT 2024


Juan Manuel Martinez =?utf-8?q?Caamaño?= <juamarti at amd.com>,
Juan Manuel Martinez =?utf-8?q?Caamaño?= <juamarti at amd.com>,
Juan Manuel Martinez =?utf-8?q?Caamaño?= <juamarti at amd.com>,
Juan Manuel Martinez =?utf-8?q?Caamaño?= <juamarti at amd.com>,
Juan Manuel Martinez =?utf-8?q?Caamaño?= <juamarti at amd.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/106415 at github.com>


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Juan Manuel Martinez Caamaño (jmmartinez)

<details>
<summary>Changes</summary>

This is a draft to get some early feedback about this work.

Currently the code is mined with TODOs. Some thing that are missing:
- [ ] Cost model - (`shouldConvert` function)
- [ ] Factorize more code from `EarlyIfConverter` since the 3 passes share a lot in common
- [ ] Proper implementation of `getReversedVCMPXOpcode`
- [ ] Do not remove `EarlyIfConverter` from the pipeline
- [ ] Test! Test! Test!
- [ ] Handle more conditionals
- [ ] The `needsPredication` function is probably wrong

This work is related to `SWDEV-477895`.

---

Patch is 70.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/106415.diff


9 Files Affected:

- (added) llvm/include/llvm/CodeGen/SSAIfConv.h (+170) 
- (modified) llvm/lib/CodeGen/CMakeLists.txt (+1) 
- (modified) llvm/lib/CodeGen/EarlyIfConversion.cpp (+100-706) 
- (added) llvm/lib/CodeGen/SSAIfConv.cpp (+481) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPU.h (+3) 
- (added) llvm/lib/Target/AMDGPU/AMDGPUIfConverter.cpp (+279) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp (+2-8) 
- (modified) llvm/lib/Target/AMDGPU/CMakeLists.txt (+1) 
- (added) llvm/test/CodeGen/AMDGPU/amdgpu-if-cvt.ll (+65) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/SSAIfConv.h b/llvm/include/llvm/CodeGen/SSAIfConv.h
new file mode 100644
index 00000000000000..9bba2f69ad4718
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/SSAIfConv.h
@@ -0,0 +1,170 @@
+#ifndef LLVM_SSA_IF_CONV_H
+#define LLVM_SSA_IF_CONV_H
+
+#include "llvm/ADT/SparseSet.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+
+//===----------------------------------------------------------------------===//
+//                                 SSAIfConv
+//===----------------------------------------------------------------------===//
+//
+// The SSAIfConv class performs if-conversion on SSA form machine code after
+// determining if it is possible. The class contains no heuristics; external
+// code should be used to determine when if-conversion is a good idea.
+//
+// SSAIfConv can convert both triangles and diamonds:
+//
+//   Triangle: Head              Diamond: Head
+//              | \                       /  \_
+//              |  \                     /    |
+//              |  [TF]BB              FBB    TBB
+//              |  /                     \    /
+//              | /                       \  /
+//             Tail                       Tail
+//
+// Instructions in the conditional blocks TBB and/or FBB are spliced into the
+// Head block, and phis in the Tail block are converted to select instructions.
+//
+namespace llvm {
+class SSAIfConv;
+
+namespace ifcvt {
+struct PredicationStrategy {
+  virtual bool canConvertIf(MachineBasicBlock *Head, MachineBasicBlock *TBB,
+                            MachineBasicBlock *FBB, MachineBasicBlock *Tail,
+                            ArrayRef<MachineOperand> Cond) {
+    return true;
+  }
+  virtual bool canPredicate(const MachineInstr &I) = 0;
+  virtual bool predicateBlock(MachineBasicBlock *Succ,
+                              ArrayRef<MachineOperand> Cond, bool Reverse) = 0;
+  virtual ~PredicationStrategy() = default;
+};
+} // namespace ifcvt
+
+class SSAIfConv {
+  const TargetInstrInfo *TII;
+  const TargetRegisterInfo *TRI;
+  MachineRegisterInfo *MRI;
+
+  // TODO INITIALIZE
+  const char *DEBUG_TYPE;
+  unsigned BlockInstrLimit;
+  bool Stress;
+
+  struct Statistics {
+    unsigned NumTrianglesSeen = 0;
+    unsigned NumDiamondsSeen = 0;
+    unsigned NumTrianglesConv = 0;
+    unsigned NumDiamondsConv = 0;
+  };
+
+  Statistics S;
+
+public:
+  SSAIfConv(const char *DEBUG_TYPE, unsigned BlockInstrLimit, bool Stress)
+      : DEBUG_TYPE(DEBUG_TYPE), BlockInstrLimit(BlockInstrLimit),
+        Stress(Stress) {}
+
+  template <typename CounterTy>
+  void updateStatistics(CounterTy &NumDiamondsSeen, CounterTy &NumDiamondsConv,
+                        CounterTy &NumTrianglesSeen,
+                        CounterTy &NumTrianglesConv) const {
+    NumDiamondsSeen += S.NumDiamondsSeen;
+    NumDiamondsConv += S.NumDiamondsConv;
+    NumTrianglesSeen += S.NumTrianglesSeen;
+    NumTrianglesConv += S.NumTrianglesConv;
+  }
+
+  /// The block containing the conditional branch.
+  MachineBasicBlock *Head;
+
+  /// The block containing phis after the if-then-else.
+  MachineBasicBlock *Tail;
+
+  /// The 'true' conditional block as determined by analyzeBranch.
+  MachineBasicBlock *TBB;
+
+  /// The 'false' conditional block as determined by analyzeBranch.
+  MachineBasicBlock *FBB;
+
+  /// isTriangle - When there is no 'else' block, either TBB or FBB will be
+  /// equal to Tail.
+  bool isTriangle() const { return TBB == Tail || FBB == Tail; }
+
+  /// Returns the Tail predecessor for the True side.
+  MachineBasicBlock *getTPred() const { return TBB == Tail ? Head : TBB; }
+
+  /// Returns the Tail predecessor for the  False side.
+  MachineBasicBlock *getFPred() const { return FBB == Tail ? Head : FBB; }
+
+  /// Information about each phi in the Tail block.
+  struct PHIInfo {
+    MachineInstr *PHI;
+    unsigned TReg = 0, FReg = 0;
+    // Latencies from Cond+Branch, TReg, and FReg to DstReg.
+    int CondCycles = 0, TCycles = 0, FCycles = 0;
+
+    PHIInfo(MachineInstr *phi) : PHI(phi) {}
+  };
+
+  SmallVector<PHIInfo, 8> PHIs;
+
+  /// The branch condition determined by analyzeBranch.
+  SmallVector<MachineOperand, 4> Cond;
+
+private:
+  /// Instructions in Head that define values used by the conditional blocks.
+  /// The hoisted instructions must be inserted after these instructions.
+  SmallPtrSet<MachineInstr *, 8> InsertAfter;
+
+  /// Register units clobbered by the conditional blocks.
+  BitVector ClobberedRegUnits;
+
+  // Scratch pad for findInsertionPoint.
+  SparseSet<unsigned> LiveRegUnits;
+
+  /// Insertion point in Head for speculatively executed instructions form TBB
+  /// and FBB.
+  MachineBasicBlock::iterator InsertionPoint;
+
+  /// Return true if all non-terminator instructions in MBB can be safely
+  /// predicated.
+  bool canPredicateInstrs(MachineBasicBlock *MBB,
+                          ifcvt::PredicationStrategy &Predicate);
+
+  /// Scan through instruction dependencies and update InsertAfter array.
+  /// Return false if any dependency is incompatible with if conversion.
+  bool InstrDependenciesAllowIfConv(MachineInstr *I);
+
+  /// Predicate all instructions of the basic block with current condition
+  /// except for terminators. Reverse the condition if ReversePredicate is set.
+  void PredicateBlock(MachineBasicBlock *MBB, bool ReversePredicate);
+
+  /// Find a valid insertion point in Head.
+  bool findInsertionPoint();
+
+  /// Replace PHI instructions in Tail with selects.
+  void replacePHIInstrs();
+
+  /// Insert selects and rewrite PHI operands to use them.
+  void rewritePHIOperands();
+
+public:
+  /// runOnMachineFunction - Initialize per-function data structures.
+  void runOnMachineFunction(MachineFunction &MF);
+
+  /// canConvertIf - If the sub-CFG headed by MBB can be if-converted,
+  /// initialize the internal state, and return true.
+  /// If predicate is set try to predicate the block otherwise try to
+  /// speculatively execute it.
+  bool canConvertIf(MachineBasicBlock *MBB, ifcvt::PredicationStrategy &S);
+
+  /// convertIf - If-convert the last block passed to canConvertIf(), assuming
+  /// it is possible. Add any blocks that are to be erased to RemoveBlocks.
+  void convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
+                 ifcvt::PredicationStrategy &S);
+};
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index f1607f85c5b319..c322ca975170e7 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -190,6 +190,7 @@ add_llvm_component_library(LLVMCodeGen
   RegisterCoalescer.cpp
   RegisterPressure.cpp
   RegisterScavenging.cpp
+  SSAIfConv.cpp
   GCEmptyBasicBlocks.cpp
   RemoveRedundantDebugValues.cpp
   RenameIndependentSubregs.cpp
diff --git a/llvm/lib/CodeGen/EarlyIfConversion.cpp b/llvm/lib/CodeGen/EarlyIfConversion.cpp
index 0de8112fb72c89..27df4dea2c3a68 100644
--- a/llvm/lib/CodeGen/EarlyIfConversion.cpp
+++ b/llvm/lib/CodeGen/EarlyIfConversion.cpp
@@ -18,7 +18,6 @@
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SparseSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
@@ -30,6 +29,7 @@
 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineTraceMetrics.h"
+#include "llvm/CodeGen/SSAIfConv.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -57,705 +57,6 @@ STATISTIC(NumDiamondsConv,  "Number of diamonds converted");
 STATISTIC(NumTrianglesSeen, "Number of triangles");
 STATISTIC(NumTrianglesConv, "Number of triangles converted");
 
-//===----------------------------------------------------------------------===//
-//                                 SSAIfConv
-//===----------------------------------------------------------------------===//
-//
-// The SSAIfConv class performs if-conversion on SSA form machine code after
-// determining if it is possible. The class contains no heuristics; external
-// code should be used to determine when if-conversion is a good idea.
-//
-// SSAIfConv can convert both triangles and diamonds:
-//
-//   Triangle: Head              Diamond: Head
-//              | \                       /  \_
-//              |  \                     /    |
-//              |  [TF]BB              FBB    TBB
-//              |  /                     \    /
-//              | /                       \  /
-//             Tail                       Tail
-//
-// Instructions in the conditional blocks TBB and/or FBB are spliced into the
-// Head block, and phis in the Tail block are converted to select instructions.
-//
-namespace {
-class SSAIfConv {
-  const TargetInstrInfo *TII;
-  const TargetRegisterInfo *TRI;
-  MachineRegisterInfo *MRI;
-
-public:
-  /// The block containing the conditional branch.
-  MachineBasicBlock *Head;
-
-  /// The block containing phis after the if-then-else.
-  MachineBasicBlock *Tail;
-
-  /// The 'true' conditional block as determined by analyzeBranch.
-  MachineBasicBlock *TBB;
-
-  /// The 'false' conditional block as determined by analyzeBranch.
-  MachineBasicBlock *FBB;
-
-  /// isTriangle - When there is no 'else' block, either TBB or FBB will be
-  /// equal to Tail.
-  bool isTriangle() const { return TBB == Tail || FBB == Tail; }
-
-  /// Returns the Tail predecessor for the True side.
-  MachineBasicBlock *getTPred() const { return TBB == Tail ? Head : TBB; }
-
-  /// Returns the Tail predecessor for the  False side.
-  MachineBasicBlock *getFPred() const { return FBB == Tail ? Head : FBB; }
-
-  /// Information about each phi in the Tail block.
-  struct PHIInfo {
-    MachineInstr *PHI;
-    unsigned TReg = 0, FReg = 0;
-    // Latencies from Cond+Branch, TReg, and FReg to DstReg.
-    int CondCycles = 0, TCycles = 0, FCycles = 0;
-
-    PHIInfo(MachineInstr *phi) : PHI(phi) {}
-  };
-
-  SmallVector<PHIInfo, 8> PHIs;
-
-  /// The branch condition determined by analyzeBranch.
-  SmallVector<MachineOperand, 4> Cond;
-
-private:
-  /// Instructions in Head that define values used by the conditional blocks.
-  /// The hoisted instructions must be inserted after these instructions.
-  SmallPtrSet<MachineInstr*, 8> InsertAfter;
-
-  /// Register units clobbered by the conditional blocks.
-  BitVector ClobberedRegUnits;
-
-  // Scratch pad for findInsertionPoint.
-  SparseSet<unsigned> LiveRegUnits;
-
-  /// Insertion point in Head for speculatively executed instructions form TBB
-  /// and FBB.
-  MachineBasicBlock::iterator InsertionPoint;
-
-  /// Return true if all non-terminator instructions in MBB can be safely
-  /// speculated.
-  bool canSpeculateInstrs(MachineBasicBlock *MBB);
-
-  /// Return true if all non-terminator instructions in MBB can be safely
-  /// predicated.
-  bool canPredicateInstrs(MachineBasicBlock *MBB);
-
-  /// Scan through instruction dependencies and update InsertAfter array.
-  /// Return false if any dependency is incompatible with if conversion.
-  bool InstrDependenciesAllowIfConv(MachineInstr *I);
-
-  /// Predicate all instructions of the basic block with current condition
-  /// except for terminators. Reverse the condition if ReversePredicate is set.
-  void PredicateBlock(MachineBasicBlock *MBB, bool ReversePredicate);
-
-  /// Find a valid insertion point in Head.
-  bool findInsertionPoint();
-
-  /// Replace PHI instructions in Tail with selects.
-  void replacePHIInstrs();
-
-  /// Insert selects and rewrite PHI operands to use them.
-  void rewritePHIOperands();
-
-public:
-  /// runOnMachineFunction - Initialize per-function data structures.
-  void runOnMachineFunction(MachineFunction &MF) {
-    TII = MF.getSubtarget().getInstrInfo();
-    TRI = MF.getSubtarget().getRegisterInfo();
-    MRI = &MF.getRegInfo();
-    LiveRegUnits.clear();
-    LiveRegUnits.setUniverse(TRI->getNumRegUnits());
-    ClobberedRegUnits.clear();
-    ClobberedRegUnits.resize(TRI->getNumRegUnits());
-  }
-
-  /// canConvertIf - If the sub-CFG headed by MBB can be if-converted,
-  /// initialize the internal state, and return true.
-  /// If predicate is set try to predicate the block otherwise try to
-  /// speculatively execute it.
-  bool canConvertIf(MachineBasicBlock *MBB, bool Predicate = false);
-
-  /// convertIf - If-convert the last block passed to canConvertIf(), assuming
-  /// it is possible. Add any blocks that are to be erased to RemoveBlocks.
-  void convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
-                 bool Predicate = false);
-};
-} // end anonymous namespace
-
-
-/// canSpeculateInstrs - Returns true if all the instructions in MBB can safely
-/// be speculated. The terminators are not considered.
-///
-/// If instructions use any values that are defined in the head basic block,
-/// the defining instructions are added to InsertAfter.
-///
-/// Any clobbered regunits are added to ClobberedRegUnits.
-///
-bool SSAIfConv::canSpeculateInstrs(MachineBasicBlock *MBB) {
-  // Reject any live-in physregs. It's probably CPSR/EFLAGS, and very hard to
-  // get right.
-  if (!MBB->livein_empty()) {
-    LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " has live-ins.\n");
-    return false;
-  }
-
-  unsigned InstrCount = 0;
-
-  // Check all instructions, except the terminators. It is assumed that
-  // terminators never have side effects or define any used register values.
-  for (MachineInstr &MI :
-       llvm::make_range(MBB->begin(), MBB->getFirstTerminator())) {
-    if (MI.isDebugInstr())
-      continue;
-
-    if (++InstrCount > BlockInstrLimit && !Stress) {
-      LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " has more than "
-                        << BlockInstrLimit << " instructions.\n");
-      return false;
-    }
-
-    // There shouldn't normally be any phis in a single-predecessor block.
-    if (MI.isPHI()) {
-      LLVM_DEBUG(dbgs() << "Can't hoist: " << MI);
-      return false;
-    }
-
-    // Don't speculate loads. Note that it may be possible and desirable to
-    // speculate GOT or constant pool loads that are guaranteed not to trap,
-    // but we don't support that for now.
-    if (MI.mayLoad()) {
-      LLVM_DEBUG(dbgs() << "Won't speculate load: " << MI);
-      return false;
-    }
-
-    // We never speculate stores, so an AA pointer isn't necessary.
-    bool DontMoveAcrossStore = true;
-    if (!MI.isSafeToMove(DontMoveAcrossStore)) {
-      LLVM_DEBUG(dbgs() << "Can't speculate: " << MI);
-      return false;
-    }
-
-    // Check for any dependencies on Head instructions.
-    if (!InstrDependenciesAllowIfConv(&MI))
-      return false;
-  }
-  return true;
-}
-
-/// Check that there is no dependencies preventing if conversion.
-///
-/// If instruction uses any values that are defined in the head basic block,
-/// the defining instructions are added to InsertAfter.
-bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *I) {
-  for (const MachineOperand &MO : I->operands()) {
-    if (MO.isRegMask()) {
-      LLVM_DEBUG(dbgs() << "Won't speculate regmask: " << *I);
-      return false;
-    }
-    if (!MO.isReg())
-      continue;
-    Register Reg = MO.getReg();
-
-    // Remember clobbered regunits.
-    if (MO.isDef() && Reg.isPhysical())
-      for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
-        ClobberedRegUnits.set(Unit);
-
-    if (!MO.readsReg() || !Reg.isVirtual())
-      continue;
-    MachineInstr *DefMI = MRI->getVRegDef(Reg);
-    if (!DefMI || DefMI->getParent() != Head)
-      continue;
-    if (InsertAfter.insert(DefMI).second)
-      LLVM_DEBUG(dbgs() << printMBBReference(*I->getParent()) << " depends on "
-                        << *DefMI);
-    if (DefMI->isTerminator()) {
-      LLVM_DEBUG(dbgs() << "Can't insert instructions below terminator.\n");
-      return false;
-    }
-  }
-  return true;
-}
-
-/// canPredicateInstrs - Returns true if all the instructions in MBB can safely
-/// be predicates. The terminators are not considered.
-///
-/// If instructions use any values that are defined in the head basic block,
-/// the defining instructions are added to InsertAfter.
-///
-/// Any clobbered regunits are added to ClobberedRegUnits.
-///
-bool SSAIfConv::canPredicateInstrs(MachineBasicBlock *MBB) {
-  // Reject any live-in physregs. It's probably CPSR/EFLAGS, and very hard to
-  // get right.
-  if (!MBB->livein_empty()) {
-    LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " has live-ins.\n");
-    return false;
-  }
-
-  unsigned InstrCount = 0;
-
-  // Check all instructions, except the terminators. It is assumed that
-  // terminators never have side effects or define any used register values.
-  for (MachineBasicBlock::iterator I = MBB->begin(),
-                                   E = MBB->getFirstTerminator();
-       I != E; ++I) {
-    if (I->isDebugInstr())
-      continue;
-
-    if (++InstrCount > BlockInstrLimit && !Stress) {
-      LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " has more than "
-                        << BlockInstrLimit << " instructions.\n");
-      return false;
-    }
-
-    // There shouldn't normally be any phis in a single-predecessor block.
-    if (I->isPHI()) {
-      LLVM_DEBUG(dbgs() << "Can't predicate: " << *I);
-      return false;
-    }
-
-    // Check that instruction is predicable
-    if (!TII->isPredicable(*I)) {
-      LLVM_DEBUG(dbgs() << "Isn't predicable: " << *I);
-      return false;
-    }
-
-    // Check that instruction is not already predicated.
-    if (TII->isPredicated(*I) && !TII->canPredicatePredicatedInstr(*I)) {
-      LLVM_DEBUG(dbgs() << "Is already predicated: " << *I);
-      return false;
-    }
-
-    // Check for any dependencies on Head instructions.
-    if (!InstrDependenciesAllowIfConv(&(*I)))
-      return false;
-  }
-  return true;
-}
-
-// Apply predicate to all instructions in the machine block.
-void SSAIfConv::PredicateBlock(MachineBasicBlock *MBB, bool ReversePredicate) {
-  auto Condition = Cond;
-  if (ReversePredicate) {
-    bool CanRevCond = !TII->reverseBranchCondition(Condition);
-    assert(CanRevCond && "Reversed predicate is not supported");
-    (void)CanRevCond;
-  }
-  // Terminators don't need to be predicated as they will be removed.
-  for (MachineBasicBlock::iterator I = MBB->begin(),
-                                   E = MBB->getFirstTerminator();
-       I != E; ++I) {
-    if (I->isDebugInstr())
-      continue;
-    TII->PredicateInstruction(*I, Condition);
-  }
-}
-
-/// Find an insertion point in Head for the speculated instructions. The
-/// insertion point must be:
-///
-/// 1. Before any terminators.
-/// 2. After any instructions in InsertAfter.
-/// 3. Not have any clobbered regunits live.
-///
-/// This function sets InsertionPoint and returns true when successful, it
-/// returns false if no valid insertion point could be found.
-///
-bool SSAIfConv::findInsertionPoint() {
-  // Keep track of live regunits before the current position.
-  // Only track RegUnits that are also in ClobberedRegUnits.
-  LiveRegUnits.clear();
-  SmallVector<MCRegister, 8> Reads;
-  MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
-  MachineBasicBlock::iterator I = Head->end();
-  MachineBasicBlock::iterator B = Head->begin();
-  while (I != B) {
-    --I;
-    // Some of the conditional code depends in I.
-    if (InsertAfter.count(&*I)) {
-      LLVM_DEBUG(dbgs() << "Can't insert code after " << *I);
-      return false;
-    }
-
-    // Update live regunits.
-    for (const MachineOperand &MO : I->operands()) {
-      // We're ignoring regmask operands. That is conservatively correct.
-      if (!MO.isReg())
-        continue;
-      Register Reg = MO.getReg();
-      if (!Reg.isPhysical())
-        continue;
-      // I clobbers Reg, so it isn't live before I.
-      if (MO.isDef())
-        for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
-          LiveRegUnits.erase(Unit);
-      // Unless I reads Reg.
-      if (MO.readsReg())
-        Reads.push_back(Reg.asMCReg());
-    }
-    // Anything read by I is live before I.
-    while (!Reads.empty())
-      for (MCRegUnit Unit : TRI->regunits(Reads.pop_back_val()))
-        if (ClobberedRegUnits.test(Unit))...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/106415


More information about the llvm-commits mailing list