[llvm] d5ec01b - Revert "[NFC][EarlyIfConverter] Replace boolean Predicate for a class (#108519)" (#111372)

via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 7 07:03:15 PDT 2024


Author: Juan Manuel Martinez CaamaƱo
Date: 2024-10-07T16:03:11+02:00
New Revision: d5ec01b0dd20d8bdacc2810539686374e7ad5918

URL: https://github.com/llvm/llvm-project/commit/d5ec01b0dd20d8bdacc2810539686374e7ad5918
DIFF: https://github.com/llvm/llvm-project/commit/d5ec01b0dd20d8bdacc2810539686374e7ad5918.diff

LOG: Revert "[NFC][EarlyIfConverter] Replace boolean Predicate for a class (#108519)" (#111372)

This reverts commit 9e7315912656628b606e884e39cdeb261b476f16.

Added: 
    

Modified: 
    llvm/lib/CodeGen/EarlyIfConversion.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/EarlyIfConversion.cpp b/llvm/lib/CodeGen/EarlyIfConversion.cpp
index 2b97fa449f08f7..c827d5bdcf55ba 100644
--- a/llvm/lib/CodeGen/EarlyIfConversion.cpp
+++ b/llvm/lib/CodeGen/EarlyIfConversion.cpp
@@ -122,18 +122,6 @@ class SSAIfConv {
   /// The branch condition determined by analyzeBranch.
   SmallVector<MachineOperand, 4> Cond;
 
-  class PredicationStrategyBase {
-  public:
-    virtual bool canConvertIf(MachineBasicBlock *Tail) { return true; }
-    virtual bool canPredicateInstr(const MachineInstr &I) = 0;
-    virtual void predicateBlock(MachineBasicBlock *MBB,
-                                ArrayRef<MachineOperand> Cond,
-                                bool Reverse) = 0;
-    virtual ~PredicationStrategyBase() = default;
-  };
-
-  PredicationStrategyBase &Predicate;
-
 private:
   /// Instructions in Head that define values used by the conditional blocks.
   /// The hoisted instructions must be inserted after these instructions.
@@ -149,6 +137,10 @@ class SSAIfConv {
   /// 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);
@@ -157,6 +149,10 @@ class SSAIfConv {
   /// 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();
 
@@ -167,8 +163,7 @@ class SSAIfConv {
   void rewritePHIOperands();
 
 public:
-  SSAIfConv(PredicationStrategyBase &Predicate, MachineFunction &MF)
-      : Predicate(Predicate) {
+  SSAIfConv(MachineFunction &MF) {
     TII = MF.getSubtarget().getInstrInfo();
     TRI = MF.getSubtarget().getRegisterInfo();
     MRI = &MF.getRegInfo();
@@ -180,14 +175,76 @@ class SSAIfConv {
 
   /// canConvertIf - If the sub-CFG headed by MBB can be if-converted,
   /// initialize the internal state, and return true.
-  bool canConvertIf(MachineBasicBlock *MBB);
+  /// 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);
+  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,
@@ -261,8 +318,17 @@ bool SSAIfConv::canPredicateInstrs(MachineBasicBlock *MBB) {
       return false;
     }
 
-    if (!Predicate.canPredicateInstr(*I))
+    // 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)))
@@ -271,6 +337,24 @@ bool SSAIfConv::canPredicateInstrs(MachineBasicBlock *MBB) {
   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:
 ///
@@ -349,7 +433,7 @@ bool SSAIfConv::findInsertionPoint() {
 /// canConvertIf - analyze the sub-cfg rooted in MBB, and return true if it is
 /// a potential candidate for if-conversion. Fill out the internal state.
 ///
-bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) {
+bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB, bool Predicate) {
   Head = MBB;
   TBB = FBB = Tail = nullptr;
 
@@ -389,6 +473,14 @@ bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) {
                       << printMBBReference(*Tail) << '\n');
   }
 
+  // This is a triangle or a diamond.
+  // Skip if we cannot predicate and there are no phis skip as there must be
+  // side effects that can only be handled with predication.
+  if (!Predicate && (Tail->empty() || !Tail->front().isPHI())) {
+    LLVM_DEBUG(dbgs() << "No phis in tail.\n");
+    return false;
+  }
+
   // The branch we're looking to eliminate must be analyzable.
   Cond.clear();
   if (TII->analyzeBranch(*Head, TBB, FBB, Cond)) {
@@ -396,10 +488,6 @@ bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) {
     return false;
   }
 
-  if (!Predicate.canConvertIf(Tail)) {
-    return false;
-  }
-
   // This is weird, probably some sort of degenerate CFG.
   if (!TBB) {
     LLVM_DEBUG(dbgs() << "analyzeBranch didn't find conditional branch.\n");
@@ -447,9 +535,17 @@ bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) {
   // Check that the conditional instructions can be speculated.
   InsertAfter.clear();
   ClobberedRegUnits.reset();
-  for (MachineBasicBlock *MBB : {TBB, FBB})
-    if (MBB != Tail && !canPredicateInstrs(MBB))
+  if (Predicate) {
+    if (TBB != Tail && !canPredicateInstrs(TBB))
       return false;
+    if (FBB != Tail && !canPredicateInstrs(FBB))
+      return false;
+  } else {
+    if (TBB != Tail && !canSpeculateInstrs(TBB))
+      return false;
+    if (FBB != Tail && !canSpeculateInstrs(FBB))
+      return false;
+  }
 
   // Try to find a valid insertion point for the speculated instructions in the
   // head basic block.
@@ -582,7 +678,8 @@ void SSAIfConv::rewritePHIOperands() {
 ///
 /// Any basic blocks that need to be erased will be added to RemoveBlocks.
 ///
-void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks) {
+void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
+                          bool Predicate) {
   assert(Head && Tail && TBB && FBB && "Call canConvertIf first.");
 
   // Update statistics.
@@ -592,15 +689,16 @@ void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks) {
     ++NumDiamondsConv;
 
   // Move all instructions into Head, except for the terminators.
-  for (MachineBasicBlock *MBB : {TBB, FBB}) {
-    if (MBB != Tail) {
-      // reverse the condition for the false bb
-      Predicate.predicateBlock(MBB, Cond, MBB == FBB);
-      Head->splice(InsertionPoint, MBB, MBB->begin(),
-                   MBB->getFirstTerminator());
-    }
+  if (TBB != Tail) {
+    if (Predicate)
+      PredicateBlock(TBB, /*ReversePredicate=*/false);
+    Head->splice(InsertionPoint, TBB, TBB->begin(), TBB->getFirstTerminator());
+  }
+  if (FBB != Tail) {
+    if (Predicate)
+      PredicateBlock(FBB, /*ReversePredicate=*/true);
+    Head->splice(InsertionPoint, FBB, FBB->begin(), FBB->getFirstTerminator());
   }
-
   // Are there extra Tail predecessors?
   bool ExtraPreds = Tail->pred_size() != 2;
   if (ExtraPreds)
@@ -764,46 +862,6 @@ template <typename Remark> Remark &operator<<(Remark &R, Cycles C) {
 }
 } // anonymous namespace
 
-class SpeculateStrategy : public SSAIfConv::PredicationStrategyBase {
-public:
-  bool canConvertIf(MachineBasicBlock *Tail) override {
-    // This is a triangle or a diamond.
-    // Skip if we cannot predicate and there are no phis skip as there must
-    // be side effects that can only be handled with predication.
-    if (Tail->empty() || !Tail->front().isPHI()) {
-      LLVM_DEBUG(dbgs() << "No phis in tail.\n");
-      return false;
-    }
-    return true;
-  }
-
-  bool canPredicateInstr(const MachineInstr &I) override {
-    // 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 (I.mayLoad()) {
-      LLVM_DEBUG(dbgs() << "Won't speculate load: " << I);
-      return false;
-    }
-
-    // We never speculate stores, so an AA pointer isn't necessary.
-    bool DontMoveAcrossStore = true;
-    if (!I.isSafeToMove(DontMoveAcrossStore)) {
-      LLVM_DEBUG(dbgs() << "Can't speculate: " << I);
-      return false;
-    }
-    return true;
-  }
-
-  void predicateBlock(MachineBasicBlock *MBB, ArrayRef<MachineOperand> Cond,
-                      bool Reverse)
-      override { /* do nothing, everything is speculatable and it's valid to
-                    move the instructions into the head */
-  }
-
-  ~SpeculateStrategy() override = default;
-};
-
 /// Apply cost model and heuristics to the if-conversion in IfConv.
 /// Return true if the conversion is a good idea.
 ///
@@ -1037,8 +1095,7 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
   MinInstr = nullptr;
 
   bool Changed = false;
-  SpeculateStrategy Speculate;
-  SSAIfConv IfConv(Speculate, MF);
+  SSAIfConv IfConv(MF);
 
   // Visit blocks in dominator tree post-order. The post-order enables nested
   // if-conversion in a single pass. The tryConvertIf() function may erase
@@ -1100,48 +1157,6 @@ void EarlyIfPredicator::getAnalysisUsage(AnalysisUsage &AU) const {
   MachineFunctionPass::getAnalysisUsage(AU);
 }
 
-class PredicatorStrategy : public SSAIfConv::PredicationStrategyBase {
-  const TargetInstrInfo *TII = nullptr;
-
-public:
-  PredicatorStrategy(const TargetInstrInfo *TII) : TII(TII) {}
-
-  bool canPredicateInstr(const MachineInstr &I) override {
-    // 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;
-    }
-    return true;
-  }
-
-  void predicateBlock(MachineBasicBlock *MBB, ArrayRef<MachineOperand> Cond,
-                      bool Reverse) override {
-    SmallVector<MachineOperand> Condition(Cond);
-    if (Reverse) {
-      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);
-    }
-  }
-
-  ~PredicatorStrategy() override = default;
-};
-
 /// Apply the target heuristic to decide if the transformation is profitable.
 bool EarlyIfPredicator::shouldConvertIf(SSAIfConv &IfConv) {
   auto TrueProbability = MBPI->getEdgeProbability(IfConv.Head, IfConv.TBB);
@@ -1186,10 +1201,11 @@ bool EarlyIfPredicator::shouldConvertIf(SSAIfConv &IfConv) {
 bool EarlyIfPredicator::tryConvertIf(SSAIfConv &IfConv,
                                      MachineBasicBlock *MBB) {
   bool Changed = false;
-  while (IfConv.canConvertIf(MBB) && shouldConvertIf(IfConv)) {
+  while (IfConv.canConvertIf(MBB, /*Predicate=*/true) &&
+         shouldConvertIf(IfConv)) {
     // If-convert MBB and update analyses.
     SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
-    IfConv.convertIf(RemoveBlocks);
+    IfConv.convertIf(RemoveBlocks, /*Predicate=*/true);
     Changed = true;
     updateDomTree(DomTree, IfConv, RemoveBlocks);
     for (MachineBasicBlock *MBB : RemoveBlocks)
@@ -1215,8 +1231,7 @@ bool EarlyIfPredicator::runOnMachineFunction(MachineFunction &MF) {
   MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
 
   bool Changed = false;
-  PredicatorStrategy Predicate(TII);
-  SSAIfConv IfConv(Predicate, MF);
+  SSAIfConv IfConv(MF);
 
   // Visit blocks in dominator tree post-order. The post-order enables nested
   // if-conversion in a single pass. The tryConvertIf() function may erase


        


More information about the llvm-commits mailing list