xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Analysis/SimplifyQuery.h (revision 36b606ae6aa4b24061096ba18582e0a08ccd5dba)
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