blob: b23316ac3d9b6cb9ad935c9cad3efe13f8a06ad4 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//====- TargetFolder.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 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"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020025#include "llvm/IR/IRBuilderFolder.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010026
27namespace llvm {
28
29class DataLayout;
30
31/// TargetFolder - Create constants with target dependent folding.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020032class TargetFolder final : public IRBuilderFolder {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010033 const DataLayout &DL;
34
35 /// Fold - Fold the constant using target specific information.
36 Constant *Fold(Constant *C) const {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020037 return ConstantFoldConstant(C, DL);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010038 }
39
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020040 virtual void anchor();
41
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010042public:
43 explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
44
45 //===--------------------------------------------------------------------===//
46 // Binary Operators
47 //===--------------------------------------------------------------------===//
48
49 Constant *CreateAdd(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020050 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010051 return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
52 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020053 Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010054 return Fold(ConstantExpr::getFAdd(LHS, RHS));
55 }
56 Constant *CreateSub(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 Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
59 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020060 Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010061 return Fold(ConstantExpr::getFSub(LHS, RHS));
62 }
63 Constant *CreateMul(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020064 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065 return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
66 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020067 Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010068 return Fold(ConstantExpr::getFMul(LHS, RHS));
69 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020070 Constant *CreateUDiv(Constant *LHS, Constant *RHS,
71 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010072 return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
73 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020074 Constant *CreateSDiv(Constant *LHS, Constant *RHS,
75 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010076 return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
77 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020078 Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010079 return Fold(ConstantExpr::getFDiv(LHS, RHS));
80 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020081 Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010082 return Fold(ConstantExpr::getURem(LHS, RHS));
83 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020084 Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010085 return Fold(ConstantExpr::getSRem(LHS, RHS));
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 Fold(ConstantExpr::getFRem(LHS, RHS));
89 }
90 Constant *CreateShl(Constant *LHS, Constant *RHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020091 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010092 return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
93 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020094 Constant *CreateLShr(Constant *LHS, Constant *RHS,
95 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010096 return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
97 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020098 Constant *CreateAShr(Constant *LHS, Constant *RHS,
99 bool isExact = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100100 return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
101 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200102 Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100103 return Fold(ConstantExpr::getAnd(LHS, RHS));
104 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200105 Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100106 return Fold(ConstantExpr::getOr(LHS, RHS));
107 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200108 Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100109 return Fold(ConstantExpr::getXor(LHS, RHS));
110 }
111
112 Constant *CreateBinOp(Instruction::BinaryOps Opc,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200113 Constant *LHS, Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100114 return Fold(ConstantExpr::get(Opc, LHS, RHS));
115 }
116
117 //===--------------------------------------------------------------------===//
118 // Unary Operators
119 //===--------------------------------------------------------------------===//
120
121 Constant *CreateNeg(Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200122 bool HasNUW = false, bool HasNSW = false) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100123 return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
124 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200125 Constant *CreateFNeg(Constant *C) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126 return Fold(ConstantExpr::getFNeg(C));
127 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200128 Constant *CreateNot(Constant *C) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100129 return Fold(ConstantExpr::getNot(C));
130 }
131
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200132 Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100133 return Fold(ConstantExpr::get(Opc, C));
134 }
135
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100136 //===--------------------------------------------------------------------===//
137 // Memory Instructions
138 //===--------------------------------------------------------------------===//
139
140 Constant *CreateGetElementPtr(Type *Ty, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200141 ArrayRef<Constant *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100142 return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
143 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200144 Constant *CreateGetElementPtr(Type *Ty, Constant *C,
145 Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100146 // This form of the function only exists to avoid ambiguous overload
147 // warnings about whether to convert Idx to ArrayRef<Constant *> or
148 // ArrayRef<Value *>.
149 return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
150 }
151 Constant *CreateGetElementPtr(Type *Ty, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200152 ArrayRef<Value *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100153 return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
154 }
155
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200156 Constant *CreateInBoundsGetElementPtr(
157 Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100158 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
159 }
160 Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200161 Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100162 // This form of the function only exists to avoid ambiguous overload
163 // warnings about whether to convert Idx to ArrayRef<Constant *> or
164 // ArrayRef<Value *>.
165 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
166 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200167 Constant *CreateInBoundsGetElementPtr(
168 Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100169 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
170 }
171
172 //===--------------------------------------------------------------------===//
173 // Cast/Conversion Operators
174 //===--------------------------------------------------------------------===//
175
176 Constant *CreateCast(Instruction::CastOps Op, Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200177 Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100178 if (C->getType() == DestTy)
179 return C; // avoid calling Fold
180 return Fold(ConstantExpr::getCast(Op, C, DestTy));
181 }
182 Constant *CreateIntCast(Constant *C, Type *DestTy,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200183 bool isSigned) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100184 if (C->getType() == DestTy)
185 return C; // avoid calling Fold
186 return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
187 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200188 Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100189 if (C->getType() == DestTy)
190 return C; // avoid calling Fold
191 return Fold(ConstantExpr::getPointerCast(C, DestTy));
192 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200193 Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100194 if (C->getType() == DestTy)
195 return C; // avoid calling Fold
196 return Fold(ConstantExpr::getFPCast(C, DestTy));
197 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200198 Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100199 return CreateCast(Instruction::BitCast, C, DestTy);
200 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200201 Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100202 return CreateCast(Instruction::IntToPtr, C, DestTy);
203 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200204 Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100205 return CreateCast(Instruction::PtrToInt, C, DestTy);
206 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200207 Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100208 if (C->getType() == DestTy)
209 return C; // avoid calling Fold
210 return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
211 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200212 Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100213 if (C->getType() == DestTy)
214 return C; // avoid calling Fold
215 return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
216 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200217 Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100218 if (C->getType() == DestTy)
219 return C; // avoid calling Fold
220 return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
221 }
222
223 Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200224 Type *DestTy) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100225 if (C->getType() == DestTy)
226 return C; // avoid calling Fold
227 return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
228 }
229
230 //===--------------------------------------------------------------------===//
231 // Compare Instructions
232 //===--------------------------------------------------------------------===//
233
234 Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200235 Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100236 return Fold(ConstantExpr::getCompare(P, LHS, RHS));
237 }
238 Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200239 Constant *RHS) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100240 return Fold(ConstantExpr::getCompare(P, LHS, RHS));
241 }
242
243 //===--------------------------------------------------------------------===//
244 // Other Instructions
245 //===--------------------------------------------------------------------===//
246
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200247 Constant *CreateSelect(Constant *C, Constant *True,
248 Constant *False) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100249 return Fold(ConstantExpr::getSelect(C, True, False));
250 }
251
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200252 Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100253 return Fold(ConstantExpr::getExtractElement(Vec, Idx));
254 }
255
256 Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200257 Constant *Idx) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100258 return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
259 }
260
261 Constant *CreateShuffleVector(Constant *V1, Constant *V2,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200262 ArrayRef<int> Mask) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100263 return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
264 }
265
266 Constant *CreateExtractValue(Constant *Agg,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200267 ArrayRef<unsigned> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100268 return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
269 }
270
271 Constant *CreateInsertValue(Constant *Agg, Constant *Val,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200272 ArrayRef<unsigned> IdxList) const override {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100273 return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
274 }
275};
276
277}
278
279#endif