1 //====- TargetFolder.h - Constant folding helper ---------------*- C++ -*-====//
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
7 //===----------------------------------------------------------------------===//
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.
16 //===----------------------------------------------------------------------===//
18 #ifndef LLVM_ANALYSIS_TARGETFOLDER_H
19 #define LLVM_ANALYSIS_TARGETFOLDER_H
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/Analysis/ConstantFolding.h"
23 #include "llvm/IR/Constants.h"
24 #include "llvm/IR/InstrTypes.h"
30 /// TargetFolder - Create constants with target dependent folding.
34 /// Fold - Fold the constant using target specific information.
35 Constant
*Fold(Constant
*C
) const {
36 if (Constant
*CF
= ConstantFoldConstant(C
, DL
))
42 explicit TargetFolder(const DataLayout
&DL
) : DL(DL
) {}
44 //===--------------------------------------------------------------------===//
46 //===--------------------------------------------------------------------===//
48 Constant
*CreateAdd(Constant
*LHS
, Constant
*RHS
,
49 bool HasNUW
= false, bool HasNSW
= false) const {
50 return Fold(ConstantExpr::getAdd(LHS
, RHS
, HasNUW
, HasNSW
));
52 Constant
*CreateFAdd(Constant
*LHS
, Constant
*RHS
) const {
53 return Fold(ConstantExpr::getFAdd(LHS
, RHS
));
55 Constant
*CreateSub(Constant
*LHS
, Constant
*RHS
,
56 bool HasNUW
= false, bool HasNSW
= false) const {
57 return Fold(ConstantExpr::getSub(LHS
, RHS
, HasNUW
, HasNSW
));
59 Constant
*CreateFSub(Constant
*LHS
, Constant
*RHS
) const {
60 return Fold(ConstantExpr::getFSub(LHS
, RHS
));
62 Constant
*CreateMul(Constant
*LHS
, Constant
*RHS
,
63 bool HasNUW
= false, bool HasNSW
= false) const {
64 return Fold(ConstantExpr::getMul(LHS
, RHS
, HasNUW
, HasNSW
));
66 Constant
*CreateFMul(Constant
*LHS
, Constant
*RHS
) const {
67 return Fold(ConstantExpr::getFMul(LHS
, RHS
));
69 Constant
*CreateUDiv(Constant
*LHS
, Constant
*RHS
, bool isExact
= false)const{
70 return Fold(ConstantExpr::getUDiv(LHS
, RHS
, isExact
));
72 Constant
*CreateSDiv(Constant
*LHS
, Constant
*RHS
, bool isExact
= false)const{
73 return Fold(ConstantExpr::getSDiv(LHS
, RHS
, isExact
));
75 Constant
*CreateFDiv(Constant
*LHS
, Constant
*RHS
) const {
76 return Fold(ConstantExpr::getFDiv(LHS
, RHS
));
78 Constant
*CreateURem(Constant
*LHS
, Constant
*RHS
) const {
79 return Fold(ConstantExpr::getURem(LHS
, RHS
));
81 Constant
*CreateSRem(Constant
*LHS
, Constant
*RHS
) const {
82 return Fold(ConstantExpr::getSRem(LHS
, RHS
));
84 Constant
*CreateFRem(Constant
*LHS
, Constant
*RHS
) const {
85 return Fold(ConstantExpr::getFRem(LHS
, RHS
));
87 Constant
*CreateShl(Constant
*LHS
, Constant
*RHS
,
88 bool HasNUW
= false, bool HasNSW
= false) const {
89 return Fold(ConstantExpr::getShl(LHS
, RHS
, HasNUW
, HasNSW
));
91 Constant
*CreateLShr(Constant
*LHS
, Constant
*RHS
, bool isExact
= false)const{
92 return Fold(ConstantExpr::getLShr(LHS
, RHS
, isExact
));
94 Constant
*CreateAShr(Constant
*LHS
, Constant
*RHS
, bool isExact
= false)const{
95 return Fold(ConstantExpr::getAShr(LHS
, RHS
, isExact
));
97 Constant
*CreateAnd(Constant
*LHS
, Constant
*RHS
) const {
98 return Fold(ConstantExpr::getAnd(LHS
, RHS
));
100 Constant
*CreateOr(Constant
*LHS
, Constant
*RHS
) const {
101 return Fold(ConstantExpr::getOr(LHS
, RHS
));
103 Constant
*CreateXor(Constant
*LHS
, Constant
*RHS
) const {
104 return Fold(ConstantExpr::getXor(LHS
, RHS
));
107 Constant
*CreateBinOp(Instruction::BinaryOps Opc
,
108 Constant
*LHS
, Constant
*RHS
) const {
109 return Fold(ConstantExpr::get(Opc
, LHS
, RHS
));
112 //===--------------------------------------------------------------------===//
114 //===--------------------------------------------------------------------===//
116 Constant
*CreateNeg(Constant
*C
,
117 bool HasNUW
= false, bool HasNSW
= false) const {
118 return Fold(ConstantExpr::getNeg(C
, HasNUW
, HasNSW
));
120 Constant
*CreateFNeg(Constant
*C
) const {
121 return Fold(ConstantExpr::getFNeg(C
));
123 Constant
*CreateNot(Constant
*C
) const {
124 return Fold(ConstantExpr::getNot(C
));
127 Constant
*CreateUnOp(Instruction::UnaryOps Opc
, Constant
*C
) const {
128 return Fold(ConstantExpr::get(Opc
, C
));
131 //===--------------------------------------------------------------------===//
132 // Memory Instructions
133 //===--------------------------------------------------------------------===//
135 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
136 ArrayRef
<Constant
*> IdxList
) const {
137 return Fold(ConstantExpr::getGetElementPtr(Ty
, C
, IdxList
));
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
));
145 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
146 ArrayRef
<Value
*> IdxList
) const {
147 return Fold(ConstantExpr::getGetElementPtr(Ty
, C
, IdxList
));
150 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
151 ArrayRef
<Constant
*> IdxList
) const {
152 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, IdxList
));
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
));
161 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
162 ArrayRef
<Value
*> IdxList
) const {
163 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, IdxList
));
166 //===--------------------------------------------------------------------===//
167 // Cast/Conversion Operators
168 //===--------------------------------------------------------------------===//
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
));
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
));
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
));
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
));
192 Constant
*CreateBitCast(Constant
*C
, Type
*DestTy
) const {
193 return CreateCast(Instruction::BitCast
, C
, DestTy
);
195 Constant
*CreateIntToPtr(Constant
*C
, Type
*DestTy
) const {
196 return CreateCast(Instruction::IntToPtr
, C
, DestTy
);
198 Constant
*CreatePtrToInt(Constant
*C
, Type
*DestTy
) const {
199 return CreateCast(Instruction::PtrToInt
, C
, DestTy
);
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
));
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
));
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
));
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
));
224 //===--------------------------------------------------------------------===//
225 // Compare Instructions
226 //===--------------------------------------------------------------------===//
228 Constant
*CreateICmp(CmpInst::Predicate P
, Constant
*LHS
,
229 Constant
*RHS
) const {
230 return Fold(ConstantExpr::getCompare(P
, LHS
, RHS
));
232 Constant
*CreateFCmp(CmpInst::Predicate P
, Constant
*LHS
,
233 Constant
*RHS
) const {
234 return Fold(ConstantExpr::getCompare(P
, LHS
, RHS
));
237 //===--------------------------------------------------------------------===//
238 // Other Instructions
239 //===--------------------------------------------------------------------===//
241 Constant
*CreateSelect(Constant
*C
, Constant
*True
, Constant
*False
) const {
242 return Fold(ConstantExpr::getSelect(C
, True
, False
));
245 Constant
*CreateExtractElement(Constant
*Vec
, Constant
*Idx
) const {
246 return Fold(ConstantExpr::getExtractElement(Vec
, Idx
));
249 Constant
*CreateInsertElement(Constant
*Vec
, Constant
*NewElt
,
250 Constant
*Idx
) const {
251 return Fold(ConstantExpr::getInsertElement(Vec
, NewElt
, Idx
));
254 Constant
*CreateShuffleVector(Constant
*V1
, Constant
*V2
,
255 Constant
*Mask
) const {
256 return Fold(ConstantExpr::getShuffleVector(V1
, V2
, Mask
));
259 Constant
*CreateExtractValue(Constant
*Agg
,
260 ArrayRef
<unsigned> IdxList
) const {
261 return Fold(ConstantExpr::getExtractValue(Agg
, IdxList
));
264 Constant
*CreateInsertValue(Constant
*Agg
, Constant
*Val
,
265 ArrayRef
<unsigned> IdxList
) const {
266 return Fold(ConstantExpr::getInsertValue(Agg
, Val
, IdxList
));