NoFolder.h revision 360784
1//===- NoFolder.h - Constant folding helper ---------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
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.
15//
16// Note: since it is not actually possible to create unfolded constants, this
17// class returns instructions rather than constants.
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_IR_NOFOLDER_H
22#define LLVM_IR_NOFOLDER_H
23
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"
29
30namespace llvm {
31
32/// NoFolder - Create "constants" (actually, instructions) with no folding.
33class NoFolder {
34public:
35  explicit NoFolder() = default;
36
37  //===--------------------------------------------------------------------===//
38  // Binary Operators
39  //===--------------------------------------------------------------------===//
40
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();
46    return BO;
47  }
48
49  Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
50    return BinaryOperator::CreateNSWAdd(LHS, RHS);
51  }
52
53  Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
54    return BinaryOperator::CreateNUWAdd(LHS, RHS);
55  }
56
57  Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
58    return BinaryOperator::CreateFAdd(LHS, RHS);
59  }
60
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();
66    return BO;
67  }
68
69  Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
70    return BinaryOperator::CreateNSWSub(LHS, RHS);
71  }
72
73  Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
74    return BinaryOperator::CreateNUWSub(LHS, RHS);
75  }
76
77  Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
78    return BinaryOperator::CreateFSub(LHS, RHS);
79  }
80
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();
86    return BO;
87  }
88
89  Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
90    return BinaryOperator::CreateNSWMul(LHS, RHS);
91  }
92
93  Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
94    return BinaryOperator::CreateNUWMul(LHS, RHS);
95  }
96
97  Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
98    return BinaryOperator::CreateFMul(LHS, RHS);
99  }
100
101  Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
102                          bool isExact = false) const {
103    if (!isExact)
104      return BinaryOperator::CreateUDiv(LHS, RHS);
105    return BinaryOperator::CreateExactUDiv(LHS, RHS);
106  }
107
108  Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
109    return BinaryOperator::CreateExactUDiv(LHS, RHS);
110  }
111
112  Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
113                          bool isExact = false) const {
114    if (!isExact)
115      return BinaryOperator::CreateSDiv(LHS, RHS);
116    return BinaryOperator::CreateExactSDiv(LHS, RHS);
117  }
118
119  Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
120    return BinaryOperator::CreateExactSDiv(LHS, RHS);
121  }
122
123  Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
124    return BinaryOperator::CreateFDiv(LHS, RHS);
125  }
126
127  Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
128    return BinaryOperator::CreateURem(LHS, RHS);
129  }
130
131  Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
132    return BinaryOperator::CreateSRem(LHS, RHS);
133  }
134
135  Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
136    return BinaryOperator::CreateFRem(LHS, RHS);
137  }
138
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();
144    return BO;
145  }
146
147  Instruction *CreateLShr(Constant *LHS, Constant *RHS,
148                          bool isExact = false) const {
149    if (!isExact)
150      return BinaryOperator::CreateLShr(LHS, RHS);
151    return BinaryOperator::CreateExactLShr(LHS, RHS);
152  }
153
154  Instruction *CreateAShr(Constant *LHS, Constant *RHS,
155                          bool isExact = false) const {
156    if (!isExact)
157      return BinaryOperator::CreateAShr(LHS, RHS);
158    return BinaryOperator::CreateExactAShr(LHS, RHS);
159  }
160
161  Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
162    return BinaryOperator::CreateAnd(LHS, RHS);
163  }
164
165  Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
166    return BinaryOperator::CreateOr(LHS, RHS);
167  }
168
169  Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
170    return BinaryOperator::CreateXor(LHS, RHS);
171  }
172
173  Instruction *CreateBinOp(Instruction::BinaryOps Opc,
174                           Constant *LHS, Constant *RHS) const {
175    return BinaryOperator::Create(Opc, LHS, RHS);
176  }
177
178  //===--------------------------------------------------------------------===//
179  // Unary Operators
180  //===--------------------------------------------------------------------===//
181
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();
187    return BO;
188  }
189
190  Instruction *CreateNSWNeg(Constant *C) const {
191    return BinaryOperator::CreateNSWNeg(C);
192  }
193
194  Instruction *CreateNUWNeg(Constant *C) const {
195    return BinaryOperator::CreateNUWNeg(C);
196  }
197
198  Instruction *CreateFNeg(Constant *C) const {
199    return UnaryOperator::CreateFNeg(C);
200  }
201
202  Instruction *CreateNot(Constant *C) const {
203    return BinaryOperator::CreateNot(C);
204  }
205
206  Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
207    return UnaryOperator::Create(Opc, C);
208  }
209
210  //===--------------------------------------------------------------------===//
211  // Memory Instructions
212  //===--------------------------------------------------------------------===//
213
214  Constant *CreateGetElementPtr(Type *Ty, Constant *C,
215                                ArrayRef<Constant *> IdxList) const {
216    return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
217  }
218
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);
224  }
225
226  Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
227                                   ArrayRef<Value *> IdxList) const {
228    return GetElementPtrInst::Create(Ty, C, IdxList);
229  }
230
231  Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
232                                        ArrayRef<Constant *> IdxList) const {
233    return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
234  }
235
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);
242  }
243
244  Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
245                                           ArrayRef<Value *> IdxList) const {
246    return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
247  }
248
249  //===--------------------------------------------------------------------===//
250  // Cast/Conversion Operators
251  //===--------------------------------------------------------------------===//
252
253  Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
254                    Type *DestTy) const {
255    return CastInst::Create(Op, C, DestTy);
256  }
257
258  Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
259    return CastInst::CreatePointerCast(C, DestTy);
260  }
261
262  Instruction *CreateIntCast(Constant *C, Type *DestTy,
263                       bool isSigned) const {
264    return CastInst::CreateIntegerCast(C, DestTy, isSigned);
265  }
266
267  Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
268    return CastInst::CreateFPCast(C, DestTy);
269  }
270
271  Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
272    return CreateCast(Instruction::BitCast, C, DestTy);
273  }
274
275  Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
276    return CreateCast(Instruction::IntToPtr, C, DestTy);
277  }
278
279  Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
280    return CreateCast(Instruction::PtrToInt, C, DestTy);
281  }
282
283  Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
284    return CastInst::CreateZExtOrBitCast(C, DestTy);
285  }
286
287  Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
288    return CastInst::CreateSExtOrBitCast(C, DestTy);
289  }
290
291  Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
292    return CastInst::CreateTruncOrBitCast(C, DestTy);
293  }
294
295  //===--------------------------------------------------------------------===//
296  // Compare Instructions
297  //===--------------------------------------------------------------------===//
298
299  Instruction *CreateICmp(CmpInst::Predicate P,
300                          Constant *LHS, Constant *RHS) const {
301    return new ICmpInst(P, LHS, RHS);
302  }
303
304  Instruction *CreateFCmp(CmpInst::Predicate P,
305                          Constant *LHS, Constant *RHS) const {
306    return new FCmpInst(P, LHS, RHS);
307  }
308
309  //===--------------------------------------------------------------------===//
310  // Other Instructions
311  //===--------------------------------------------------------------------===//
312
313  Instruction *CreateSelect(Constant *C,
314                            Constant *True, Constant *False) const {
315    return SelectInst::Create(C, True, False);
316  }
317
318  Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
319    return ExtractElementInst::Create(Vec, Idx);
320  }
321
322  Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
323                                   Constant *Idx) const {
324    return InsertElementInst::Create(Vec, NewElt, Idx);
325  }
326
327  Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
328                                   Constant *Mask) const {
329    return new ShuffleVectorInst(V1, V2, Mask);
330  }
331
332  Instruction *CreateExtractValue(Constant *Agg,
333                                  ArrayRef<unsigned> IdxList) const {
334    return ExtractValueInst::Create(Agg, IdxList);
335  }
336
337  Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
338                                 ArrayRef<unsigned> IdxList) const {
339    return InsertValueInst::Create(Agg, Val, IdxList);
340  }
341};
342
343} // end namespace llvm
344
345#endif // LLVM_IR_NOFOLDER_H
346