]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/Analysis/TargetFolder.h
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / Analysis / TargetFolder.h
1 //====- TargetFolder.h - Constant folding helper ---------------*- 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 // This file defines the TargetFolder class, a helper for IRBuilder.
10 // It provides IRBuilder with a set of methods for creating constants with
11 // target dependent folding, in addition to the same target-independent
12 // folding that the ConstantFolder class provides.  For general constant
13 // creation and folding, use ConstantExpr and the routines in
14 // llvm/Analysis/ConstantFolding.h.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_ANALYSIS_TARGETFOLDER_H
19 #define LLVM_ANALYSIS_TARGETFOLDER_H
20
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/Analysis/ConstantFolding.h"
23 #include "llvm/IR/Constants.h"
24 #include "llvm/IR/InstrTypes.h"
25
26 namespace llvm {
27
28 class DataLayout;
29
30 /// TargetFolder - Create constants with target dependent folding.
31 class TargetFolder {
32   const DataLayout &DL;
33
34   /// Fold - Fold the constant using target specific information.
35   Constant *Fold(Constant *C) const {
36     if (Constant *CF = ConstantFoldConstant(C, DL))
37       return CF;
38     return C;
39   }
40
41 public:
42   explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
43
44   //===--------------------------------------------------------------------===//
45   // Binary Operators
46   //===--------------------------------------------------------------------===//
47
48   Constant *CreateAdd(Constant *LHS, Constant *RHS,
49                       bool HasNUW = false, bool HasNSW = false) const {
50     return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
51   }
52   Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
53     return Fold(ConstantExpr::getFAdd(LHS, RHS));
54   }
55   Constant *CreateSub(Constant *LHS, Constant *RHS,
56                       bool HasNUW = false, bool HasNSW = false) const {
57     return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
58   }
59   Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
60     return Fold(ConstantExpr::getFSub(LHS, RHS));
61   }
62   Constant *CreateMul(Constant *LHS, Constant *RHS,
63                       bool HasNUW = false, bool HasNSW = false) const {
64     return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
65   }
66   Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
67     return Fold(ConstantExpr::getFMul(LHS, RHS));
68   }
69   Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
70     return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
71   }
72   Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
73     return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
74   }
75   Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
76     return Fold(ConstantExpr::getFDiv(LHS, RHS));
77   }
78   Constant *CreateURem(Constant *LHS, Constant *RHS) const {
79     return Fold(ConstantExpr::getURem(LHS, RHS));
80   }
81   Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
82     return Fold(ConstantExpr::getSRem(LHS, RHS));
83   }
84   Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
85     return Fold(ConstantExpr::getFRem(LHS, RHS));
86   }
87   Constant *CreateShl(Constant *LHS, Constant *RHS,
88                       bool HasNUW = false, bool HasNSW = false) const {
89     return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
90   }
91   Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
92     return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
93   }
94   Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
95     return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
96   }
97   Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
98     return Fold(ConstantExpr::getAnd(LHS, RHS));
99   }
100   Constant *CreateOr(Constant *LHS, Constant *RHS) const {
101     return Fold(ConstantExpr::getOr(LHS, RHS));
102   }
103   Constant *CreateXor(Constant *LHS, Constant *RHS) const {
104     return Fold(ConstantExpr::getXor(LHS, RHS));
105   }
106
107   Constant *CreateBinOp(Instruction::BinaryOps Opc,
108                         Constant *LHS, Constant *RHS) const {
109     return Fold(ConstantExpr::get(Opc, LHS, RHS));
110   }
111
112   //===--------------------------------------------------------------------===//
113   // Unary Operators
114   //===--------------------------------------------------------------------===//
115
116   Constant *CreateNeg(Constant *C,
117                       bool HasNUW = false, bool HasNSW = false) const {
118     return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
119   }
120   Constant *CreateFNeg(Constant *C) const {
121     return Fold(ConstantExpr::getFNeg(C));
122   }
123   Constant *CreateNot(Constant *C) const {
124     return Fold(ConstantExpr::getNot(C));
125   }
126
127   Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
128     return Fold(ConstantExpr::get(Opc, C));
129   }
130
131   //===--------------------------------------------------------------------===//
132   // Memory Instructions
133   //===--------------------------------------------------------------------===//
134
135   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
136                                 ArrayRef<Constant *> IdxList) const {
137     return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
138   }
139   Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
140     // This form of the function only exists to avoid ambiguous overload
141     // warnings about whether to convert Idx to ArrayRef<Constant *> or
142     // ArrayRef<Value *>.
143     return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
144   }
145   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
146                                 ArrayRef<Value *> IdxList) const {
147     return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
148   }
149
150   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
151                                         ArrayRef<Constant *> IdxList) const {
152     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
153   }
154   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
155                                         Constant *Idx) const {
156     // This form of the function only exists to avoid ambiguous overload
157     // warnings about whether to convert Idx to ArrayRef<Constant *> or
158     // ArrayRef<Value *>.
159     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
160   }
161   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
162                                         ArrayRef<Value *> IdxList) const {
163     return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
164   }
165
166   //===--------------------------------------------------------------------===//
167   // Cast/Conversion Operators
168   //===--------------------------------------------------------------------===//
169
170   Constant *CreateCast(Instruction::CastOps Op, Constant *C,
171                        Type *DestTy) const {
172     if (C->getType() == DestTy)
173       return C; // avoid calling Fold
174     return Fold(ConstantExpr::getCast(Op, C, DestTy));
175   }
176   Constant *CreateIntCast(Constant *C, Type *DestTy,
177                           bool isSigned) const {
178     if (C->getType() == DestTy)
179       return C; // avoid calling Fold
180     return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
181   }
182   Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
183     if (C->getType() == DestTy)
184       return C; // avoid calling Fold
185     return Fold(ConstantExpr::getPointerCast(C, DestTy));
186   }
187   Constant *CreateFPCast(Constant *C, Type *DestTy) const {
188     if (C->getType() == DestTy)
189       return C; // avoid calling Fold
190     return Fold(ConstantExpr::getFPCast(C, DestTy));
191   }
192   Constant *CreateBitCast(Constant *C, Type *DestTy) const {
193     return CreateCast(Instruction::BitCast, C, DestTy);
194   }
195   Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
196     return CreateCast(Instruction::IntToPtr, C, DestTy);
197   }
198   Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
199     return CreateCast(Instruction::PtrToInt, C, DestTy);
200   }
201   Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
202     if (C->getType() == DestTy)
203       return C; // avoid calling Fold
204     return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
205   }
206   Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
207     if (C->getType() == DestTy)
208       return C; // avoid calling Fold
209     return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
210   }
211   Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
212     if (C->getType() == DestTy)
213       return C; // avoid calling Fold
214     return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
215   }
216
217   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
218                                                 Type *DestTy) const {
219     if (C->getType() == DestTy)
220       return C; // avoid calling Fold
221     return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
222   }
223
224   //===--------------------------------------------------------------------===//
225   // Compare Instructions
226   //===--------------------------------------------------------------------===//
227
228   Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
229                        Constant *RHS) const {
230     return Fold(ConstantExpr::getCompare(P, LHS, RHS));
231   }
232   Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
233                        Constant *RHS) const {
234     return Fold(ConstantExpr::getCompare(P, LHS, RHS));
235   }
236
237   //===--------------------------------------------------------------------===//
238   // Other Instructions
239   //===--------------------------------------------------------------------===//
240
241   Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
242     return Fold(ConstantExpr::getSelect(C, True, False));
243   }
244
245   Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
246     return Fold(ConstantExpr::getExtractElement(Vec, Idx));
247   }
248
249   Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
250                                 Constant *Idx) const {
251     return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
252   }
253
254   Constant *CreateShuffleVector(Constant *V1, Constant *V2,
255                                 Constant *Mask) const {
256     return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
257   }
258
259   Constant *CreateExtractValue(Constant *Agg,
260                                ArrayRef<unsigned> IdxList) const {
261     return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
262   }
263
264   Constant *CreateInsertValue(Constant *Agg, Constant *Val,
265                               ArrayRef<unsigned> IdxList) const {
266     return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
267   }
268 };
269
270 }
271
272 #endif