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