Line data Source code
1 : //===- NoFolder.h - Constant folding helper ---------------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the NoFolder class, a helper for IRBuilder. It provides
11 : // IRBuilder with a set of methods for creating unfolded constants. This is
12 : // useful for learners trying to understand how LLVM IR works, and who don't
13 : // want details to be hidden by the constant folder. For general constant
14 : // creation and folding, use ConstantExpr and the routines in
15 : // llvm/Analysis/ConstantFolding.h.
16 : //
17 : // Note: since it is not actually possible to create unfolded constants, this
18 : // class returns instructions rather than constants.
19 : //
20 : //===----------------------------------------------------------------------===//
21 :
22 : #ifndef LLVM_IR_NOFOLDER_H
23 : #define LLVM_IR_NOFOLDER_H
24 :
25 : #include "llvm/ADT/ArrayRef.h"
26 : #include "llvm/IR/Constants.h"
27 : #include "llvm/IR/InstrTypes.h"
28 : #include "llvm/IR/Instruction.h"
29 : #include "llvm/IR/Instructions.h"
30 :
31 : namespace llvm {
32 :
33 : /// NoFolder - Create "constants" (actually, instructions) with no folding.
34 : class NoFolder {
35 : public:
36 : explicit NoFolder() = default;
37 :
38 : //===--------------------------------------------------------------------===//
39 : // Binary Operators
40 : //===--------------------------------------------------------------------===//
41 :
42 16 : Instruction *CreateAdd(Constant *LHS, Constant *RHS,
43 : bool HasNUW = false, bool HasNSW = false) const {
44 16 : BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
45 16 : if (HasNUW) BO->setHasNoUnsignedWrap();
46 16 : if (HasNSW) BO->setHasNoSignedWrap();
47 16 : return BO;
48 : }
49 :
50 : Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
51 : return BinaryOperator::CreateNSWAdd(LHS, RHS);
52 : }
53 :
54 : Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
55 : return BinaryOperator::CreateNUWAdd(LHS, RHS);
56 : }
57 :
58 : Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
59 : return BinaryOperator::CreateFAdd(LHS, RHS);
60 : }
61 :
62 10 : Instruction *CreateSub(Constant *LHS, Constant *RHS,
63 : bool HasNUW = false, bool HasNSW = false) const {
64 10 : BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
65 10 : if (HasNUW) BO->setHasNoUnsignedWrap();
66 10 : if (HasNSW) BO->setHasNoSignedWrap();
67 10 : return BO;
68 : }
69 :
70 : Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
71 : return BinaryOperator::CreateNSWSub(LHS, RHS);
72 : }
73 :
74 : Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
75 : return BinaryOperator::CreateNUWSub(LHS, RHS);
76 : }
77 :
78 : Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
79 : return BinaryOperator::CreateFSub(LHS, RHS);
80 : }
81 :
82 8 : Instruction *CreateMul(Constant *LHS, Constant *RHS,
83 : bool HasNUW = false, bool HasNSW = false) const {
84 8 : BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
85 8 : if (HasNUW) BO->setHasNoUnsignedWrap();
86 8 : if (HasNSW) BO->setHasNoSignedWrap();
87 8 : return BO;
88 : }
89 :
90 : Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
91 : return BinaryOperator::CreateNSWMul(LHS, RHS);
92 : }
93 :
94 : Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
95 : return BinaryOperator::CreateNUWMul(LHS, RHS);
96 : }
97 :
98 : Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
99 : return BinaryOperator::CreateFMul(LHS, RHS);
100 : }
101 :
102 0 : Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
103 : bool isExact = false) const {
104 0 : if (!isExact)
105 0 : return BinaryOperator::CreateUDiv(LHS, RHS);
106 0 : return BinaryOperator::CreateExactUDiv(LHS, RHS);
107 : }
108 :
109 : Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
110 : return BinaryOperator::CreateExactUDiv(LHS, RHS);
111 : }
112 :
113 : Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
114 : bool isExact = false) const {
115 : if (!isExact)
116 : return BinaryOperator::CreateSDiv(LHS, RHS);
117 : return BinaryOperator::CreateExactSDiv(LHS, RHS);
118 : }
119 :
120 : Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
121 : return BinaryOperator::CreateExactSDiv(LHS, RHS);
122 : }
123 :
124 : Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
125 : return BinaryOperator::CreateFDiv(LHS, RHS);
126 : }
127 :
128 : Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
129 : return BinaryOperator::CreateURem(LHS, RHS);
130 : }
131 :
132 : Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
133 : return BinaryOperator::CreateSRem(LHS, RHS);
134 : }
135 :
136 : Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
137 : return BinaryOperator::CreateFRem(LHS, RHS);
138 : }
139 :
140 8 : Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
141 : bool HasNSW = false) const {
142 8 : BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
143 8 : if (HasNUW) BO->setHasNoUnsignedWrap();
144 8 : if (HasNSW) BO->setHasNoSignedWrap();
145 8 : return BO;
146 : }
147 :
148 0 : Instruction *CreateLShr(Constant *LHS, Constant *RHS,
149 : bool isExact = false) const {
150 0 : if (!isExact)
151 0 : return BinaryOperator::CreateLShr(LHS, RHS);
152 0 : return BinaryOperator::CreateExactLShr(LHS, RHS);
153 : }
154 :
155 : Instruction *CreateAShr(Constant *LHS, Constant *RHS,
156 : bool isExact = false) const {
157 : if (!isExact)
158 : return BinaryOperator::CreateAShr(LHS, RHS);
159 : return BinaryOperator::CreateExactAShr(LHS, RHS);
160 : }
161 :
162 0 : Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
163 6 : return BinaryOperator::CreateAnd(LHS, RHS);
164 : }
165 :
166 0 : Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
167 0 : return BinaryOperator::CreateOr(LHS, RHS);
168 : }
169 :
170 : Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
171 : return BinaryOperator::CreateXor(LHS, RHS);
172 : }
173 :
174 0 : Instruction *CreateBinOp(Instruction::BinaryOps Opc,
175 : Constant *LHS, Constant *RHS) const {
176 2 : return BinaryOperator::Create(Opc, LHS, RHS);
177 : }
178 :
179 : //===--------------------------------------------------------------------===//
180 : // Unary Operators
181 : //===--------------------------------------------------------------------===//
182 :
183 : Instruction *CreateNeg(Constant *C,
184 : bool HasNUW = false, bool HasNSW = false) const {
185 : BinaryOperator *BO = BinaryOperator::CreateNeg(C);
186 : if (HasNUW) BO->setHasNoUnsignedWrap();
187 : if (HasNSW) BO->setHasNoSignedWrap();
188 : return BO;
189 : }
190 :
191 : Instruction *CreateNSWNeg(Constant *C) const {
192 : return BinaryOperator::CreateNSWNeg(C);
193 : }
194 :
195 : Instruction *CreateNUWNeg(Constant *C) const {
196 : return BinaryOperator::CreateNUWNeg(C);
197 : }
198 :
199 : Instruction *CreateFNeg(Constant *C) const {
200 : return BinaryOperator::CreateFNeg(C);
201 : }
202 :
203 0 : Instruction *CreateNot(Constant *C) const {
204 15 : return BinaryOperator::CreateNot(C);
205 : }
206 :
207 : //===--------------------------------------------------------------------===//
208 : // Memory Instructions
209 : //===--------------------------------------------------------------------===//
210 :
211 : Constant *CreateGetElementPtr(Type *Ty, Constant *C,
212 : ArrayRef<Constant *> IdxList) const {
213 : return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
214 : }
215 :
216 : Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
217 : // This form of the function only exists to avoid ambiguous overload
218 : // warnings about whether to convert Idx to ArrayRef<Constant *> or
219 : // ArrayRef<Value *>.
220 : return ConstantExpr::getGetElementPtr(Ty, C, Idx);
221 : }
222 :
223 0 : Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
224 : ArrayRef<Value *> IdxList) const {
225 1 : return GetElementPtrInst::Create(Ty, C, IdxList);
226 : }
227 :
228 : Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
229 : ArrayRef<Constant *> IdxList) const {
230 : return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
231 : }
232 :
233 : Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
234 : Constant *Idx) const {
235 : // This form of the function only exists to avoid ambiguous overload
236 : // warnings about whether to convert Idx to ArrayRef<Constant *> or
237 : // ArrayRef<Value *>.
238 : return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
239 : }
240 :
241 0 : Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
242 : ArrayRef<Value *> IdxList) const {
243 0 : return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
244 : }
245 :
246 : //===--------------------------------------------------------------------===//
247 : // Cast/Conversion Operators
248 : //===--------------------------------------------------------------------===//
249 :
250 0 : Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
251 : Type *DestTy) const {
252 2 : return CastInst::Create(Op, C, DestTy);
253 : }
254 :
255 : Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
256 : return CastInst::CreatePointerCast(C, DestTy);
257 : }
258 :
259 : Instruction *CreateIntCast(Constant *C, Type *DestTy,
260 : bool isSigned) const {
261 : return CastInst::CreateIntegerCast(C, DestTy, isSigned);
262 : }
263 :
264 : Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
265 : return CastInst::CreateFPCast(C, DestTy);
266 : }
267 :
268 : Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
269 : return CreateCast(Instruction::BitCast, C, DestTy);
270 : }
271 :
272 : Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
273 : return CreateCast(Instruction::IntToPtr, C, DestTy);
274 : }
275 :
276 : Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
277 : return CreateCast(Instruction::PtrToInt, C, DestTy);
278 : }
279 :
280 : Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
281 : return CastInst::CreateZExtOrBitCast(C, DestTy);
282 : }
283 :
284 : Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
285 : return CastInst::CreateSExtOrBitCast(C, DestTy);
286 : }
287 :
288 : Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
289 : return CastInst::CreateTruncOrBitCast(C, DestTy);
290 : }
291 :
292 : //===--------------------------------------------------------------------===//
293 : // Compare Instructions
294 : //===--------------------------------------------------------------------===//
295 :
296 0 : Instruction *CreateICmp(CmpInst::Predicate P,
297 : Constant *LHS, Constant *RHS) const {
298 0 : return new ICmpInst(P, LHS, RHS);
299 : }
300 :
301 0 : Instruction *CreateFCmp(CmpInst::Predicate P,
302 : Constant *LHS, Constant *RHS) const {
303 0 : return new FCmpInst(P, LHS, RHS);
304 : }
305 :
306 : //===--------------------------------------------------------------------===//
307 : // Other Instructions
308 : //===--------------------------------------------------------------------===//
309 :
310 0 : Instruction *CreateSelect(Constant *C,
311 : Constant *True, Constant *False) const {
312 0 : return SelectInst::Create(C, True, False);
313 : }
314 :
315 0 : Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
316 0 : return ExtractElementInst::Create(Vec, Idx);
317 : }
318 :
319 0 : Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
320 : Constant *Idx) const {
321 0 : return InsertElementInst::Create(Vec, NewElt, Idx);
322 : }
323 :
324 0 : Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
325 : Constant *Mask) const {
326 0 : return new ShuffleVectorInst(V1, V2, Mask);
327 : }
328 :
329 : Instruction *CreateExtractValue(Constant *Agg,
330 : ArrayRef<unsigned> IdxList) const {
331 : return ExtractValueInst::Create(Agg, IdxList);
332 : }
333 :
334 : Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
335 : ArrayRef<unsigned> IdxList) const {
336 : return InsertValueInst::Create(Agg, Val, IdxList);
337 : }
338 : };
339 :
340 : } // end namespace llvm
341 :
342 : #endif // LLVM_IR_NOFOLDER_H
|