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