OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
| 5 import '../common_elements.dart' show CommonElements; |
5 import '../constants/constant_system.dart'; | 6 import '../constants/constant_system.dart'; |
6 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
7 import '../elements/elements.dart' show Name; | 8 import '../elements/elements.dart' show Name; |
8 import '../elements/entities.dart'; | 9 import '../elements/entities.dart'; |
9 import '../js_backend/backend_helpers.dart'; | |
10 import '../options.dart'; | 10 import '../options.dart'; |
11 import '../types/types.dart'; | 11 import '../types/types.dart'; |
12 import '../universe/call_structure.dart'; | 12 import '../universe/call_structure.dart'; |
13 import '../universe/selector.dart'; | 13 import '../universe/selector.dart'; |
14 import '../world.dart' show ClosedWorld; | 14 import '../world.dart' show ClosedWorld; |
15 import 'nodes.dart'; | 15 import 'nodes.dart'; |
16 import 'types.dart'; | 16 import 'types.dart'; |
17 | 17 |
18 /** | 18 /** |
19 * [InvokeDynamicSpecializer] and its subclasses are helpers to | 19 * [InvokeDynamicSpecializer] and its subclasses are helpers to |
20 * optimize intercepted dynamic calls. It knows what input types | 20 * optimize intercepted dynamic calls. It knows what input types |
21 * would be beneficial for performance, and how to change a invoke | 21 * would be beneficial for performance, and how to change a invoke |
22 * dynamic to a builtin instruction (e.g. HIndex, HBitNot). | 22 * dynamic to a builtin instruction (e.g. HIndex, HBitNot). |
23 */ | 23 */ |
24 class InvokeDynamicSpecializer { | 24 class InvokeDynamicSpecializer { |
25 const InvokeDynamicSpecializer(); | 25 const InvokeDynamicSpecializer(); |
26 | 26 |
27 TypeMask computeTypeFromInputTypes( | 27 TypeMask computeTypeFromInputTypes( |
28 HInvokeDynamic instruction, | 28 HInvokeDynamic instruction, |
29 GlobalTypeInferenceResults results, | 29 GlobalTypeInferenceResults results, |
30 CompilerOptions options, | 30 CompilerOptions options, |
31 BackendHelpers helpers, | |
32 ClosedWorld closedWorld) { | 31 ClosedWorld closedWorld) { |
33 return TypeMaskFactory.inferredTypeForSelector( | 32 return TypeMaskFactory.inferredTypeForSelector( |
34 instruction.selector, instruction.mask, results); | 33 instruction.selector, instruction.mask, results); |
35 } | 34 } |
36 | 35 |
37 HInstruction tryConvertToBuiltin( | 36 HInstruction tryConvertToBuiltin( |
38 HInvokeDynamic instruction, | 37 HInvokeDynamic instruction, |
39 HGraph graph, | 38 HGraph graph, |
40 GlobalTypeInferenceResults results, | 39 GlobalTypeInferenceResults results, |
41 CompilerOptions options, | 40 CompilerOptions options, |
42 BackendHelpers helpers, | 41 CommonElements commonElements, |
43 ClosedWorld closedWorld) { | 42 ClosedWorld closedWorld) { |
44 return null; | 43 return null; |
45 } | 44 } |
46 | 45 |
47 void clearAllSideEffects(HInstruction instruction) { | 46 void clearAllSideEffects(HInstruction instruction) { |
48 instruction.sideEffects.clearAllSideEffects(); | 47 instruction.sideEffects.clearAllSideEffects(); |
49 instruction.sideEffects.clearAllDependencies(); | 48 instruction.sideEffects.clearAllDependencies(); |
50 instruction.setUseGvn(); | 49 instruction.setUseGvn(); |
51 } | 50 } |
52 | 51 |
53 Selector renameToOptimizedSelector( | 52 Selector renameToOptimizedSelector( |
54 String name, Selector selector, BackendHelpers helpers) { | 53 String name, Selector selector, CommonElements commonElements) { |
55 if (selector.name == name) return selector; | 54 if (selector.name == name) return selector; |
56 return new Selector.call(new Name(name, helpers.interceptorsLibrary), | 55 return new Selector.call(new Name(name, commonElements.interceptorsLibrary), |
57 new CallStructure(selector.argumentCount)); | 56 new CallStructure(selector.argumentCount)); |
58 } | 57 } |
59 | 58 |
60 Operation operation(ConstantSystem constantSystem) => null; | 59 Operation operation(ConstantSystem constantSystem) => null; |
61 | 60 |
62 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) { | 61 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) { |
63 if (selector.isIndex) return const IndexSpecializer(); | 62 if (selector.isIndex) return const IndexSpecializer(); |
64 if (selector.isIndexSet) return const IndexAssignSpecializer(); | 63 if (selector.isIndexSet) return const IndexAssignSpecializer(); |
65 String name = selector.name; | 64 String name = selector.name; |
66 if (selector.isOperator) { | 65 if (selector.isOperator) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 } | 112 } |
114 | 113 |
115 class IndexAssignSpecializer extends InvokeDynamicSpecializer { | 114 class IndexAssignSpecializer extends InvokeDynamicSpecializer { |
116 const IndexAssignSpecializer(); | 115 const IndexAssignSpecializer(); |
117 | 116 |
118 HInstruction tryConvertToBuiltin( | 117 HInstruction tryConvertToBuiltin( |
119 HInvokeDynamic instruction, | 118 HInvokeDynamic instruction, |
120 HGraph graph, | 119 HGraph graph, |
121 GlobalTypeInferenceResults results, | 120 GlobalTypeInferenceResults results, |
122 CompilerOptions options, | 121 CompilerOptions options, |
123 BackendHelpers helpers, | 122 CommonElements commonElements, |
124 ClosedWorld closedWorld) { | 123 ClosedWorld closedWorld) { |
125 if (instruction.inputs[1].isMutableIndexable(closedWorld)) { | 124 if (instruction.inputs[1].isMutableIndexable(closedWorld)) { |
126 if (!instruction.inputs[2].isInteger(closedWorld) && | 125 if (!instruction.inputs[2].isInteger(closedWorld) && |
127 options.enableTypeAssertions) { | 126 options.enableTypeAssertions) { |
128 // We want the right checked mode error. | 127 // We want the right checked mode error. |
129 return null; | 128 return null; |
130 } | 129 } |
131 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2], | 130 return new HIndexAssign(instruction.inputs[1], instruction.inputs[2], |
132 instruction.inputs[3], instruction.selector); | 131 instruction.inputs[3], instruction.selector); |
133 } | 132 } |
134 return null; | 133 return null; |
135 } | 134 } |
136 } | 135 } |
137 | 136 |
138 class IndexSpecializer extends InvokeDynamicSpecializer { | 137 class IndexSpecializer extends InvokeDynamicSpecializer { |
139 const IndexSpecializer(); | 138 const IndexSpecializer(); |
140 | 139 |
141 HInstruction tryConvertToBuiltin( | 140 HInstruction tryConvertToBuiltin( |
142 HInvokeDynamic instruction, | 141 HInvokeDynamic instruction, |
143 HGraph graph, | 142 HGraph graph, |
144 GlobalTypeInferenceResults results, | 143 GlobalTypeInferenceResults results, |
145 CompilerOptions options, | 144 CompilerOptions options, |
146 BackendHelpers helpers, | 145 CommonElements commonElements, |
147 ClosedWorld closedWorld) { | 146 ClosedWorld closedWorld) { |
148 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null; | 147 if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null; |
149 if (!instruction.inputs[2].isInteger(closedWorld) && | 148 if (!instruction.inputs[2].isInteger(closedWorld) && |
150 options.enableTypeAssertions) { | 149 options.enableTypeAssertions) { |
151 // We want the right checked mode error. | 150 // We want the right checked mode error. |
152 return null; | 151 return null; |
153 } | 152 } |
154 TypeMask receiverType = | 153 TypeMask receiverType = |
155 instruction.getDartReceiver(closedWorld).instructionType; | 154 instruction.getDartReceiver(closedWorld).instructionType; |
156 TypeMask type = TypeMaskFactory.inferredTypeForSelector( | 155 TypeMask type = TypeMaskFactory.inferredTypeForSelector( |
157 instruction.selector, receiverType, results); | 156 instruction.selector, receiverType, results); |
158 return new HIndex(instruction.inputs[1], instruction.inputs[2], | 157 return new HIndex(instruction.inputs[1], instruction.inputs[2], |
159 instruction.selector, type); | 158 instruction.selector, type); |
160 } | 159 } |
161 } | 160 } |
162 | 161 |
163 class BitNotSpecializer extends InvokeDynamicSpecializer { | 162 class BitNotSpecializer extends InvokeDynamicSpecializer { |
164 const BitNotSpecializer(); | 163 const BitNotSpecializer(); |
165 | 164 |
166 UnaryOperation operation(ConstantSystem constantSystem) { | 165 UnaryOperation operation(ConstantSystem constantSystem) { |
167 return constantSystem.bitNot; | 166 return constantSystem.bitNot; |
168 } | 167 } |
169 | 168 |
170 TypeMask computeTypeFromInputTypes( | 169 TypeMask computeTypeFromInputTypes( |
171 HInvokeDynamic instruction, | 170 HInvokeDynamic instruction, |
172 GlobalTypeInferenceResults results, | 171 GlobalTypeInferenceResults results, |
173 CompilerOptions options, | 172 CompilerOptions options, |
174 BackendHelpers helpers, | |
175 ClosedWorld closedWorld) { | 173 ClosedWorld closedWorld) { |
176 // All bitwise operations on primitive types either produce an | 174 // All bitwise operations on primitive types either produce an |
177 // integer or throw an error. | 175 // integer or throw an error. |
178 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { | 176 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { |
179 return closedWorld.commonMasks.uint32Type; | 177 return closedWorld.commonMasks.uint32Type; |
180 } | 178 } |
181 return super.computeTypeFromInputTypes( | 179 return super |
182 instruction, results, options, helpers, closedWorld); | 180 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
183 } | 181 } |
184 | 182 |
185 HInstruction tryConvertToBuiltin( | 183 HInstruction tryConvertToBuiltin( |
186 HInvokeDynamic instruction, | 184 HInvokeDynamic instruction, |
187 HGraph graph, | 185 HGraph graph, |
188 GlobalTypeInferenceResults results, | 186 GlobalTypeInferenceResults results, |
189 CompilerOptions options, | 187 CompilerOptions options, |
190 BackendHelpers helpers, | 188 CommonElements commonElements, |
191 ClosedWorld closedWorld) { | 189 ClosedWorld closedWorld) { |
192 HInstruction input = instruction.inputs[1]; | 190 HInstruction input = instruction.inputs[1]; |
193 if (input.isNumber(closedWorld)) { | 191 if (input.isNumber(closedWorld)) { |
194 return new HBitNot( | 192 return new HBitNot( |
195 input, | 193 input, |
196 instruction.selector, | 194 instruction.selector, |
197 computeTypeFromInputTypes( | 195 computeTypeFromInputTypes( |
198 instruction, results, options, helpers, closedWorld)); | 196 instruction, results, options, closedWorld)); |
199 } | 197 } |
200 return null; | 198 return null; |
201 } | 199 } |
202 } | 200 } |
203 | 201 |
204 class UnaryNegateSpecializer extends InvokeDynamicSpecializer { | 202 class UnaryNegateSpecializer extends InvokeDynamicSpecializer { |
205 const UnaryNegateSpecializer(); | 203 const UnaryNegateSpecializer(); |
206 | 204 |
207 UnaryOperation operation(ConstantSystem constantSystem) { | 205 UnaryOperation operation(ConstantSystem constantSystem) { |
208 return constantSystem.negate; | 206 return constantSystem.negate; |
209 } | 207 } |
210 | 208 |
211 TypeMask computeTypeFromInputTypes( | 209 TypeMask computeTypeFromInputTypes( |
212 HInvokeDynamic instruction, | 210 HInvokeDynamic instruction, |
213 GlobalTypeInferenceResults results, | 211 GlobalTypeInferenceResults results, |
214 CompilerOptions options, | 212 CompilerOptions options, |
215 BackendHelpers helpers, | |
216 ClosedWorld closedWorld) { | 213 ClosedWorld closedWorld) { |
217 TypeMask operandType = instruction.inputs[1].instructionType; | 214 TypeMask operandType = instruction.inputs[1].instructionType; |
218 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType; | 215 if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType; |
219 return super.computeTypeFromInputTypes( | 216 return super |
220 instruction, results, options, helpers, closedWorld); | 217 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
221 } | 218 } |
222 | 219 |
223 HInstruction tryConvertToBuiltin( | 220 HInstruction tryConvertToBuiltin( |
224 HInvokeDynamic instruction, | 221 HInvokeDynamic instruction, |
225 HGraph graph, | 222 HGraph graph, |
226 GlobalTypeInferenceResults results, | 223 GlobalTypeInferenceResults results, |
227 CompilerOptions options, | 224 CompilerOptions options, |
228 BackendHelpers helpers, | 225 CommonElements commonElements, |
229 ClosedWorld closedWorld) { | 226 ClosedWorld closedWorld) { |
230 HInstruction input = instruction.inputs[1]; | 227 HInstruction input = instruction.inputs[1]; |
231 if (input.isNumber(closedWorld)) { | 228 if (input.isNumber(closedWorld)) { |
232 return new HNegate(input, instruction.selector, input.instructionType); | 229 return new HNegate(input, instruction.selector, input.instructionType); |
233 } | 230 } |
234 return null; | 231 return null; |
235 } | 232 } |
236 } | 233 } |
237 | 234 |
238 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer { | 235 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer { |
239 const BinaryArithmeticSpecializer(); | 236 const BinaryArithmeticSpecializer(); |
240 | 237 |
241 TypeMask computeTypeFromInputTypes( | 238 TypeMask computeTypeFromInputTypes( |
242 HInvokeDynamic instruction, | 239 HInvokeDynamic instruction, |
243 GlobalTypeInferenceResults results, | 240 GlobalTypeInferenceResults results, |
244 CompilerOptions options, | 241 CompilerOptions options, |
245 BackendHelpers helpers, | |
246 ClosedWorld closedWorld) { | 242 ClosedWorld closedWorld) { |
247 HInstruction left = instruction.inputs[1]; | 243 HInstruction left = instruction.inputs[1]; |
248 HInstruction right = instruction.inputs[2]; | 244 HInstruction right = instruction.inputs[2]; |
249 if (left.isIntegerOrNull(closedWorld) && | 245 if (left.isIntegerOrNull(closedWorld) && |
250 right.isIntegerOrNull(closedWorld)) { | 246 right.isIntegerOrNull(closedWorld)) { |
251 return closedWorld.commonMasks.intType; | 247 return closedWorld.commonMasks.intType; |
252 } | 248 } |
253 if (left.isNumberOrNull(closedWorld)) { | 249 if (left.isNumberOrNull(closedWorld)) { |
254 if (left.isDoubleOrNull(closedWorld) || | 250 if (left.isDoubleOrNull(closedWorld) || |
255 right.isDoubleOrNull(closedWorld)) { | 251 right.isDoubleOrNull(closedWorld)) { |
256 return closedWorld.commonMasks.doubleType; | 252 return closedWorld.commonMasks.doubleType; |
257 } | 253 } |
258 return closedWorld.commonMasks.numType; | 254 return closedWorld.commonMasks.numType; |
259 } | 255 } |
260 return super.computeTypeFromInputTypes( | 256 return super |
261 instruction, results, options, helpers, closedWorld); | 257 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
262 } | 258 } |
263 | 259 |
264 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) { | 260 bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) { |
265 return instruction.inputs[1].isNumber(closedWorld) && | 261 return instruction.inputs[1].isNumber(closedWorld) && |
266 instruction.inputs[2].isNumber(closedWorld); | 262 instruction.inputs[2].isNumber(closedWorld); |
267 } | 263 } |
268 | 264 |
269 HInstruction tryConvertToBuiltin( | 265 HInstruction tryConvertToBuiltin( |
270 HInvokeDynamic instruction, | 266 HInvokeDynamic instruction, |
271 HGraph graph, | 267 HGraph graph, |
272 GlobalTypeInferenceResults results, | 268 GlobalTypeInferenceResults results, |
273 CompilerOptions options, | 269 CompilerOptions options, |
274 BackendHelpers helpers, | 270 CommonElements commonElements, |
275 ClosedWorld closedWorld) { | 271 ClosedWorld closedWorld) { |
276 if (isBuiltin(instruction, closedWorld)) { | 272 if (isBuiltin(instruction, closedWorld)) { |
277 HInstruction builtin = newBuiltinVariant( | 273 HInstruction builtin = |
278 instruction, results, options, helpers, closedWorld); | 274 newBuiltinVariant(instruction, results, options, closedWorld); |
279 if (builtin != null) return builtin; | 275 if (builtin != null) return builtin; |
280 // Even if there is no builtin equivalent instruction, we know | 276 // Even if there is no builtin equivalent instruction, we know |
281 // the instruction does not have any side effect, and that it | 277 // the instruction does not have any side effect, and that it |
282 // can be GVN'ed. | 278 // can be GVN'ed. |
283 clearAllSideEffects(instruction); | 279 clearAllSideEffects(instruction); |
284 } | 280 } |
285 return null; | 281 return null; |
286 } | 282 } |
287 | 283 |
288 bool inputsArePositiveIntegers( | 284 bool inputsArePositiveIntegers( |
289 HInstruction instruction, ClosedWorld closedWorld) { | 285 HInstruction instruction, ClosedWorld closedWorld) { |
290 HInstruction left = instruction.inputs[1]; | 286 HInstruction left = instruction.inputs[1]; |
291 HInstruction right = instruction.inputs[2]; | 287 HInstruction right = instruction.inputs[2]; |
292 return left.isPositiveIntegerOrNull(closedWorld) && | 288 return left.isPositiveIntegerOrNull(closedWorld) && |
293 right.isPositiveIntegerOrNull(closedWorld); | 289 right.isPositiveIntegerOrNull(closedWorld); |
294 } | 290 } |
295 | 291 |
296 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) { | 292 bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) { |
297 HInstruction left = instruction.inputs[1]; | 293 HInstruction left = instruction.inputs[1]; |
298 HInstruction right = instruction.inputs[2]; | 294 HInstruction right = instruction.inputs[2]; |
299 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld); | 295 return left.isUInt31(closedWorld) && right.isUInt31(closedWorld); |
300 } | 296 } |
301 | 297 |
302 HInstruction newBuiltinVariant( | 298 HInstruction newBuiltinVariant( |
303 HInvokeDynamic instruction, | 299 HInvokeDynamic instruction, |
304 GlobalTypeInferenceResults results, | 300 GlobalTypeInferenceResults results, |
305 CompilerOptions options, | 301 CompilerOptions options, |
306 BackendHelpers helpers, | |
307 ClosedWorld closedWorld); | 302 ClosedWorld closedWorld); |
308 } | 303 } |
309 | 304 |
310 class AddSpecializer extends BinaryArithmeticSpecializer { | 305 class AddSpecializer extends BinaryArithmeticSpecializer { |
311 const AddSpecializer(); | 306 const AddSpecializer(); |
312 | 307 |
313 TypeMask computeTypeFromInputTypes( | 308 TypeMask computeTypeFromInputTypes( |
314 HInvokeDynamic instruction, | 309 HInvokeDynamic instruction, |
315 GlobalTypeInferenceResults results, | 310 GlobalTypeInferenceResults results, |
316 CompilerOptions options, | 311 CompilerOptions options, |
317 BackendHelpers helpers, | |
318 ClosedWorld closedWorld) { | 312 ClosedWorld closedWorld) { |
319 if (inputsAreUInt31(instruction, closedWorld)) { | 313 if (inputsAreUInt31(instruction, closedWorld)) { |
320 return closedWorld.commonMasks.uint32Type; | 314 return closedWorld.commonMasks.uint32Type; |
321 } | 315 } |
322 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 316 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
323 return closedWorld.commonMasks.positiveIntType; | 317 return closedWorld.commonMasks.positiveIntType; |
324 } | 318 } |
325 return super.computeTypeFromInputTypes( | 319 return super |
326 instruction, results, options, helpers, closedWorld); | 320 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
327 } | 321 } |
328 | 322 |
329 BinaryOperation operation(ConstantSystem constantSystem) { | 323 BinaryOperation operation(ConstantSystem constantSystem) { |
330 return constantSystem.add; | 324 return constantSystem.add; |
331 } | 325 } |
332 | 326 |
333 HInstruction newBuiltinVariant( | 327 HInstruction newBuiltinVariant( |
334 HInvokeDynamic instruction, | 328 HInvokeDynamic instruction, |
335 GlobalTypeInferenceResults results, | 329 GlobalTypeInferenceResults results, |
336 CompilerOptions options, | 330 CompilerOptions options, |
337 BackendHelpers helpers, | |
338 ClosedWorld closedWorld) { | 331 ClosedWorld closedWorld) { |
339 return new HAdd( | 332 return new HAdd( |
340 instruction.inputs[1], | 333 instruction.inputs[1], |
341 instruction.inputs[2], | 334 instruction.inputs[2], |
342 instruction.selector, | 335 instruction.selector, |
343 computeTypeFromInputTypes( | 336 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
344 instruction, results, options, helpers, closedWorld)); | |
345 } | 337 } |
346 } | 338 } |
347 | 339 |
348 class DivideSpecializer extends BinaryArithmeticSpecializer { | 340 class DivideSpecializer extends BinaryArithmeticSpecializer { |
349 const DivideSpecializer(); | 341 const DivideSpecializer(); |
350 | 342 |
351 BinaryOperation operation(ConstantSystem constantSystem) { | 343 BinaryOperation operation(ConstantSystem constantSystem) { |
352 return constantSystem.divide; | 344 return constantSystem.divide; |
353 } | 345 } |
354 | 346 |
355 TypeMask computeTypeFromInputTypes( | 347 TypeMask computeTypeFromInputTypes( |
356 HInstruction instruction, | 348 HInstruction instruction, |
357 GlobalTypeInferenceResults results, | 349 GlobalTypeInferenceResults results, |
358 CompilerOptions options, | 350 CompilerOptions options, |
359 BackendHelpers helpers, | |
360 ClosedWorld closedWorld) { | 351 ClosedWorld closedWorld) { |
361 HInstruction left = instruction.inputs[1]; | 352 HInstruction left = instruction.inputs[1]; |
362 if (left.isNumberOrNull(closedWorld)) { | 353 if (left.isNumberOrNull(closedWorld)) { |
363 return closedWorld.commonMasks.doubleType; | 354 return closedWorld.commonMasks.doubleType; |
364 } | 355 } |
365 return super.computeTypeFromInputTypes( | 356 return super |
366 instruction, results, options, helpers, closedWorld); | 357 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
367 } | 358 } |
368 | 359 |
369 HInstruction newBuiltinVariant( | 360 HInstruction newBuiltinVariant( |
370 HInvokeDynamic instruction, | 361 HInvokeDynamic instruction, |
371 GlobalTypeInferenceResults results, | 362 GlobalTypeInferenceResults results, |
372 CompilerOptions options, | 363 CompilerOptions options, |
373 BackendHelpers helpers, | |
374 ClosedWorld closedWorld) { | 364 ClosedWorld closedWorld) { |
375 return new HDivide(instruction.inputs[1], instruction.inputs[2], | 365 return new HDivide(instruction.inputs[1], instruction.inputs[2], |
376 instruction.selector, closedWorld.commonMasks.doubleType); | 366 instruction.selector, closedWorld.commonMasks.doubleType); |
377 } | 367 } |
378 } | 368 } |
379 | 369 |
380 class ModuloSpecializer extends BinaryArithmeticSpecializer { | 370 class ModuloSpecializer extends BinaryArithmeticSpecializer { |
381 const ModuloSpecializer(); | 371 const ModuloSpecializer(); |
382 | 372 |
383 TypeMask computeTypeFromInputTypes( | 373 TypeMask computeTypeFromInputTypes( |
384 HInvokeDynamic instruction, | 374 HInvokeDynamic instruction, |
385 GlobalTypeInferenceResults results, | 375 GlobalTypeInferenceResults results, |
386 CompilerOptions options, | 376 CompilerOptions options, |
387 BackendHelpers helpers, | |
388 ClosedWorld closedWorld) { | 377 ClosedWorld closedWorld) { |
389 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 378 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
390 return closedWorld.commonMasks.positiveIntType; | 379 return closedWorld.commonMasks.positiveIntType; |
391 } | 380 } |
392 return super.computeTypeFromInputTypes( | 381 return super |
393 instruction, results, options, helpers, closedWorld); | 382 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
394 } | 383 } |
395 | 384 |
396 BinaryOperation operation(ConstantSystem constantSystem) { | 385 BinaryOperation operation(ConstantSystem constantSystem) { |
397 return constantSystem.modulo; | 386 return constantSystem.modulo; |
398 } | 387 } |
399 | 388 |
400 HInstruction newBuiltinVariant( | 389 HInstruction newBuiltinVariant( |
401 HInvokeDynamic instruction, | 390 HInvokeDynamic instruction, |
402 GlobalTypeInferenceResults results, | 391 GlobalTypeInferenceResults results, |
403 CompilerOptions options, | 392 CompilerOptions options, |
404 BackendHelpers helpers, | |
405 ClosedWorld closedWorld) { | 393 ClosedWorld closedWorld) { |
406 // Modulo cannot be mapped to the native operator (different semantics). | 394 // Modulo cannot be mapped to the native operator (different semantics). |
407 | 395 |
408 // We can use HRemainder if both inputs are non-negative and the receiver | 396 // We can use HRemainder if both inputs are non-negative and the receiver |
409 // cannot be -0.0. Note that -0.0 is considered to be an int, so until we | 397 // cannot be -0.0. Note that -0.0 is considered to be an int, so until we |
410 // track -0.0 precisely, we have to syntatically filter inputs that cannot | 398 // track -0.0 precisely, we have to syntatically filter inputs that cannot |
411 // generate -0.0. | 399 // generate -0.0. |
412 bool canBePositiveZero(HInstruction input) { | 400 bool canBePositiveZero(HInstruction input) { |
413 if (input is HConstant) { | 401 if (input is HConstant) { |
414 ConstantValue value = input.constant; | 402 ConstantValue value = input.constant; |
(...skipping 28 matching lines...) Expand all Loading... |
443 return true; | 431 return true; |
444 } | 432 } |
445 | 433 |
446 if (inputsArePositiveIntegers(instruction, closedWorld) && | 434 if (inputsArePositiveIntegers(instruction, closedWorld) && |
447 !canBeNegativeZero(instruction.getDartReceiver(closedWorld))) { | 435 !canBeNegativeZero(instruction.getDartReceiver(closedWorld))) { |
448 return new HRemainder( | 436 return new HRemainder( |
449 instruction.inputs[1], | 437 instruction.inputs[1], |
450 instruction.inputs[2], | 438 instruction.inputs[2], |
451 instruction.selector, | 439 instruction.selector, |
452 computeTypeFromInputTypes( | 440 computeTypeFromInputTypes( |
453 instruction, results, options, helpers, closedWorld)); | 441 instruction, results, options, closedWorld)); |
454 } | 442 } |
455 // TODO(sra): | 443 // TODO(sra): |
456 // a % N --> a & (N-1), N=2^k, where a>=0, does not have -0.0 problem. | 444 // a % N --> a & (N-1), N=2^k, where a>=0, does not have -0.0 problem. |
457 | 445 |
458 // TODO(sra): We could avoid problems with -0.0 if we generate x % y as (x + | 446 // TODO(sra): We could avoid problems with -0.0 if we generate x % y as (x + |
459 // 0) % y, but we would have to fix HAdd optimizations. | 447 // 0) % y, but we would have to fix HAdd optimizations. |
460 | 448 |
461 // TODO(sra): We could replace $mod with HRemainder when we don't care about | 449 // TODO(sra): We could replace $mod with HRemainder when we don't care about |
462 // a -0.0 result (e.g. a % 10 == 0, a[i % 3]). This is tricky, since we | 450 // a -0.0 result (e.g. a % 10 == 0, a[i % 3]). This is tricky, since we |
463 // don't want to ruin GVN opportunities. | 451 // don't want to ruin GVN opportunities. |
464 return null; | 452 return null; |
465 } | 453 } |
466 } | 454 } |
467 | 455 |
468 class RemainderSpecializer extends BinaryArithmeticSpecializer { | 456 class RemainderSpecializer extends BinaryArithmeticSpecializer { |
469 const RemainderSpecializer(); | 457 const RemainderSpecializer(); |
470 | 458 |
471 TypeMask computeTypeFromInputTypes( | 459 TypeMask computeTypeFromInputTypes( |
472 HInvokeDynamic instruction, | 460 HInvokeDynamic instruction, |
473 GlobalTypeInferenceResults results, | 461 GlobalTypeInferenceResults results, |
474 CompilerOptions options, | 462 CompilerOptions options, |
475 BackendHelpers helpers, | |
476 ClosedWorld closedWorld) { | 463 ClosedWorld closedWorld) { |
477 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 464 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
478 return closedWorld.commonMasks.positiveIntType; | 465 return closedWorld.commonMasks.positiveIntType; |
479 } | 466 } |
480 return super.computeTypeFromInputTypes( | 467 return super |
481 instruction, results, options, helpers, closedWorld); | 468 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
482 } | 469 } |
483 | 470 |
484 BinaryOperation operation(ConstantSystem constantSystem) { | 471 BinaryOperation operation(ConstantSystem constantSystem) { |
485 return constantSystem.remainder; | 472 return constantSystem.remainder; |
486 } | 473 } |
487 | 474 |
488 HInstruction newBuiltinVariant( | 475 HInstruction newBuiltinVariant( |
489 HInvokeDynamic instruction, | 476 HInvokeDynamic instruction, |
490 GlobalTypeInferenceResults results, | 477 GlobalTypeInferenceResults results, |
491 CompilerOptions options, | 478 CompilerOptions options, |
492 BackendHelpers helpers, | |
493 ClosedWorld closedWorld) { | 479 ClosedWorld closedWorld) { |
494 return new HRemainder( | 480 return new HRemainder( |
495 instruction.inputs[1], | 481 instruction.inputs[1], |
496 instruction.inputs[2], | 482 instruction.inputs[2], |
497 instruction.selector, | 483 instruction.selector, |
498 computeTypeFromInputTypes( | 484 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
499 instruction, results, options, helpers, closedWorld)); | |
500 } | 485 } |
501 } | 486 } |
502 | 487 |
503 class MultiplySpecializer extends BinaryArithmeticSpecializer { | 488 class MultiplySpecializer extends BinaryArithmeticSpecializer { |
504 const MultiplySpecializer(); | 489 const MultiplySpecializer(); |
505 | 490 |
506 BinaryOperation operation(ConstantSystem constantSystem) { | 491 BinaryOperation operation(ConstantSystem constantSystem) { |
507 return constantSystem.multiply; | 492 return constantSystem.multiply; |
508 } | 493 } |
509 | 494 |
510 TypeMask computeTypeFromInputTypes( | 495 TypeMask computeTypeFromInputTypes( |
511 HInvokeDynamic instruction, | 496 HInvokeDynamic instruction, |
512 GlobalTypeInferenceResults results, | 497 GlobalTypeInferenceResults results, |
513 CompilerOptions options, | 498 CompilerOptions options, |
514 BackendHelpers helpers, | |
515 ClosedWorld closedWorld) { | 499 ClosedWorld closedWorld) { |
516 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 500 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
517 return closedWorld.commonMasks.positiveIntType; | 501 return closedWorld.commonMasks.positiveIntType; |
518 } | 502 } |
519 return super.computeTypeFromInputTypes( | 503 return super |
520 instruction, results, options, helpers, closedWorld); | 504 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
521 } | 505 } |
522 | 506 |
523 HInstruction newBuiltinVariant( | 507 HInstruction newBuiltinVariant( |
524 HInvokeDynamic instruction, | 508 HInvokeDynamic instruction, |
525 GlobalTypeInferenceResults results, | 509 GlobalTypeInferenceResults results, |
526 CompilerOptions options, | 510 CompilerOptions options, |
527 BackendHelpers helpers, | |
528 ClosedWorld closedWorld) { | 511 ClosedWorld closedWorld) { |
529 return new HMultiply( | 512 return new HMultiply( |
530 instruction.inputs[1], | 513 instruction.inputs[1], |
531 instruction.inputs[2], | 514 instruction.inputs[2], |
532 instruction.selector, | 515 instruction.selector, |
533 computeTypeFromInputTypes( | 516 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
534 instruction, results, options, helpers, closedWorld)); | |
535 } | 517 } |
536 } | 518 } |
537 | 519 |
538 class SubtractSpecializer extends BinaryArithmeticSpecializer { | 520 class SubtractSpecializer extends BinaryArithmeticSpecializer { |
539 const SubtractSpecializer(); | 521 const SubtractSpecializer(); |
540 | 522 |
541 BinaryOperation operation(ConstantSystem constantSystem) { | 523 BinaryOperation operation(ConstantSystem constantSystem) { |
542 return constantSystem.subtract; | 524 return constantSystem.subtract; |
543 } | 525 } |
544 | 526 |
545 HInstruction newBuiltinVariant( | 527 HInstruction newBuiltinVariant( |
546 HInvokeDynamic instruction, | 528 HInvokeDynamic instruction, |
547 GlobalTypeInferenceResults results, | 529 GlobalTypeInferenceResults results, |
548 CompilerOptions options, | 530 CompilerOptions options, |
549 BackendHelpers helpers, | |
550 ClosedWorld closedWorld) { | 531 ClosedWorld closedWorld) { |
551 return new HSubtract( | 532 return new HSubtract( |
552 instruction.inputs[1], | 533 instruction.inputs[1], |
553 instruction.inputs[2], | 534 instruction.inputs[2], |
554 instruction.selector, | 535 instruction.selector, |
555 computeTypeFromInputTypes( | 536 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
556 instruction, results, options, helpers, closedWorld)); | |
557 } | 537 } |
558 } | 538 } |
559 | 539 |
560 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { | 540 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { |
561 const TruncatingDivideSpecializer(); | 541 const TruncatingDivideSpecializer(); |
562 | 542 |
563 BinaryOperation operation(ConstantSystem constantSystem) { | 543 BinaryOperation operation(ConstantSystem constantSystem) { |
564 return constantSystem.truncatingDivide; | 544 return constantSystem.truncatingDivide; |
565 } | 545 } |
566 | 546 |
567 TypeMask computeTypeFromInputTypes( | 547 TypeMask computeTypeFromInputTypes( |
568 HInvokeDynamic instruction, | 548 HInvokeDynamic instruction, |
569 GlobalTypeInferenceResults results, | 549 GlobalTypeInferenceResults results, |
570 CompilerOptions options, | 550 CompilerOptions options, |
571 BackendHelpers helpers, | |
572 ClosedWorld closedWorld) { | 551 ClosedWorld closedWorld) { |
573 if (hasUint31Result(instruction, closedWorld)) { | 552 if (hasUint31Result(instruction, closedWorld)) { |
574 return closedWorld.commonMasks.uint31Type; | 553 return closedWorld.commonMasks.uint31Type; |
575 } | 554 } |
576 if (inputsArePositiveIntegers(instruction, closedWorld)) { | 555 if (inputsArePositiveIntegers(instruction, closedWorld)) { |
577 return closedWorld.commonMasks.positiveIntType; | 556 return closedWorld.commonMasks.positiveIntType; |
578 } | 557 } |
579 return super.computeTypeFromInputTypes( | 558 return super |
580 instruction, results, options, helpers, closedWorld); | 559 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
581 } | 560 } |
582 | 561 |
583 bool isNotZero(HInstruction instruction) { | 562 bool isNotZero(HInstruction instruction) { |
584 if (!instruction.isConstantInteger()) return false; | 563 if (!instruction.isConstantInteger()) return false; |
585 HConstant rightConstant = instruction; | 564 HConstant rightConstant = instruction; |
586 IntConstantValue intConstant = rightConstant.constant; | 565 IntConstantValue intConstant = rightConstant.constant; |
587 int count = intConstant.primitiveValue; | 566 int count = intConstant.primitiveValue; |
588 return count != 0; | 567 return count != 0; |
589 } | 568 } |
590 | 569 |
(...skipping 17 matching lines...) Expand all Loading... |
608 } | 587 } |
609 } | 588 } |
610 return false; | 589 return false; |
611 } | 590 } |
612 | 591 |
613 HInstruction tryConvertToBuiltin( | 592 HInstruction tryConvertToBuiltin( |
614 HInvokeDynamic instruction, | 593 HInvokeDynamic instruction, |
615 HGraph graph, | 594 HGraph graph, |
616 GlobalTypeInferenceResults results, | 595 GlobalTypeInferenceResults results, |
617 CompilerOptions options, | 596 CompilerOptions options, |
618 BackendHelpers helpers, | 597 CommonElements commonElements, |
619 ClosedWorld closedWorld) { | 598 ClosedWorld closedWorld) { |
620 HInstruction right = instruction.inputs[2]; | 599 HInstruction right = instruction.inputs[2]; |
621 if (isBuiltin(instruction, closedWorld)) { | 600 if (isBuiltin(instruction, closedWorld)) { |
622 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) { | 601 if (right.isPositiveInteger(closedWorld) && isNotZero(right)) { |
623 if (hasUint31Result(instruction, closedWorld)) { | 602 if (hasUint31Result(instruction, closedWorld)) { |
624 return newBuiltinVariant( | 603 return newBuiltinVariant(instruction, results, options, closedWorld); |
625 instruction, results, options, helpers, closedWorld); | |
626 } | 604 } |
627 // We can call _tdivFast because the rhs is a 32bit integer | 605 // We can call _tdivFast because the rhs is a 32bit integer |
628 // and not 0, nor -1. | 606 // and not 0, nor -1. |
629 instruction.selector = renameToOptimizedSelector( | 607 instruction.selector = renameToOptimizedSelector( |
630 '_tdivFast', instruction.selector, helpers); | 608 '_tdivFast', instruction.selector, commonElements); |
631 } | 609 } |
632 clearAllSideEffects(instruction); | 610 clearAllSideEffects(instruction); |
633 } | 611 } |
634 return null; | 612 return null; |
635 } | 613 } |
636 | 614 |
637 HInstruction newBuiltinVariant( | 615 HInstruction newBuiltinVariant( |
638 HInvokeDynamic instruction, | 616 HInvokeDynamic instruction, |
639 GlobalTypeInferenceResults results, | 617 GlobalTypeInferenceResults results, |
640 CompilerOptions options, | 618 CompilerOptions options, |
641 BackendHelpers helpers, | |
642 ClosedWorld closedWorld) { | 619 ClosedWorld closedWorld) { |
643 return new HTruncatingDivide( | 620 return new HTruncatingDivide( |
644 instruction.inputs[1], | 621 instruction.inputs[1], |
645 instruction.inputs[2], | 622 instruction.inputs[2], |
646 instruction.selector, | 623 instruction.selector, |
647 computeTypeFromInputTypes( | 624 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
648 instruction, results, options, helpers, closedWorld)); | |
649 } | 625 } |
650 } | 626 } |
651 | 627 |
652 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 628 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
653 const BinaryBitOpSpecializer(); | 629 const BinaryBitOpSpecializer(); |
654 | 630 |
655 TypeMask computeTypeFromInputTypes( | 631 TypeMask computeTypeFromInputTypes( |
656 HInvokeDynamic instruction, | 632 HInvokeDynamic instruction, |
657 GlobalTypeInferenceResults results, | 633 GlobalTypeInferenceResults results, |
658 CompilerOptions options, | 634 CompilerOptions options, |
659 BackendHelpers helpers, | |
660 ClosedWorld closedWorld) { | 635 ClosedWorld closedWorld) { |
661 // All bitwise operations on primitive types either produce an | 636 // All bitwise operations on primitive types either produce an |
662 // integer or throw an error. | 637 // integer or throw an error. |
663 HInstruction left = instruction.inputs[1]; | 638 HInstruction left = instruction.inputs[1]; |
664 if (left.isPrimitiveOrNull(closedWorld)) { | 639 if (left.isPrimitiveOrNull(closedWorld)) { |
665 return closedWorld.commonMasks.uint32Type; | 640 return closedWorld.commonMasks.uint32Type; |
666 } | 641 } |
667 return super.computeTypeFromInputTypes( | 642 return super |
668 instruction, results, options, helpers, closedWorld); | 643 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
669 } | 644 } |
670 | 645 |
671 bool argumentLessThan32(HInstruction instruction) { | 646 bool argumentLessThan32(HInstruction instruction) { |
672 return argumentInRange(instruction, 0, 31); | 647 return argumentInRange(instruction, 0, 31); |
673 } | 648 } |
674 | 649 |
675 bool argumentInRange(HInstruction instruction, int low, int high) { | 650 bool argumentInRange(HInstruction instruction, int low, int high) { |
676 if (instruction.isConstantInteger()) { | 651 if (instruction.isConstantInteger()) { |
677 HConstant rightConstant = instruction; | 652 HConstant rightConstant = instruction; |
678 IntConstantValue intConstant = rightConstant.constant; | 653 IntConstantValue intConstant = rightConstant.constant; |
(...skipping 21 matching lines...) Expand all Loading... |
700 | 675 |
701 BinaryOperation operation(ConstantSystem constantSystem) { | 676 BinaryOperation operation(ConstantSystem constantSystem) { |
702 return constantSystem.shiftLeft; | 677 return constantSystem.shiftLeft; |
703 } | 678 } |
704 | 679 |
705 HInstruction tryConvertToBuiltin( | 680 HInstruction tryConvertToBuiltin( |
706 HInvokeDynamic instruction, | 681 HInvokeDynamic instruction, |
707 HGraph graph, | 682 HGraph graph, |
708 GlobalTypeInferenceResults results, | 683 GlobalTypeInferenceResults results, |
709 CompilerOptions options, | 684 CompilerOptions options, |
710 BackendHelpers helpers, | 685 CommonElements commonElements, |
711 ClosedWorld closedWorld) { | 686 ClosedWorld closedWorld) { |
712 HInstruction left = instruction.inputs[1]; | 687 HInstruction left = instruction.inputs[1]; |
713 HInstruction right = instruction.inputs[2]; | 688 HInstruction right = instruction.inputs[2]; |
714 if (left.isNumber(closedWorld)) { | 689 if (left.isNumber(closedWorld)) { |
715 if (argumentLessThan32(right)) { | 690 if (argumentLessThan32(right)) { |
716 return newBuiltinVariant( | 691 return newBuiltinVariant(instruction, results, options, closedWorld); |
717 instruction, results, options, helpers, closedWorld); | |
718 } | 692 } |
719 // Even if there is no builtin equivalent instruction, we know | 693 // Even if there is no builtin equivalent instruction, we know |
720 // the instruction does not have any side effect, and that it | 694 // the instruction does not have any side effect, and that it |
721 // can be GVN'ed. | 695 // can be GVN'ed. |
722 clearAllSideEffects(instruction); | 696 clearAllSideEffects(instruction); |
723 if (isPositive(right, closedWorld)) { | 697 if (isPositive(right, closedWorld)) { |
724 instruction.selector = renameToOptimizedSelector( | 698 instruction.selector = renameToOptimizedSelector( |
725 '_shlPositive', instruction.selector, helpers); | 699 '_shlPositive', instruction.selector, commonElements); |
726 } | 700 } |
727 } | 701 } |
728 return null; | 702 return null; |
729 } | 703 } |
730 | 704 |
731 HInstruction newBuiltinVariant( | 705 HInstruction newBuiltinVariant( |
732 HInvokeDynamic instruction, | 706 HInvokeDynamic instruction, |
733 GlobalTypeInferenceResults results, | 707 GlobalTypeInferenceResults results, |
734 CompilerOptions options, | 708 CompilerOptions options, |
735 BackendHelpers helpers, | |
736 ClosedWorld closedWorld) { | 709 ClosedWorld closedWorld) { |
737 return new HShiftLeft( | 710 return new HShiftLeft( |
738 instruction.inputs[1], | 711 instruction.inputs[1], |
739 instruction.inputs[2], | 712 instruction.inputs[2], |
740 instruction.selector, | 713 instruction.selector, |
741 computeTypeFromInputTypes( | 714 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
742 instruction, results, options, helpers, closedWorld)); | |
743 } | 715 } |
744 } | 716 } |
745 | 717 |
746 class ShiftRightSpecializer extends BinaryBitOpSpecializer { | 718 class ShiftRightSpecializer extends BinaryBitOpSpecializer { |
747 const ShiftRightSpecializer(); | 719 const ShiftRightSpecializer(); |
748 | 720 |
749 TypeMask computeTypeFromInputTypes( | 721 TypeMask computeTypeFromInputTypes( |
750 HInvokeDynamic instruction, | 722 HInvokeDynamic instruction, |
751 GlobalTypeInferenceResults results, | 723 GlobalTypeInferenceResults results, |
752 CompilerOptions options, | 724 CompilerOptions options, |
753 BackendHelpers helpers, | |
754 ClosedWorld closedWorld) { | 725 ClosedWorld closedWorld) { |
755 HInstruction left = instruction.inputs[1]; | 726 HInstruction left = instruction.inputs[1]; |
756 if (left.isUInt32(closedWorld)) return left.instructionType; | 727 if (left.isUInt32(closedWorld)) return left.instructionType; |
757 return super.computeTypeFromInputTypes( | 728 return super |
758 instruction, results, options, helpers, closedWorld); | 729 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
759 } | 730 } |
760 | 731 |
761 HInstruction tryConvertToBuiltin( | 732 HInstruction tryConvertToBuiltin( |
762 HInvokeDynamic instruction, | 733 HInvokeDynamic instruction, |
763 HGraph graph, | 734 HGraph graph, |
764 GlobalTypeInferenceResults results, | 735 GlobalTypeInferenceResults results, |
765 CompilerOptions options, | 736 CompilerOptions options, |
766 BackendHelpers helpers, | 737 CommonElements commonElements, |
767 ClosedWorld closedWorld) { | 738 ClosedWorld closedWorld) { |
768 HInstruction left = instruction.inputs[1]; | 739 HInstruction left = instruction.inputs[1]; |
769 HInstruction right = instruction.inputs[2]; | 740 HInstruction right = instruction.inputs[2]; |
770 if (left.isNumber(closedWorld)) { | 741 if (left.isNumber(closedWorld)) { |
771 if (argumentLessThan32(right) && isPositive(left, closedWorld)) { | 742 if (argumentLessThan32(right) && isPositive(left, closedWorld)) { |
772 return newBuiltinVariant( | 743 return newBuiltinVariant(instruction, results, options, closedWorld); |
773 instruction, results, options, helpers, closedWorld); | |
774 } | 744 } |
775 // Even if there is no builtin equivalent instruction, we know | 745 // Even if there is no builtin equivalent instruction, we know |
776 // the instruction does not have any side effect, and that it | 746 // the instruction does not have any side effect, and that it |
777 // can be GVN'ed. | 747 // can be GVN'ed. |
778 clearAllSideEffects(instruction); | 748 clearAllSideEffects(instruction); |
779 if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) { | 749 if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) { |
780 instruction.selector = renameToOptimizedSelector( | 750 instruction.selector = renameToOptimizedSelector( |
781 '_shrBothPositive', instruction.selector, helpers); | 751 '_shrBothPositive', instruction.selector, commonElements); |
782 } else if (isPositive(left, closedWorld) && right.isNumber(closedWorld)) { | 752 } else if (isPositive(left, closedWorld) && right.isNumber(closedWorld)) { |
783 instruction.selector = renameToOptimizedSelector( | 753 instruction.selector = renameToOptimizedSelector( |
784 '_shrReceiverPositive', instruction.selector, helpers); | 754 '_shrReceiverPositive', instruction.selector, commonElements); |
785 } else if (isPositive(right, closedWorld)) { | 755 } else if (isPositive(right, closedWorld)) { |
786 instruction.selector = renameToOptimizedSelector( | 756 instruction.selector = renameToOptimizedSelector( |
787 '_shrOtherPositive', instruction.selector, helpers); | 757 '_shrOtherPositive', instruction.selector, commonElements); |
788 } | 758 } |
789 } | 759 } |
790 return null; | 760 return null; |
791 } | 761 } |
792 | 762 |
793 HInstruction newBuiltinVariant( | 763 HInstruction newBuiltinVariant( |
794 HInvokeDynamic instruction, | 764 HInvokeDynamic instruction, |
795 GlobalTypeInferenceResults results, | 765 GlobalTypeInferenceResults results, |
796 CompilerOptions options, | 766 CompilerOptions options, |
797 BackendHelpers helpers, | |
798 ClosedWorld closedWorld) { | 767 ClosedWorld closedWorld) { |
799 return new HShiftRight( | 768 return new HShiftRight( |
800 instruction.inputs[1], | 769 instruction.inputs[1], |
801 instruction.inputs[2], | 770 instruction.inputs[2], |
802 instruction.selector, | 771 instruction.selector, |
803 computeTypeFromInputTypes( | 772 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
804 instruction, results, options, helpers, closedWorld)); | |
805 } | 773 } |
806 | 774 |
807 BinaryOperation operation(ConstantSystem constantSystem) { | 775 BinaryOperation operation(ConstantSystem constantSystem) { |
808 return constantSystem.shiftRight; | 776 return constantSystem.shiftRight; |
809 } | 777 } |
810 } | 778 } |
811 | 779 |
812 class BitOrSpecializer extends BinaryBitOpSpecializer { | 780 class BitOrSpecializer extends BinaryBitOpSpecializer { |
813 const BitOrSpecializer(); | 781 const BitOrSpecializer(); |
814 | 782 |
815 BinaryOperation operation(ConstantSystem constantSystem) { | 783 BinaryOperation operation(ConstantSystem constantSystem) { |
816 return constantSystem.bitOr; | 784 return constantSystem.bitOr; |
817 } | 785 } |
818 | 786 |
819 TypeMask computeTypeFromInputTypes( | 787 TypeMask computeTypeFromInputTypes( |
820 HInvokeDynamic instruction, | 788 HInvokeDynamic instruction, |
821 GlobalTypeInferenceResults results, | 789 GlobalTypeInferenceResults results, |
822 CompilerOptions options, | 790 CompilerOptions options, |
823 BackendHelpers helpers, | |
824 ClosedWorld closedWorld) { | 791 ClosedWorld closedWorld) { |
825 HInstruction left = instruction.inputs[1]; | 792 HInstruction left = instruction.inputs[1]; |
826 HInstruction right = instruction.inputs[2]; | 793 HInstruction right = instruction.inputs[2]; |
827 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { | 794 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { |
828 return closedWorld.commonMasks.uint31Type; | 795 return closedWorld.commonMasks.uint31Type; |
829 } | 796 } |
830 return super.computeTypeFromInputTypes( | 797 return super |
831 instruction, results, options, helpers, closedWorld); | 798 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
832 } | 799 } |
833 | 800 |
834 HInstruction newBuiltinVariant( | 801 HInstruction newBuiltinVariant( |
835 HInvokeDynamic instruction, | 802 HInvokeDynamic instruction, |
836 GlobalTypeInferenceResults results, | 803 GlobalTypeInferenceResults results, |
837 CompilerOptions options, | 804 CompilerOptions options, |
838 BackendHelpers helpers, | |
839 ClosedWorld closedWorld) { | 805 ClosedWorld closedWorld) { |
840 return new HBitOr( | 806 return new HBitOr( |
841 instruction.inputs[1], | 807 instruction.inputs[1], |
842 instruction.inputs[2], | 808 instruction.inputs[2], |
843 instruction.selector, | 809 instruction.selector, |
844 computeTypeFromInputTypes( | 810 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
845 instruction, results, options, helpers, closedWorld)); | |
846 } | 811 } |
847 } | 812 } |
848 | 813 |
849 class BitAndSpecializer extends BinaryBitOpSpecializer { | 814 class BitAndSpecializer extends BinaryBitOpSpecializer { |
850 const BitAndSpecializer(); | 815 const BitAndSpecializer(); |
851 | 816 |
852 BinaryOperation operation(ConstantSystem constantSystem) { | 817 BinaryOperation operation(ConstantSystem constantSystem) { |
853 return constantSystem.bitAnd; | 818 return constantSystem.bitAnd; |
854 } | 819 } |
855 | 820 |
856 TypeMask computeTypeFromInputTypes( | 821 TypeMask computeTypeFromInputTypes( |
857 HInvokeDynamic instruction, | 822 HInvokeDynamic instruction, |
858 GlobalTypeInferenceResults results, | 823 GlobalTypeInferenceResults results, |
859 CompilerOptions options, | 824 CompilerOptions options, |
860 BackendHelpers helpers, | |
861 ClosedWorld closedWorld) { | 825 ClosedWorld closedWorld) { |
862 HInstruction left = instruction.inputs[1]; | 826 HInstruction left = instruction.inputs[1]; |
863 HInstruction right = instruction.inputs[2]; | 827 HInstruction right = instruction.inputs[2]; |
864 if (left.isPrimitiveOrNull(closedWorld) && | 828 if (left.isPrimitiveOrNull(closedWorld) && |
865 (left.isUInt31(closedWorld) || right.isUInt31(closedWorld))) { | 829 (left.isUInt31(closedWorld) || right.isUInt31(closedWorld))) { |
866 return closedWorld.commonMasks.uint31Type; | 830 return closedWorld.commonMasks.uint31Type; |
867 } | 831 } |
868 return super.computeTypeFromInputTypes( | 832 return super |
869 instruction, results, options, helpers, closedWorld); | 833 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
870 } | 834 } |
871 | 835 |
872 HInstruction newBuiltinVariant( | 836 HInstruction newBuiltinVariant( |
873 HInvokeDynamic instruction, | 837 HInvokeDynamic instruction, |
874 GlobalTypeInferenceResults results, | 838 GlobalTypeInferenceResults results, |
875 CompilerOptions options, | 839 CompilerOptions options, |
876 BackendHelpers helpers, | |
877 ClosedWorld closedWorld) { | 840 ClosedWorld closedWorld) { |
878 return new HBitAnd( | 841 return new HBitAnd( |
879 instruction.inputs[1], | 842 instruction.inputs[1], |
880 instruction.inputs[2], | 843 instruction.inputs[2], |
881 instruction.selector, | 844 instruction.selector, |
882 computeTypeFromInputTypes( | 845 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
883 instruction, results, options, helpers, closedWorld)); | |
884 } | 846 } |
885 } | 847 } |
886 | 848 |
887 class BitXorSpecializer extends BinaryBitOpSpecializer { | 849 class BitXorSpecializer extends BinaryBitOpSpecializer { |
888 const BitXorSpecializer(); | 850 const BitXorSpecializer(); |
889 | 851 |
890 BinaryOperation operation(ConstantSystem constantSystem) { | 852 BinaryOperation operation(ConstantSystem constantSystem) { |
891 return constantSystem.bitXor; | 853 return constantSystem.bitXor; |
892 } | 854 } |
893 | 855 |
894 TypeMask computeTypeFromInputTypes( | 856 TypeMask computeTypeFromInputTypes( |
895 HInvokeDynamic instruction, | 857 HInvokeDynamic instruction, |
896 GlobalTypeInferenceResults results, | 858 GlobalTypeInferenceResults results, |
897 CompilerOptions options, | 859 CompilerOptions options, |
898 BackendHelpers helpers, | |
899 ClosedWorld closedWorld) { | 860 ClosedWorld closedWorld) { |
900 HInstruction left = instruction.inputs[1]; | 861 HInstruction left = instruction.inputs[1]; |
901 HInstruction right = instruction.inputs[2]; | 862 HInstruction right = instruction.inputs[2]; |
902 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { | 863 if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) { |
903 return closedWorld.commonMasks.uint31Type; | 864 return closedWorld.commonMasks.uint31Type; |
904 } | 865 } |
905 return super.computeTypeFromInputTypes( | 866 return super |
906 instruction, results, options, helpers, closedWorld); | 867 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
907 } | 868 } |
908 | 869 |
909 HInstruction newBuiltinVariant( | 870 HInstruction newBuiltinVariant( |
910 HInvokeDynamic instruction, | 871 HInvokeDynamic instruction, |
911 GlobalTypeInferenceResults results, | 872 GlobalTypeInferenceResults results, |
912 CompilerOptions options, | 873 CompilerOptions options, |
913 BackendHelpers helpers, | |
914 ClosedWorld closedWorld) { | 874 ClosedWorld closedWorld) { |
915 return new HBitXor( | 875 return new HBitXor( |
916 instruction.inputs[1], | 876 instruction.inputs[1], |
917 instruction.inputs[2], | 877 instruction.inputs[2], |
918 instruction.selector, | 878 instruction.selector, |
919 computeTypeFromInputTypes( | 879 computeTypeFromInputTypes(instruction, results, options, closedWorld)); |
920 instruction, results, options, helpers, closedWorld)); | |
921 } | 880 } |
922 } | 881 } |
923 | 882 |
924 abstract class RelationalSpecializer extends InvokeDynamicSpecializer { | 883 abstract class RelationalSpecializer extends InvokeDynamicSpecializer { |
925 const RelationalSpecializer(); | 884 const RelationalSpecializer(); |
926 | 885 |
927 TypeMask computeTypeFromInputTypes( | 886 TypeMask computeTypeFromInputTypes( |
928 HInvokeDynamic instruction, | 887 HInvokeDynamic instruction, |
929 GlobalTypeInferenceResults results, | 888 GlobalTypeInferenceResults results, |
930 CompilerOptions options, | 889 CompilerOptions options, |
931 BackendHelpers helpers, | |
932 ClosedWorld closedWorld) { | 890 ClosedWorld closedWorld) { |
933 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { | 891 if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) { |
934 return closedWorld.commonMasks.boolType; | 892 return closedWorld.commonMasks.boolType; |
935 } | 893 } |
936 return super.computeTypeFromInputTypes( | 894 return super |
937 instruction, results, options, helpers, closedWorld); | 895 .computeTypeFromInputTypes(instruction, results, options, closedWorld); |
938 } | 896 } |
939 | 897 |
940 HInstruction tryConvertToBuiltin( | 898 HInstruction tryConvertToBuiltin( |
941 HInvokeDynamic instruction, | 899 HInvokeDynamic instruction, |
942 HGraph graph, | 900 HGraph graph, |
943 GlobalTypeInferenceResults results, | 901 GlobalTypeInferenceResults results, |
944 CompilerOptions options, | 902 CompilerOptions options, |
945 BackendHelpers helpers, | 903 CommonElements commonElements, |
946 ClosedWorld closedWorld) { | 904 ClosedWorld closedWorld) { |
947 HInstruction left = instruction.inputs[1]; | 905 HInstruction left = instruction.inputs[1]; |
948 HInstruction right = instruction.inputs[2]; | 906 HInstruction right = instruction.inputs[2]; |
949 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) { | 907 if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) { |
950 return newBuiltinVariant(instruction, closedWorld); | 908 return newBuiltinVariant(instruction, closedWorld); |
951 } | 909 } |
952 return null; | 910 return null; |
953 } | 911 } |
954 | 912 |
955 HInstruction newBuiltinVariant( | 913 HInstruction newBuiltinVariant( |
956 HInvokeDynamic instruction, ClosedWorld closedWorld); | 914 HInvokeDynamic instruction, ClosedWorld closedWorld); |
957 } | 915 } |
958 | 916 |
959 class EqualsSpecializer extends RelationalSpecializer { | 917 class EqualsSpecializer extends RelationalSpecializer { |
960 const EqualsSpecializer(); | 918 const EqualsSpecializer(); |
961 | 919 |
962 HInstruction tryConvertToBuiltin( | 920 HInstruction tryConvertToBuiltin( |
963 HInvokeDynamic instruction, | 921 HInvokeDynamic instruction, |
964 HGraph graph, | 922 HGraph graph, |
965 GlobalTypeInferenceResults results, | 923 GlobalTypeInferenceResults results, |
966 CompilerOptions options, | 924 CompilerOptions options, |
967 BackendHelpers helpers, | 925 CommonElements commonElements, |
968 ClosedWorld closedWorld) { | 926 ClosedWorld closedWorld) { |
969 HInstruction left = instruction.inputs[1]; | 927 HInstruction left = instruction.inputs[1]; |
970 HInstruction right = instruction.inputs[2]; | 928 HInstruction right = instruction.inputs[2]; |
971 TypeMask instructionType = left.instructionType; | 929 TypeMask instructionType = left.instructionType; |
972 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) { | 930 if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) { |
973 return newBuiltinVariant(instruction, closedWorld); | 931 return newBuiltinVariant(instruction, closedWorld); |
974 } | 932 } |
975 Iterable<MemberEntity> matches = | 933 Iterable<MemberEntity> matches = |
976 closedWorld.allFunctions.filter(instruction.selector, instructionType); | 934 closedWorld.allFunctions.filter(instruction.selector, instructionType); |
977 // This test relies the on `Object.==` and `Interceptor.==` always being | 935 // This test relies the on `Object.==` and `Interceptor.==` always being |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 | 1014 |
1057 BinaryOperation operation(ConstantSystem constantSystem) { | 1015 BinaryOperation operation(ConstantSystem constantSystem) { |
1058 return constantSystem.codeUnitAt; | 1016 return constantSystem.codeUnitAt; |
1059 } | 1017 } |
1060 | 1018 |
1061 HInstruction tryConvertToBuiltin( | 1019 HInstruction tryConvertToBuiltin( |
1062 HInvokeDynamic instruction, | 1020 HInvokeDynamic instruction, |
1063 HGraph graph, | 1021 HGraph graph, |
1064 GlobalTypeInferenceResults results, | 1022 GlobalTypeInferenceResults results, |
1065 CompilerOptions options, | 1023 CompilerOptions options, |
1066 BackendHelpers helpers, | 1024 CommonElements commonElements, |
1067 ClosedWorld closedWorld) { | 1025 ClosedWorld closedWorld) { |
1068 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index | 1026 // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index |
1069 // bounds checking optimizations as for HIndex. | 1027 // bounds checking optimizations as for HIndex. |
1070 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1028 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
1071 if (receiver.isStringOrNull(closedWorld)) { | 1029 if (receiver.isStringOrNull(closedWorld)) { |
1072 // Even if there is no builtin equivalent instruction, we know | 1030 // Even if there is no builtin equivalent instruction, we know |
1073 // String.codeUnitAt does not have any side effect (other than throwing), | 1031 // String.codeUnitAt does not have any side effect (other than throwing), |
1074 // and that it can be GVN'ed. | 1032 // and that it can be GVN'ed. |
1075 clearAllSideEffects(instruction); | 1033 clearAllSideEffects(instruction); |
1076 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { | 1034 if (instruction.inputs.last.isPositiveInteger(closedWorld)) { |
1077 instruction.selector = renameToOptimizedSelector( | 1035 instruction.selector = renameToOptimizedSelector( |
1078 '_codeUnitAt', instruction.selector, helpers); | 1036 '_codeUnitAt', instruction.selector, commonElements); |
1079 } | 1037 } |
1080 } | 1038 } |
1081 return null; | 1039 return null; |
1082 } | 1040 } |
1083 } | 1041 } |
1084 | 1042 |
1085 class CompareToSpecializer extends InvokeDynamicSpecializer { | 1043 class CompareToSpecializer extends InvokeDynamicSpecializer { |
1086 const CompareToSpecializer(); | 1044 const CompareToSpecializer(); |
1087 | 1045 |
1088 HInstruction tryConvertToBuiltin( | 1046 HInstruction tryConvertToBuiltin( |
1089 HInvokeDynamic instruction, | 1047 HInvokeDynamic instruction, |
1090 HGraph graph, | 1048 HGraph graph, |
1091 GlobalTypeInferenceResults results, | 1049 GlobalTypeInferenceResults results, |
1092 CompilerOptions options, | 1050 CompilerOptions options, |
1093 BackendHelpers helpers, | 1051 CommonElements commonElements, |
1094 ClosedWorld closedWorld) { | 1052 ClosedWorld closedWorld) { |
1095 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1053 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
1096 // `compareTo` has no side-effect (other than throwing) and can be GVN'ed | 1054 // `compareTo` has no side-effect (other than throwing) and can be GVN'ed |
1097 // for some known types. | 1055 // for some known types. |
1098 if (receiver.isStringOrNull(closedWorld) || | 1056 if (receiver.isStringOrNull(closedWorld) || |
1099 receiver.isNumberOrNull(closedWorld)) { | 1057 receiver.isNumberOrNull(closedWorld)) { |
1100 // Replace `a.compareTo(a)` with `0`, but only if receiver and argument | 1058 // Replace `a.compareTo(a)` with `0`, but only if receiver and argument |
1101 // are such that no exceptions can be thrown. | 1059 // are such that no exceptions can be thrown. |
1102 HInstruction argument = instruction.inputs.last; | 1060 HInstruction argument = instruction.inputs.last; |
1103 if ((receiver.isNumber(closedWorld) && argument.isNumber(closedWorld)) || | 1061 if ((receiver.isNumber(closedWorld) && argument.isNumber(closedWorld)) || |
1104 (receiver.isString(closedWorld) && argument.isString(closedWorld))) { | 1062 (receiver.isString(closedWorld) && argument.isString(closedWorld))) { |
1105 if (identical(receiver.nonCheck(), argument.nonCheck())) { | 1063 if (identical(receiver.nonCheck(), argument.nonCheck())) { |
1106 return graph.addConstantInt(0, closedWorld); | 1064 return graph.addConstantInt(0, closedWorld); |
1107 } | 1065 } |
1108 } | 1066 } |
1109 clearAllSideEffects(instruction); | 1067 clearAllSideEffects(instruction); |
1110 } | 1068 } |
1111 return null; | 1069 return null; |
1112 } | 1070 } |
1113 } | 1071 } |
1114 | 1072 |
1115 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { | 1073 class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer { |
1116 const IdempotentStringOperationSpecializer(); | 1074 const IdempotentStringOperationSpecializer(); |
1117 | 1075 |
1118 HInstruction tryConvertToBuiltin( | 1076 HInstruction tryConvertToBuiltin( |
1119 HInvokeDynamic instruction, | 1077 HInvokeDynamic instruction, |
1120 HGraph graph, | 1078 HGraph graph, |
1121 GlobalTypeInferenceResults results, | 1079 GlobalTypeInferenceResults results, |
1122 CompilerOptions options, | 1080 CompilerOptions options, |
1123 BackendHelpers helpers, | 1081 CommonElements commonElements, |
1124 ClosedWorld closedWorld) { | 1082 ClosedWorld closedWorld) { |
1125 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1083 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
1126 if (receiver.isStringOrNull(closedWorld)) { | 1084 if (receiver.isStringOrNull(closedWorld)) { |
1127 // String.xxx does not have any side effect (other than throwing), and it | 1085 // String.xxx does not have any side effect (other than throwing), and it |
1128 // can be GVN'ed. | 1086 // can be GVN'ed. |
1129 clearAllSideEffects(instruction); | 1087 clearAllSideEffects(instruction); |
1130 } | 1088 } |
1131 return null; | 1089 return null; |
1132 } | 1090 } |
1133 } | 1091 } |
1134 | 1092 |
1135 class SubstringSpecializer extends IdempotentStringOperationSpecializer { | 1093 class SubstringSpecializer extends IdempotentStringOperationSpecializer { |
1136 const SubstringSpecializer(); | 1094 const SubstringSpecializer(); |
1137 } | 1095 } |
1138 | 1096 |
1139 class TrimSpecializer extends IdempotentStringOperationSpecializer { | 1097 class TrimSpecializer extends IdempotentStringOperationSpecializer { |
1140 const TrimSpecializer(); | 1098 const TrimSpecializer(); |
1141 } | 1099 } |
1142 | 1100 |
1143 class PatternMatchSpecializer extends InvokeDynamicSpecializer { | 1101 class PatternMatchSpecializer extends InvokeDynamicSpecializer { |
1144 const PatternMatchSpecializer(); | 1102 const PatternMatchSpecializer(); |
1145 | 1103 |
1146 HInstruction tryConvertToBuiltin( | 1104 HInstruction tryConvertToBuiltin( |
1147 HInvokeDynamic instruction, | 1105 HInvokeDynamic instruction, |
1148 HGraph graph, | 1106 HGraph graph, |
1149 GlobalTypeInferenceResults results, | 1107 GlobalTypeInferenceResults results, |
1150 CompilerOptions options, | 1108 CompilerOptions options, |
1151 BackendHelpers helpers, | 1109 CommonElements commonElements, |
1152 ClosedWorld closedWorld) { | 1110 ClosedWorld closedWorld) { |
1153 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1111 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
1154 HInstruction pattern = instruction.inputs[2]; | 1112 HInstruction pattern = instruction.inputs[2]; |
1155 if (receiver.isStringOrNull(closedWorld) && | 1113 if (receiver.isStringOrNull(closedWorld) && |
1156 pattern.isStringOrNull(closedWorld)) { | 1114 pattern.isStringOrNull(closedWorld)) { |
1157 // String.contains(String s) does not have any side effect (other than | 1115 // String.contains(String s) does not have any side effect (other than |
1158 // throwing), and it can be GVN'ed. | 1116 // throwing), and it can be GVN'ed. |
1159 clearAllSideEffects(instruction); | 1117 clearAllSideEffects(instruction); |
1160 } | 1118 } |
1161 return null; | 1119 return null; |
1162 } | 1120 } |
1163 } | 1121 } |
1164 | 1122 |
1165 class RoundSpecializer extends InvokeDynamicSpecializer { | 1123 class RoundSpecializer extends InvokeDynamicSpecializer { |
1166 const RoundSpecializer(); | 1124 const RoundSpecializer(); |
1167 | 1125 |
1168 UnaryOperation operation(ConstantSystem constantSystem) { | 1126 UnaryOperation operation(ConstantSystem constantSystem) { |
1169 return constantSystem.round; | 1127 return constantSystem.round; |
1170 } | 1128 } |
1171 | 1129 |
1172 HInstruction tryConvertToBuiltin( | 1130 HInstruction tryConvertToBuiltin( |
1173 HInvokeDynamic instruction, | 1131 HInvokeDynamic instruction, |
1174 HGraph graph, | 1132 HGraph graph, |
1175 GlobalTypeInferenceResults results, | 1133 GlobalTypeInferenceResults results, |
1176 CompilerOptions options, | 1134 CompilerOptions options, |
1177 BackendHelpers helpers, | 1135 CommonElements commonElements, |
1178 ClosedWorld closedWorld) { | 1136 ClosedWorld closedWorld) { |
1179 HInstruction receiver = instruction.getDartReceiver(closedWorld); | 1137 HInstruction receiver = instruction.getDartReceiver(closedWorld); |
1180 if (receiver.isNumberOrNull(closedWorld)) { | 1138 if (receiver.isNumberOrNull(closedWorld)) { |
1181 // Even if there is no builtin equivalent instruction, we know the | 1139 // Even if there is no builtin equivalent instruction, we know the |
1182 // instruction does not have any side effect, and that it can be GVN'ed. | 1140 // instruction does not have any side effect, and that it can be GVN'ed. |
1183 clearAllSideEffects(instruction); | 1141 clearAllSideEffects(instruction); |
1184 } | 1142 } |
1185 return null; | 1143 return null; |
1186 } | 1144 } |
1187 } | 1145 } |
OLD | NEW |