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); |
} |
} |