From 5855a4be9cbc3c4584d8a1632886c347044dfbef Mon Sep 17 00:00:00 2001 From: DianQK 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 0000000000000..9c5cbfac62d9f --- /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 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 b109b7f7e65ae..7b2bfdac75a8f 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 33651783cb177..2ba6036056d99 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 180e6b4c82388..83d56b56fc801 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(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 9c5cbfac62d9f..27191d6f54c2d 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 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 7b2bfdac75a8f..f013a4a75d3d6 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 { public: diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 2ba6036056d99..80136a090a801 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, 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(PImpl); -} - bool LazyValueInfoWrapperPass::runOnFunction(Function &F) { Info.AC = &getAnalysis().getAssumptionCache(F); Info.TLI = &getAnalysis().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(PImpl); +} + +LazyValueInfoImpl *LazyValueInfo::getImpl() { + if (!PImpl) + return nullptr; + return static_cast(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.