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/PassManager.h" 18 #include "llvm/Pass.h" 19 20 namespace llvm { 21 class AssumptionCache; 22 class Constant; 23 class ConstantRange; 24 class DataLayout; 25 class DominatorTree; 26 class Instruction; 27 class TargetLibraryInfo; 28 class Value; 29 30 /// This pass computes, caches, and vends lazy value constraint information. 31 class LazyValueInfo { 32 friend class LazyValueInfoWrapperPass; 33 AssumptionCache *AC = nullptr; 34 const DataLayout *DL = nullptr; 35 class TargetLibraryInfo *TLI = nullptr; 36 DominatorTree *DT = nullptr; 37 void *PImpl = nullptr; 38 LazyValueInfo(const LazyValueInfo&) = delete; 39 void operator=(const LazyValueInfo&) = delete; 40 public: 41 ~LazyValueInfo(); 42 LazyValueInfo() {} 43 LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_, TargetLibraryInfo *TLI_, 44 DominatorTree *DT_) 45 : AC(AC_), DL(DL_), TLI(TLI_), DT(DT_) {} 46 LazyValueInfo(LazyValueInfo &&Arg) 47 : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) { 48 Arg.PImpl = nullptr; 49 } 50 LazyValueInfo &operator=(LazyValueInfo &&Arg) { 51 releaseMemory(); 52 AC = Arg.AC; 53 DL = Arg.DL; 54 TLI = Arg.TLI; 55 DT = Arg.DT; 56 PImpl = Arg.PImpl; 57 Arg.PImpl = nullptr; 58 return *this; 59 } 60 61 /// This is used to return true/false/dunno results. 62 enum Tristate { 63 Unknown = -1, False = 0, True = 1 64 }; 65 66 // Public query interface. 67 68 /// Determine whether the specified value comparison with a constant is known 69 /// to be true or false on the specified CFG edge. 70 /// Pred is a CmpInst predicate. 71 Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C, 72 BasicBlock *FromBB, BasicBlock *ToBB, 73 Instruction *CxtI = nullptr); 74 75 /// Determine whether the specified value comparison with a constant is known 76 /// to be true or false at the specified instruction 77 /// (from an assume intrinsic). Pred is a CmpInst predicate. 78 Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C, 79 Instruction *CxtI); 80 81 /// Determine whether the specified value is known to be a 82 /// constant at the end of the specified block. Return null if not. 83 Constant *getConstant(Value *V, BasicBlock *BB, Instruction *CxtI = nullptr); 84 85 /// Return the ConstantRange constraint that is known to hold for the 86 /// specified value at the end of the specified block. This may only be called 87 /// on integer-typed Values. 88 ConstantRange getConstantRange(Value *V, BasicBlock *BB, Instruction *CxtI = nullptr); 89 90 /// Determine whether the specified value is known to be a 91 /// constant on the specified edge. Return null if not. 92 Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, 93 Instruction *CxtI = nullptr); 94 95 /// Return the ConstantRage constraint that is known to hold for the 96 /// specified value on the specified edge. This may be only be called 97 /// on integer-typed Values. 98 ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB, 99 BasicBlock *ToBB, 100 Instruction *CxtI = nullptr); 101 102 /// Inform the analysis cache that we have threaded an edge from 103 /// PredBB to OldSucc to be from PredBB to NewSucc instead. 104 void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc); 105 106 /// Inform the analysis cache that we have erased a block. 107 void eraseBlock(BasicBlock *BB); 108 109 /// Print the \LazyValueInfo Analysis. 110 /// We pass in the DTree that is required for identifying which basic blocks 111 /// we can solve/print for, in the LVIPrinter. The DT is optional 112 /// in LVI, so we need to pass it here as an argument. 113 void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS); 114 115 /// Disables use of the DominatorTree within LVI. 116 void disableDT(); 117 118 /// Enables use of the DominatorTree within LVI. Does nothing if the class 119 /// instance was initialized without a DT pointer. 120 void enableDT(); 121 122 // For old PM pass. Delete once LazyValueInfoWrapperPass is gone. 123 void releaseMemory(); 124 125 /// Handle invalidation events in the new pass manager. 126 bool invalidate(Function &F, const PreservedAnalyses &PA, 127 FunctionAnalysisManager::Invalidator &Inv); 128 }; 129 130 /// Analysis to compute lazy value information. 131 class LazyValueAnalysis : public AnalysisInfoMixin<LazyValueAnalysis> { 132 public: 133 typedef LazyValueInfo Result; 134 Result run(Function &F, FunctionAnalysisManager &FAM); 135 136 private: 137 static AnalysisKey Key; 138 friend struct AnalysisInfoMixin<LazyValueAnalysis>; 139 }; 140 141 /// Wrapper around LazyValueInfo. 142 class LazyValueInfoWrapperPass : public FunctionPass { 143 LazyValueInfoWrapperPass(const LazyValueInfoWrapperPass&) = delete; 144 void operator=(const LazyValueInfoWrapperPass&) = delete; 145 public: 146 static char ID; 147 LazyValueInfoWrapperPass() : FunctionPass(ID) { 148 initializeLazyValueInfoWrapperPassPass(*PassRegistry::getPassRegistry()); 149 } 150 ~LazyValueInfoWrapperPass() override { 151 assert(!Info.PImpl && "releaseMemory not called"); 152 } 153 154 LazyValueInfo &getLVI(); 155 156 void getAnalysisUsage(AnalysisUsage &AU) const override; 157 void releaseMemory() override; 158 bool runOnFunction(Function &F) override; 159 private: 160 LazyValueInfo Info; 161 }; 162 163 } // end namespace llvm 164 165 #endif 166 167