10b57cec5SDimitry Andric //===- LazyValueInfo.h - Value constraint analysis --------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the interface for lazy computation of value constraint 100b57cec5SDimitry Andric // information. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H 150b57cec5SDimitry Andric #define LLVM_ANALYSIS_LAZYVALUEINFO_H 160b57cec5SDimitry Andric 17*0fca6ea1SDimitry Andric #include "llvm/IR/InstrTypes.h" 180b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 190b57cec5SDimitry Andric #include "llvm/Pass.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric class AssumptionCache; 23*0fca6ea1SDimitry Andric class BasicBlock; 240b57cec5SDimitry Andric class Constant; 250b57cec5SDimitry Andric class ConstantRange; 260b57cec5SDimitry Andric class DataLayout; 270b57cec5SDimitry Andric class DominatorTree; 280b57cec5SDimitry Andric class Instruction; 290b57cec5SDimitry Andric class TargetLibraryInfo; 300b57cec5SDimitry Andric class Value; 31*0fca6ea1SDimitry Andric class Use; 325f757f3fSDimitry Andric class LazyValueInfoImpl; 330b57cec5SDimitry Andric /// This pass computes, caches, and vends lazy value constraint information. 340b57cec5SDimitry Andric class LazyValueInfo { 350b57cec5SDimitry Andric friend class LazyValueInfoWrapperPass; 360b57cec5SDimitry Andric AssumptionCache *AC = nullptr; 370b57cec5SDimitry Andric const DataLayout *DL = nullptr; 385f757f3fSDimitry Andric LazyValueInfoImpl *PImpl = nullptr; 390b57cec5SDimitry Andric LazyValueInfo(const LazyValueInfo &) = delete; 400b57cec5SDimitry Andric void operator=(const LazyValueInfo &) = delete; 415f757f3fSDimitry Andric 425f757f3fSDimitry Andric LazyValueInfoImpl *getImpl(); 435f757f3fSDimitry Andric LazyValueInfoImpl &getOrCreateImpl(const Module *M); 445f757f3fSDimitry Andric 450b57cec5SDimitry Andric public: 460b57cec5SDimitry Andric ~LazyValueInfo(); 471fd87a68SDimitry Andric LazyValueInfo() = default; LazyValueInfo(AssumptionCache * AC_,const DataLayout * DL_)48cb14a3feSDimitry Andric LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_) 49cb14a3feSDimitry Andric : AC(AC_), DL(DL_) {} LazyValueInfo(LazyValueInfo && Arg)500b57cec5SDimitry Andric LazyValueInfo(LazyValueInfo &&Arg) 51cb14a3feSDimitry Andric : AC(Arg.AC), DL(Arg.DL), PImpl(Arg.PImpl) { 520b57cec5SDimitry Andric Arg.PImpl = nullptr; 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric LazyValueInfo &operator=(LazyValueInfo &&Arg) { 550b57cec5SDimitry Andric releaseMemory(); 560b57cec5SDimitry Andric AC = Arg.AC; 570b57cec5SDimitry Andric DL = Arg.DL; 580b57cec5SDimitry Andric PImpl = Arg.PImpl; 590b57cec5SDimitry Andric Arg.PImpl = nullptr; 600b57cec5SDimitry Andric return *this; 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // Public query interface. 640b57cec5SDimitry Andric 655f757f3fSDimitry Andric /// Determine whether the specified value comparison with a constant is 665f757f3fSDimitry Andric /// known to be true or false on the specified CFG edge. Pred is a CmpInst 675f757f3fSDimitry Andric /// predicate. 68*0fca6ea1SDimitry Andric Constant *getPredicateOnEdge(CmpInst::Predicate Pred, Value *V, Constant *C, 690b57cec5SDimitry Andric BasicBlock *FromBB, BasicBlock *ToBB, 700b57cec5SDimitry Andric Instruction *CxtI = nullptr); 710b57cec5SDimitry Andric 725f757f3fSDimitry Andric /// Determine whether the specified value comparison with a constant is 735f757f3fSDimitry Andric /// known to be true or false at the specified instruction. \p Pred is a 745f757f3fSDimitry Andric /// CmpInst predicate. If \p UseBlockValue is true, the block value is also 755f757f3fSDimitry Andric /// taken into account. 76*0fca6ea1SDimitry Andric Constant *getPredicateAt(CmpInst::Predicate Pred, Value *V, Constant *C, 77fe6060f1SDimitry Andric Instruction *CxtI, bool UseBlockValue); 78fe6060f1SDimitry Andric 79fe6060f1SDimitry Andric /// Determine whether the specified value comparison is known to be true 80fe6060f1SDimitry Andric /// or false at the specified instruction. While this takes two Value's, 81fe6060f1SDimitry Andric /// it still requires that one of them is a constant. 82fe6060f1SDimitry Andric /// \p Pred is a CmpInst predicate. 83fe6060f1SDimitry Andric /// If \p UseBlockValue is true, the block value is also taken into account. 84*0fca6ea1SDimitry Andric Constant *getPredicateAt(CmpInst::Predicate Pred, Value *LHS, Value *RHS, 85fe6060f1SDimitry Andric Instruction *CxtI, bool UseBlockValue); 860b57cec5SDimitry Andric 87e8d8bef9SDimitry Andric /// Determine whether the specified value is known to be a constant at the 88e8d8bef9SDimitry Andric /// specified instruction. Return null if not. 89e8d8bef9SDimitry Andric Constant *getConstant(Value *V, Instruction *CxtI); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// Return the ConstantRange constraint that is known to hold for the 92e8d8bef9SDimitry Andric /// specified value at the specified instruction. This may only be called 930b57cec5SDimitry Andric /// on integer-typed Values. 94e8d8bef9SDimitry Andric ConstantRange getConstantRange(Value *V, Instruction *CxtI, 955f757f3fSDimitry Andric bool UndefAllowed); 960b57cec5SDimitry Andric 97bdd1243dSDimitry Andric /// Return the ConstantRange constraint that is known to hold for the value 98bdd1243dSDimitry Andric /// at a specific use-site. 995f757f3fSDimitry Andric ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed); 100bdd1243dSDimitry Andric 1010b57cec5SDimitry Andric /// Determine whether the specified value is known to be a 1020b57cec5SDimitry Andric /// constant on the specified edge. Return null if not. 1030b57cec5SDimitry Andric Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, 1040b57cec5SDimitry Andric Instruction *CxtI = nullptr); 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric /// Return the ConstantRage constraint that is known to hold for the 1070b57cec5SDimitry Andric /// specified value on the specified edge. This may be only be called 1080b57cec5SDimitry Andric /// on integer-typed Values. 1090b57cec5SDimitry Andric ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB, 1100b57cec5SDimitry Andric BasicBlock *ToBB, 1110b57cec5SDimitry Andric Instruction *CxtI = nullptr); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric /// Inform the analysis cache that we have threaded an edge from 1140b57cec5SDimitry Andric /// PredBB to OldSucc to be from PredBB to NewSucc instead. 1155f757f3fSDimitry Andric void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, 1165f757f3fSDimitry Andric BasicBlock *NewSucc); 1170b57cec5SDimitry Andric 1188a4dda33SDimitry Andric /// Remove information related to this value from the cache. 1198a4dda33SDimitry Andric void forgetValue(Value *V); 1208a4dda33SDimitry Andric 1210b57cec5SDimitry Andric /// Inform the analysis cache that we have erased a block. 1220b57cec5SDimitry Andric void eraseBlock(BasicBlock *BB); 1230b57cec5SDimitry Andric 12481ad6265SDimitry Andric /// Complete flush all previously computed values 1255f757f3fSDimitry Andric void clear(); 12681ad6265SDimitry Andric 1270b57cec5SDimitry Andric /// Print the \LazyValueInfo Analysis. 1280b57cec5SDimitry Andric /// We pass in the DTree that is required for identifying which basic blocks 1295ffd83dbSDimitry Andric /// we can solve/print for, in the LVIPrinter. 1300b57cec5SDimitry Andric void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS); 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // For old PM pass. Delete once LazyValueInfoWrapperPass is gone. 1330b57cec5SDimitry Andric void releaseMemory(); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric /// Handle invalidation events in the new pass manager. 1360b57cec5SDimitry Andric bool invalidate(Function &F, const PreservedAnalyses &PA, 1370b57cec5SDimitry Andric FunctionAnalysisManager::Invalidator &Inv); 1380b57cec5SDimitry Andric }; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric /// Analysis to compute lazy value information. 1410b57cec5SDimitry Andric class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> { 1420b57cec5SDimitry Andric public: 1430b57cec5SDimitry Andric typedef LazyValueInfo Result; 1440b57cec5SDimitry Andric Result run(Function &F, FunctionAnalysisManager &FAM); 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric private: 1470b57cec5SDimitry Andric static AnalysisKey Key; 1480b57cec5SDimitry Andric friend struct AnalysisInfoMixin<LazyValueAnalysis>; 1490b57cec5SDimitry Andric }; 1500b57cec5SDimitry Andric 1515f757f3fSDimitry Andric /// Printer pass for the LazyValueAnalysis results. 1525f757f3fSDimitry Andric class LazyValueInfoPrinterPass 1535f757f3fSDimitry Andric : public PassInfoMixin<LazyValueInfoPrinterPass> { 1545f757f3fSDimitry Andric raw_ostream &OS; 1555f757f3fSDimitry Andric 1565f757f3fSDimitry Andric public: 1575f757f3fSDimitry Andric explicit LazyValueInfoPrinterPass(raw_ostream &OS) : OS(OS) {} 1585f757f3fSDimitry Andric 1595f757f3fSDimitry Andric PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 1601db9f3b2SDimitry Andric 1611db9f3b2SDimitry Andric static bool isRequired() { return true; } 1625f757f3fSDimitry Andric }; 1635f757f3fSDimitry Andric 1640b57cec5SDimitry Andric /// Wrapper around LazyValueInfo. 1650b57cec5SDimitry Andric class LazyValueInfoWrapperPass : public FunctionPass { 1660b57cec5SDimitry Andric LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete; 1670b57cec5SDimitry Andric void operator=(const LazyValueInfoWrapperPass&) = delete; 1680b57cec5SDimitry Andric public: 1690b57cec5SDimitry Andric static char ID; 170480093f4SDimitry Andric LazyValueInfoWrapperPass(); 1710b57cec5SDimitry Andric ~LazyValueInfoWrapperPass() override { 1720b57cec5SDimitry Andric assert(!Info.PImpl && "releaseMemory not called"); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric LazyValueInfo &getLVI(); 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 1780b57cec5SDimitry Andric void releaseMemory() override; 1790b57cec5SDimitry Andric bool runOnFunction(Function &F) override; 1800b57cec5SDimitry Andric private: 1810b57cec5SDimitry Andric LazyValueInfo Info; 1820b57cec5SDimitry Andric }; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric } // end namespace llvm 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric #endif 1870b57cec5SDimitry Andric 188