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