[llvm] [SPIR-V] Cache PartialOrderingVisitor in Splitter instead of rebuilding per call (PR #211198)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 22 01:24:11 PDT 2026


https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/211198

None

>From 4724c055266f0cb83032f7eeaf823e806edf0b37 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 22 Jul 2026 10:23:31 +0200
Subject: [PATCH] [SPIR-V] Cache PartialOrderingVisitor in Splitter instead of
 rebuilding per call

---
 llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp b/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp
index 0e6f5ecab1437..db4413b9d4277 100644
--- a/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVStructurizer.cpp
@@ -28,6 +28,7 @@
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/LoopSimplify.h"
 #include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
+#include <optional>
 #include <stack>
 
 using namespace llvm;
@@ -36,14 +37,6 @@ using namespace SPIRV;
 using BlockSet = SmallPtrSet<BasicBlock *, 0>;
 using Edge = std::pair<BasicBlock *, BasicBlock *>;
 
-// Helper function to do a partial order visit from the block |Start|, calling
-// |Op| on each visited node.
-static void partialOrderVisit(BasicBlock &Start,
-                              std::function<bool(BasicBlock *)> Op) {
-  PartialOrderingVisitor V(*Start.getParent());
-  V.partialOrderVisit(Start, std::move(Op));
-}
-
 // Returns the exact convergence region in the tree defined by `Node` for which
 // `BB` is the header, nullptr otherwise.
 static const ConvergenceRegion *
@@ -313,12 +306,14 @@ class SPIRVStructurizerImpl {
     LoopInfo &LI;
     DomTreeBuilder::BBDomTree DT;
     DomTreeBuilder::BBPostDomTree PDT;
+    std::optional<PartialOrderingVisitor> POV;
 
     Splitter(Function &F, LoopInfo &LI) : F(F), LI(LI) { invalidate(); }
 
     void invalidate() {
       PDT.recalculate(F);
       DT.recalculate(F);
+      POV.emplace(F);
     }
 
     // Returns the list of blocks that belong to a SPIR-V loop construct,
@@ -327,7 +322,7 @@ class SPIRVStructurizerImpl {
                                                      BasicBlock *Merge) {
       assert(DT.dominates(Header, Merge));
       std::vector<BasicBlock *> Output;
-      partialOrderVisit(*Header, [&](BasicBlock *BB) {
+      POV->partialOrderVisit(*Header, [&](BasicBlock *BB) {
         if (BB == Merge)
           return false;
         if (DT.dominates(Merge, BB) || !DT.dominates(Header, BB))
@@ -353,7 +348,7 @@ class SPIRVStructurizerImpl {
       }
 
       std::vector<BasicBlock *> Output;
-      partialOrderVisit(*Node->Header, [&](BasicBlock *BB) {
+      POV->partialOrderVisit(*Node->Header, [&](BasicBlock *BB) {
         if (OutsideBlocks.count(BB) != 0)
           return false;
         if (DT.dominates(Node->Merge, BB) || !DT.dominates(Node->Header, BB))
@@ -370,7 +365,7 @@ class SPIRVStructurizerImpl {
       assert(DT.dominates(Header, Merge));
 
       std::vector<BasicBlock *> Output;
-      partialOrderVisit(*Header, [&](BasicBlock *BB) {
+      POV->partialOrderVisit(*Header, [&](BasicBlock *BB) {
         // the blocks structurally dominated by a switch header,
         if (!DT.dominates(Header, BB))
           return false;
@@ -390,7 +385,7 @@ class SPIRVStructurizerImpl {
       assert(DT.dominates(Target, Merge));
 
       std::vector<BasicBlock *> Output;
-      partialOrderVisit(*Target, [&](BasicBlock *BB) {
+      POV->partialOrderVisit(*Target, [&](BasicBlock *BB) {
         // the blocks structurally dominated by an OpSwitch Target or Default
         // block
         if (!DT.dominates(Target, BB))



More information about the llvm-commits mailing list