| Index: sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart (revision 30754)
|
| +++ sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart (working copy)
|
| @@ -220,12 +220,29 @@
|
| instruction.setUseGvn();
|
| }
|
|
|
| + bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) {
|
| + HInstruction left = instruction.inputs[1];
|
| + HInstruction right = instruction.inputs[2];
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return left.isPositiveIntegerOrNull(compiler)
|
| + && right.isPositiveIntegerOrNull(compiler);
|
| + }
|
| +
|
| HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);
|
| }
|
|
|
| class AddSpecializer extends BinaryArithmeticSpecializer {
|
| const AddSpecializer();
|
|
|
| + TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
|
| + Compiler compiler) {
|
| + if (inputsArePositiveIntegers(instruction, compiler)) {
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return backend.positiveIntType;
|
| + }
|
| + return super.computeTypeFromInputTypes(instruction, compiler);
|
| + }
|
| +
|
| BinaryOperation operation(ConstantSystem constantSystem) {
|
| return constantSystem.add;
|
| }
|
| @@ -267,6 +284,15 @@
|
| class ModuloSpecializer extends BinaryArithmeticSpecializer {
|
| const ModuloSpecializer();
|
|
|
| + TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
|
| + Compiler compiler) {
|
| + if (inputsArePositiveIntegers(instruction, compiler)) {
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return backend.positiveIntType;
|
| + }
|
| + return super.computeTypeFromInputTypes(instruction, compiler);
|
| + }
|
| +
|
| BinaryOperation operation(ConstantSystem constantSystem) {
|
| return constantSystem.modulo;
|
| }
|
| @@ -285,6 +311,15 @@
|
| return constantSystem.multiply;
|
| }
|
|
|
| + TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
|
| + Compiler compiler) {
|
| + if (inputsArePositiveIntegers(instruction, compiler)) {
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return backend.positiveIntType;
|
| + }
|
| + return super.computeTypeFromInputTypes(instruction, compiler);
|
| + }
|
| +
|
| HInstruction newBuiltinVariant(HInvokeDynamic instruction,
|
| Compiler compiler) {
|
| return new HMultiply(
|
| @@ -315,6 +350,15 @@
|
| return constantSystem.truncatingDivide;
|
| }
|
|
|
| + TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
|
| + Compiler compiler) {
|
| + if (inputsArePositiveIntegers(instruction, compiler)) {
|
| + JavaScriptBackend backend = compiler.backend;
|
| + return backend.positiveIntType;
|
| + }
|
| + return super.computeTypeFromInputTypes(instruction, compiler);
|
| + }
|
| +
|
| HInstruction newBuiltinVariant(HInvokeDynamic instruction,
|
| Compiler compiler) {
|
| // Truncating divide does not have a JS equivalent.
|
| @@ -348,7 +392,7 @@
|
| bool isPositive(HInstruction instruction, Compiler compiler) {
|
| // TODO: We should use the value range analysis. Currently, ranges
|
| // are discarded just after the analysis.
|
| - return instruction.isUInt32(compiler);
|
| + return instruction.isPositiveInteger(compiler);
|
| }
|
| }
|
|
|
|
|