1 //===- ConstantFolder.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 ConstantFolder class, a helper for IRBuilder.
10 // It provides IRBuilder with a set of methods for creating constants
11 // with minimal folding.  For general constant creation and folding,
12 // use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_IR_CONSTANTFOLDER_H
17 #define LLVM_IR_CONSTANTFOLDER_H
18 
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/InstrTypes.h"
22 #include "llvm/IR/Instruction.h"
23 #include "llvm/IR/IRBuilderFolder.h"
24 
25 namespace llvm {
26 
27 /// ConstantFolder - Create constants with minimum, target independent, folding.
28 class ConstantFolder final : public IRBuilderFolder {
29   virtual void anchor();
30 
31 public:
32   explicit ConstantFolder() = default;
33 
34   //===--------------------------------------------------------------------===//
35   // Binary Operators
36   //===--------------------------------------------------------------------===//
37 
38   Constant *CreateAdd(Constant *LHS, Constant *RHS,
39                       bool HasNUW = false, bool HasNSW = false) const override {
40     return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
41   }
42 
CreateFAdd(Constant * LHS,Constant * RHS)43   Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
44     return ConstantExpr::getFAdd(LHS, RHS);
45   }
46 
47   Constant *CreateSub(Constant *LHS, Constant *RHS,
48                       bool HasNUW = false, bool HasNSW = false) const override {
49     return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
50   }
51 
CreateFSub(Constant * LHS,Constant * RHS)52   Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
53     return ConstantExpr::getFSub(LHS, RHS);
54   }
55 
56   Constant *CreateMul(Constant *LHS, Constant *RHS,
57                       bool HasNUW = false, bool HasNSW = false) const override {
58     return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
59   }
60 
CreateFMul(Constant * LHS,Constant * RHS)61   Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
62     return ConstantExpr::getFMul(LHS, RHS);
63   }
64 
65   Constant *CreateUDiv(Constant *LHS, Constant *RHS,
66                                bool isExact = false) const override {
67     return ConstantExpr::getUDiv(LHS, RHS, isExact);
68   }
69 
70   Constant *CreateSDiv(Constant *LHS, Constant *RHS,
71                                bool isExact = false) const override {
72     return ConstantExpr::getSDiv(LHS, RHS, isExact);
73   }
74 
CreateFDiv(Constant * LHS,Constant * RHS)75   Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
76     return ConstantExpr::getFDiv(LHS, RHS);
77   }
78 
CreateURem(Constant * LHS,Constant * RHS)79   Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
80     return ConstantExpr::getURem(LHS, RHS);
81   }
82 
CreateSRem(Constant * LHS,Constant * RHS)83   Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
84     return ConstantExpr::getSRem(LHS, RHS);
85   }
86 
CreateFRem(Constant * LHS,Constant * RHS)87   Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
88     return ConstantExpr::getFRem(LHS, RHS);
89   }
90 
91   Constant *CreateShl(Constant *LHS, Constant *RHS,
92                       bool HasNUW = false, bool HasNSW = false) const override {
93     return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
94   }
95 
96   Constant *CreateLShr(Constant *LHS, Constant *RHS,
97                        bool isExact = false) const override {
98     return ConstantExpr::getLShr(LHS, RHS, isExact);
99   }
100 
101   Constant *CreateAShr(Constant *LHS, Constant *RHS,
102                        bool isExact = false) const override {
103     return ConstantExpr::getAShr(LHS, RHS, isExact);
104   }
105 
CreateAnd(Constant * LHS,Constant * RHS)106   Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
107     return ConstantExpr::getAnd(LHS, RHS);
108   }
109 
CreateOr(Constant * LHS,Constant * RHS)110   Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
111     return ConstantExpr::getOr(LHS, RHS);
112   }
113 
CreateXor(Constant * LHS,Constant * RHS)114   Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
115     return ConstantExpr::getXor(LHS, RHS);
116   }
117 
CreateBinOp(Instruction::BinaryOps Opc,Constant * LHS,Constant * RHS)118   Constant *CreateBinOp(Instruction::BinaryOps Opc,
119                         Constant *LHS, Constant *RHS) const override {
120     return ConstantExpr::get(Opc, LHS, RHS);
121   }
122 
123   //===--------------------------------------------------------------------===//
124   // Unary Operators
125   //===--------------------------------------------------------------------===//
126 
127   Constant *CreateNeg(Constant *C,
128                       bool HasNUW = false, bool HasNSW = false) const override {
129     return ConstantExpr::getNeg(C, HasNUW, HasNSW);
130   }
131 
CreateFNeg(Constant * C)132   Constant *CreateFNeg(Constant *C) const override {
133     return ConstantExpr::getFNeg(C);
134   }
135 
CreateNot(Constant * C)136   Constant *CreateNot(Constant *C) const override {
137     return ConstantExpr::getNot(C);
138   }
139 
CreateUnOp(Instruction::UnaryOps Opc,Constant * C)140   Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
141     return ConstantExpr::get(Opc, C);
142   }
143 
144   //===--------------------------------------------------------------------===//
145   // Memory Instructions
146   //===--------------------------------------------------------------------===//
147 
CreateGetElementPtr(Type * Ty,Constant * C,ArrayRef<Constant * > IdxList)148   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
149                                 ArrayRef<Constant *> IdxList) const override {
150     return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
151   }
152 
CreateGetElementPtr(Type * Ty,Constant * C,Constant * Idx)153   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
154                                 Constant *Idx) const override {
155     // This form of the function only exists to avoid ambiguous overload
156     // warnings about whether to convert Idx to ArrayRef<Constant *> or
157     // ArrayRef<Value *>.
158     return ConstantExpr::getGetElementPtr(Ty, C, Idx);
159   }
160 
CreateGetElementPtr(Type * Ty,Constant * C,ArrayRef<Value * > IdxList)161   Constant *CreateGetElementPtr(Type *Ty, Constant *C,
162                                 ArrayRef<Value *> IdxList) const override {
163     return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
164   }
165 
CreateInBoundsGetElementPtr(Type * Ty,Constant * C,ArrayRef<Constant * > IdxList)166   Constant *CreateInBoundsGetElementPtr(
167       Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
168     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
169   }
170 
CreateInBoundsGetElementPtr(Type * Ty,Constant * C,Constant * Idx)171   Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
172                                         Constant *Idx) const override {
173     // This form of the function only exists to avoid ambiguous overload
174     // warnings about whether to convert Idx to ArrayRef<Constant *> or
175     // ArrayRef<Value *>.
176     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
177   }
178 
CreateInBoundsGetElementPtr(Type * Ty,Constant * C,ArrayRef<Value * > IdxList)179   Constant *CreateInBoundsGetElementPtr(
180       Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
181     return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
182   }
183 
184   //===--------------------------------------------------------------------===//
185   // Cast/Conversion Operators
186   //===--------------------------------------------------------------------===//
187 
CreateCast(Instruction::CastOps Op,Constant * C,Type * DestTy)188   Constant *CreateCast(Instruction::CastOps Op, Constant *C,
189                        Type *DestTy) const override {
190     return ConstantExpr::getCast(Op, C, DestTy);
191   }
192 
CreatePointerCast(Constant * C,Type * DestTy)193   Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
194     return ConstantExpr::getPointerCast(C, DestTy);
195   }
196 
CreatePointerBitCastOrAddrSpaceCast(Constant * C,Type * DestTy)197   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
198                                                 Type *DestTy) const override {
199     return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
200   }
201 
CreateIntCast(Constant * C,Type * DestTy,bool isSigned)202   Constant *CreateIntCast(Constant *C, Type *DestTy,
203                           bool isSigned) const override {
204     return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
205   }
206 
CreateFPCast(Constant * C,Type * DestTy)207   Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
208     return ConstantExpr::getFPCast(C, DestTy);
209   }
210 
CreateBitCast(Constant * C,Type * DestTy)211   Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
212     return CreateCast(Instruction::BitCast, C, DestTy);
213   }
214 
CreateIntToPtr(Constant * C,Type * DestTy)215   Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
216     return CreateCast(Instruction::IntToPtr, C, DestTy);
217   }
218 
CreatePtrToInt(Constant * C,Type * DestTy)219   Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
220     return CreateCast(Instruction::PtrToInt, C, DestTy);
221   }
222 
CreateZExtOrBitCast(Constant * C,Type * DestTy)223   Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
224     return ConstantExpr::getZExtOrBitCast(C, DestTy);
225   }
226 
CreateSExtOrBitCast(Constant * C,Type * DestTy)227   Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
228     return ConstantExpr::getSExtOrBitCast(C, DestTy);
229   }
230 
CreateTruncOrBitCast(Constant * C,Type * DestTy)231   Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
232     return ConstantExpr::getTruncOrBitCast(C, DestTy);
233   }
234 
235   //===--------------------------------------------------------------------===//
236   // Compare Instructions
237   //===--------------------------------------------------------------------===//
238 
CreateICmp(CmpInst::Predicate P,Constant * LHS,Constant * RHS)239   Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
240                        Constant *RHS) const override {
241     return ConstantExpr::getCompare(P, LHS, RHS);
242   }
243 
CreateFCmp(CmpInst::Predicate P,Constant * LHS,Constant * RHS)244   Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
245                        Constant *RHS) const override {
246     return ConstantExpr::getCompare(P, LHS, RHS);
247   }
248 
249   //===--------------------------------------------------------------------===//
250   // Other Instructions
251   //===--------------------------------------------------------------------===//
252 
CreateSelect(Constant * C,Constant * True,Constant * False)253   Constant *CreateSelect(Constant *C, Constant *True,
254                          Constant *False) const override {
255     return ConstantExpr::getSelect(C, True, False);
256   }
257 
CreateExtractElement(Constant * Vec,Constant * Idx)258   Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
259     return ConstantExpr::getExtractElement(Vec, Idx);
260   }
261 
CreateInsertElement(Constant * Vec,Constant * NewElt,Constant * Idx)262   Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
263                                 Constant *Idx) const override {
264     return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
265   }
266 
CreateShuffleVector(Constant * V1,Constant * V2,ArrayRef<int> Mask)267   Constant *CreateShuffleVector(Constant *V1, Constant *V2,
268                                 ArrayRef<int> Mask) const override {
269     return ConstantExpr::getShuffleVector(V1, V2, Mask);
270   }
271 
CreateExtractValue(Constant * Agg,ArrayRef<unsigned> IdxList)272   Constant *CreateExtractValue(Constant *Agg,
273                                ArrayRef<unsigned> IdxList) const override {
274     return ConstantExpr::getExtractValue(Agg, IdxList);
275   }
276 
CreateInsertValue(Constant * Agg,Constant * Val,ArrayRef<unsigned> IdxList)277   Constant *CreateInsertValue(Constant *Agg, Constant *Val,
278                               ArrayRef<unsigned> IdxList) const override {
279     return ConstantExpr::getInsertValue(Agg, Val, IdxList);
280   }
281 };
282 
283 } // end namespace llvm
284 
285 #endif // LLVM_IR_CONSTANTFOLDER_H
286