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/IR/PatternMatch.h"
13 
14 namespace llvm {
15 
16 class AssumptionCache;
17 class DomConditionCache;
18 class DominatorTree;
19 class TargetLibraryInfo;
20 
21 /// InstrInfoQuery provides an interface to query additional information for
22 /// instructions like metadata or keywords like nsw, which provides conservative
23 /// results if the users specified it is safe to use.
24 struct InstrInfoQuery {
InstrInfoQueryInstrInfoQuery25   InstrInfoQuery(bool UMD) : UseInstrInfo(UMD) {}
26   InstrInfoQuery() = default;
27   bool UseInstrInfo = true;
28 
getMetadataInstrInfoQuery29   MDNode *getMetadata(const Instruction *I, unsigned KindID) const {
30     if (UseInstrInfo)
31       return I->getMetadata(KindID);
32     return nullptr;
33   }
34 
hasNoUnsignedWrapInstrInfoQuery35   template <class InstT> bool hasNoUnsignedWrap(const InstT *Op) const {
36     if (UseInstrInfo)
37       return Op->hasNoUnsignedWrap();
38     return false;
39   }
40 
hasNoSignedWrapInstrInfoQuery41   template <class InstT> bool hasNoSignedWrap(const InstT *Op) const {
42     if (UseInstrInfo)
43       return Op->hasNoSignedWrap();
44     return false;
45   }
46 
isExactInstrInfoQuery47   bool isExact(const BinaryOperator *Op) const {
48     if (UseInstrInfo && isa<PossiblyExactOperator>(Op))
49       return cast<PossiblyExactOperator>(Op)->isExact();
50     return false;
51   }
52 
hasNoSignedZerosInstrInfoQuery53   template <class InstT> bool hasNoSignedZeros(const InstT *Op) const {
54     if (UseInstrInfo)
55       return Op->hasNoSignedZeros();
56     return false;
57   }
58 };
59 
60 struct SimplifyQuery {
61   const DataLayout &DL;
62   const TargetLibraryInfo *TLI = nullptr;
63   const DominatorTree *DT = nullptr;
64   AssumptionCache *AC = nullptr;
65   const Instruction *CxtI = nullptr;
66   const DomConditionCache *DC = nullptr;
67 
68   // Wrapper to query additional information for instructions like metadata or
69   // keywords like nsw, which provides conservative results if those cannot
70   // be safely used.
71   const InstrInfoQuery IIQ;
72 
73   /// Controls whether simplifications are allowed to constrain the range of
74   /// possible values for uses of undef. If it is false, simplifications are not
75   /// allowed to assume a particular value for a use of undef for example.
76   bool CanUseUndef = true;
77 
78   SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr)
DLSimplifyQuery79       : DL(DL), CxtI(CXTI) {}
80 
81   SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI,
82                 const DominatorTree *DT = nullptr,
83                 AssumptionCache *AC = nullptr,
84                 const Instruction *CXTI = nullptr, bool UseInstrInfo = true,
85                 bool CanUseUndef = true, const DomConditionCache *DC = nullptr)
DLSimplifyQuery86       : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI), DC(DC), IIQ(UseInstrInfo),
87         CanUseUndef(CanUseUndef) {}
88 
89   SimplifyQuery(const DataLayout &DL, const DominatorTree *DT,
90                 AssumptionCache *AC = nullptr,
91                 const Instruction *CXTI = nullptr, bool UseInstrInfo = true,
92                 bool CanUseUndef = true)
DLSimplifyQuery93       : DL(DL), DT(DT), AC(AC), CxtI(CXTI), IIQ(UseInstrInfo),
94         CanUseUndef(CanUseUndef) {}
95 
getWithInstructionSimplifyQuery96   SimplifyQuery getWithInstruction(const Instruction *I) const {
97     SimplifyQuery Copy(*this);
98     Copy.CxtI = I;
99     return Copy;
100   }
getWithoutUndefSimplifyQuery101   SimplifyQuery getWithoutUndef() const {
102     SimplifyQuery Copy(*this);
103     Copy.CanUseUndef = false;
104     return Copy;
105   }
106 
107   /// If CanUseUndef is true, returns whether \p V is undef.
108   /// Otherwise always return false.
isUndefValueSimplifyQuery109   bool isUndefValue(Value *V) const {
110     if (!CanUseUndef)
111       return false;
112 
113     using namespace PatternMatch;
114     return match(V, m_Undef());
115   }
116 };
117 
118 } // end namespace llvm
119 
120 #endif
121