[llvm] [VPlan] Compute blend masks from minimum set of edge masks (PR #201783)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 20 00:11:57 PDT 2026
================
@@ -233,6 +246,103 @@ void VPPredicator::createSwitchEdgeMasks(const VPInstruction *SI) {
setEdgeMask(Src, DefaultDst, DefaultMask);
}
+// Start by keeping track of what edges lead to which value. Then see if any
+// node has the same value for all outgoing edges. If so then propagate that
+// value up to every node it postdominates. E.g:
+//
+// Entry Edges = {C->ɸ : %x, D->ɸ : %x, F->ɸ : %y}
+// / \ [C,D,F all outgoing edges equal: go up postdom frontier]
+// A B ~> {A->C : %x, A->D : %x, Entry->B : %y}
+// / \ |\ [A all outgoing edges equal: go up postdom frontier]
+// C D | E ~> {Entry->A : %x, Entry->B : %y}
+// \ \ |/
+// \ | F
+// \ | /
+// ɸ = phi [%x, C], [%x, D], [%y, F]
+MapVector<VPPredicator::EdgeTy, VPValue *>
+VPPredicator::computeBlendEdges(VPPhi *Phi) {
+ MapVector<EdgeTy, VPValue *> Edges;
+
+ // Mark the given edge as providing the value \p V.
+ auto AddEdge = [&Edges](const VPBlockBase *From, const VPBlockBase *To,
+ VPValue *V) {
+ EdgeTy Edge = {cast<VPBasicBlock>(From), cast<VPBasicBlock>(To)};
+ assert((!Edges.contains(Edge) || Edges.lookup(Edge) == V) &&
+ "Clobbering an edge?");
+ Edges[Edge] = V;
+ };
+
+ for (auto [InVal, InVPBB] : Phi->incoming_values_and_blocks())
+ AddEdge(InVPBB, Phi->getParent(), InVal);
+
+ SetVector<const VPBlockBase *> Worklist(from_range, Phi->incoming_blocks());
+ while (!Worklist.empty()) {
+ auto *VPBB = cast<VPBasicBlock>(Worklist.pop_back_val());
+
+ // Check that all outgoing edges from VPBB have the same value.
+ SmallVector<EdgeTy> OutEdges;
+ for (const VPBlockBase *Succ : VPBB->getSuccessors())
+ OutEdges.emplace_back(VPBB, cast<VPBasicBlock>(Succ));
+ auto OutVals =
+ map_range(OutEdges, [&Edges](EdgeTy E) { return Edges.lookup(E); });
+ VPValue *Common = *OutVals.begin();
+ if (!Common || !all_equal(OutVals))
+ continue;
+
+ // They have the same value: we can move the edges up.
+ for (EdgeTy Edge : OutEdges)
+ Edges.erase(Edge);
+
+ // Iterate up through the post dominance frontier.
+ for (const VPBlockBase *Frontier : VPPDF.find(VPBB)->second) {
----------------
lukel97 wrote:
Done in d8aa8301f5e37c11020b73751c5812d7923401b6, thanks
https://github.com/llvm/llvm-project/pull/201783
More information about the llvm-commits
mailing list