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