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