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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 /** | 7 /** |
8 * [InvokeDynamicSpecializer] and its subclasses are helpers to | 8 * [InvokeDynamicSpecializer] and its subclasses are helpers to |
9 * optimize intercepted dynamic calls. It knows what input types | 9 * optimize intercepted dynamic calls. It knows what input types |
10 * would be beneficial for performance, and how to change a invoke | 10 * would be beneficial for performance, and how to change a invoke |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 instruction.sideEffects.clearAllDependencies(); | 219 instruction.sideEffects.clearAllDependencies(); |
220 instruction.setUseGvn(); | 220 instruction.setUseGvn(); |
221 } | 221 } |
222 | 222 |
223 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); | 223 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); |
224 } | 224 } |
225 | 225 |
226 class AddSpecializer extends BinaryArithmeticSpecializer { | 226 class AddSpecializer extends BinaryArithmeticSpecializer { |
227 const AddSpecializer(); | 227 const AddSpecializer(); |
228 | 228 |
229 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | |
kasperl
2013/11/28 09:09:47
Share this code between add, modulo, multiply, tru
ngeoffray
2013/11/28 11:21:47
Done.
| |
230 Compiler compiler) { | |
231 HInstruction left = instruction.inputs[1]; | |
232 HInstruction right = instruction.inputs[2]; | |
233 JavaScriptBackend backend = compiler.backend; | |
234 if (left.isPositiveIntegerOrNull(compiler) | |
235 && right.isPositiveIntegerOrNull(compiler)) { | |
236 return backend.positiveIntType; | |
237 } | |
238 return super.computeTypeFromInputTypes(instruction, compiler); | |
239 } | |
240 | |
229 BinaryOperation operation(ConstantSystem constantSystem) { | 241 BinaryOperation operation(ConstantSystem constantSystem) { |
230 return constantSystem.add; | 242 return constantSystem.add; |
231 } | 243 } |
232 | 244 |
233 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 245 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
234 Compiler compiler) { | 246 Compiler compiler) { |
235 return new HAdd( | 247 return new HAdd( |
236 instruction.inputs[1], instruction.inputs[2], | 248 instruction.inputs[1], instruction.inputs[2], |
237 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 249 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
238 } | 250 } |
(...skipping 21 matching lines...) Expand all Loading... | |
260 JavaScriptBackend backend = compiler.backend; | 272 JavaScriptBackend backend = compiler.backend; |
261 return new HDivide( | 273 return new HDivide( |
262 instruction.inputs[1], instruction.inputs[2], | 274 instruction.inputs[1], instruction.inputs[2], |
263 instruction.selector, backend.doubleType); | 275 instruction.selector, backend.doubleType); |
264 } | 276 } |
265 } | 277 } |
266 | 278 |
267 class ModuloSpecializer extends BinaryArithmeticSpecializer { | 279 class ModuloSpecializer extends BinaryArithmeticSpecializer { |
268 const ModuloSpecializer(); | 280 const ModuloSpecializer(); |
269 | 281 |
282 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | |
283 Compiler compiler) { | |
284 HInstruction left = instruction.inputs[1]; | |
285 HInstruction right = instruction.inputs[2]; | |
286 JavaScriptBackend backend = compiler.backend; | |
287 if (left.isPositiveIntegerOrNull(compiler) | |
288 && right.isPositiveIntegerOrNull(compiler)) { | |
289 return backend.positiveIntType; | |
290 } | |
291 return super.computeTypeFromInputTypes(instruction, compiler); | |
292 } | |
293 | |
270 BinaryOperation operation(ConstantSystem constantSystem) { | 294 BinaryOperation operation(ConstantSystem constantSystem) { |
271 return constantSystem.modulo; | 295 return constantSystem.modulo; |
272 } | 296 } |
273 | 297 |
274 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 298 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
275 Compiler compiler) { | 299 Compiler compiler) { |
276 // Modulo cannot be mapped to the native operator (different semantics). | 300 // Modulo cannot be mapped to the native operator (different semantics). |
277 return null; | 301 return null; |
278 } | 302 } |
279 } | 303 } |
280 | 304 |
281 class MultiplySpecializer extends BinaryArithmeticSpecializer { | 305 class MultiplySpecializer extends BinaryArithmeticSpecializer { |
282 const MultiplySpecializer(); | 306 const MultiplySpecializer(); |
283 | 307 |
284 BinaryOperation operation(ConstantSystem constantSystem) { | 308 BinaryOperation operation(ConstantSystem constantSystem) { |
285 return constantSystem.multiply; | 309 return constantSystem.multiply; |
286 } | 310 } |
287 | 311 |
312 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | |
313 Compiler compiler) { | |
314 HInstruction left = instruction.inputs[1]; | |
315 HInstruction right = instruction.inputs[2]; | |
316 JavaScriptBackend backend = compiler.backend; | |
317 if (left.isPositiveIntegerOrNull(compiler) | |
318 && right.isPositiveIntegerOrNull(compiler)) { | |
319 return backend.positiveIntType; | |
320 } | |
321 return super.computeTypeFromInputTypes(instruction, compiler); | |
322 } | |
323 | |
288 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 324 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
289 Compiler compiler) { | 325 Compiler compiler) { |
290 return new HMultiply( | 326 return new HMultiply( |
291 instruction.inputs[1], instruction.inputs[2], | 327 instruction.inputs[1], instruction.inputs[2], |
292 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 328 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
293 } | 329 } |
294 } | 330 } |
295 | 331 |
296 class SubtractSpecializer extends BinaryArithmeticSpecializer { | 332 class SubtractSpecializer extends BinaryArithmeticSpecializer { |
297 const SubtractSpecializer(); | 333 const SubtractSpecializer(); |
(...skipping 10 matching lines...) Expand all Loading... | |
308 } | 344 } |
309 } | 345 } |
310 | 346 |
311 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { | 347 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer { |
312 const TruncatingDivideSpecializer(); | 348 const TruncatingDivideSpecializer(); |
313 | 349 |
314 BinaryOperation operation(ConstantSystem constantSystem) { | 350 BinaryOperation operation(ConstantSystem constantSystem) { |
315 return constantSystem.truncatingDivide; | 351 return constantSystem.truncatingDivide; |
316 } | 352 } |
317 | 353 |
354 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | |
355 Compiler compiler) { | |
356 HInstruction left = instruction.inputs[1]; | |
357 HInstruction right = instruction.inputs[2]; | |
358 JavaScriptBackend backend = compiler.backend; | |
359 if (left.isPositiveIntegerOrNull(compiler) | |
360 && right.isPositiveIntegerOrNull(compiler)) { | |
361 return backend.positiveIntType; | |
362 } | |
363 return super.computeTypeFromInputTypes(instruction, compiler); | |
364 } | |
365 | |
318 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 366 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
319 Compiler compiler) { | 367 Compiler compiler) { |
320 // Truncating divide does not have a JS equivalent. | 368 // Truncating divide does not have a JS equivalent. |
321 return null; | 369 return null; |
322 } | 370 } |
323 } | 371 } |
324 | 372 |
325 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 373 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
326 const BinaryBitOpSpecializer(); | 374 const BinaryBitOpSpecializer(); |
327 | 375 |
(...skipping 13 matching lines...) Expand all Loading... | |
341 if (!instruction.isConstantInteger()) return false; | 389 if (!instruction.isConstantInteger()) return false; |
342 HConstant rightConstant = instruction; | 390 HConstant rightConstant = instruction; |
343 IntConstant intConstant = rightConstant.constant; | 391 IntConstant intConstant = rightConstant.constant; |
344 int count = intConstant.value; | 392 int count = intConstant.value; |
345 return count >= 0 && count <= 31; | 393 return count >= 0 && count <= 31; |
346 } | 394 } |
347 | 395 |
348 bool isPositive(HInstruction instruction, Compiler compiler) { | 396 bool isPositive(HInstruction instruction, Compiler compiler) { |
349 // TODO: We should use the value range analysis. Currently, ranges | 397 // TODO: We should use the value range analysis. Currently, ranges |
350 // are discarded just after the analysis. | 398 // are discarded just after the analysis. |
351 return instruction.isUInt32(compiler); | 399 return instruction.isPositiveInteger(compiler); |
352 } | 400 } |
353 } | 401 } |
354 | 402 |
355 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { | 403 class ShiftLeftSpecializer extends BinaryBitOpSpecializer { |
356 const ShiftLeftSpecializer(); | 404 const ShiftLeftSpecializer(); |
357 | 405 |
358 BinaryOperation operation(ConstantSystem constantSystem) { | 406 BinaryOperation operation(ConstantSystem constantSystem) { |
359 return constantSystem.shiftLeft; | 407 return constantSystem.shiftLeft; |
360 } | 408 } |
361 | 409 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
625 } | 673 } |
626 | 674 |
627 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 675 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
628 Compiler compiler) { | 676 Compiler compiler) { |
629 JavaScriptBackend backend = compiler.backend; | 677 JavaScriptBackend backend = compiler.backend; |
630 return new HLessEqual( | 678 return new HLessEqual( |
631 instruction.inputs[1], instruction.inputs[2], | 679 instruction.inputs[1], instruction.inputs[2], |
632 instruction.selector, backend.boolType); | 680 instruction.selector, backend.boolType); |
633 } | 681 } |
634 } | 682 } |
OLD | NEW |