[llvm] fd8afa4 - [VPlan] Use VPUser to manage CondBit

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 9 13:54:12 PST 2021


Author: Florian Hahn
Date: 2021-02-09T21:53:50Z
New Revision: fd8afa41ebc0e78aff4629e0a3738f608dcbac11

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

LOG: [VPlan] Use VPUser to manage CondBit

VP blocks keep track of a condition, which is a VPValue. This patch
updates VPBlockBase to manage the value using VPUser, so
replaceAllUsesWith properly updates the condition bit as well.

This is required to enable VP2VP transformations and it helps with
simplifying some of the code required to manage condition bits.

Reviewed By: gilr

Differential Revision: https://reviews.llvm.org/D95382

Added: 
    

Modified: 
    llvm/lib/Transforms/Vectorize/VPlan.cpp
    llvm/lib/Transforms/Vectorize/VPlan.h
    llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
    llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
    llvm/lib/Transforms/Vectorize/VPlanValue.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index 9abec7022de9..b5f41ff8ab2a 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -1132,9 +1132,6 @@ void VPSlotTracker::assignSlots(const VPlan &Plan) {
   for (const VPValue *V : Plan.VPExternalDefs)
     assignSlot(V);
 
-  for (const VPValue *V : Plan.VPCBVs)
-    assignSlot(V);
-
   if (Plan.BackedgeTakenCount)
     assignSlot(Plan.BackedgeTakenCount);
 

diff  --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index cac58aea95e8..eab8b5fb8077 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -403,8 +403,10 @@ class VPBlockBase {
   /// List of successor blocks.
   SmallVector<VPBlockBase *, 1> Successors;
 
-  /// Successor selector, null for zero or single successor blocks.
-  VPValue *CondBit = nullptr;
+  /// Successor selector managed by a VPUser. For blocks with zero or one
+  /// successors, there is no operand. Otherwise there is exactly one operand
+  /// which is the branch condition.
+  VPUser CondBitUser;
 
   /// Current block predicate - null if the block does not need a predicate.
   VPValue *Predicate = nullptr;
@@ -553,11 +555,29 @@ class VPBlockBase {
   }
 
   /// \return the condition bit selecting the successor.
-  VPValue *getCondBit() { return CondBit; }
+  VPValue *getCondBit() {
+    if (CondBitUser.getNumOperands())
+      return CondBitUser.getOperand(0);
+    return nullptr;
+  }
 
-  const VPValue *getCondBit() const { return CondBit; }
+  const VPValue *getCondBit() const {
+    if (CondBitUser.getNumOperands())
+      return CondBitUser.getOperand(0);
+    return nullptr;
+  }
 
-  void setCondBit(VPValue *CV) { CondBit = CV; }
+  void setCondBit(VPValue *CV) {
+    if (!CV) {
+      if (CondBitUser.getNumOperands() == 1)
+        CondBitUser.removeLastOperand();
+      return;
+    }
+    if (CondBitUser.getNumOperands() == 1)
+      CondBitUser.setOperand(0, CV);
+    else
+      CondBitUser.addOperand(CV);
+  }
 
   VPValue *getPredicate() { return Predicate; }
 
@@ -581,7 +601,7 @@ class VPBlockBase {
                         VPValue *Condition) {
     assert(Successors.empty() && "Setting two successors when others exist.");
     assert(Condition && "Setting two successors without condition!");
-    CondBit = Condition;
+    setCondBit(Condition);
     appendSuccessor(IfTrue);
     appendSuccessor(IfFalse);
   }
@@ -601,7 +621,7 @@ class VPBlockBase {
   /// Remove all the successors of this block and set to null its condition bit
   void clearSuccessors() {
     Successors.clear();
-    CondBit = nullptr;
+    setCondBit(nullptr);
   }
 
   /// The method which generates the output IR that correspond to this
@@ -1736,9 +1756,6 @@ class VPlan {
   /// Holds the VPLoopInfo analysis for this VPlan.
   VPLoopInfo VPLInfo;
 
-  /// Holds the condition bit values built during VPInstruction to VPRecipe transformation.
-  SmallVector<VPValue *, 4> VPCBVs;
-
 public:
   VPlan(VPBlockBase *Entry = nullptr) : Entry(Entry) {
     if (Entry)
@@ -1759,8 +1776,6 @@ class VPlan {
       delete BackedgeTakenCount;
     for (VPValue *Def : VPExternalDefs)
       delete Def;
-    for (VPValue *CBV : VPCBVs)
-      delete CBV;
   }
 
   /// Generate the IR code for this VPlan.
@@ -1796,11 +1811,6 @@ class VPlan {
     VPExternalDefs.insert(VPVal);
   }
 
-  /// Add \p CBV to the vector of condition bit values.
-  void addCBV(VPValue *CBV) {
-    VPCBVs.push_back(CBV);
-  }
-
   void addVPValue(Value *V) {
     assert(V && "Trying to add a null Value to VPlan");
     assert(!Value2VPValue.count(V) && "Value already exists in VPlan");

diff  --git a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
index df96f67288f1..744adc8a0184 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp
@@ -253,7 +253,13 @@ VPRegionBlock *PlainCFGBuilder::buildPlainCFG() {
   assert((PreheaderBB->getTerminator()->getNumSuccessors() == 1) &&
          "Unexpected loop preheader");
   VPBasicBlock *PreheaderVPBB = getOrCreateVPBB(PreheaderBB);
-  createVPInstructionsForVPBB(PreheaderVPBB, PreheaderBB);
+  for (auto &I : *PreheaderBB) {
+    if (I.getType()->isVoidTy())
+      continue;
+    VPValue *VPV = new VPValue(&I);
+    Plan.addExternalDef(VPV);
+    IRDef2VPValue[&I] = VPV;
+  }
   // Create empty VPBB for Loop H so that we can link PH->H.
   VPBlockBase *HeaderVPBB = getOrCreateVPBB(TheLoop->getHeader());
   // Preheader's predecessors will be set during the loop RPO traversal below.

diff  --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 2def29063551..8b569fb57b12 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -24,17 +24,6 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
   auto *TopRegion = cast<VPRegionBlock>(Plan->getEntry());
   ReversePostOrderTraversal<VPBlockBase *> RPOT(TopRegion->getEntry());
 
-  // Condition bit VPValues get deleted during transformation to VPRecipes.
-  // Create new VPValues and save away as condition bits. These will be deleted
-  // after finalizing the vector IR basic blocks.
-  for (VPBlockBase *Base : RPOT) {
-    VPBasicBlock *VPBB = Base->getEntryBasicBlock();
-    if (auto *CondBit = VPBB->getCondBit()) {
-      auto *NCondBit = new VPValue(CondBit->getUnderlyingValue());
-      VPBB->setCondBit(NCondBit);
-      Plan->addCBV(NCondBit);
-    }
-  }
   for (VPBlockBase *Base : RPOT) {
     // Do not widen instructions in pre-header and exit blocks.
     if (Base->getNumPredecessors() == 0 || Base->getNumSuccessors() == 0)

diff  --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h
index ed572ca36627..c4773ebe2b71 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanValue.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h
@@ -229,6 +229,11 @@ class VPUser {
     New->addUser(*this);
   }
 
+  void removeLastOperand() {
+    VPValue *Op = Operands.pop_back_val();
+    Op->removeUser(*this);
+  }
+
   typedef SmallVectorImpl<VPValue *>::iterator operand_iterator;
   typedef SmallVectorImpl<VPValue *>::const_iterator const_operand_iterator;
   typedef iterator_range<operand_iterator> operand_range;


        


More information about the llvm-commits mailing list