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 //===--------------------------------------------------------------------===//
128 // Memory Instructions
129 //===--------------------------------------------------------------------===//
131 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
132 ArrayRef
<Constant
*> IdxList
) const {
133 return Fold(ConstantExpr::getGetElementPtr(Ty
, C
, IdxList
));
135 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
, Constant
*Idx
) const {
136 // This form of the function only exists to avoid ambiguous overload
137 // warnings about whether to convert Idx to ArrayRef<Constant *> or
138 // ArrayRef<Value *>.
139 return Fold(ConstantExpr::getGetElementPtr(Ty
, C
, Idx
));
141 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
142 ArrayRef
<Value
*> IdxList
) const {
143 return Fold(ConstantExpr::getGetElementPtr(Ty
, C
, IdxList
));
146 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
147 ArrayRef
<Constant
*> IdxList
) const {
148 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, IdxList
));
150 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
151 Constant
*Idx
) const {
152 // This form of the function only exists to avoid ambiguous overload
153 // warnings about whether to convert Idx to ArrayRef<Constant *> or
154 // ArrayRef<Value *>.
155 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, Idx
));
157 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
158 ArrayRef
<Value
*> IdxList
) const {
159 return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, IdxList
));
162 //===--------------------------------------------------------------------===//
163 // Cast/Conversion Operators
164 //===--------------------------------------------------------------------===//
166 Constant
*CreateCast(Instruction::CastOps Op
, Constant
*C
,
167 Type
*DestTy
) const {
168 if (C
->getType() == DestTy
)
169 return C
; // avoid calling Fold
170 return Fold(ConstantExpr::getCast(Op
, C
, DestTy
));
172 Constant
*CreateIntCast(Constant
*C
, Type
*DestTy
,
173 bool isSigned
) const {
174 if (C
->getType() == DestTy
)
175 return C
; // avoid calling Fold
176 return Fold(ConstantExpr::getIntegerCast(C
, DestTy
, isSigned
));
178 Constant
*CreatePointerCast(Constant
*C
, Type
*DestTy
) const {
179 if (C
->getType() == DestTy
)
180 return C
; // avoid calling Fold
181 return Fold(ConstantExpr::getPointerCast(C
, DestTy
));
183 Constant
*CreateFPCast(Constant
*C
, Type
*DestTy
) const {
184 if (C
->getType() == DestTy
)
185 return C
; // avoid calling Fold
186 return Fold(ConstantExpr::getFPCast(C
, DestTy
));
188 Constant
*CreateBitCast(Constant
*C
, Type
*DestTy
) const {
189 return CreateCast(Instruction::BitCast
, C
, DestTy
);
191 Constant
*CreateIntToPtr(Constant
*C
, Type
*DestTy
) const {
192 return CreateCast(Instruction::IntToPtr
, C
, DestTy
);
194 Constant
*CreatePtrToInt(Constant
*C
, Type
*DestTy
) const {
195 return CreateCast(Instruction::PtrToInt
, C
, DestTy
);
197 Constant
*CreateZExtOrBitCast(Constant
*C
, Type
*DestTy
) const {
198 if (C
->getType() == DestTy
)
199 return C
; // avoid calling Fold
200 return Fold(ConstantExpr::getZExtOrBitCast(C
, DestTy
));
202 Constant
*CreateSExtOrBitCast(Constant
*C
, Type
*DestTy
) const {
203 if (C
->getType() == DestTy
)
204 return C
; // avoid calling Fold
205 return Fold(ConstantExpr::getSExtOrBitCast(C
, DestTy
));
207 Constant
*CreateTruncOrBitCast(Constant
*C
, Type
*DestTy
) const {
208 if (C
->getType() == DestTy
)
209 return C
; // avoid calling Fold
210 return Fold(ConstantExpr::getTruncOrBitCast(C
, DestTy
));
213 Constant
*CreatePointerBitCastOrAddrSpaceCast(Constant
*C
,
214 Type
*DestTy
) const {
215 if (C
->getType() == DestTy
)
216 return C
; // avoid calling Fold
217 return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C
, DestTy
));
220 //===--------------------------------------------------------------------===//
221 // Compare Instructions
222 //===--------------------------------------------------------------------===//
224 Constant
*CreateICmp(CmpInst::Predicate P
, Constant
*LHS
,
225 Constant
*RHS
) const {
226 return Fold(ConstantExpr::getCompare(P
, LHS
, RHS
));
228 Constant
*CreateFCmp(CmpInst::Predicate P
, Constant
*LHS
,
229 Constant
*RHS
) const {
230 return Fold(ConstantExpr::getCompare(P
, LHS
, RHS
));
233 //===--------------------------------------------------------------------===//
234 // Other Instructions
235 //===--------------------------------------------------------------------===//
237 Constant
*CreateSelect(Constant
*C
, Constant
*True
, Constant
*False
) const {
238 return Fold(ConstantExpr::getSelect(C
, True
, False
));
241 Constant
*CreateExtractElement(Constant
*Vec
, Constant
*Idx
) const {
242 return Fold(ConstantExpr::getExtractElement(Vec
, Idx
));
245 Constant
*CreateInsertElement(Constant
*Vec
, Constant
*NewElt
,
246 Constant
*Idx
) const {
247 return Fold(ConstantExpr::getInsertElement(Vec
, NewElt
, Idx
));
250 Constant
*CreateShuffleVector(Constant
*V1
, Constant
*V2
,
251 Constant
*Mask
) const {
252 return Fold(ConstantExpr::getShuffleVector(V1
, V2
, Mask
));
255 Constant
*CreateExtractValue(Constant
*Agg
,
256 ArrayRef
<unsigned> IdxList
) const {
257 return Fold(ConstantExpr::getExtractValue(Agg
, IdxList
));
260 Constant
*CreateInsertValue(Constant
*Agg
, Constant
*Val
,
261 ArrayRef
<unsigned> IdxList
) const {
262 return Fold(ConstantExpr::getInsertValue(Agg
, Val
, IdxList
));