blob: da4a18e3c181a60c7ec04eb4ae403a76c31cf8ed [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- ConstantFolder.h - Constant folding helper ---------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020023#include "llvm/IR/IRBuilderFolder.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010024
25namespace llvm {
26
27/// ConstantFolder - Create constants with minimum, target independent, folding.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020028class ConstantFolder final : public IRBuilderFolder {
29 virtual void anchor();
30
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010031public:
32 explicit ConstantFolder() = default;
33
34 //===--------------------------------------------------------------------===//
35 // Binary Operators
36 //===--------------------------------------------------------------------===//
37
38 Constant *CreateAdd(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020039 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010040 return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
41 }
42
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020043 Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010044 return ConstantExpr::getFAdd(LHS, RHS);
45 }
46
47 Constant *CreateSub(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020048 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010049 return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
50 }
51
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020052 Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010053 return ConstantExpr::getFSub(LHS, RHS);
54 }
55
56 Constant *CreateMul(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020057 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010058 return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
59 }
60
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020061 Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010062 return ConstantExpr::getFMul(LHS, RHS);
63 }
64
65 Constant *CreateUDiv(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020066 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010067 return ConstantExpr::getUDiv(LHS, RHS, isExact);
68 }
69
70 Constant *CreateSDiv(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020071 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010072 return ConstantExpr::getSDiv(LHS, RHS, isExact);
73 }
74
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020075 Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010076 return ConstantExpr::getFDiv(LHS, RHS);
77 }
78
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020079 Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010080 return ConstantExpr::getURem(LHS, RHS);
81 }
82
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020083 Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010084 return ConstantExpr::getSRem(LHS, RHS);
85 }
86
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020087 Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010088 return ConstantExpr::getFRem(LHS, RHS);
89 }
90
91 Constant *CreateShl(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020092 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010093 return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
94 }
95
96 Constant *CreateLShr(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020097 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010098 return ConstantExpr::getLShr(LHS, RHS, isExact);
99 }
100
101 Constant *CreateAShr(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200102 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100103 return ConstantExpr::getAShr(LHS, RHS, isExact);
104 }
105
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200106 Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100107 return ConstantExpr::getAnd(LHS, RHS);
108 }
109
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200110 Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100111 return ConstantExpr::getOr(LHS, RHS);
112 }
113
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200114 Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100115 return ConstantExpr::getXor(LHS, RHS);
116 }
117
118 Constant *CreateBinOp(Instruction::BinaryOps Opc,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200119 Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100120 return ConstantExpr::get(Opc, LHS, RHS);
121 }
122
123 //===--------------------------------------------------------------------===//
124 // Unary Operators
125 //===--------------------------------------------------------------------===//
126
127 Constant *CreateNeg(Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200128 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100129 return ConstantExpr::getNeg(C, HasNUW, HasNSW);
130 }
131
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200132 Constant *CreateFNeg(Constant *C) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100133 return ConstantExpr::getFNeg(C);
134 }
135
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200136 Constant *CreateNot(Constant *C) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100137 return ConstantExpr::getNot(C);
138 }
139
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200140 Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100141 return ConstantExpr::get(Opc, C);
142 }
143
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100144 //===--------------------------------------------------------------------===//
145 // Memory Instructions
146 //===--------------------------------------------------------------------===//
147
148 Constant *CreateGetElementPtr(Type *Ty, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200149 ArrayRef<Constant *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100150 return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
151 }
152
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200153 Constant *CreateGetElementPtr(Type *Ty, Constant *C,
154 Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100155 // 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,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200162 ArrayRef<Value *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100163 return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
164 }
165
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200166 Constant *CreateInBoundsGetElementPtr(
167 Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100168 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
169 }
170
171 Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200172 Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100173 // 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
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200179 Constant *CreateInBoundsGetElementPtr(
180 Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100181 return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
182 }
183
184 //===--------------------------------------------------------------------===//
185 // Cast/Conversion Operators
186 //===--------------------------------------------------------------------===//
187
188 Constant *CreateCast(Instruction::CastOps Op, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200189 Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100190 return ConstantExpr::getCast(Op, C, DestTy);
191 }
192
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200193 Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100194 return ConstantExpr::getPointerCast(C, DestTy);
195 }
196
197 Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200198 Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100199 return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
200 }
201
202 Constant *CreateIntCast(Constant *C, Type *DestTy,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200203 bool isSigned) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100204 return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
205 }
206
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200207 Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100208 return ConstantExpr::getFPCast(C, DestTy);
209 }
210
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200211 Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100212 return CreateCast(Instruction::BitCast, C, DestTy);
213 }
214
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200215 Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100216 return CreateCast(Instruction::IntToPtr, C, DestTy);
217 }
218
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200219 Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100220 return CreateCast(Instruction::PtrToInt, C, DestTy);
221 }
222
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200223 Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100224 return ConstantExpr::getZExtOrBitCast(C, DestTy);
225 }
226
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200227 Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100228 return ConstantExpr::getSExtOrBitCast(C, DestTy);
229 }
230
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200231 Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100232 return ConstantExpr::getTruncOrBitCast(C, DestTy);
233 }
234
235 //===--------------------------------------------------------------------===//
236 // Compare Instructions
237 //===--------------------------------------------------------------------===//
238
239 Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200240 Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100241 return ConstantExpr::getCompare(P, LHS, RHS);
242 }
243
244 Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200245 Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100246 return ConstantExpr::getCompare(P, LHS, RHS);
247 }
248
249 //===--------------------------------------------------------------------===//
250 // Other Instructions
251 //===--------------------------------------------------------------------===//
252
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200253 Constant *CreateSelect(Constant *C, Constant *True,
254 Constant *False) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100255 return ConstantExpr::getSelect(C, True, False);
256 }
257
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200258 Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100259 return ConstantExpr::getExtractElement(Vec, Idx);
260 }
261
262 Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200263 Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100264 return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
265 }
266
267 Constant *CreateShuffleVector(Constant *V1, Constant *V2,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200268 ArrayRef<int> Mask) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100269 return ConstantExpr::getShuffleVector(V1, V2, Mask);
270 }
271
272 Constant *CreateExtractValue(Constant *Agg,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200273 ArrayRef<unsigned> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100274 return ConstantExpr::getExtractValue(Agg, IdxList);
275 }
276
277 Constant *CreateInsertValue(Constant *Agg, Constant *Val,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200278 ArrayRef<unsigned> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100279 return ConstantExpr::getInsertValue(Agg, Val, IdxList);
280 }
281};
282
283} // end namespace llvm
284
285#endif // LLVM_IR_CONSTANTFOLDER_H