xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/LazyValueInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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