1 //===- NoFolder.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 NoFolder class, a helper for IRBuilder. It provides
10 // IRBuilder with a set of methods for creating unfolded constants. This is
11 // useful for learners trying to understand how LLVM IR works, and who don't
12 // want details to be hidden by the constant folder. For general constant
13 // creation and folding, use ConstantExpr and the routines in
14 // llvm/Analysis/ConstantFolding.h.
16 // Note: since it is not actually possible to create unfolded constants, this
17 // class returns instructions rather than constants.
19 //===----------------------------------------------------------------------===//
21 #ifndef LLVM_IR_NOFOLDER_H
22 #define LLVM_IR_NOFOLDER_H
24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/InstrTypes.h"
27 #include "llvm/IR/Instruction.h"
28 #include "llvm/IR/Instructions.h"
32 /// NoFolder - Create "constants" (actually, instructions) with no folding.
35 explicit NoFolder() = default;
37 //===--------------------------------------------------------------------===//
39 //===--------------------------------------------------------------------===//
41 Instruction
*CreateAdd(Constant
*LHS
, Constant
*RHS
,
42 bool HasNUW
= false, bool HasNSW
= false) const {
43 BinaryOperator
*BO
= BinaryOperator::CreateAdd(LHS
, RHS
);
44 if (HasNUW
) BO
->setHasNoUnsignedWrap();
45 if (HasNSW
) BO
->setHasNoSignedWrap();
49 Instruction
*CreateNSWAdd(Constant
*LHS
, Constant
*RHS
) const {
50 return BinaryOperator::CreateNSWAdd(LHS
, RHS
);
53 Instruction
*CreateNUWAdd(Constant
*LHS
, Constant
*RHS
) const {
54 return BinaryOperator::CreateNUWAdd(LHS
, RHS
);
57 Instruction
*CreateFAdd(Constant
*LHS
, Constant
*RHS
) const {
58 return BinaryOperator::CreateFAdd(LHS
, RHS
);
61 Instruction
*CreateSub(Constant
*LHS
, Constant
*RHS
,
62 bool HasNUW
= false, bool HasNSW
= false) const {
63 BinaryOperator
*BO
= BinaryOperator::CreateSub(LHS
, RHS
);
64 if (HasNUW
) BO
->setHasNoUnsignedWrap();
65 if (HasNSW
) BO
->setHasNoSignedWrap();
69 Instruction
*CreateNSWSub(Constant
*LHS
, Constant
*RHS
) const {
70 return BinaryOperator::CreateNSWSub(LHS
, RHS
);
73 Instruction
*CreateNUWSub(Constant
*LHS
, Constant
*RHS
) const {
74 return BinaryOperator::CreateNUWSub(LHS
, RHS
);
77 Instruction
*CreateFSub(Constant
*LHS
, Constant
*RHS
) const {
78 return BinaryOperator::CreateFSub(LHS
, RHS
);
81 Instruction
*CreateMul(Constant
*LHS
, Constant
*RHS
,
82 bool HasNUW
= false, bool HasNSW
= false) const {
83 BinaryOperator
*BO
= BinaryOperator::CreateMul(LHS
, RHS
);
84 if (HasNUW
) BO
->setHasNoUnsignedWrap();
85 if (HasNSW
) BO
->setHasNoSignedWrap();
89 Instruction
*CreateNSWMul(Constant
*LHS
, Constant
*RHS
) const {
90 return BinaryOperator::CreateNSWMul(LHS
, RHS
);
93 Instruction
*CreateNUWMul(Constant
*LHS
, Constant
*RHS
) const {
94 return BinaryOperator::CreateNUWMul(LHS
, RHS
);
97 Instruction
*CreateFMul(Constant
*LHS
, Constant
*RHS
) const {
98 return BinaryOperator::CreateFMul(LHS
, RHS
);
101 Instruction
*CreateUDiv(Constant
*LHS
, Constant
*RHS
,
102 bool isExact
= false) const {
104 return BinaryOperator::CreateUDiv(LHS
, RHS
);
105 return BinaryOperator::CreateExactUDiv(LHS
, RHS
);
108 Instruction
*CreateExactUDiv(Constant
*LHS
, Constant
*RHS
) const {
109 return BinaryOperator::CreateExactUDiv(LHS
, RHS
);
112 Instruction
*CreateSDiv(Constant
*LHS
, Constant
*RHS
,
113 bool isExact
= false) const {
115 return BinaryOperator::CreateSDiv(LHS
, RHS
);
116 return BinaryOperator::CreateExactSDiv(LHS
, RHS
);
119 Instruction
*CreateExactSDiv(Constant
*LHS
, Constant
*RHS
) const {
120 return BinaryOperator::CreateExactSDiv(LHS
, RHS
);
123 Instruction
*CreateFDiv(Constant
*LHS
, Constant
*RHS
) const {
124 return BinaryOperator::CreateFDiv(LHS
, RHS
);
127 Instruction
*CreateURem(Constant
*LHS
, Constant
*RHS
) const {
128 return BinaryOperator::CreateURem(LHS
, RHS
);
131 Instruction
*CreateSRem(Constant
*LHS
, Constant
*RHS
) const {
132 return BinaryOperator::CreateSRem(LHS
, RHS
);
135 Instruction
*CreateFRem(Constant
*LHS
, Constant
*RHS
) const {
136 return BinaryOperator::CreateFRem(LHS
, RHS
);
139 Instruction
*CreateShl(Constant
*LHS
, Constant
*RHS
, bool HasNUW
= false,
140 bool HasNSW
= false) const {
141 BinaryOperator
*BO
= BinaryOperator::CreateShl(LHS
, RHS
);
142 if (HasNUW
) BO
->setHasNoUnsignedWrap();
143 if (HasNSW
) BO
->setHasNoSignedWrap();
147 Instruction
*CreateLShr(Constant
*LHS
, Constant
*RHS
,
148 bool isExact
= false) const {
150 return BinaryOperator::CreateLShr(LHS
, RHS
);
151 return BinaryOperator::CreateExactLShr(LHS
, RHS
);
154 Instruction
*CreateAShr(Constant
*LHS
, Constant
*RHS
,
155 bool isExact
= false) const {
157 return BinaryOperator::CreateAShr(LHS
, RHS
);
158 return BinaryOperator::CreateExactAShr(LHS
, RHS
);
161 Instruction
*CreateAnd(Constant
*LHS
, Constant
*RHS
) const {
162 return BinaryOperator::CreateAnd(LHS
, RHS
);
165 Instruction
*CreateOr(Constant
*LHS
, Constant
*RHS
) const {
166 return BinaryOperator::CreateOr(LHS
, RHS
);
169 Instruction
*CreateXor(Constant
*LHS
, Constant
*RHS
) const {
170 return BinaryOperator::CreateXor(LHS
, RHS
);
173 Instruction
*CreateBinOp(Instruction::BinaryOps Opc
,
174 Constant
*LHS
, Constant
*RHS
) const {
175 return BinaryOperator::Create(Opc
, LHS
, RHS
);
178 //===--------------------------------------------------------------------===//
180 //===--------------------------------------------------------------------===//
182 Instruction
*CreateNeg(Constant
*C
,
183 bool HasNUW
= false, bool HasNSW
= false) const {
184 BinaryOperator
*BO
= BinaryOperator::CreateNeg(C
);
185 if (HasNUW
) BO
->setHasNoUnsignedWrap();
186 if (HasNSW
) BO
->setHasNoSignedWrap();
190 Instruction
*CreateNSWNeg(Constant
*C
) const {
191 return BinaryOperator::CreateNSWNeg(C
);
194 Instruction
*CreateNUWNeg(Constant
*C
) const {
195 return BinaryOperator::CreateNUWNeg(C
);
198 Instruction
*CreateFNeg(Constant
*C
) const {
199 return BinaryOperator::CreateFNeg(C
);
202 Instruction
*CreateNot(Constant
*C
) const {
203 return BinaryOperator::CreateNot(C
);
206 //===--------------------------------------------------------------------===//
207 // Memory Instructions
208 //===--------------------------------------------------------------------===//
210 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
211 ArrayRef
<Constant
*> IdxList
) const {
212 return ConstantExpr::getGetElementPtr(Ty
, C
, IdxList
);
215 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
, Constant
*Idx
) const {
216 // This form of the function only exists to avoid ambiguous overload
217 // warnings about whether to convert Idx to ArrayRef<Constant *> or
218 // ArrayRef<Value *>.
219 return ConstantExpr::getGetElementPtr(Ty
, C
, Idx
);
222 Instruction
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
223 ArrayRef
<Value
*> IdxList
) const {
224 return GetElementPtrInst::Create(Ty
, C
, IdxList
);
227 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
228 ArrayRef
<Constant
*> IdxList
) const {
229 return ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, IdxList
);
232 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
233 Constant
*Idx
) const {
234 // This form of the function only exists to avoid ambiguous overload
235 // warnings about whether to convert Idx to ArrayRef<Constant *> or
236 // ArrayRef<Value *>.
237 return ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, Idx
);
240 Instruction
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
241 ArrayRef
<Value
*> IdxList
) const {
242 return GetElementPtrInst::CreateInBounds(Ty
, C
, IdxList
);
245 //===--------------------------------------------------------------------===//
246 // Cast/Conversion Operators
247 //===--------------------------------------------------------------------===//
249 Instruction
*CreateCast(Instruction::CastOps Op
, Constant
*C
,
250 Type
*DestTy
) const {
251 return CastInst::Create(Op
, C
, DestTy
);
254 Instruction
*CreatePointerCast(Constant
*C
, Type
*DestTy
) const {
255 return CastInst::CreatePointerCast(C
, DestTy
);
258 Instruction
*CreateIntCast(Constant
*C
, Type
*DestTy
,
259 bool isSigned
) const {
260 return CastInst::CreateIntegerCast(C
, DestTy
, isSigned
);
263 Instruction
*CreateFPCast(Constant
*C
, Type
*DestTy
) const {
264 return CastInst::CreateFPCast(C
, DestTy
);
267 Instruction
*CreateBitCast(Constant
*C
, Type
*DestTy
) const {
268 return CreateCast(Instruction::BitCast
, C
, DestTy
);
271 Instruction
*CreateIntToPtr(Constant
*C
, Type
*DestTy
) const {
272 return CreateCast(Instruction::IntToPtr
, C
, DestTy
);
275 Instruction
*CreatePtrToInt(Constant
*C
, Type
*DestTy
) const {
276 return CreateCast(Instruction::PtrToInt
, C
, DestTy
);
279 Instruction
*CreateZExtOrBitCast(Constant
*C
, Type
*DestTy
) const {
280 return CastInst::CreateZExtOrBitCast(C
, DestTy
);
283 Instruction
*CreateSExtOrBitCast(Constant
*C
, Type
*DestTy
) const {
284 return CastInst::CreateSExtOrBitCast(C
, DestTy
);
287 Instruction
*CreateTruncOrBitCast(Constant
*C
, Type
*DestTy
) const {
288 return CastInst::CreateTruncOrBitCast(C
, DestTy
);
291 //===--------------------------------------------------------------------===//
292 // Compare Instructions
293 //===--------------------------------------------------------------------===//
295 Instruction
*CreateICmp(CmpInst::Predicate P
,
296 Constant
*LHS
, Constant
*RHS
) const {
297 return new ICmpInst(P
, LHS
, RHS
);
300 Instruction
*CreateFCmp(CmpInst::Predicate P
,
301 Constant
*LHS
, Constant
*RHS
) const {
302 return new FCmpInst(P
, LHS
, RHS
);
305 //===--------------------------------------------------------------------===//
306 // Other Instructions
307 //===--------------------------------------------------------------------===//
309 Instruction
*CreateSelect(Constant
*C
,
310 Constant
*True
, Constant
*False
) const {
311 return SelectInst::Create(C
, True
, False
);
314 Instruction
*CreateExtractElement(Constant
*Vec
, Constant
*Idx
) const {
315 return ExtractElementInst::Create(Vec
, Idx
);
318 Instruction
*CreateInsertElement(Constant
*Vec
, Constant
*NewElt
,
319 Constant
*Idx
) const {
320 return InsertElementInst::Create(Vec
, NewElt
, Idx
);
323 Instruction
*CreateShuffleVector(Constant
*V1
, Constant
*V2
,
324 Constant
*Mask
) const {
325 return new ShuffleVectorInst(V1
, V2
, Mask
);
328 Instruction
*CreateExtractValue(Constant
*Agg
,
329 ArrayRef
<unsigned> IdxList
) const {
330 return ExtractValueInst::Create(Agg
, IdxList
);
333 Instruction
*CreateInsertValue(Constant
*Agg
, Constant
*Val
,
334 ArrayRef
<unsigned> IdxList
) const {
335 return InsertValueInst::Create(Agg
, Val
, IdxList
);
339 } // end namespace llvm
341 #endif // LLVM_IR_NOFOLDER_H