xref: /llvm-project/llvm/include/llvm/Analysis/LazyValueInfo.h (revision 0da2ba811ac8a01509bc533428941fb9519c0715)
1 //===- LazyValueInfo.h - Value constraint analysis --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the interface for lazy computation of value constraint
10 // information.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
15 #define LLVM_ANALYSIS_LAZYVALUEINFO_H
16 
17 #include "llvm/IR/InstrTypes.h"
18 #include "llvm/IR/PassManager.h"
19 #include "llvm/Pass.h"
20 
21 namespace llvm {
22   class AssumptionCache;
23   class BasicBlock;
24   class Constant;
25   class DataLayout;
26   class DominatorTree;
27   class Instruction;
28   class Value;
29   class Use;
30   class LazyValueInfoImpl;
31   /// This pass computes, caches, and vends lazy value constraint information.
32   class LazyValueInfo {
33     friend class LazyValueInfoWrapperPass;
34     AssumptionCache *AC = nullptr;
35     const DataLayout *DL = nullptr;
36     LazyValueInfoImpl *PImpl = nullptr;
37     LazyValueInfo(const LazyValueInfo &) = delete;
38     void operator=(const LazyValueInfo &) = delete;
39 
40     LazyValueInfoImpl *getImpl();
41     LazyValueInfoImpl &getOrCreateImpl(const Module *M);
42 
43   public:
44     ~LazyValueInfo();
45     LazyValueInfo() = default;
46     LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_)
47         : AC(AC_), DL(DL_) {}
48     LazyValueInfo(LazyValueInfo &&Arg)
49         : AC(Arg.AC), DL(Arg.DL), PImpl(Arg.PImpl) {
50       Arg.PImpl = nullptr;
51     }
52     LazyValueInfo &operator=(LazyValueInfo &&Arg) {
53       releaseMemory();
54       AC = Arg.AC;
55       DL = Arg.DL;
56       PImpl = Arg.PImpl;
57       Arg.PImpl = nullptr;
58       return *this;
59     }
60 
61     // Public query interface.
62 
63     /// Determine whether the specified value comparison with a constant is
64     /// known to be true or false on the specified CFG edge. Pred is a CmpInst
65     /// predicate.
66     Constant *getPredicateOnEdge(CmpInst::Predicate Pred, Value *V, Constant *C,
67                                  BasicBlock *FromBB, BasicBlock *ToBB,
68                                  Instruction *CxtI = nullptr);
69 
70     /// Determine whether the specified value comparison with a constant is
71     /// known to be true or false at the specified instruction. \p Pred is a
72     /// CmpInst predicate. If \p UseBlockValue is true, the block value is also
73     /// taken into account.
74     Constant *getPredicateAt(CmpInst::Predicate Pred, Value *V, Constant *C,
75                              Instruction *CxtI, bool UseBlockValue);
76 
77     /// Determine whether the specified value comparison is known to be true
78     /// or false at the specified instruction. While this takes two Value's,
79     /// it still requires that one of them is a constant.
80     /// \p Pred is a CmpInst predicate.
81     /// If \p UseBlockValue is true, the block value is also taken into account.
82     Constant *getPredicateAt(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
83                              Instruction *CxtI, bool UseBlockValue);
84 
85     /// Determine whether the specified value is known to be a constant at the
86     /// specified instruction. Return null if not.
87     Constant *getConstant(Value *V, Instruction *CxtI);
88 
89     /// Return the ConstantRange constraint that is known to hold for the
90     /// specified value at the specified instruction. This may only be called
91     /// on integer-typed Values.
92     ConstantRange getConstantRange(Value *V, Instruction *CxtI,
93                                    bool UndefAllowed);
94 
95     /// Return the ConstantRange constraint that is known to hold for the value
96     /// at a specific use-site.
97     ConstantRange getConstantRangeAtUse(const Use &U, bool UndefAllowed);
98 
99     /// Determine whether the specified value is known to be a
100     /// constant on the specified edge.  Return null if not.
101     Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
102                                 Instruction *CxtI = nullptr);
103 
104     /// Return the ConstantRage constraint that is known to hold for the
105     /// specified value on the specified edge. This may be only be called
106     /// on integer-typed Values.
107     ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB,
108                                          BasicBlock *ToBB,
109                                          Instruction *CxtI = nullptr);
110 
111     /// Inform the analysis cache that we have threaded an edge from
112     /// PredBB to OldSucc to be from PredBB to NewSucc instead.
113     void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
114                     BasicBlock *NewSucc);
115 
116     /// Remove information related to this value from the cache.
117     void forgetValue(Value *V);
118 
119     /// Inform the analysis cache that we have erased a block.
120     void eraseBlock(BasicBlock *BB);
121 
122     /// Complete flush all previously computed values
123     void clear();
124 
125     /// Print the \LazyValueInfo Analysis.
126     /// We pass in the DTree that is required for identifying which basic blocks
127     /// we can solve/print for, in the LVIPrinter.
128     void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
129 
130     // For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
131     void releaseMemory();
132 
133     /// Handle invalidation events in the new pass manager.
134     bool invalidate(Function &F, const PreservedAnalyses &PA,
135                     FunctionAnalysisManager::Invalidator &Inv);
136   };
137 
138 /// Analysis to compute lazy value information.
139 class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> {
140 public:
141   typedef LazyValueInfo Result;
142   Result run(Function &F, FunctionAnalysisManager &FAM);
143 
144 private:
145   static AnalysisKey Key;
146   friend struct AnalysisInfoMixin<LazyValueAnalysis>;
147 };
148 
149 /// Printer pass for the LazyValueAnalysis results.
150 class LazyValueInfoPrinterPass
151     : public PassInfoMixin<LazyValueInfoPrinterPass> {
152   raw_ostream &OS;
153 
154 public:
155   explicit LazyValueInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
156 
157   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
158 
159   static bool isRequired() { return true; }
160 };
161 
162 /// Wrapper around LazyValueInfo.
163 class LazyValueInfoWrapperPass : public FunctionPass {
164   LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete;
165   void operator=(const LazyValueInfoWrapperPass&) = delete;
166 public:
167   static char ID;
168   LazyValueInfoWrapperPass();
169   ~LazyValueInfoWrapperPass() override {
170     assert(!Info.PImpl && "releaseMemory not called");
171   }
172 
173   LazyValueInfo &getLVI();
174 
175   void getAnalysisUsage(AnalysisUsage &AU) const override;
176   void releaseMemory() override;
177   bool runOnFunction(Function &F) override;
178 private:
179   LazyValueInfo Info;
180 };
181 
182 }  // end namespace llvm
183 
184 #endif
185 
186