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 Instruction
*CreateUnOp(Instruction::UnaryOps Opc
, Constant
*C
) const {
207 return UnaryOperator::Create(Opc
, C
);
210 //===--------------------------------------------------------------------===//
211 // Memory Instructions
212 //===--------------------------------------------------------------------===//
214 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
215 ArrayRef
<Constant
*> IdxList
) const {
216 return ConstantExpr::getGetElementPtr(Ty
, C
, IdxList
);
219 Constant
*CreateGetElementPtr(Type
*Ty
, Constant
*C
, Constant
*Idx
) const {
220 // This form of the function only exists to avoid ambiguous overload
221 // warnings about whether to convert Idx to ArrayRef<Constant *> or
222 // ArrayRef<Value *>.
223 return ConstantExpr::getGetElementPtr(Ty
, C
, Idx
);
226 Instruction
*CreateGetElementPtr(Type
*Ty
, Constant
*C
,
227 ArrayRef
<Value
*> IdxList
) const {
228 return GetElementPtrInst::Create(Ty
, C
, IdxList
);
231 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
232 ArrayRef
<Constant
*> IdxList
) const {
233 return ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, IdxList
);
236 Constant
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
237 Constant
*Idx
) const {
238 // This form of the function only exists to avoid ambiguous overload
239 // warnings about whether to convert Idx to ArrayRef<Constant *> or
240 // ArrayRef<Value *>.
241 return ConstantExpr::getInBoundsGetElementPtr(Ty
, C
, Idx
);
244 Instruction
*CreateInBoundsGetElementPtr(Type
*Ty
, Constant
*C
,
245 ArrayRef
<Value
*> IdxList
) const {
246 return GetElementPtrInst::CreateInBounds(Ty
, C
, IdxList
);
249 //===--------------------------------------------------------------------===//
250 // Cast/Conversion Operators
251 //===--------------------------------------------------------------------===//
253 Instruction
*CreateCast(Instruction::CastOps Op
, Constant
*C
,
254 Type
*DestTy
) const {
255 return CastInst::Create(Op
, C
, DestTy
);
258 Instruction
*CreatePointerCast(Constant
*C
, Type
*DestTy
) const {
259 return CastInst::CreatePointerCast(C
, DestTy
);
262 Instruction
*CreateIntCast(Constant
*C
, Type
*DestTy
,
263 bool isSigned
) const {
264 return CastInst::CreateIntegerCast(C
, DestTy
, isSigned
);
267 Instruction
*CreateFPCast(Constant
*C
, Type
*DestTy
) const {
268 return CastInst::CreateFPCast(C
, DestTy
);
271 Instruction
*CreateBitCast(Constant
*C
, Type
*DestTy
) const {
272 return CreateCast(Instruction::BitCast
, C
, DestTy
);
275 Instruction
*CreateIntToPtr(Constant
*C
, Type
*DestTy
) const {
276 return CreateCast(Instruction::IntToPtr
, C
, DestTy
);
279 Instruction
*CreatePtrToInt(Constant
*C
, Type
*DestTy
) const {
280 return CreateCast(Instruction::PtrToInt
, C
, DestTy
);
283 Instruction
*CreateZExtOrBitCast(Constant
*C
, Type
*DestTy
) const {
284 return CastInst::CreateZExtOrBitCast(C
, DestTy
);
287 Instruction
*CreateSExtOrBitCast(Constant
*C
, Type
*DestTy
) const {
288 return CastInst::CreateSExtOrBitCast(C
, DestTy
);
291 Instruction
*CreateTruncOrBitCast(Constant
*C
, Type
*DestTy
) const {
292 return CastInst::CreateTruncOrBitCast(C
, DestTy
);
295 //===--------------------------------------------------------------------===//
296 // Compare Instructions
297 //===--------------------------------------------------------------------===//
299 Instruction
*CreateICmp(CmpInst::Predicate P
,
300 Constant
*LHS
, Constant
*RHS
) const {
301 return new ICmpInst(P
, LHS
, RHS
);
304 Instruction
*CreateFCmp(CmpInst::Predicate P
,
305 Constant
*LHS
, Constant
*RHS
) const {
306 return new FCmpInst(P
, LHS
, RHS
);
309 //===--------------------------------------------------------------------===//
310 // Other Instructions
311 //===--------------------------------------------------------------------===//
313 Instruction
*CreateSelect(Constant
*C
,
314 Constant
*True
, Constant
*False
) const {
315 return SelectInst::Create(C
, True
, False
);
318 Instruction
*CreateExtractElement(Constant
*Vec
, Constant
*Idx
) const {
319 return ExtractElementInst::Create(Vec
, Idx
);
322 Instruction
*CreateInsertElement(Constant
*Vec
, Constant
*NewElt
,
323 Constant
*Idx
) const {
324 return InsertElementInst::Create(Vec
, NewElt
, Idx
);
327 Instruction
*CreateShuffleVector(Constant
*V1
, Constant
*V2
,
328 Constant
*Mask
) const {
329 return new ShuffleVectorInst(V1
, V2
, Mask
);
332 Instruction
*CreateExtractValue(Constant
*Agg
,
333 ArrayRef
<unsigned> IdxList
) const {
334 return ExtractValueInst::Create(Agg
, IdxList
);
337 Instruction
*CreateInsertValue(Constant
*Agg
, Constant
*Val
,
338 ArrayRef
<unsigned> IdxList
) const {
339 return InsertValueInst::Create(Agg
, Val
, IdxList
);
343 } // end namespace llvm
345 #endif // LLVM_IR_NOFOLDER_H