[llvm] [UniformityAnalysis] Add CallbackVH to keep UniformValues consistent on value deletion (PR #187658)
Pankaj Dwivedi via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 13 07:34:45 PDT 2026
https://github.com/PankajDwivedi-25 updated https://github.com/llvm/llvm-project/pull/187658
>From 14bbeb4621d51633071a3c77fbd0690679c06220 Mon Sep 17 00:00:00 2001
From: padivedi <padivedi at amd.com>
Date: Thu, 9 Apr 2026 12:01:46 +0530
Subject: [PATCH 1/4] add callBackVH sdupport in uniformity
---
llvm/include/llvm/ADT/GenericUniformityImpl.h | 14 ++++++
llvm/include/llvm/ADT/GenericUniformityInfo.h | 1 +
llvm/lib/Analysis/UniformityAnalysis.cpp | 45 +++++++++++++++++++
.../lib/CodeGen/MachineUniformityAnalysis.cpp | 4 ++
.../Target/AMDGPU/UniformityAnalysisTest.cpp | 43 ++++++++++++++++++
5 files changed, 107 insertions(+)
diff --git a/llvm/include/llvm/ADT/GenericUniformityImpl.h b/llvm/include/llvm/ADT/GenericUniformityImpl.h
index d5859981ce1a7..d439571b7bc4c 100644
--- a/llvm/include/llvm/ADT/GenericUniformityImpl.h
+++ b/llvm/include/llvm/ADT/GenericUniformityImpl.h
@@ -57,6 +57,12 @@
namespace llvm {
+/// Interface for keeping UniformValues in sync when IR values are deleted.
+/// IR specialization installs a concrete CallbackVH-based implementation.
+struct UniformValueCallbackManager {
+ virtual ~UniformValueCallbackManager() = default;
+};
+
// Forward decl from llvm/CodeGen/MachineInstr.h
class MachineInstr;
@@ -376,6 +382,10 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
/// Divergence is seeded by calls to \p markDivergent.
void compute();
+ /// \brief Register callbacks (e.g., CallbackVH for IR) to keep
+ /// UniformValues in sync when values are deleted after analysis.
+ void registerCallbacks();
+
/// \brief Whether \p Val will always return a uniform value regardless of its
/// operands
bool isAlwaysUniform(const InstructionT &Instr) const;
@@ -447,6 +457,10 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
// values not in this set are conservatively treated as divergent.
DenseSet<ConstValueRefT> UniformValues;
+ // For IR: callbacks to remove from UniformValues on value deletion,
+ // avoiding stale pointers when addresses are reused.
+ std::unique_ptr<UniformValueCallbackManager> UniformValueCallbacks;
+
// Internal worklist for divergence propagation.
std::vector<const InstructionT *> Worklist;
diff --git a/llvm/include/llvm/ADT/GenericUniformityInfo.h b/llvm/include/llvm/ADT/GenericUniformityInfo.h
index a504335ec078e..7dff3d84d92cf 100644
--- a/llvm/include/llvm/ADT/GenericUniformityInfo.h
+++ b/llvm/include/llvm/ADT/GenericUniformityInfo.h
@@ -52,6 +52,7 @@ template <typename ContextT> class GenericUniformityInfo {
void compute() {
DA->initialize();
DA->compute();
+ DA->registerCallbacks();
}
/// The GPU kernel this analysis result is for
diff --git a/llvm/lib/Analysis/UniformityAnalysis.cpp b/llvm/lib/Analysis/UniformityAnalysis.cpp
index 41519bcd09baa..b3d56737d2ad8 100644
--- a/llvm/lib/Analysis/UniformityAnalysis.cpp
+++ b/llvm/lib/Analysis/UniformityAnalysis.cpp
@@ -14,10 +14,46 @@
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
using namespace llvm;
+namespace {
+
+/// CallbackVH that removes the value from UniformValues on deletion.
+/// Prevents stale pointers when a deleted value's address is reused.
+class UniformValueHandle : public CallbackVH {
+ DenseSet<const Value *> &UniformSet;
+
+public:
+ UniformValueHandle(Value *V, DenseSet<const Value *> &S)
+ : CallbackVH(V), UniformSet(S) {}
+ virtual ~UniformValueHandle() = default;
+
+ void deleted() override {
+ UniformSet.erase(getValPtr());
+ CallbackVH::deleted();
+ }
+};
+
+/// IR implementation: registers CallbackVH for each uniform value.
+class IRUniformValueCallbackManager : public UniformValueCallbackManager {
+ DenseSet<const Value *> &UniformSet;
+ std::vector<std::unique_ptr<UniformValueHandle>> Handles;
+
+public:
+ explicit IRUniformValueCallbackManager(DenseSet<const Value *> &S)
+ : UniformSet(S) {}
+
+ void registerValue(const Value *V) {
+ Handles.push_back(std::make_unique<UniformValueHandle>(
+ const_cast<Value *>(V), UniformSet));
+ }
+};
+
+} // namespace
+
template <>
bool llvm::GenericUniformityAnalysisImpl<SSAContext>::hasDivergentDefs(
const Instruction &I) const {
@@ -107,6 +143,15 @@ template <> void llvm::GenericUniformityAnalysisImpl<SSAContext>::initialize() {
pushUsers(Arg);
}
+template <>
+void llvm::GenericUniformityAnalysisImpl<SSAContext>::registerCallbacks() {
+ IRUniformValueCallbackManager *Manager =
+ new IRUniformValueCallbackManager(UniformValues);
+ for (const Value *V : UniformValues)
+ Manager->registerValue(V);
+ UniformValueCallbacks.reset(Manager);
+}
+
template <>
bool llvm::GenericUniformityAnalysisImpl<SSAContext>::usesValueFromCycle(
const Instruction &I, const Cycle &DefCycle) const {
diff --git a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
index aa85b95a96d09..5467e88c41745 100644
--- a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
+++ b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
@@ -84,6 +84,10 @@ void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() {
}
}
+template <>
+void llvm::GenericUniformityAnalysisImpl<
+ MachineSSAContext>::registerCallbacks() {}
+
template <>
void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers(
Register Reg) {
diff --git a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp
index ae44d3ef6cbf2..7ad54af38f443 100644
--- a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp
+++ b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp
@@ -93,3 +93,46 @@ TEST(UniformityAnalysis, NewValueIsConservativelyDivergent) {
EXPECT_TRUE(UI.isDivergent(NewInst))
<< "New instruction created after analysis must be reported divergent";
}
+
+TEST(UniformityAnalysis, DeletionCallbackMakesNewInstDivergent) {
+ // Delete a uniform instruction. CallbackVH::deleted() removes it from
+ // UniformValues during eraseFromParent(). A newly created instruction is
+ // not in UniformValues and must be conservatively reported as divergent.
+ LLVMInitializeAMDGPUTargetInfo();
+ LLVMInitializeAMDGPUTarget();
+ LLVMInitializeAMDGPUTargetMC();
+
+ StringRef ModuleString = R"(
+ target triple = "amdgcn-unknown-amdhsa"
+ define amdgpu_kernel void @test(i32 inreg %a, i32 inreg %b) {
+ %add = add i32 %a, %b
+ ret void
+ }
+ )";
+ LLVMContext Context;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, Context);
+ ASSERT_TRUE(M) << Err.getMessage();
+
+ Function *F = M->getFunction("test");
+ ASSERT_TRUE(F);
+
+ std::unique_ptr<TargetMachine> TM =
+ createAMDGPUTargetMachine("amdgcn-amd-", "gfx1010", "+wavefrontsize32");
+ ASSERT_TRUE(TM);
+ TargetTransformInfo TTI = TM->getTargetTransformInfo(*F);
+
+ UniformityInfo UI = computeUniformity(&TTI, F);
+
+ Instruction *AddInst = &*F->getEntryBlock().begin();
+ ASSERT_TRUE(isa<BinaryOperator>(AddInst));
+ EXPECT_FALSE(UI.isDivergent(AddInst)) << "%add should be uniform";
+
+ AddInst->eraseFromParent();
+
+ IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
+ Value *NewInst = Builder.CreateAdd(F->getArg(0), F->getArg(1), "new_add");
+
+ EXPECT_TRUE(UI.isDivergent(NewInst))
+ << "New instruction after deletion must be reported divergent";
+}
>From c30110b31c99ed0b2509a121f2e8e2701db5bd76 Mon Sep 17 00:00:00 2001
From: Pankaj Dwivedi <pankajkumar.divedi at amd.com>
Date: Thu, 9 Apr 2026 19:29:17 +0530
Subject: [PATCH 2/4] Update UniformityAnalysis.cpp
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Juan Manuel Martinez CaamaƱo <jmartinezcaamao at gmail.com>
---
llvm/lib/Analysis/UniformityAnalysis.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Analysis/UniformityAnalysis.cpp b/llvm/lib/Analysis/UniformityAnalysis.cpp
index b3d56737d2ad8..1ccad01192737 100644
--- a/llvm/lib/Analysis/UniformityAnalysis.cpp
+++ b/llvm/lib/Analysis/UniformityAnalysis.cpp
@@ -145,11 +145,11 @@ template <> void llvm::GenericUniformityAnalysisImpl<SSAContext>::initialize() {
template <>
void llvm::GenericUniformityAnalysisImpl<SSAContext>::registerCallbacks() {
- IRUniformValueCallbackManager *Manager =
- new IRUniformValueCallbackManager(UniformValues);
+ std::unique_ptr<IRUniformValueCallbackManager> Manager =
+ std::make_unique<IRUniformValueCallbackManager>(UniformValues);
for (const Value *V : UniformValues)
Manager->registerValue(V);
- UniformValueCallbacks.reset(Manager);
+ UniformValueCallbacks = std::move(Manager);
}
template <>
>From b8f3fbc23bf30228afa62245ac496541f15b95a4 Mon Sep 17 00:00:00 2001
From: padivedi <padivedi at amd.com>
Date: Mon, 13 Apr 2026 20:00:12 +0530
Subject: [PATCH 3/4] replace callbackVH with assertingVH
---
llvm/include/llvm/ADT/GenericSSAContext.h | 5 +++
llvm/include/llvm/ADT/GenericUniformityImpl.h | 24 +++++-----
llvm/include/llvm/ADT/GenericUniformityInfo.h | 5 ++-
llvm/include/llvm/CodeGen/MachineSSAContext.h | 1 +
llvm/include/llvm/IR/SSAContext.h | 2 +
llvm/lib/Analysis/UniformityAnalysis.cpp | 45 -------------------
.../lib/CodeGen/MachineUniformityAnalysis.cpp | 4 --
.../Target/AMDGPU/UniformityAnalysisTest.cpp | 9 ++--
8 files changed, 27 insertions(+), 68 deletions(-)
diff --git a/llvm/include/llvm/ADT/GenericSSAContext.h b/llvm/include/llvm/ADT/GenericSSAContext.h
index 36d0e2e8f70cd..db1a44f79633d 100644
--- a/llvm/include/llvm/ADT/GenericSSAContext.h
+++ b/llvm/include/llvm/ADT/GenericSSAContext.h
@@ -63,6 +63,11 @@ template <typename _FunctionT> class GenericSSAContext {
// instruction.
using UseT = typename SSATraits::UseT;
+ // The key type for the DenseSet tracking uniform values. For IR this is
+ // AssertingVH<const Value> to catch forgotten eraseValue() calls in debug
+ // builds; for MIR it is Register.
+ using UniformSetKeyT = typename SSATraits::UniformSetKeyT;
+
// A BlockT is a sequence of InstructionT, and forms a node of the CFG. It
// has global methods predecessors() and successors() that return
// the list of incoming CFG edges and outgoing CFG edges
diff --git a/llvm/include/llvm/ADT/GenericUniformityImpl.h b/llvm/include/llvm/ADT/GenericUniformityImpl.h
index d439571b7bc4c..1877c7a4b33c8 100644
--- a/llvm/include/llvm/ADT/GenericUniformityImpl.h
+++ b/llvm/include/llvm/ADT/GenericUniformityImpl.h
@@ -57,12 +57,6 @@
namespace llvm {
-/// Interface for keeping UniformValues in sync when IR values are deleted.
-/// IR specialization installs a concrete CallbackVH-based implementation.
-struct UniformValueCallbackManager {
- virtual ~UniformValueCallbackManager() = default;
-};
-
// Forward decl from llvm/CodeGen/MachineInstr.h
class MachineInstr;
@@ -382,9 +376,9 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
/// Divergence is seeded by calls to \p markDivergent.
void compute();
- /// \brief Register callbacks (e.g., CallbackVH for IR) to keep
- /// UniformValues in sync when values are deleted after analysis.
- void registerCallbacks();
+ /// \brief Remove \p V from UniformValues. Must be called before deleting
+ /// a value that was present during analysis to prevent stale pointers.
+ void eraseValue(ConstValueRefT V) { UniformValues.erase(V); }
/// \brief Whether \p Val will always return a uniform value regardless of its
/// operands
@@ -455,11 +449,7 @@ template <typename ContextT> class GenericUniformityAnalysisImpl {
// Values known to be uniform. Populated in initialize() with all values,
// then values are removed as divergence is propagated. After analysis,
// values not in this set are conservatively treated as divergent.
- DenseSet<ConstValueRefT> UniformValues;
-
- // For IR: callbacks to remove from UniformValues on value deletion,
- // avoiding stale pointers when addresses are reused.
- std::unique_ptr<UniformValueCallbackManager> UniformValueCallbacks;
+ DenseSet<typename ContextT::UniformSetKeyT> UniformValues;
// Internal worklist for divergence propagation.
std::vector<const InstructionT *> Worklist;
@@ -1325,6 +1315,12 @@ bool GenericUniformityInfo<ContextT>::hasDivergentTerminator(const BlockT &B) {
return DA && DA->hasDivergentTerminator(B);
}
+template <typename ContextT>
+void GenericUniformityInfo<ContextT>::eraseValue(ConstValueRefT V) {
+ if (DA)
+ DA->eraseValue(V);
+}
+
/// \brief T helper function for printing.
template <typename ContextT>
void GenericUniformityInfo<ContextT>::print(raw_ostream &out) const {
diff --git a/llvm/include/llvm/ADT/GenericUniformityInfo.h b/llvm/include/llvm/ADT/GenericUniformityInfo.h
index 7dff3d84d92cf..63782651e7b9d 100644
--- a/llvm/include/llvm/ADT/GenericUniformityInfo.h
+++ b/llvm/include/llvm/ADT/GenericUniformityInfo.h
@@ -52,7 +52,6 @@ template <typename ContextT> class GenericUniformityInfo {
void compute() {
DA->initialize();
DA->compute();
- DA->registerCallbacks();
}
/// The GPU kernel this analysis result is for
@@ -77,6 +76,10 @@ template <typename ContextT> class GenericUniformityInfo {
bool hasDivergentTerminator(const BlockT &B);
+ /// \brief Remove \p V from the analysis. Must be called before deleting
+ /// a value that was present during analysis to prevent stale pointers.
+ void eraseValue(ConstValueRefT V);
+
void print(raw_ostream &Out) const;
iterator_range<TemporalDivergenceTuple *> getTemporalDivergenceList() const;
diff --git a/llvm/include/llvm/CodeGen/MachineSSAContext.h b/llvm/include/llvm/CodeGen/MachineSSAContext.h
index 0e4304f69380f..697b94f83a1c7 100644
--- a/llvm/include/llvm/CodeGen/MachineSSAContext.h
+++ b/llvm/include/llvm/CodeGen/MachineSSAContext.h
@@ -33,6 +33,7 @@ template <> struct GenericSSATraits<MachineFunction> {
using ValueRefT = Register;
using ConstValueRefT = Register;
using UseT = MachineOperand;
+ using UniformSetKeyT = Register;
};
using MachineSSAContext = GenericSSAContext<MachineFunction>;
diff --git a/llvm/include/llvm/IR/SSAContext.h b/llvm/include/llvm/IR/SSAContext.h
index d0da5e222a8e6..15755c8b287c4 100644
--- a/llvm/include/llvm/IR/SSAContext.h
+++ b/llvm/include/llvm/IR/SSAContext.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/GenericSSAContext.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/ValueHandle.h"
namespace llvm {
class BasicBlock;
@@ -35,6 +36,7 @@ template <> struct GenericSSATraits<Function> {
using ValueRefT = Value *;
using ConstValueRefT = const Value *;
using UseT = Use;
+ using UniformSetKeyT = AssertingVH<const Value>;
};
using SSAContext = GenericSSAContext<Function>;
diff --git a/llvm/lib/Analysis/UniformityAnalysis.cpp b/llvm/lib/Analysis/UniformityAnalysis.cpp
index 1ccad01192737..41519bcd09baa 100644
--- a/llvm/lib/Analysis/UniformityAnalysis.cpp
+++ b/llvm/lib/Analysis/UniformityAnalysis.cpp
@@ -14,46 +14,10 @@
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
using namespace llvm;
-namespace {
-
-/// CallbackVH that removes the value from UniformValues on deletion.
-/// Prevents stale pointers when a deleted value's address is reused.
-class UniformValueHandle : public CallbackVH {
- DenseSet<const Value *> &UniformSet;
-
-public:
- UniformValueHandle(Value *V, DenseSet<const Value *> &S)
- : CallbackVH(V), UniformSet(S) {}
- virtual ~UniformValueHandle() = default;
-
- void deleted() override {
- UniformSet.erase(getValPtr());
- CallbackVH::deleted();
- }
-};
-
-/// IR implementation: registers CallbackVH for each uniform value.
-class IRUniformValueCallbackManager : public UniformValueCallbackManager {
- DenseSet<const Value *> &UniformSet;
- std::vector<std::unique_ptr<UniformValueHandle>> Handles;
-
-public:
- explicit IRUniformValueCallbackManager(DenseSet<const Value *> &S)
- : UniformSet(S) {}
-
- void registerValue(const Value *V) {
- Handles.push_back(std::make_unique<UniformValueHandle>(
- const_cast<Value *>(V), UniformSet));
- }
-};
-
-} // namespace
-
template <>
bool llvm::GenericUniformityAnalysisImpl<SSAContext>::hasDivergentDefs(
const Instruction &I) const {
@@ -143,15 +107,6 @@ template <> void llvm::GenericUniformityAnalysisImpl<SSAContext>::initialize() {
pushUsers(Arg);
}
-template <>
-void llvm::GenericUniformityAnalysisImpl<SSAContext>::registerCallbacks() {
- std::unique_ptr<IRUniformValueCallbackManager> Manager =
- std::make_unique<IRUniformValueCallbackManager>(UniformValues);
- for (const Value *V : UniformValues)
- Manager->registerValue(V);
- UniformValueCallbacks = std::move(Manager);
-}
-
template <>
bool llvm::GenericUniformityAnalysisImpl<SSAContext>::usesValueFromCycle(
const Instruction &I, const Cycle &DefCycle) const {
diff --git a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
index 5467e88c41745..aa85b95a96d09 100644
--- a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
+++ b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
@@ -84,10 +84,6 @@ void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::initialize() {
}
}
-template <>
-void llvm::GenericUniformityAnalysisImpl<
- MachineSSAContext>::registerCallbacks() {}
-
template <>
void llvm::GenericUniformityAnalysisImpl<MachineSSAContext>::pushUsers(
Register Reg) {
diff --git a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp
index 7ad54af38f443..ed55062769525 100644
--- a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp
+++ b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp
@@ -94,10 +94,10 @@ TEST(UniformityAnalysis, NewValueIsConservativelyDivergent) {
<< "New instruction created after analysis must be reported divergent";
}
-TEST(UniformityAnalysis, DeletionCallbackMakesNewInstDivergent) {
- // Delete a uniform instruction. CallbackVH::deleted() removes it from
- // UniformValues during eraseFromParent(). A newly created instruction is
- // not in UniformValues and must be conservatively reported as divergent.
+TEST(UniformityAnalysis, EraseValueBeforeDeletion) {
+ // Passes must call eraseValue() before deleting a value that was present
+ // during analysis. After deletion, a newly created instruction is not in
+ // UniformValues and must be conservatively reported as divergent.
LLVMInitializeAMDGPUTargetInfo();
LLVMInitializeAMDGPUTarget();
LLVMInitializeAMDGPUTargetMC();
@@ -128,6 +128,7 @@ TEST(UniformityAnalysis, DeletionCallbackMakesNewInstDivergent) {
ASSERT_TRUE(isa<BinaryOperator>(AddInst));
EXPECT_FALSE(UI.isDivergent(AddInst)) << "%add should be uniform";
+ UI.eraseValue(AddInst);
AddInst->eraseFromParent();
IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
>From 6b9547f6a9e06d01c466c0b473e0a18c47ae24e1 Mon Sep 17 00:00:00 2001
From: padivedi <padivedi at amd.com>
Date: Mon, 13 Apr 2026 20:04:00 +0530
Subject: [PATCH 4/4] update the affcted files which use uniformity and
eraseFromParent
---
.../AMDGPU/AMDGPUAnnotateUniformValues.cpp | 7 +++-
.../Target/AMDGPU/AMDGPUAtomicOptimizer.cpp | 14 ++++---
.../Target/AMDGPU/AMDGPUCodeGenPrepare.cpp | 25 +++++++-----
.../AMDGPU/AMDGPULateCodeGenPrepare.cpp | 10 +++--
.../AMDGPU/AMDGPURewriteUndefForPHI.cpp | 8 +++-
.../AMDGPU/AMDGPUUniformIntrinsicCombine.cpp | 29 +++++++-------
.../AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp | 39 ++++++++++++-------
.../Target/AMDGPU/SIAnnotateControlFlow.cpp | 8 +++-
llvm/lib/Transforms/Scalar/StructurizeCFG.cpp | 21 +++++++---
9 files changed, 105 insertions(+), 56 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAnnotateUniformValues.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAnnotateUniformValues.cpp
index 77b042c8e7076..82be576131fa3 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAnnotateUniformValues.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAnnotateUniformValues.cpp
@@ -92,8 +92,11 @@ AMDGPUAnnotateUniformValuesPass::run(Function &F,
AMDGPUAnnotateUniformValues Impl(UI, MSSA, AA, F);
Impl.visit(F);
- if (!Impl.changed())
- return PreservedAnalyses::all();
+ if (!Impl.changed()) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
+ }
PreservedAnalyses PA = PreservedAnalyses::none();
// TODO: Should preserve nearly everything
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
index b4d51522e28af..9f1111459575c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp
@@ -68,7 +68,7 @@ class AMDGPUAtomicOptimizerImpl
private:
Function &F;
SmallVector<ReplacementInfo, 8> ToReplace;
- const UniformityInfo &UA;
+ UniformityInfo &UA;
const DataLayout &DL;
DomTreeUpdater &DTU;
const GCNSubtarget &ST;
@@ -92,7 +92,7 @@ class AMDGPUAtomicOptimizerImpl
public:
AMDGPUAtomicOptimizerImpl() = delete;
- AMDGPUAtomicOptimizerImpl(Function &F, const UniformityInfo &UA,
+ AMDGPUAtomicOptimizerImpl(Function &F, UniformityInfo &UA,
DomTreeUpdater &DTU, const GCNSubtarget &ST,
ScanOptions ScanImpl)
: F(F), UA(UA), DL(F.getDataLayout()), DTU(DTU), ST(ST),
@@ -116,7 +116,7 @@ bool AMDGPUAtomicOptimizer::runOnFunction(Function &F) {
return false;
}
- const UniformityInfo &UA =
+ UniformityInfo &UA =
getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
DominatorTreeWrapperPass *DTW =
@@ -133,7 +133,7 @@ bool AMDGPUAtomicOptimizer::runOnFunction(Function &F) {
PreservedAnalyses AMDGPUAtomicOptimizerPass::run(Function &F,
FunctionAnalysisManager &AM) {
- const auto &UA = AM.getResult<UniformityInfoAnalysis>(F);
+ UniformityInfo &UA = AM.getResult<UniformityInfoAnalysis>(F);
DomTreeUpdater DTU(&AM.getResult<DominatorTreeAnalysis>(F),
DomTreeUpdater::UpdateStrategy::Lazy);
@@ -142,7 +142,9 @@ PreservedAnalyses AMDGPUAtomicOptimizerPass::run(Function &F,
bool IsChanged = AMDGPUAtomicOptimizerImpl(F, UA, DTU, ST, ScanImpl).run();
if (!IsChanged) {
- return PreservedAnalyses::all();
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
}
PreservedAnalyses PA;
@@ -972,7 +974,7 @@ void AMDGPUAtomicOptimizerImpl::optimizeAtomic(Instruction &I,
}
}
- // And delete the original.
+ UA.eraseValue(&I);
I.eraseFromParent();
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
index d049df810c476..1962629d22687 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
@@ -101,7 +101,7 @@ class AMDGPUCodeGenPrepareImpl
const GCNSubtarget &ST;
const AMDGPUTargetMachine &TM;
const TargetLibraryInfo *TLI;
- const UniformityInfo &UA;
+ UniformityInfo &UA;
const DataLayout &DL;
SimplifyQuery SQ;
const bool HasFP32DenormalFlush;
@@ -114,7 +114,7 @@ class AMDGPUCodeGenPrepareImpl
AMDGPUCodeGenPrepareImpl(Function &F, const AMDGPUTargetMachine &TM,
const TargetLibraryInfo *TLI, AssumptionCache *AC,
- const DominatorTree *DT, const UniformityInfo &UA)
+ const DominatorTree *DT, UniformityInfo &UA)
: F(F), ST(TM.getSubtarget<GCNSubtarget>(F)), TM(TM), TLI(TLI), UA(UA),
DL(F.getDataLayout()), SQ(DL, TLI, DT, AC),
HasFP32DenormalFlush(SIModeRegisterDefaults(F, ST).FP32Denormals ==
@@ -301,8 +301,9 @@ bool AMDGPUCodeGenPrepareImpl::run() {
}
while (!DeadVals.empty()) {
- if (auto *I = dyn_cast_or_null<Instruction>(DeadVals.pop_back_val()))
- RecursivelyDeleteTriviallyDeadInstructions(I, TLI);
+ if (Instruction *I = dyn_cast_or_null<Instruction>(DeadVals.pop_back_val()))
+ RecursivelyDeleteTriviallyDeadInstructions(
+ I, TLI, nullptr, [&](Value *V) { UA.eraseValue(V); });
}
return MadeChange;
@@ -1371,7 +1372,7 @@ Value *AMDGPUCodeGenPrepareImpl::shrinkDivRem64(IRBuilder<> &Builder,
void AMDGPUCodeGenPrepareImpl::expandDivRem64(BinaryOperator &I) const {
Instruction::BinaryOps Opc = I.getOpcode();
- // Do the general expansion.
+ UA.eraseValue(&I);
if (Opc == Instruction::UDiv || Opc == Instruction::SDiv) {
expandDivisionUpTo64Bits(&I);
return;
@@ -2272,7 +2273,7 @@ bool AMDGPUCodeGenPrepare::runOnFunction(Function &F) {
&getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
- const UniformityInfo &UA =
+ UniformityInfo &UA =
getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
return AMDGPUCodeGenPrepareImpl(F, TM, TLI, AC, DT, UA).run();
}
@@ -2283,10 +2284,13 @@ PreservedAnalyses AMDGPUCodeGenPreparePass::run(Function &F,
const TargetLibraryInfo *TLI = &FAM.getResult<TargetLibraryAnalysis>(F);
AssumptionCache *AC = &FAM.getResult<AssumptionAnalysis>(F);
const DominatorTree *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
- const UniformityInfo &UA = FAM.getResult<UniformityInfoAnalysis>(F);
+ UniformityInfo &UA = FAM.getResult<UniformityInfoAnalysis>(F);
AMDGPUCodeGenPrepareImpl Impl(F, ATM, TLI, AC, DT, UA);
- if (!Impl.run())
- return PreservedAnalyses::all();
+ if (!Impl.run()) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
+ }
PreservedAnalyses PA = PreservedAnalyses::none();
if (!Impl.FlowChanged)
PA.preserveSet<CFGAnalyses>();
@@ -2312,6 +2316,7 @@ CallInst *AMDGPUCodeGenPrepareImpl::createWorkitemIdX(IRBuilder<> &B) const {
void AMDGPUCodeGenPrepareImpl::replaceWithWorkitemIdX(Instruction &I) const {
IRBuilder<> B(&I);
CallInst *Tid = createWorkitemIdX(B);
+ UA.eraseValue(&I);
BasicBlock::iterator BI(&I);
ReplaceInstWithValue(BI, Tid);
}
@@ -2323,6 +2328,7 @@ void AMDGPUCodeGenPrepareImpl::replaceWithMaskedWorkitemIdX(
CallInst *Tid = createWorkitemIdX(B);
Constant *Mask = ConstantInt::get(Tid->getType(), WaveSize - 1);
Value *AndInst = B.CreateAnd(Tid, Mask);
+ UA.eraseValue(&I);
BasicBlock::iterator BI(&I);
ReplaceInstWithValue(BI, AndInst);
}
@@ -2384,6 +2390,7 @@ bool AMDGPUCodeGenPrepareImpl::visitMbcntHi(IntrinsicInst &I) const {
// Replace mbcnt.hi(mask, val) with val only when work group size matches
// wave size (single wave per work group).
if (*MaybeX == Wave) {
+ UA.eraseValue(&I);
BasicBlock::iterator BI(&I);
ReplaceInstWithValue(BI, I.getArgOperand(1));
return true;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp
index 63e265612cbf7..f80493f0c576b 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp
@@ -225,7 +225,8 @@ bool AMDGPULateCodeGenPrepare::run() {
Changed |= LRO.optimizeLiveType(&I, DeadInsts);
}
- RecursivelyDeleteTriviallyDeadInstructionsPermissive(DeadInsts);
+ RecursivelyDeleteTriviallyDeadInstructionsPermissive(
+ DeadInsts, nullptr, nullptr, [&](Value *V) { UA.eraseValue(V); });
return Changed;
}
@@ -559,8 +560,11 @@ AMDGPULateCodeGenPreparePass::run(Function &F, FunctionAnalysisManager &FAM) {
bool Changed = AMDGPULateCodeGenPrepare(F, ST, &AC, UI).run();
- if (!Changed)
- return PreservedAnalyses::all();
+ if (!Changed) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
+ }
PreservedAnalyses PA = PreservedAnalyses::none();
PA.preserveSet<CFGAnalyses>();
return PA;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteUndefForPHI.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteUndefForPHI.cpp
index 1c135f09080e1..81111e95cf21c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURewriteUndefForPHI.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteUndefForPHI.cpp
@@ -161,8 +161,10 @@ bool rewritePHIs(Function &F, UniformityInfo &UA, DominatorTree *DT) {
}
}
- for (auto *PHI : ToBeDeleted)
+ for (PHINode *PHI : ToBeDeleted) {
+ UA.eraseValue(PHI);
PHI->eraseFromParent();
+ }
return Changed;
}
@@ -185,7 +187,9 @@ AMDGPURewriteUndefForPHIPass::run(Function &F, FunctionAnalysisManager &AM) {
return PA;
}
- return PreservedAnalyses::all();
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
}
FunctionPass *llvm::createAMDGPURewriteUndefForPHILegacyPass() {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUUniformIntrinsicCombine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUUniformIntrinsicCombine.cpp
index 864d877fe9ac0..536fbd1abf27b 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUUniformIntrinsicCombine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUUniformIntrinsicCombine.cpp
@@ -44,7 +44,7 @@ using namespace llvm::PatternMatch;
/// Wrapper for querying uniformity info that first checks locally tracked
/// instructions.
static bool
-isDivergentUseWithNew(const Use &U, const UniformityInfo &UI,
+isDivergentUseWithNew(const Use &U, UniformityInfo &UI,
const ValueMap<const Value *, bool> &Tracker) {
Value *V = U.get();
if (auto It = Tracker.find(V); It != Tracker.end())
@@ -53,8 +53,7 @@ isDivergentUseWithNew(const Use &U, const UniformityInfo &UI,
}
/// Optimizes uniform intrinsics calls if their operand can be proven uniform.
-static bool optimizeUniformIntrinsic(IntrinsicInst &II,
- const UniformityInfo &UI,
+static bool optimizeUniformIntrinsic(IntrinsicInst &II, UniformityInfo &UI,
ValueMap<const Value *, bool> &Tracker) {
llvm::Intrinsic::ID IID = II.getIntrinsicID();
/// We deliberately do not simplify readfirstlane with a uniform argument, so
@@ -68,6 +67,7 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
return false;
LLVM_DEBUG(dbgs() << "Replacing " << II << " with " << *Src << '\n');
II.replaceAllUsesWith(Src);
+ UI.eraseValue(&II);
II.eraseFromParent();
return true;
}
@@ -102,9 +102,10 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
}
}
}
- // Erase the intrinsic if it has no remaining uses.
- if (II.use_empty())
+ if (II.use_empty()) {
+ UI.eraseValue(&II);
II.eraseFromParent();
+ }
return Changed;
}
case Intrinsic::amdgcn_wave_shuffle: {
@@ -114,6 +115,7 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
// Like with readlane, if Value is uniform then just propagate it
if (!isDivergentUseWithNew(Val, UI, Tracker)) {
II.replaceAllUsesWith(Val);
+ UI.eraseValue(&II);
II.eraseFromParent();
return true;
}
@@ -136,7 +138,7 @@ static bool optimizeUniformIntrinsic(IntrinsicInst &II,
}
/// Iterates over intrinsic calls in the Function to optimize.
-static bool runUniformIntrinsicCombine(Function &F, const UniformityInfo &UI) {
+static bool runUniformIntrinsicCombine(Function &F, UniformityInfo &UI) {
bool IsChanged = false;
ValueMap<const Value *, bool> Tracker;
@@ -152,13 +154,14 @@ static bool runUniformIntrinsicCombine(Function &F, const UniformityInfo &UI) {
PreservedAnalyses
AMDGPUUniformIntrinsicCombinePass::run(Function &F,
FunctionAnalysisManager &AM) {
- const auto &UI = AM.getResult<UniformityInfoAnalysis>(F);
- if (!runUniformIntrinsicCombine(F, UI))
- return PreservedAnalyses::all();
+ UniformityInfo &UI = AM.getResult<UniformityInfoAnalysis>(F);
+ if (!runUniformIntrinsicCombine(F, UI)) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
+ }
- PreservedAnalyses PA;
- PA.preserve<UniformityInfoAnalysis>();
- return PA;
+ return PreservedAnalyses::none();
}
namespace {
@@ -184,7 +187,7 @@ char &llvm::AMDGPUUniformIntrinsicCombineLegacyPassID =
bool AMDGPUUniformIntrinsicCombineLegacy::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
- const UniformityInfo &UI =
+ UniformityInfo &UI =
getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
return runUniformIntrinsicCombine(F, UI);
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp b/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp
index b772cf0bd87b2..3d5815a77d104 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp
@@ -66,9 +66,9 @@ class AMDGPUUnifyDivergentExitNodesImpl {
// We can preserve non-critical-edgeness when we unify function exit nodes
BasicBlock *unifyReturnBlockSet(Function &F, DomTreeUpdater &DTU,
ArrayRef<BasicBlock *> ReturningBlocks,
- StringRef Name);
+ UniformityInfo &UA, StringRef Name);
bool run(Function &F, DominatorTree *DT, const PostDominatorTree &PDT,
- const UniformityInfo &UA);
+ UniformityInfo &UA);
};
class AMDGPUUnifyDivergentExitNodes : public FunctionPass {
@@ -135,7 +135,7 @@ static bool isUniformlyReached(const UniformityInfo &UA, BasicBlock &BB) {
BasicBlock *AMDGPUUnifyDivergentExitNodesImpl::unifyReturnBlockSet(
Function &F, DomTreeUpdater &DTU, ArrayRef<BasicBlock *> ReturningBlocks,
- StringRef Name) {
+ UniformityInfo &UA, StringRef Name) {
// Otherwise, we need to insert a new basic block into the function, add a PHI
// nodes (if the function returns values), and convert all of the return
// instructions into unconditional branches.
@@ -163,6 +163,7 @@ BasicBlock *AMDGPUUnifyDivergentExitNodesImpl::unifyReturnBlockSet(
PN->addIncoming(BB->getTerminator()->getOperand(0), BB);
// Remove and delete the return inst.
+ UA.eraseValue(BB->getTerminator());
BB->getTerminator()->eraseFromParent();
UncondBrInst::Create(NewRetBlock, BB);
Updates.emplace_back(DominatorTree::Insert, BB, NewRetBlock);
@@ -172,8 +173,14 @@ BasicBlock *AMDGPUUnifyDivergentExitNodesImpl::unifyReturnBlockSet(
DTU.applyUpdates(Updates);
Updates.clear();
+ // simplifyCFG may delete instructions from blocks beyond the ones being
+ // simplified, so pre-erase all values from the uniformity set. The analysis
+ // is stale after this pass anyway.
+ for (BasicBlock &BB : F)
+ for (Instruction &I : BB)
+ UA.eraseValue(&I);
+
for (BasicBlock *BB : ReturningBlocks) {
- // Cleanup possible branch to unconditional branch to the return.
simplifyCFG(BB, *TTI, RequireAndPreserveDomTree ? &DTU : nullptr,
SimplifyCFGOptions().bonusInstThreshold(2));
}
@@ -223,7 +230,7 @@ static void handleNBranch(Function &F, BasicBlock *BB, Instruction *BI,
bool AMDGPUUnifyDivergentExitNodesImpl::run(Function &F, DominatorTree *DT,
const PostDominatorTree &PDT,
- const UniformityInfo &UA) {
+ UniformityInfo &UA) {
if (PDT.root_size() == 0 ||
(PDT.root_size() == 1 && !isa<UncondBrInst, CondBrInst, CallBrInst>(
PDT.getRoot()->getTerminator())))
@@ -265,7 +272,8 @@ bool AMDGPUUnifyDivergentExitNodesImpl::run(Function &F, DominatorTree *DT,
DummyReturnBB = createDummyReturnBlock(F, ReturningBlocks);
BasicBlock *LoopHeaderBB = BI->getSuccessor();
- BI->eraseFromParent(); // Delete the unconditional branch.
+ UA.eraseValue(BI);
+ BI->eraseFromParent();
// Add a new conditional branch with a dummy edge to the return block.
CondBrInst::Create(ConstantInt::getTrue(F.getContext()), LoopHeaderBB,
DummyReturnBB, BB);
@@ -294,7 +302,7 @@ bool AMDGPUUnifyDivergentExitNodesImpl::run(Function &F, DominatorTree *DT,
Updates.reserve(Updates.size() + UnreachableBlocks.size());
for (BasicBlock *BB : UnreachableBlocks) {
- // Remove and delete the unreachable inst.
+ UA.eraseValue(BB->getTerminator());
BB->getTerminator()->eraseFromParent();
UncondBrInst::Create(UnreachableBlock, BB);
Updates.emplace_back(DominatorTree::Insert, BB, UnreachableBlock);
@@ -308,7 +316,7 @@ bool AMDGPUUnifyDivergentExitNodesImpl::run(Function &F, DominatorTree *DT,
Type *RetTy = F.getReturnType();
Value *RetVal = RetTy->isVoidTy() ? nullptr : PoisonValue::get(RetTy);
- // Remove and delete the unreachable inst.
+ UA.eraseValue(UnreachableBlock->getTerminator());
UnreachableBlock->getTerminator()->eraseFromParent();
Function *UnreachableIntrin = Intrinsic::getOrInsertDeclaration(
@@ -340,7 +348,7 @@ bool AMDGPUUnifyDivergentExitNodesImpl::run(Function &F, DominatorTree *DT,
if (ReturningBlocks.size() == 1)
return Changed; // Already has a single return block
- unifyReturnBlockSet(F, DTU, ReturningBlocks, "UnifiedReturnBlock");
+ unifyReturnBlockSet(F, DTU, ReturningBlocks, UA, "UnifiedReturnBlock");
return true;
}
@@ -350,7 +358,8 @@ bool AMDGPUUnifyDivergentExitNodes::runOnFunction(Function &F) {
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
const auto &PDT =
getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
- const auto &UA = getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
+ UniformityInfo &UA =
+ getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
const auto *TranformInfo =
&getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
return AMDGPUUnifyDivergentExitNodesImpl(TranformInfo).run(F, DT, PDT, UA);
@@ -364,9 +373,11 @@ AMDGPUUnifyDivergentExitNodesPass::run(Function &F,
DT = &AM.getResult<DominatorTreeAnalysis>(F);
const auto &PDT = AM.getResult<PostDominatorTreeAnalysis>(F);
- const auto &UA = AM.getResult<UniformityInfoAnalysis>(F);
+ UniformityInfo &UA = AM.getResult<UniformityInfoAnalysis>(F);
const auto *TransformInfo = &AM.getResult<TargetIRAnalysis>(F);
- return AMDGPUUnifyDivergentExitNodesImpl(TransformInfo).run(F, DT, PDT, UA)
- ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
+ if (AMDGPUUnifyDivergentExitNodesImpl(TransformInfo).run(F, DT, PDT, UA))
+ return PreservedAnalyses::none();
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
}
diff --git a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
index 54ec4a51a4ab3..8233f9095fe07 100644
--- a/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
+++ b/llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cpp
@@ -176,6 +176,7 @@ bool SIAnnotateControlFlow::hasKill(const BasicBlock *BB) {
// Erase "Phi" if it is not used any more. Return true if any change was made.
bool SIAnnotateControlFlow::eraseIfUnused(PHINode *Phi) {
+ UA->eraseValue(Phi);
bool Changed = RecursivelyDeleteDeadPHINode(Phi);
if (Changed)
LLVM_DEBUG(dbgs() << "Erased unused condition phi\n");
@@ -398,8 +399,11 @@ PreservedAnalyses SIAnnotateControlFlowPass::run(Function &F,
SIAnnotateControlFlow Impl(F, ST, DT, LI, UI);
bool Changed = Impl.run();
- if (!Changed)
- return PreservedAnalyses::all();
+ if (!Changed) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
+ }
// TODO: Is LoopInfo preserved?
PreservedAnalyses PA = PreservedAnalyses::none();
diff --git a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
index 04ece92b74375..9957cce3a1deb 100644
--- a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
@@ -724,8 +724,11 @@ void StructurizeCFG::simplifyConditions() {
}
}
}
- for (auto *I : InstToErase)
+ for (auto *I : InstToErase) {
+ if (UA)
+ UA->eraseValue(I);
I->eraseFromParent();
+ }
}
/// Remove all PHI values coming from "From" into "To" and remember
@@ -1011,9 +1014,11 @@ void StructurizeCFG::simplifyAffectedPhis() {
// to achieve better register pressure.
Q.CanUseUndef = false;
for (WeakVH VH : AffectedPhis) {
- if (auto Phi = dyn_cast_or_null<PHINode>(VH)) {
- if (auto NewValue = simplifyInstruction(Phi, Q)) {
+ if (PHINode *Phi = dyn_cast_or_null<PHINode>(VH)) {
+ if (Value *NewValue = simplifyInstruction(Phi, Q)) {
Phi->replaceAllUsesWith(NewValue);
+ if (UA)
+ UA->eraseValue(Phi);
Phi->eraseFromParent();
Changed = true;
}
@@ -1032,6 +1037,8 @@ DebugLoc StructurizeCFG::killTerminator(BasicBlock *BB) {
delPhiValues(BB, Succ);
DebugLoc DL = Term->getDebugLoc();
+ if (UA)
+ UA->eraseValue(Term);
Term->eraseFromParent();
return DL;
}
@@ -1490,8 +1497,12 @@ PreservedAnalyses StructurizeCFGPass::run(Function &F,
Changed |= SCFG.run(R, DT, TTI);
}
- if (!Changed)
- return PreservedAnalyses::all();
+ if (!Changed) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ if (SkipUniformRegions)
+ PA.abandon<UniformityInfoAnalysis>();
+ return PA;
+ }
PreservedAnalyses PA;
PA.preserve<DominatorTreeAnalysis>();
return PA;
More information about the llvm-commits
mailing list