#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
#define LLVM_ANALYSIS_LAZYVALUEINFO_H
+#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
class Value;
/// This pass computes, caches, and vends lazy value constraint information.
-class LazyValueInfo : public FunctionPass {
- AssumptionCache *AC;
- class TargetLibraryInfo *TLI;
- DominatorTree *DT;
- void *PImpl;
+class LazyValueInfo {
+ friend class LazyValueInfoWrapperPass;
+ AssumptionCache *AC = nullptr;
+ class TargetLibraryInfo *TLI = nullptr;
+ DominatorTree *DT = nullptr;
+ void *PImpl = nullptr;
LazyValueInfo(const LazyValueInfo&) = delete;
void operator=(const LazyValueInfo&) = delete;
public:
- static char ID;
- LazyValueInfo() : FunctionPass(ID), PImpl(nullptr) {
- initializeLazyValueInfoPass(*PassRegistry::getPassRegistry());
+ ~LazyValueInfo();
+ LazyValueInfo() {}
+ LazyValueInfo(AssumptionCache *AC_, TargetLibraryInfo *TLI_,
+ DominatorTree *DT_)
+ : AC(AC_), TLI(TLI_), DT(DT_) {}
+ LazyValueInfo(LazyValueInfo &&Arg)
+ : AC(Arg.AC), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
+ Arg.PImpl = nullptr;
+ }
+ LazyValueInfo &operator=(LazyValueInfo &&Arg) {
+ releaseMemory();
+ AC = Arg.AC;
+ TLI = Arg.TLI;
+ DT = Arg.DT;
+ PImpl = Arg.PImpl;
+ Arg.PImpl = nullptr;
+ return *this;
}
- ~LazyValueInfo() override { assert(!PImpl && "releaseMemory not called"); }
/// This is used to return true/false/dunno results.
enum Tristate {
/// Inform the analysis cache that we have erased a block.
void eraseBlock(BasicBlock *BB);
- // Implementation boilerplate.
+ // For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
+ void releaseMemory();
+};
+
+/// \brief Analysis to compute lazy value information.
+class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> {
+public:
+ typedef LazyValueInfo Result;
+ Result run(Function &F, FunctionAnalysisManager &FAM);
+
+private:
+ static char PassID;
+ friend struct AnalysisInfoMixin<LazyValueAnalysis>;
+};
+
+/// Wrapper around LazyValueInfo.
+class LazyValueInfoWrapperPass : public FunctionPass {
+ LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete;
+ void operator=(const LazyValueInfoWrapperPass&) = delete;
+public:
+ static char ID;
+ LazyValueInfoWrapperPass() : FunctionPass(ID) {
+ initializeLazyValueInfoWrapperPassPass(*PassRegistry::getPassRegistry());
+ }
+ ~LazyValueInfoWrapperPass() override {
+ assert(!Info.PImpl && "releaseMemory not called");
+ }
+
+ LazyValueInfo &getLVI();
void getAnalysisUsage(AnalysisUsage &AU) const override;
void releaseMemory() override;
bool runOnFunction(Function &F) override;
+private:
+ LazyValueInfo Info;
};
} // end namespace llvm
void initializeJumpThreadingPass(PassRegistry&);
void initializeLCSSAWrapperPassPass(PassRegistry &);
void initializeLICMPass(PassRegistry&);
-void initializeLazyValueInfoPass(PassRegistry&);
+void initializeLazyValueInfoWrapperPassPass(PassRegistry&);
void initializeLintPass(PassRegistry&);
void initializeLiveDebugValuesPass(PassRegistry&);
void initializeLiveDebugVariablesPass(PassRegistry&);
initializeIVUsersPass(Registry);
initializeInstCountPass(Registry);
initializeIntervalPartitionPass(Registry);
- initializeLazyValueInfoPass(Registry);
+ initializeLazyValueInfoWrapperPassPass(Registry);
initializeLintPass(Registry);
initializeLoopInfoWrapperPassPass(Registry);
initializeMemDepPrinterPass(Registry);
#define DEBUG_TYPE "lazy-value-info"
-char LazyValueInfo::ID = 0;
-INITIALIZE_PASS_BEGIN(LazyValueInfo, "lazy-value-info",
+char LazyValueInfoWrapperPass::ID = 0;
+INITIALIZE_PASS_BEGIN(LazyValueInfoWrapperPass, "lazy-value-info",
"Lazy Value Information Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_END(LazyValueInfo, "lazy-value-info",
+INITIALIZE_PASS_END(LazyValueInfoWrapperPass, "lazy-value-info",
"Lazy Value Information Analysis", false, true)
namespace llvm {
- FunctionPass *createLazyValueInfoPass() { return new LazyValueInfo(); }
+ FunctionPass *createLazyValueInfoPass() { return new LazyValueInfoWrapperPass(); }
}
+char LazyValueAnalysis::PassID;
//===----------------------------------------------------------------------===//
// LVILatticeVal
return *static_cast<LazyValueInfoCache*>(PImpl);
}
-bool LazyValueInfo::runOnFunction(Function &F) {
- AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+bool LazyValueInfoWrapperPass::runOnFunction(Function &F) {
+ Info.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
const DataLayout &DL = F.getParent()->getDataLayout();
DominatorTreeWrapperPass *DTWP =
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
- DT = DTWP ? &DTWP->getDomTree() : nullptr;
+ Info.DT = DTWP ? &DTWP->getDomTree() : nullptr;
+ Info.TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
- TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
-
- if (PImpl)
- getCache(PImpl, AC, &DL, DT).clear();
+ if (Info.PImpl)
+ getCache(Info.PImpl, Info.AC, &DL, Info.DT).clear();
// Fully lazy.
return false;
}
-void LazyValueInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+void LazyValueInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
+LazyValueInfo &LazyValueInfoWrapperPass::getLVI() { return Info; }
+
+LazyValueInfo::~LazyValueInfo() { releaseMemory(); }
+
void LazyValueInfo::releaseMemory() {
// If the cache was allocated, free it.
if (PImpl) {
}
}
+void LazyValueInfoWrapperPass::releaseMemory() { Info.releaseMemory(); }
+
+LazyValueInfo LazyValueAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
+ auto &AC = FAM.getResult<AssumptionAnalysis>(F);
+ auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
+ auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
+
+ return LazyValueInfo(&AC, &TLI, DT);
+}
+
Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB,
Instruction *CxtI) {
const DataLayout &DL = BB->getModule()->getDataLayout();
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/PostDominators.h"
FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis())
FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis())
FUNCTION_ANALYSIS("loops", LoopAnalysis())
+FUNCTION_ANALYSIS("lazy-value-info", LazyValueAnalysis())
FUNCTION_ANALYSIS("da", DependenceAnalysis())
FUNCTION_ANALYSIS("memdep", MemoryDependenceAnalysis())
FUNCTION_ANALYSIS("memoryssa", MemorySSAAnalysis())
bool runOnFunction(Function &F) override;
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<LazyValueInfo>();
+ AU.addRequired<LazyValueInfoWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
}
};
char CorrelatedValuePropagation::ID = 0;
INITIALIZE_PASS_BEGIN(CorrelatedValuePropagation, "correlated-propagation",
"Value Propagation", false, false)
-INITIALIZE_PASS_DEPENDENCY(LazyValueInfo)
+INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
INITIALIZE_PASS_END(CorrelatedValuePropagation, "correlated-propagation",
"Value Propagation", false, false)
if (skipFunction(F))
return false;
- LVI = &getAnalysis<LazyValueInfo>();
+ LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
bool FnChanged = false;
bool runOnFunction(Function &F) override;
void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<LazyValueInfo>();
- AU.addPreserved<LazyValueInfo>();
+ AU.addRequired<LazyValueInfoWrapperPass>();
+ AU.addPreserved<LazyValueInfoWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
}
char JumpThreading::ID = 0;
INITIALIZE_PASS_BEGIN(JumpThreading, "jump-threading",
"Jump Threading", false, false)
-INITIALIZE_PASS_DEPENDENCY(LazyValueInfo)
+INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(JumpThreading, "jump-threading",
"Jump Threading", false, false)
DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n");
TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
- LVI = &getAnalysis<LazyValueInfo>();
+ LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
BFI.reset();
BPI.reset();
// When profile data is available, we need to update edge weights after