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 15 namespace llvm { 16 17 class AssumptionCache; 18 class DomConditionCache; 19 class DominatorTree; 20 class TargetLibraryInfo; 21 22 /// InstrInfoQuery provides an interface to query additional information for 23 /// instructions like metadata or keywords like nsw, which provides conservative 24 /// results if the users specified it is safe to use. 25 struct InstrInfoQuery { InstrInfoQueryInstrInfoQuery26 InstrInfoQuery(bool UMD) : UseInstrInfo(UMD) {} 27 InstrInfoQuery() = default; 28 bool UseInstrInfo = true; 29 getMetadataInstrInfoQuery30 MDNode *getMetadata(const Instruction *I, unsigned KindID) const { 31 if (UseInstrInfo) 32 return I->getMetadata(KindID); 33 return nullptr; 34 } 35 hasNoUnsignedWrapInstrInfoQuery36 template <class InstT> bool hasNoUnsignedWrap(const InstT *Op) const { 37 if (UseInstrInfo) 38 return Op->hasNoUnsignedWrap(); 39 return false; 40 } 41 hasNoSignedWrapInstrInfoQuery42 template <class InstT> bool hasNoSignedWrap(const InstT *Op) const { 43 if (UseInstrInfo) 44 return Op->hasNoSignedWrap(); 45 return false; 46 } 47 isExactInstrInfoQuery48 bool isExact(const BinaryOperator *Op) const { 49 if (UseInstrInfo && isa<PossiblyExactOperator>(Op)) 50 return cast<PossiblyExactOperator>(Op)->isExact(); 51 return false; 52 } 53 hasNoSignedZerosInstrInfoQuery54 template <class InstT> bool hasNoSignedZeros(const InstT *Op) const { 55 if (UseInstrInfo) 56 return Op->hasNoSignedZeros(); 57 return false; 58 } 59 }; 60 61 /// Evaluate query assuming this condition holds. 62 struct CondContext { 63 Value *Cond; 64 bool Invert = false; 65 SmallPtrSet<Value *, 4> AffectedValues; 66 CondContextCondContext67 CondContext(Value *Cond) : Cond(Cond) {} 68 }; 69 70 struct SimplifyQuery { 71 const DataLayout &DL; 72 const TargetLibraryInfo *TLI = nullptr; 73 const DominatorTree *DT = nullptr; 74 AssumptionCache *AC = nullptr; 75 const Instruction *CxtI = nullptr; 76 const DomConditionCache *DC = nullptr; 77 const CondContext *CC = nullptr; 78 79 // Wrapper to query additional information for instructions like metadata or 80 // keywords like nsw, which provides conservative results if those cannot 81 // be safely used. 82 const InstrInfoQuery IIQ; 83 84 /// Controls whether simplifications are allowed to constrain the range of 85 /// possible values for uses of undef. If it is false, simplifications are not 86 /// allowed to assume a particular value for a use of undef for example. 87 bool CanUseUndef = true; 88 89 SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr) DLSimplifyQuery90 : DL(DL), CxtI(CXTI) {} 91 92 SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI, 93 const DominatorTree *DT = nullptr, 94 AssumptionCache *AC = nullptr, 95 const Instruction *CXTI = nullptr, bool UseInstrInfo = true, 96 bool CanUseUndef = true, const DomConditionCache *DC = nullptr) DLSimplifyQuery97 : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI), DC(DC), IIQ(UseInstrInfo), 98 CanUseUndef(CanUseUndef) {} 99 100 SimplifyQuery(const DataLayout &DL, const DominatorTree *DT, 101 AssumptionCache *AC = nullptr, 102 const Instruction *CXTI = nullptr, bool UseInstrInfo = true, 103 bool CanUseUndef = true) DLSimplifyQuery104 : DL(DL), DT(DT), AC(AC), CxtI(CXTI), IIQ(UseInstrInfo), 105 CanUseUndef(CanUseUndef) {} 106 getWithInstructionSimplifyQuery107 SimplifyQuery getWithInstruction(const Instruction *I) const { 108 SimplifyQuery Copy(*this); 109 Copy.CxtI = I; 110 return Copy; 111 } getWithoutUndefSimplifyQuery112 SimplifyQuery getWithoutUndef() const { 113 SimplifyQuery Copy(*this); 114 Copy.CanUseUndef = false; 115 return Copy; 116 } 117 118 /// If CanUseUndef is true, returns whether \p V is undef. 119 /// Otherwise always return false. 120 bool isUndefValue(Value *V) const; 121 getWithoutDomCondCacheSimplifyQuery122 SimplifyQuery getWithoutDomCondCache() const { 123 SimplifyQuery Copy(*this); 124 Copy.DC = nullptr; 125 return Copy; 126 } 127 getWithCondContextSimplifyQuery128 SimplifyQuery getWithCondContext(const CondContext &CC) const { 129 SimplifyQuery Copy(*this); 130 Copy.CC = &CC; 131 return Copy; 132 } 133 getWithoutCondContextSimplifyQuery134 SimplifyQuery getWithoutCondContext() const { 135 SimplifyQuery Copy(*this); 136 Copy.CC = nullptr; 137 return Copy; 138 } 139 }; 140 141 } // end namespace llvm 142 143 #endif 144