Chromium Code Reviews| 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 | 222 |
| 223 bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) { | 223 bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) { |
| 224 HInstruction left = instruction.inputs[1]; | 224 HInstruction left = instruction.inputs[1]; |
| 225 HInstruction right = instruction.inputs[2]; | 225 HInstruction right = instruction.inputs[2]; |
| 226 JavaScriptBackend backend = compiler.backend; | 226 JavaScriptBackend backend = compiler.backend; |
| 227 return left.isPositiveIntegerOrNull(compiler) | 227 return left.isPositiveIntegerOrNull(compiler) |
| 228 && right.isPositiveIntegerOrNull(compiler); | 228 && right.isPositiveIntegerOrNull(compiler); |
| 229 } | 229 } |
| 230 | 230 |
| 231 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); | 231 HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler); |
| 232 | |
| 233 | |
|
kasperl
2013/12/10 14:22:54
Too much whitespace.
ngeoffray
2013/12/10 15:26:17
Done.
| |
| 234 Selector renameToOptimizedSelector(String name, | |
| 235 Selector selector, | |
| 236 Compiler compiler) { | |
| 237 if (selector.name == name) return selector; | |
| 238 return new TypedSelector( | |
| 239 selector.mask, | |
| 240 new Selector(SelectorKind.CALL, | |
| 241 name, | |
| 242 compiler.interceptorsLibrary, | |
| 243 selector.argumentCount)); | |
| 244 } | |
| 232 } | 245 } |
| 233 | 246 |
| 234 class AddSpecializer extends BinaryArithmeticSpecializer { | 247 class AddSpecializer extends BinaryArithmeticSpecializer { |
| 235 const AddSpecializer(); | 248 const AddSpecializer(); |
| 236 | 249 |
| 237 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | 250 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 238 Compiler compiler) { | 251 Compiler compiler) { |
| 239 if (inputsArePositiveIntegers(instruction, compiler)) { | 252 if (inputsArePositiveIntegers(instruction, compiler)) { |
| 240 JavaScriptBackend backend = compiler.backend; | 253 JavaScriptBackend backend = compiler.backend; |
| 241 return backend.positiveIntType; | 254 return backend.positiveIntType; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 | 365 |
| 353 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | 366 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 354 Compiler compiler) { | 367 Compiler compiler) { |
| 355 if (inputsArePositiveIntegers(instruction, compiler)) { | 368 if (inputsArePositiveIntegers(instruction, compiler)) { |
| 356 JavaScriptBackend backend = compiler.backend; | 369 JavaScriptBackend backend = compiler.backend; |
| 357 return backend.positiveIntType; | 370 return backend.positiveIntType; |
| 358 } | 371 } |
| 359 return super.computeTypeFromInputTypes(instruction, compiler); | 372 return super.computeTypeFromInputTypes(instruction, compiler); |
| 360 } | 373 } |
| 361 | 374 |
| 375 bool isNotZero(HInstruction instruction, Compiler compiler) { | |
| 376 if (!instruction.isConstantInteger()) return false; | |
| 377 HConstant rightConstant = instruction; | |
| 378 IntConstant intConstant = rightConstant.constant; | |
| 379 int count = intConstant.value; | |
| 380 return count != 0; | |
| 381 } | |
| 382 | |
| 383 HInstruction tryConvertToBuiltin(HInvokeDynamic instruction, | |
| 384 Compiler compiler) { | |
| 385 HInstruction left = instruction.inputs[1]; | |
| 386 HInstruction right = instruction.inputs[2]; | |
| 387 if (isBuiltin(instruction, compiler)) { | |
| 388 if (right.isUInt32(compiler) && isNotZero(right, compiler)) { | |
|
floitsch
2013/12/10 15:45:16
Right side only needs to be an integer != 0.
ngeoffray
2013/12/10 15:48:15
Done.
| |
| 389 if (left.isUInt32(compiler)) { | |
|
floitsch
2013/12/10 15:45:16
left.isUInt31, or left.isInt32
ngeoffray
2013/12/10 15:48:15
Changed to left.isUInt31 (we don't have isInt32).
| |
| 390 return newBuiltinVariant(instruction, compiler); | |
| 391 } | |
| 392 clearAllSideEffects(instruction); | |
| 393 instruction.selector = renameToOptimizedSelector( | |
|
kasperl
2013/12/10 14:22:54
Add a comment that explains what the contract for
ngeoffray
2013/12/10 15:26:17
Done.
| |
| 394 '_tdivFast', instruction.selector, compiler); | |
| 395 } | |
| 396 } | |
| 397 return null; | |
| 398 } | |
| 399 | |
| 362 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 400 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
| 363 Compiler compiler) { | 401 Compiler compiler) { |
| 364 // Truncating divide does not have a JS equivalent. | 402 return new HTruncatingDivide( |
| 365 return null; | 403 instruction.inputs[1], instruction.inputs[2], |
| 404 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | |
| 366 } | 405 } |
| 367 } | 406 } |
| 368 | 407 |
| 369 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { | 408 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer { |
| 370 const BinaryBitOpSpecializer(); | 409 const BinaryBitOpSpecializer(); |
| 371 | 410 |
| 372 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, | 411 TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction, |
| 373 Compiler compiler) { | 412 Compiler compiler) { |
| 374 // All bitwise operations on primitive types either produce an | 413 // All bitwise operations on primitive types either produce an |
| 375 // integer or throw an error. | 414 // integer or throw an error. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 HInstruction left = instruction.inputs[1]; | 447 HInstruction left = instruction.inputs[1]; |
| 409 HInstruction right = instruction.inputs[2]; | 448 HInstruction right = instruction.inputs[2]; |
| 410 if (left.isNumber(compiler)) { | 449 if (left.isNumber(compiler)) { |
| 411 if (argumentLessThan32(right)) { | 450 if (argumentLessThan32(right)) { |
| 412 return newBuiltinVariant(instruction, compiler); | 451 return newBuiltinVariant(instruction, compiler); |
| 413 } | 452 } |
| 414 // Even if there is no builtin equivalent instruction, we know | 453 // Even if there is no builtin equivalent instruction, we know |
| 415 // the instruction does not have any side effect, and that it | 454 // the instruction does not have any side effect, and that it |
| 416 // can be GVN'ed. | 455 // can be GVN'ed. |
| 417 clearAllSideEffects(instruction); | 456 clearAllSideEffects(instruction); |
| 457 Selector selector = instruction.selector; | |
| 458 if (isPositive(right, compiler)) { | |
| 459 instruction.selector = renameToOptimizedSelector( | |
| 460 '_shlPositive', instruction.selector, compiler); | |
| 461 } | |
| 418 } | 462 } |
| 419 return null; | 463 return null; |
| 420 } | 464 } |
| 421 | 465 |
| 422 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 466 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
| 423 Compiler compiler) { | 467 Compiler compiler) { |
| 424 JavaScriptBackend backend = compiler.backend; | 468 JavaScriptBackend backend = compiler.backend; |
| 425 return new HShiftLeft( | 469 return new HShiftLeft( |
| 426 instruction.inputs[1], instruction.inputs[2], | 470 instruction.inputs[1], instruction.inputs[2], |
| 427 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 471 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 445 HInstruction left = instruction.inputs[1]; | 489 HInstruction left = instruction.inputs[1]; |
| 446 HInstruction right = instruction.inputs[2]; | 490 HInstruction right = instruction.inputs[2]; |
| 447 if (left.isNumber(compiler)) { | 491 if (left.isNumber(compiler)) { |
| 448 if (argumentLessThan32(right) && isPositive(left, compiler)) { | 492 if (argumentLessThan32(right) && isPositive(left, compiler)) { |
| 449 return newBuiltinVariant(instruction, compiler); | 493 return newBuiltinVariant(instruction, compiler); |
| 450 } | 494 } |
| 451 // Even if there is no builtin equivalent instruction, we know | 495 // Even if there is no builtin equivalent instruction, we know |
| 452 // the instruction does not have any side effect, and that it | 496 // the instruction does not have any side effect, and that it |
| 453 // can be GVN'ed. | 497 // can be GVN'ed. |
| 454 clearAllSideEffects(instruction); | 498 clearAllSideEffects(instruction); |
| 499 if (isPositive(right, compiler) && isPositive(left, compiler)) { | |
| 500 instruction.selector = renameToOptimizedSelector( | |
| 501 '_shrBothPositive', instruction.selector, compiler); | |
| 502 } else if (isPositive(left, compiler) && right.isNumber(compiler)) { | |
| 503 instruction.selector = renameToOptimizedSelector( | |
| 504 '_shrReceiverPositive', instruction.selector, compiler); | |
| 505 } else if (isPositive(right, compiler)) { | |
| 506 instruction.selector = renameToOptimizedSelector( | |
| 507 '_shrOtherPositive', instruction.selector, compiler); | |
| 508 } | |
| 455 } | 509 } |
| 456 return null; | 510 return null; |
| 457 } | 511 } |
| 458 | 512 |
| 459 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 513 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
| 460 Compiler compiler) { | 514 Compiler compiler) { |
| 461 JavaScriptBackend backend = compiler.backend; | 515 JavaScriptBackend backend = compiler.backend; |
| 462 return new HShiftRight( | 516 return new HShiftRight( |
| 463 instruction.inputs[1], instruction.inputs[2], | 517 instruction.inputs[1], instruction.inputs[2], |
| 464 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); | 518 instruction.selector, computeTypeFromInputTypes(instruction, compiler)); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 669 } | 723 } |
| 670 | 724 |
| 671 HInstruction newBuiltinVariant(HInvokeDynamic instruction, | 725 HInstruction newBuiltinVariant(HInvokeDynamic instruction, |
| 672 Compiler compiler) { | 726 Compiler compiler) { |
| 673 JavaScriptBackend backend = compiler.backend; | 727 JavaScriptBackend backend = compiler.backend; |
| 674 return new HLessEqual( | 728 return new HLessEqual( |
| 675 instruction.inputs[1], instruction.inputs[2], | 729 instruction.inputs[1], instruction.inputs[2], |
| 676 instruction.selector, backend.boolType); | 730 instruction.selector, backend.boolType); |
| 677 } | 731 } |
| 678 } | 732 } |
| OLD | NEW |