[llvm] [PredicateInfo] Support `PredicateInfo` by adding `PHI` nodes that pick up info from created branch predicates (PR #151132)

Rajveer Singh Bharadwaj via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 12 08:17:33 PST 2025


================
@@ -460,6 +471,114 @@ void PredicateInfoBuilder::processSwitch(
   }
 }
 
+void PredicateInfoBuilder::identifyPHICandidates(
+    SmallVectorImpl<Value *> &OpsToRename) {
+  for (Value *Op : OpsToRename) {
+    const auto &ValueInfo = getValueInfo(Op);
+    SmallPtrSet<BasicBlock *, 4> DefiningBlocks;
+    for (const auto *PInfo : ValueInfo.Infos) {
+      if (auto *PBranch = dyn_cast<PredicateBranch>(PInfo)) {
+        DefiningBlocks.insert(PBranch->From);
+      } else if (auto *PSwitch = dyn_cast<PredicateSwitch>(PInfo)) {
+        DefiningBlocks.insert(PSwitch->From);
+      }
+    }
+
+    if (DefiningBlocks.size() > 1) {
+      SmallPtrSet<BasicBlock *, 8> PHIBlocks;
+      needsPHIInsertion(Op, DefiningBlocks, PHIBlocks);
+      for (BasicBlock *PHIBlock : PHIBlocks) {
+        PHICandidates[PHIBlock].push_back(Op);
+      }
+    }
+  }
+}
+
+void PredicateInfoBuilder::needsPHIInsertion(
+    Value *Op, const SmallPtrSetImpl<BasicBlock *> &DefiningBlocks,
+    SmallPtrSetImpl<BasicBlock *> &PHIBlocks) {
+  IDFCalculator<false> IDF(DT);
+  IDF.setDefiningBlocks(DefiningBlocks);
+
+  SmallPtrSet<BasicBlock *, 8> LiveInBlocks;
+  for (auto CurUser = Op->users().begin(); CurUser != Op->users().end();
+       ++CurUser) {
+    if (auto *I = dyn_cast<Instruction>(*CurUser)) {
+      LiveInBlocks.insert(I->getParent());
+    }
+  }
+  IDF.setLiveInBlocks(LiveInBlocks);
+
+  SmallVector<BasicBlock *, 4> IDFBlocks;
+  IDF.calculate(IDFBlocks);
+
+  for (const auto &IDFBlock : IDFBlocks) {
+    PHIBlocks.insert(std::move(IDFBlock));
+  }
+}
+
+PHINode *PredicateInfoBuilder::insertPredicatePHIs(
+    Value *Op, BasicBlock *PHIBlock, SmallVectorImpl<Value *> &OpsToRename) {
+  IRBuilder<> Builder(&PHIBlock->front());
+
+  PHINode *PHI = Builder.CreatePHI(Op->getType(), pred_size(PHIBlock),
+                                   Op->getName() + ".predicate.phi");
+  const auto &ValueInfo = getValueInfo(Op);
+
+  for (BasicBlock *Pred : predecessors(PHIBlock)) {
+    Value *IncomingValue = nullptr;
+    for (const auto *PInfo : ValueInfo.Infos) {
+      if (auto *PBranch = dyn_cast<PredicateBranch>(PInfo)) {
+        if (PBranch->From == Pred && PBranch->To == PHIBlock) {
+          IncomingValue = PBranch->OriginalOp;
+        }
+      } else if (auto *PSwitch = dyn_cast<PredicateSwitch>(PInfo)) {
+        if (PSwitch->From == Pred && PSwitch->To == PHIBlock) {
+          IncomingValue = PSwitch->OriginalOp;
+        }
+      }
+    }
+    if (IncomingValue) {
+      PHI->addIncoming(IncomingValue, Pred);
+    } else {
+      PHI->eraseFromParent();
+      return nullptr;
+    }
+  }
+
+  return PHI;
+}
+
+void PredicateInfoBuilder::processPredicatePHIs(
+    SmallVectorImpl<Value *> &OpsToRename) {
+  SmallVector<PHINode *, 4> InsertedPHINodes;
+
+  for (const auto &PHICandidate : PHICandidates) {
+    BasicBlock *PHIBlock = PHICandidate.first;
+    for (Value *Op : PHICandidate.second) {
+      auto *PHI = insertPredicatePHIs(Op, PHIBlock, OpsToRename);
+      InsertedPHINodes.push_back(PHI);
+    }
+  }
+
+  size_t Idx = 0, NumNodes = InsertedPHINodes.size();
+  for (const auto &PHICandidate : PHICandidates) {
+    BasicBlock *PHIBlock = PHICandidate.first;
+    for (Value *Op : PHICandidate.second) {
+      while (Idx < NumNodes && InsertedPHINodes[Idx] == nullptr) {
----------------
Rajveer100 wrote:

Sure, in short, I am replacing the candidates with the created phi nodes.

The indexing method which I am using is to keep track which nodes I replaced, if not I skip it.

For example, as of now I am skipping already existing phi nodes in the IR (there may be few more such instructions we may want to skip), if not done, there will be recursive phis at the same op.

Another possible option for this is since we explicitly named our predicate phis, maybe we could filter by name (i.e string value).

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


More information about the llvm-commits mailing list