[llvm] [JumpThreading] Invalidate LVI after `combineMetadataForCSE`. (PR #65219)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 3 20:50:28 PDT 2023
https://github.com/DianQK updated https://github.com/llvm/llvm-project/pull/65219:
>From 5855a4be9cbc3c4584d8a1632886c347044dfbef Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Sun, 3 Sep 2023 12:18:57 +0800
Subject: [PATCH 1/3] [JumpThreading][NFC] Pre-commit for invalid LVI.
---
.../JumpThreading/invalidate-lvi.ll | 53 +++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 llvm/test/Transforms/JumpThreading/invalidate-lvi.ll
diff --git a/llvm/test/Transforms/JumpThreading/invalidate-lvi.ll b/llvm/test/Transforms/JumpThreading/invalidate-lvi.ll
new file mode 100644
index 00000000000000..9c5cbfac62d9fb
--- /dev/null
+++ b/llvm/test/Transforms/JumpThreading/invalidate-lvi.ll
@@ -0,0 +1,53 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -S -passes=jump-threading < %s | FileCheck %s
+
+declare void @set_value(ptr)
+
+declare void @bar()
+
+define void @foo(i1 %0) {
+; CHECK-LABEL: define void @foo(
+; CHECK-SAME: i1 [[TMP0:%.*]]) {
+; CHECK-NEXT: start:
+; CHECK-NEXT: [[V:%.*]] = alloca i64, align 8
+; CHECK-NEXT: call void @set_value(ptr [[V]])
+; CHECK-NEXT: [[L1:%.*]] = load i64, ptr [[V]], align 8
+; CHECK-NEXT: br i1 [[TMP0]], label [[BB0:%.*]], label [[BB4:%.*]]
+; CHECK: bb0:
+; CHECK-NEXT: [[C1:%.*]] = icmp eq i64 [[L1]], 0
+; CHECK-NEXT: br i1 [[C1]], label [[BB1:%.*]], label [[BB4]]
+; CHECK: bb1:
+; CHECK-NEXT: store i64 0, ptr [[V]], align 8
+; CHECK-NEXT: br label [[BB4]]
+; CHECK: bb4:
+; CHECK-NEXT: [[L2:%.*]] = phi i64 [ 0, [[BB1]] ], [ [[L1]], [[BB0]] ], [ [[L1]], [[START:%.*]] ]
+; CHECK-NEXT: ret void
+;
+start:
+ %v = alloca i64, align 8
+ call void @set_value(ptr %v)
+ %l1 = load i64, ptr %v, align 8, !range !0
+ br i1 %0, label %bb0, label %bb2
+
+bb0: ; preds = %start
+ %c1 = icmp eq i64 %l1, 0
+ br i1 %c1, label %bb1, label %bb2
+
+bb1: ; preds = %bb0
+ store i64 0, ptr %v, align 8
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb0, %start
+ %l2 = load i64, ptr %v, align 8
+ %1 = icmp eq i64 %l2, 2
+ br i1 %1, label %bb3, label %bb4
+
+bb3: ; preds = %bb2
+ call void @bar()
+ ret void
+
+bb4: ; preds = %bb2
+ ret void
+}
+
+!0 = !{i64 0, i64 2}
>From 7ded71b1e43fff0be3acb74038bfea87f38d5cfa Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Sun, 3 Sep 2023 12:23:33 +0800
Subject: [PATCH 2/3] [JumpThreading] Invalidate LVI after
`combineMetadataForCSE`.
---
llvm/include/llvm/Analysis/LazyValueInfo.h | 3 +++
llvm/lib/Analysis/LazyValueInfo.cpp | 9 +++++++++
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 2 ++
.../Transforms/JumpThreading/invalidate-lvi.ll | 16 +++++++++++-----
4 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/Analysis/LazyValueInfo.h b/llvm/include/llvm/Analysis/LazyValueInfo.h
index b109b7f7e65ae7..7b2bfdac75a8fa 100644
--- a/llvm/include/llvm/Analysis/LazyValueInfo.h
+++ b/llvm/include/llvm/Analysis/LazyValueInfo.h
@@ -115,6 +115,9 @@ class LazyValueInfo {
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
+ /// Remove information related to this value from the cache.
+ void forgetValue(Value *V);
+
/// Inform the analysis cache that we have erased a block.
void eraseBlock(BasicBlock *BB);
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 33651783cb1777..2ba6036056d991 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -465,6 +465,10 @@ class LazyValueInfoImpl {
F.print(OS, &Writer);
}
+ /// This is part of the update interface to remove information related to this
+ /// value from the cache.
+ void forgetValue(Value *V) { TheCache.eraseValue(V); }
+
/// This is part of the update interface to inform the cache
/// that a block has been deleted.
void eraseBlock(BasicBlock *BB) {
@@ -1969,6 +1973,11 @@ void LazyValueInfo::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
}
}
+void LazyValueInfo::forgetValue(Value *V) {
+ if (PImpl)
+ getImpl(PImpl, AC, nullptr).forgetValue(V);
+}
+
void LazyValueInfo::eraseBlock(BasicBlock *BB) {
if (PImpl) {
getImpl(PImpl, AC, BB->getModule()).eraseBlock(BB);
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 180e6b4c823880..83d56b56fc801b 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1269,6 +1269,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
if (IsLoadCSE) {
LoadInst *NLoadI = cast<LoadInst>(AvailableVal);
combineMetadataForCSE(NLoadI, LoadI, false);
+ LVI->forgetValue(NLoadI);
};
// If the returned value is the load itself, replace with poison. This can
@@ -1461,6 +1462,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
for (LoadInst *PredLoadI : CSELoads) {
combineMetadataForCSE(PredLoadI, LoadI, true);
+ LVI->forgetValue(PredLoadI);
}
LoadI->replaceAllUsesWith(PN);
diff --git a/llvm/test/Transforms/JumpThreading/invalidate-lvi.ll b/llvm/test/Transforms/JumpThreading/invalidate-lvi.ll
index 9c5cbfac62d9fb..27191d6f54c2d8 100644
--- a/llvm/test/Transforms/JumpThreading/invalidate-lvi.ll
+++ b/llvm/test/Transforms/JumpThreading/invalidate-lvi.ll
@@ -12,15 +12,21 @@ define void @foo(i1 %0) {
; CHECK-NEXT: [[V:%.*]] = alloca i64, align 8
; CHECK-NEXT: call void @set_value(ptr [[V]])
; CHECK-NEXT: [[L1:%.*]] = load i64, ptr [[V]], align 8
-; CHECK-NEXT: br i1 [[TMP0]], label [[BB0:%.*]], label [[BB4:%.*]]
+; CHECK-NEXT: br i1 [[TMP0]], label [[BB0:%.*]], label [[BB2:%.*]]
; CHECK: bb0:
; CHECK-NEXT: [[C1:%.*]] = icmp eq i64 [[L1]], 0
-; CHECK-NEXT: br i1 [[C1]], label [[BB1:%.*]], label [[BB4]]
-; CHECK: bb1:
+; CHECK-NEXT: br i1 [[C1]], label [[BB2_THREAD:%.*]], label [[BB2]]
+; CHECK: bb2.thread:
; CHECK-NEXT: store i64 0, ptr [[V]], align 8
-; CHECK-NEXT: br label [[BB4]]
+; CHECK-NEXT: br label [[BB4:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: [[L2:%.*]] = phi i64 [ [[L1]], [[BB0]] ], [ [[L1]], [[START:%.*]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[L2]], 2
+; CHECK-NEXT: br i1 [[TMP1]], label [[BB3:%.*]], label [[BB4]]
+; CHECK: bb3:
+; CHECK-NEXT: call void @bar()
+; CHECK-NEXT: ret void
; CHECK: bb4:
-; CHECK-NEXT: [[L2:%.*]] = phi i64 [ 0, [[BB1]] ], [ [[L1]], [[BB0]] ], [ [[L1]], [[START:%.*]] ]
; CHECK-NEXT: ret void
;
start:
>From 7af408e89bd0915ff830fea8824e05d8f7e71d4d Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Sun, 3 Sep 2023 20:58:08 +0800
Subject: [PATCH 3/3] [JumpThreading][NFC] Improved access to
LazyValueInfoImpl.
---
llvm/include/llvm/Analysis/LazyValueInfo.h | 221 +++++++++++----------
llvm/lib/Analysis/LazyValueInfo.cpp | 96 +++++----
2 files changed, 159 insertions(+), 158 deletions(-)
diff --git a/llvm/include/llvm/Analysis/LazyValueInfo.h b/llvm/include/llvm/Analysis/LazyValueInfo.h
index 7b2bfdac75a8fa..f013a4a75d3d6a 100644
--- a/llvm/include/llvm/Analysis/LazyValueInfo.h
+++ b/llvm/include/llvm/Analysis/LazyValueInfo.h
@@ -26,117 +26,120 @@ namespace llvm {
class Instruction;
class TargetLibraryInfo;
class Value;
-
-/// This pass computes, caches, and vends lazy value constraint information.
-class LazyValueInfo {
- friend class LazyValueInfoWrapperPass;
- AssumptionCache *AC = nullptr;
- const DataLayout *DL = nullptr;
- class TargetLibraryInfo *TLI = nullptr;
- void *PImpl = nullptr;
- LazyValueInfo(const LazyValueInfo&) = delete;
- void operator=(const LazyValueInfo&) = delete;
-public:
- ~LazyValueInfo();
- LazyValueInfo() = default;
- LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_,
- TargetLibraryInfo *TLI_)
- : AC(AC_), DL(DL_), TLI(TLI_) {}
- LazyValueInfo(LazyValueInfo &&Arg)
- : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), PImpl(Arg.PImpl) {
- Arg.PImpl = nullptr;
- }
- LazyValueInfo &operator=(LazyValueInfo &&Arg) {
- releaseMemory();
- AC = Arg.AC;
- DL = Arg.DL;
- TLI = Arg.TLI;
- PImpl = Arg.PImpl;
- Arg.PImpl = nullptr;
- return *this;
- }
-
- /// This is used to return true/false/dunno results.
- enum Tristate {
- Unknown = -1, False = 0, True = 1
+ class LazyValueInfoImpl;
+ /// This pass computes, caches, and vends lazy value constraint information.
+ class LazyValueInfo {
+ friend class LazyValueInfoWrapperPass;
+ AssumptionCache *AC = nullptr;
+ const DataLayout *DL = nullptr;
+ class TargetLibraryInfo *TLI = nullptr;
+ LazyValueInfoImpl *PImpl = nullptr;
+ LazyValueInfo(const LazyValueInfo &) = delete;
+ void operator=(const LazyValueInfo &) = delete;
+
+ LazyValueInfoImpl *getImpl();
+ LazyValueInfoImpl &getOrCreateImpl(const Module *M);
+
+ public:
+ ~LazyValueInfo();
+ LazyValueInfo() = default;
+ LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_,
+ TargetLibraryInfo *TLI_)
+ : AC(AC_), DL(DL_), TLI(TLI_) {}
+ LazyValueInfo(LazyValueInfo &&Arg)
+ : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), PImpl(Arg.PImpl) {
+ Arg.PImpl = nullptr;
+ }
+ LazyValueInfo &operator=(LazyValueInfo &&Arg) {
+ releaseMemory();
+ AC = Arg.AC;
+ DL = Arg.DL;
+ TLI = Arg.TLI;
+ PImpl = Arg.PImpl;
+ Arg.PImpl = nullptr;
+ return *this;
+ }
+
+ /// This is used to return true/false/dunno results.
+ enum Tristate { Unknown = -1, False = 0, True = 1 };
+
+ // Public query interface.
+
+ /// Determine whether the specified value comparison with a constant is
+ /// known to be true or false on the specified CFG edge. Pred is a CmpInst
+ /// predicate.
+ Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
+ BasicBlock *FromBB, BasicBlock *ToBB,
+ Instruction *CxtI = nullptr);
+
+ /// Determine whether the specified value comparison with a constant is
+ /// known to be true or false at the specified instruction. \p Pred is a
+ /// CmpInst predicate. If \p UseBlockValue is true, the block value is also
+ /// taken into account.
+ Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C,
+ Instruction *CxtI, bool UseBlockValue);
+
+ /// Determine whether the specified value comparison is known to be true
+ /// or false at the specified instruction. While this takes two Value's,
+ /// it still requires that one of them is a constant.
+ /// \p Pred is a CmpInst predicate.
+ /// If \p UseBlockValue is true, the block value is also taken into account.
+ Tristate getPredicateAt(unsigned Pred, Value *LHS, Value *RHS,
+ Instruction *CxtI, bool UseBlockValue);
+
+ /// Determine whether the specified value is known to be a constant at the
+ /// specified instruction. Return null if not.
+ Constant *getConstant(Value *V, Instruction *CxtI);
+
+ /// Return the ConstantRange constraint that is known to hold for the
+ /// specified value at the specified instruction. This may only be called
+ /// on integer-typed Values.
+ ConstantRange getConstantRange(Value *V, Instruction *CxtI,
+ bool UndefAllowed = true);
+
+ /// Return the ConstantRange constraint that is known to hold for the value
+ /// at a specific use-site.
+ ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed = true);
+
+ /// Determine whether the specified value is known to be a
+ /// constant on the specified edge. Return null if not.
+ Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
+ Instruction *CxtI = nullptr);
+
+ /// Return the ConstantRage constraint that is known to hold for the
+ /// specified value on the specified edge. This may be only be called
+ /// on integer-typed Values.
+ ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
+ BasicBlock *ToBB,
+ Instruction *CxtI = nullptr);
+
+ /// Inform the analysis cache that we have threaded an edge from
+ /// PredBB to OldSucc to be from PredBB to NewSucc instead.
+ void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
+ BasicBlock *NewSucc);
+
+ /// Remove information related to this value from the cache.
+ void forgetValue(Value *V);
+
+ /// Inform the analysis cache that we have erased a block.
+ void eraseBlock(BasicBlock *BB);
+
+ /// Complete flush all previously computed values
+ void clear();
+
+ /// Print the \LazyValueInfo Analysis.
+ /// We pass in the DTree that is required for identifying which basic blocks
+ /// we can solve/print for, in the LVIPrinter.
+ void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
+
+ // For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
+ void releaseMemory();
+
+ /// Handle invalidation events in the new pass manager.
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
};
- // Public query interface.
-
- /// Determine whether the specified value comparison with a constant is known
- /// to be true or false on the specified CFG edge.
- /// Pred is a CmpInst predicate.
- Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
- BasicBlock *FromBB, BasicBlock *ToBB,
- Instruction *CxtI = nullptr);
-
- /// Determine whether the specified value comparison with a constant is known
- /// to be true or false at the specified instruction.
- /// \p Pred is a CmpInst predicate. If \p UseBlockValue is true, the block
- /// value is also taken into account.
- Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C,
- Instruction *CxtI, bool UseBlockValue);
-
- /// Determine whether the specified value comparison is known to be true
- /// or false at the specified instruction. While this takes two Value's,
- /// it still requires that one of them is a constant.
- /// \p Pred is a CmpInst predicate.
- /// If \p UseBlockValue is true, the block value is also taken into account.
- Tristate getPredicateAt(unsigned Pred, Value *LHS, Value *RHS,
- Instruction *CxtI, bool UseBlockValue);
-
- /// Determine whether the specified value is known to be a constant at the
- /// specified instruction. Return null if not.
- Constant *getConstant(Value *V, Instruction *CxtI);
-
- /// Return the ConstantRange constraint that is known to hold for the
- /// specified value at the specified instruction. This may only be called
- /// on integer-typed Values.
- ConstantRange getConstantRange(Value *V, Instruction *CxtI,
- bool UndefAllowed = true);
-
- /// Return the ConstantRange constraint that is known to hold for the value
- /// at a specific use-site.
- ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed = true);
-
- /// Determine whether the specified value is known to be a
- /// constant on the specified edge. Return null if not.
- Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
- Instruction *CxtI = nullptr);
-
- /// Return the ConstantRage constraint that is known to hold for the
- /// specified value on the specified edge. This may be only be called
- /// on integer-typed Values.
- ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
- BasicBlock *ToBB,
- Instruction *CxtI = nullptr);
-
- /// Inform the analysis cache that we have threaded an edge from
- /// PredBB to OldSucc to be from PredBB to NewSucc instead.
- void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
-
- /// Remove information related to this value from the cache.
- void forgetValue(Value *V);
-
- /// Inform the analysis cache that we have erased a block.
- void eraseBlock(BasicBlock *BB);
-
- /// Complete flush all previously computed values
- void clear(const Module *M);
-
- /// Print the \LazyValueInfo Analysis.
- /// We pass in the DTree that is required for identifying which basic blocks
- /// we can solve/print for, in the LVIPrinter.
- void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
-
- // For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
- void releaseMemory();
-
- /// Handle invalidation events in the new pass manager.
- bool invalidate(Function &F, const PreservedAnalyses &PA,
- FunctionAnalysisManager::Invalidator &Inv);
-};
-
/// Analysis to compute lazy value information.
class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> {
public:
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 2ba6036056d991..80136a090a8010 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -336,11 +336,10 @@ void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
}
}
-
+namespace llvm {
namespace {
/// An assembly annotator class to print LazyValueCache information in
/// comments.
-class LazyValueInfoImpl;
class LazyValueInfoAnnotatedWriter : public AssemblyAnnotationWriter {
LazyValueInfoImpl *LVIImpl;
// While analyzing which blocks we can solve values for, we need the dominator
@@ -357,8 +356,7 @@ class LazyValueInfoAnnotatedWriter : public AssemblyAnnotationWriter {
void emitInstructionAnnot(const Instruction *I,
formatted_raw_ostream &OS) override;
};
-}
-namespace {
+} // namespace
// The actual implementation of the lazy analysis and update. Note that the
// inheritance from LazyValueInfoCache is intended to be temporary while
// splitting the code and then transitioning to a has-a relationship.
@@ -483,8 +481,7 @@ class LazyValueInfoImpl {
Function *GuardDecl)
: AC(AC), DL(DL), GuardDecl(GuardDecl) {}
};
-} // end anonymous namespace
-
+} // namespace llvm
void LazyValueInfoImpl::solve() {
SmallVector<std::pair<BasicBlock *, Value *>, 8> StartingStack(
@@ -1546,25 +1543,12 @@ void LazyValueInfoImpl::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
// LazyValueInfo Impl
//===----------------------------------------------------------------------===//
-/// This lazily constructs the LazyValueInfoImpl.
-static LazyValueInfoImpl &getImpl(void *&PImpl, AssumptionCache *AC,
- const Module *M) {
- if (!PImpl) {
- assert(M && "getCache() called with a null Module");
- const DataLayout &DL = M->getDataLayout();
- Function *GuardDecl = M->getFunction(
- Intrinsic::getName(Intrinsic::experimental_guard));
- PImpl = new LazyValueInfoImpl(AC, DL, GuardDecl);
- }
- return *static_cast<LazyValueInfoImpl*>(PImpl);
-}
-
bool LazyValueInfoWrapperPass::runOnFunction(Function &F) {
Info.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
Info.TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- if (Info.PImpl)
- getImpl(Info.PImpl, Info.AC, F.getParent()).clear();
+ if (auto *Impl = Info.getImpl())
+ Impl->clear();
// Fully lazy.
return false;
@@ -1578,12 +1562,30 @@ void LazyValueInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
LazyValueInfo &LazyValueInfoWrapperPass::getLVI() { return Info; }
+/// This lazily constructs the LazyValueInfoImpl.
+LazyValueInfoImpl &LazyValueInfo::getOrCreateImpl(const Module *M) {
+ if (!PImpl) {
+ assert(M && "getCache() called with a null Module");
+ const DataLayout &DL = M->getDataLayout();
+ Function *GuardDecl =
+ M->getFunction(Intrinsic::getName(Intrinsic::experimental_guard));
+ PImpl = new LazyValueInfoImpl(AC, DL, GuardDecl);
+ }
+ return *static_cast<LazyValueInfoImpl *>(PImpl);
+}
+
+LazyValueInfoImpl *LazyValueInfo::getImpl() {
+ if (!PImpl)
+ return nullptr;
+ return static_cast<LazyValueInfoImpl *>(PImpl);
+}
+
LazyValueInfo::~LazyValueInfo() { releaseMemory(); }
void LazyValueInfo::releaseMemory() {
// If the cache was allocated, free it.
- if (PImpl) {
- delete &getImpl(PImpl, AC, nullptr);
+ if (auto *Impl = getImpl()) {
+ delete &*Impl;
PImpl = nullptr;
}
}
@@ -1630,7 +1632,7 @@ Constant *LazyValueInfo::getConstant(Value *V, Instruction *CxtI) {
BasicBlock *BB = CxtI->getParent();
ValueLatticeElement Result =
- getImpl(PImpl, AC, BB->getModule()).getValueInBlock(V, BB, CxtI);
+ getOrCreateImpl(BB->getModule()).getValueInBlock(V, BB, CxtI);
if (Result.isConstant())
return Result.getConstant();
@@ -1648,7 +1650,7 @@ ConstantRange LazyValueInfo::getConstantRange(Value *V, Instruction *CxtI,
unsigned Width = V->getType()->getIntegerBitWidth();
BasicBlock *BB = CxtI->getParent();
ValueLatticeElement Result =
- getImpl(PImpl, AC, BB->getModule()).getValueInBlock(V, BB, CxtI);
+ getOrCreateImpl(BB->getModule()).getValueInBlock(V, BB, CxtI);
if (Result.isUnknown())
return ConstantRange::getEmpty(Width);
if (Result.isConstantRange(UndefAllowed))
@@ -1714,7 +1716,7 @@ Constant *LazyValueInfo::getConstantOnEdge(Value *V, BasicBlock *FromBB,
Instruction *CxtI) {
Module *M = FromBB->getModule();
ValueLatticeElement Result =
- getImpl(PImpl, AC, M).getValueOnEdge(V, FromBB, ToBB, CxtI);
+ getOrCreateImpl(M).getValueOnEdge(V, FromBB, ToBB, CxtI);
if (Result.isConstant())
return Result.getConstant();
@@ -1733,7 +1735,7 @@ ConstantRange LazyValueInfo::getConstantRangeOnEdge(Value *V,
unsigned Width = V->getType()->getIntegerBitWidth();
Module *M = FromBB->getModule();
ValueLatticeElement Result =
- getImpl(PImpl, AC, M).getValueOnEdge(V, FromBB, ToBB, CxtI);
+ getOrCreateImpl(M).getValueOnEdge(V, FromBB, ToBB, CxtI);
if (Result.isUnknown())
return ConstantRange::getEmpty(Width);
@@ -1819,7 +1821,7 @@ LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
Instruction *CxtI) {
Module *M = FromBB->getModule();
ValueLatticeElement Result =
- getImpl(PImpl, AC, M).getValueOnEdge(V, FromBB, ToBB, CxtI);
+ getOrCreateImpl(M).getValueOnEdge(V, FromBB, ToBB, CxtI);
return getPredicateResult(Pred, C, Result, M->getDataLayout(), TLI);
}
@@ -1841,9 +1843,10 @@ LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C,
return LazyValueInfo::True;
}
- ValueLatticeElement Result = UseBlockValue
- ? getImpl(PImpl, AC, M).getValueInBlock(V, CxtI->getParent(), CxtI)
- : getImpl(PImpl, AC, M).getValueAt(V, CxtI);
+ auto &Impl = getOrCreateImpl(M);
+ ValueLatticeElement Result =
+ UseBlockValue ? Impl.getValueInBlock(V, CxtI->getParent(), CxtI)
+ : Impl.getValueAt(V, CxtI);
Tristate Ret = getPredicateResult(Pred, C, Result, DL, TLI);
if (Ret != Unknown)
return Ret;
@@ -1947,12 +1950,12 @@ LazyValueInfo::Tristate LazyValueInfo::getPredicateAt(unsigned P, Value *LHS,
if (UseBlockValue) {
Module *M = CxtI->getModule();
ValueLatticeElement L =
- getImpl(PImpl, AC, M).getValueInBlock(LHS, CxtI->getParent(), CxtI);
+ getOrCreateImpl(M).getValueInBlock(LHS, CxtI->getParent(), CxtI);
if (L.isOverdefined())
return LazyValueInfo::Unknown;
ValueLatticeElement R =
- getImpl(PImpl, AC, M).getValueInBlock(RHS, CxtI->getParent(), CxtI);
+ getOrCreateImpl(M).getValueInBlock(RHS, CxtI->getParent(), CxtI);
Type *Ty = CmpInst::makeCmpResultType(LHS->getType());
if (Constant *Res = L.getCompare((CmpInst::Predicate)P, Ty, R,
M->getDataLayout())) {
@@ -1967,33 +1970,28 @@ LazyValueInfo::Tristate LazyValueInfo::getPredicateAt(unsigned P, Value *LHS,
void LazyValueInfo::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
BasicBlock *NewSucc) {
- if (PImpl) {
- getImpl(PImpl, AC, PredBB->getModule())
- .threadEdge(PredBB, OldSucc, NewSucc);
- }
+ if (auto *Impl = getImpl())
+ Impl->threadEdge(PredBB, OldSucc, NewSucc);
}
void LazyValueInfo::forgetValue(Value *V) {
- if (PImpl)
- getImpl(PImpl, AC, nullptr).forgetValue(V);
+ if (auto *Impl = getImpl())
+ getImpl()->forgetValue(V);
}
void LazyValueInfo::eraseBlock(BasicBlock *BB) {
- if (PImpl) {
- getImpl(PImpl, AC, BB->getModule()).eraseBlock(BB);
- }
+ if (auto *Impl = getImpl())
+ getImpl()->eraseBlock(BB);
}
-void LazyValueInfo::clear(const Module *M) {
- if (PImpl) {
- getImpl(PImpl, AC, M).clear();
- }
+void LazyValueInfo::clear() {
+ if (auto *Impl = getImpl())
+ getImpl()->clear();
}
void LazyValueInfo::printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS) {
- if (PImpl) {
- getImpl(PImpl, AC, F.getParent()).printLVI(F, DTree, OS);
- }
+ if (auto *Impl = getImpl())
+ getImpl()->printLVI(F, DTree, OS);
}
// Print the LVI for the function arguments at the start of each basic block.
More information about the llvm-commits
mailing list