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