1 //===-- SimplifyQuery.h - Context for simplifications -----------*- 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 #ifndef LLVM_ANALYSIS_SIMPLIFYQUERY_H 10 #define LLVM_ANALYSIS_SIMPLIFYQUERY_H 11 12 #include "llvm/ADT/SmallPtrSet.h" 13 #include "llvm/IR/Operator.h" 14 #include "llvm/Support/Compiler.h" 15 16 namespace llvm { 17 18 class AssumptionCache; 19 class DomConditionCache; 20 class DominatorTree; 21 class TargetLibraryInfo; 22 23 /// InstrInfoQuery provides an interface to query additional information for 24 /// instructions like metadata or keywords like nsw, which provides conservative 25 /// results if the users specified it is safe to use. 26 struct InstrInfoQuery { InstrInfoQueryInstrInfoQuery27 InstrInfoQuery(bool UMD) : UseInstrInfo(UMD) {} 28 InstrInfoQuery() = default; 29 bool UseInstrInfo = true; 30 getMetadataInstrInfoQuery31 MDNode *getMetadata(const Instruction *I, unsigned KindID) const { 32 if (UseInstrInfo) 33 return I->getMetadata(KindID); 34 return nullptr; 35 } 36 hasNoUnsignedWrapInstrInfoQuery37 template <class InstT> bool hasNoUnsignedWrap(const InstT *Op) const { 38 if (UseInstrInfo) 39 return Op->hasNoUnsignedWrap(); 40 return false; 41 } 42 hasNoSignedWrapInstrInfoQuery43 template <class InstT> bool hasNoSignedWrap(const InstT *Op) const { 44 if (UseInstrInfo) 45 return Op->hasNoSignedWrap(); 46 return false; 47 } 48 isExactInstrInfoQuery49 bool isExact(const BinaryOperator *Op) const { 50 if (UseInstrInfo && isa<PossiblyExactOperator>(Op)) 51 return cast<PossiblyExactOperator>(Op)->isExact(); 52 return false; 53 } 54 hasNoSignedZerosInstrInfoQuery55 template <class InstT> bool hasNoSignedZeros(const InstT *Op) const { 56 if (UseInstrInfo) 57 return Op->hasNoSignedZeros(); 58 return false; 59 } 60 }; 61 62 /// Evaluate query assuming this condition holds. 63 struct CondContext { 64 Value *Cond; 65 bool Invert = false; 66 SmallPtrSet<Value *, 4> AffectedValues; 67 CondContextCondContext68 CondContext(Value *Cond) : Cond(Cond) {} 69 }; 70 71 struct SimplifyQuery { 72 const DataLayout &DL; 73 const TargetLibraryInfo *TLI = nullptr; 74 const DominatorTree *DT = nullptr; 75 AssumptionCache *AC = nullptr; 76 const Instruction *CxtI = nullptr; 77 const DomConditionCache *DC = nullptr; 78 const CondContext *CC = nullptr; 79 80 // Wrapper to query additional information for instructions like metadata or 81 // keywords like nsw, which provides conservative results if those cannot 82 // be safely used. 83 const InstrInfoQuery IIQ; 84 85 /// Controls whether simplifications are allowed to constrain the range of 86 /// possible values for uses of undef. If it is false, simplifications are not 87 /// allowed to assume a particular value for a use of undef for example. 88 bool CanUseUndef = true; 89 90 SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr) DLSimplifyQuery91 : DL(DL), CxtI(CXTI) {} 92 93 SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI, 94 const DominatorTree *DT = nullptr, 95 AssumptionCache *AC = nullptr, 96 const Instruction *CXTI = nullptr, bool UseInstrInfo = true, 97 bool CanUseUndef = true, const DomConditionCache *DC = nullptr) DLSimplifyQuery98 : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI), DC(DC), IIQ(UseInstrInfo), 99 CanUseUndef(CanUseUndef) {} 100 101 SimplifyQuery(const DataLayout &DL, const DominatorTree *DT, 102 AssumptionCache *AC = nullptr, 103 const Instruction *CXTI = nullptr, bool UseInstrInfo = true, 104 bool CanUseUndef = true) DLSimplifyQuery105 : DL(DL), DT(DT), AC(AC), CxtI(CXTI), IIQ(UseInstrInfo), 106 CanUseUndef(CanUseUndef) {} 107 getWithInstructionSimplifyQuery108 SimplifyQuery getWithInstruction(const Instruction *I) const { 109 SimplifyQuery Copy(*this); 110 Copy.CxtI = I; 111 return Copy; 112 } getWithoutUndefSimplifyQuery113 SimplifyQuery getWithoutUndef() const { 114 SimplifyQuery Copy(*this); 115 Copy.CanUseUndef = false; 116 return Copy; 117 } 118 119 /// If CanUseUndef is true, returns whether \p V is undef. 120 /// Otherwise always return false. 121 LLVM_ABI bool isUndefValue(Value *V) const; 122 getWithoutDomCondCacheSimplifyQuery123 SimplifyQuery getWithoutDomCondCache() const { 124 SimplifyQuery Copy(*this); 125 Copy.DC = nullptr; 126 return Copy; 127 } 128 getWithCondContextSimplifyQuery129 SimplifyQuery getWithCondContext(const CondContext &CC) const { 130 SimplifyQuery Copy(*this); 131 Copy.CC = &CC; 132 return Copy; 133 } 134 getWithoutCondContextSimplifyQuery135 SimplifyQuery getWithoutCondContext() const { 136 SimplifyQuery Copy(*this); 137 Copy.CC = nullptr; 138 return Copy; 139 } 140 }; 141 142 } // end namespace llvm 143 144 #endif 145