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