| Index: pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
|
| index 63e3a26aa3761b6d11e5d16c480fd1921960b65d..e4137488cbe3b8b1fb8d7def2fa81e2ccc13f29e 100644
|
| --- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
|
| +++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
|
| @@ -24,13 +24,13 @@ class InvokeDynamicSpecializer {
|
| const InvokeDynamicSpecializer();
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| return TypeMaskFactory.inferredTypeForSelector(
|
| instruction.selector, instruction.mask, compiler);
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| return null;
|
| }
|
|
|
| @@ -85,9 +85,9 @@ class IndexAssignSpecializer extends InvokeDynamicSpecializer {
|
| const IndexAssignSpecializer();
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - if (instruction.inputs[1].isMutableIndexable(compiler)) {
|
| - if (!instruction.inputs[2].isInteger(compiler) &&
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (instruction.inputs[1].isMutableIndexable(closedWorld)) {
|
| + if (!instruction.inputs[2].isInteger(closedWorld) &&
|
| compiler.options.enableTypeAssertions) {
|
| // We want the right checked mode error.
|
| return null;
|
| @@ -103,9 +103,9 @@ class IndexSpecializer extends InvokeDynamicSpecializer {
|
| const IndexSpecializer();
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - if (!instruction.inputs[1].isIndexablePrimitive(compiler)) return null;
|
| - if (!instruction.inputs[2].isInteger(compiler) &&
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (!instruction.inputs[1].isIndexablePrimitive(closedWorld)) return null;
|
| + if (!instruction.inputs[2].isInteger(closedWorld) &&
|
| compiler.options.enableTypeAssertions) {
|
| // We want the right checked mode error.
|
| return null;
|
| @@ -127,22 +127,21 @@ class BitNotSpecializer extends InvokeDynamicSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| // All bitwise operations on primitive types either produce an
|
| // integer or throw an error.
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
|
| - return backend.uint32Type;
|
| + if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) {
|
| + return closedWorld.commonMasks.uint32Type;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction input = instruction.inputs[1];
|
| - if (input.isNumber(compiler)) {
|
| + if (input.isNumber(closedWorld)) {
|
| return new HBitNot(input, instruction.selector,
|
| - computeTypeFromInputTypes(instruction, compiler));
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| return null;
|
| }
|
| @@ -156,16 +155,16 @@ class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| TypeMask operandType = instruction.inputs[1].instructionType;
|
| - if (instruction.inputs[1].isNumberOrNull(compiler)) return operandType;
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType;
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction input = instruction.inputs[1];
|
| - if (input.isNumber(compiler)) {
|
| + if (input.isNumber(closedWorld)) {
|
| return new HNegate(input, instruction.selector, input.instructionType);
|
| }
|
| return null;
|
| @@ -176,31 +175,33 @@ abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
|
| const BinaryArithmeticSpecializer();
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (left.isIntegerOrNull(compiler) && right.isIntegerOrNull(compiler)) {
|
| - return backend.intType;
|
| + if (left.isIntegerOrNull(closedWorld) &&
|
| + right.isIntegerOrNull(closedWorld)) {
|
| + return closedWorld.commonMasks.intType;
|
| }
|
| - if (left.isNumberOrNull(compiler)) {
|
| - if (left.isDoubleOrNull(compiler) || right.isDoubleOrNull(compiler)) {
|
| - return backend.doubleType;
|
| + if (left.isNumberOrNull(closedWorld)) {
|
| + if (left.isDoubleOrNull(closedWorld) ||
|
| + right.isDoubleOrNull(closedWorld)) {
|
| + return closedWorld.commonMasks.doubleType;
|
| }
|
| - return backend.numType;
|
| + return closedWorld.commonMasks.numType;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| - bool isBuiltin(HInvokeDynamic instruction, Compiler compiler) {
|
| - return instruction.inputs[1].isNumber(compiler) &&
|
| - instruction.inputs[2].isNumber(compiler);
|
| + bool isBuiltin(HInvokeDynamic instruction, ClosedWorld closedWorld) {
|
| + return instruction.inputs[1].isNumber(closedWorld) &&
|
| + instruction.inputs[2].isNumber(closedWorld);
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - if (isBuiltin(instruction, compiler)) {
|
| - HInstruction builtin = newBuiltinVariant(instruction, compiler);
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (isBuiltin(instruction, closedWorld)) {
|
| + HInstruction builtin =
|
| + newBuiltinVariant(instruction, compiler, closedWorld);
|
| if (builtin != null) return builtin;
|
| // Even if there is no builtin equivalent instruction, we know
|
| // the instruction does not have any side effect, and that it
|
| @@ -210,20 +211,22 @@ abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
|
| return null;
|
| }
|
|
|
| - bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) {
|
| + bool inputsArePositiveIntegers(
|
| + HInstruction instruction, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - return left.isPositiveIntegerOrNull(compiler) &&
|
| - right.isPositiveIntegerOrNull(compiler);
|
| + return left.isPositiveIntegerOrNull(closedWorld) &&
|
| + right.isPositiveIntegerOrNull(closedWorld);
|
| }
|
|
|
| - bool inputsAreUInt31(HInstruction instruction, Compiler compiler) {
|
| + bool inputsAreUInt31(HInstruction instruction, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - return left.isUInt31(compiler) && right.isUInt31(compiler);
|
| + return left.isUInt31(closedWorld) && right.isUInt31(closedWorld);
|
| }
|
|
|
| - HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);
|
| + HInstruction newBuiltinVariant(
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld);
|
|
|
| Selector renameToOptimizedSelector(
|
| String name, Selector selector, Compiler compiler) {
|
| @@ -239,16 +242,14 @@ class AddSpecializer extends BinaryArithmeticSpecializer {
|
| const AddSpecializer();
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - if (inputsAreUInt31(instruction, compiler)) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| - return backend.uint32Type;
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (inputsAreUInt31(instruction, closedWorld)) {
|
| + return closedWorld.commonMasks.uint32Type;
|
| }
|
| - if (inputsArePositiveIntegers(instruction, compiler)) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| - return backend.positiveIntType;
|
| + if (inputsArePositiveIntegers(instruction, closedWorld)) {
|
| + return closedWorld.commonMasks.positiveIntType;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem) {
|
| @@ -256,9 +257,12 @@ class AddSpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HAdd(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HAdd(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -270,20 +274,18 @@ class DivideSpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInstruction instruction, Compiler compiler) {
|
| + HInstruction instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (left.isNumberOrNull(compiler)) {
|
| - return backend.doubleType;
|
| + if (left.isNumberOrNull(closedWorld)) {
|
| + return closedWorld.commonMasks.doubleType;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| return new HDivide(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, backend.doubleType);
|
| + instruction.selector, closedWorld.commonMasks.doubleType);
|
| }
|
| }
|
|
|
| @@ -291,12 +293,11 @@ class ModuloSpecializer extends BinaryArithmeticSpecializer {
|
| const ModuloSpecializer();
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - if (inputsArePositiveIntegers(instruction, compiler)) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| - return backend.positiveIntType;
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (inputsArePositiveIntegers(instruction, closedWorld)) {
|
| + return closedWorld.commonMasks.positiveIntType;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem) {
|
| @@ -304,7 +305,7 @@ class ModuloSpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| // Modulo cannot be mapped to the native operator (different semantics).
|
| // TODO(sra): For non-negative values we can use JavaScript's %.
|
| return null;
|
| @@ -319,18 +320,20 @@ class MultiplySpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - if (inputsArePositiveIntegers(instruction, compiler)) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| - return backend.positiveIntType;
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (inputsArePositiveIntegers(instruction, closedWorld)) {
|
| + return closedWorld.commonMasks.positiveIntType;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HMultiply(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HMultiply(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -342,9 +345,12 @@ class SubtractSpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HSubtract(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HSubtract(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -356,18 +362,17 @@ class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (hasUint31Result(instruction, compiler)) {
|
| - return backend.uint31Type;
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (hasUint31Result(instruction, closedWorld)) {
|
| + return closedWorld.commonMasks.uint31Type;
|
| }
|
| - if (inputsArePositiveIntegers(instruction, compiler)) {
|
| - return backend.positiveIntType;
|
| + if (inputsArePositiveIntegers(instruction, closedWorld)) {
|
| + return closedWorld.commonMasks.positiveIntType;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| - bool isNotZero(HInstruction instruction, Compiler compiler) {
|
| + bool isNotZero(HInstruction instruction) {
|
| if (!instruction.isConstantInteger()) return false;
|
| HConstant rightConstant = instruction;
|
| IntConstantValue intConstant = rightConstant.constant;
|
| @@ -375,7 +380,7 @@ class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
|
| return count != 0;
|
| }
|
|
|
| - bool isTwoOrGreater(HInstruction instruction, Compiler compiler) {
|
| + bool isTwoOrGreater(HInstruction instruction) {
|
| if (!instruction.isConstantInteger()) return false;
|
| HConstant rightConstant = instruction;
|
| IntConstantValue intConstant = rightConstant.constant;
|
| @@ -383,14 +388,14 @@ class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
|
| return count >= 2;
|
| }
|
|
|
| - bool hasUint31Result(HInstruction instruction, Compiler compiler) {
|
| + bool hasUint31Result(HInstruction instruction, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - if (right.isPositiveInteger(compiler)) {
|
| - if (left.isUInt31(compiler) && isNotZero(right, compiler)) {
|
| + if (right.isPositiveInteger(closedWorld)) {
|
| + if (left.isUInt31(closedWorld) && isNotZero(right)) {
|
| return true;
|
| }
|
| - if (left.isUInt32(compiler) && isTwoOrGreater(right, compiler)) {
|
| + if (left.isUInt32(closedWorld) && isTwoOrGreater(right)) {
|
| return true;
|
| }
|
| }
|
| @@ -398,12 +403,12 @@ class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction right = instruction.inputs[2];
|
| - if (isBuiltin(instruction, compiler)) {
|
| - if (right.isPositiveInteger(compiler) && isNotZero(right, compiler)) {
|
| - if (hasUint31Result(instruction, compiler)) {
|
| - return newBuiltinVariant(instruction, compiler);
|
| + if (isBuiltin(instruction, closedWorld)) {
|
| + if (right.isPositiveInteger(closedWorld) && isNotZero(right)) {
|
| + if (hasUint31Result(instruction, closedWorld)) {
|
| + return newBuiltinVariant(instruction, compiler, closedWorld);
|
| }
|
| // We can call _tdivFast because the rhs is a 32bit integer
|
| // and not 0, nor -1.
|
| @@ -416,9 +421,12 @@ class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HTruncatingDivide(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HTruncatingDivide(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -426,15 +434,14 @@ abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
|
| const BinaryBitOpSpecializer();
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| // All bitwise operations on primitive types either produce an
|
| // integer or throw an error.
|
| HInstruction left = instruction.inputs[1];
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (left.isPrimitiveOrNull(compiler)) {
|
| - return backend.uint32Type;
|
| + if (left.isPrimitiveOrNull(closedWorld)) {
|
| + return closedWorld.commonMasks.uint32Type;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| bool argumentLessThan32(HInstruction instruction) {
|
| @@ -445,10 +452,10 @@ abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
|
| return count >= 0 && count <= 31;
|
| }
|
|
|
| - bool isPositive(HInstruction instruction, Compiler compiler) {
|
| + bool isPositive(HInstruction instruction, ClosedWorld closedWorld) {
|
| // TODO: We should use the value range analysis. Currently, ranges
|
| // are discarded just after the analysis.
|
| - return instruction.isPositiveInteger(compiler);
|
| + return instruction.isPositiveInteger(closedWorld);
|
| }
|
| }
|
|
|
| @@ -460,18 +467,18 @@ class ShiftLeftSpecializer extends BinaryBitOpSpecializer {
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - if (left.isNumber(compiler)) {
|
| + if (left.isNumber(closedWorld)) {
|
| if (argumentLessThan32(right)) {
|
| - return newBuiltinVariant(instruction, compiler);
|
| + return newBuiltinVariant(instruction, compiler, closedWorld);
|
| }
|
| // Even if there is no builtin equivalent instruction, we know
|
| // the instruction does not have any side effect, and that it
|
| // can be GVN'ed.
|
| clearAllSideEffects(instruction);
|
| - if (isPositive(right, compiler)) {
|
| + if (isPositive(right, closedWorld)) {
|
| instruction.selector = renameToOptimizedSelector(
|
| '_shlPositive', instruction.selector, compiler);
|
| }
|
| @@ -480,9 +487,12 @@ class ShiftLeftSpecializer extends BinaryBitOpSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HShiftLeft(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HShiftLeft(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -490,31 +500,31 @@ class ShiftRightSpecializer extends BinaryBitOpSpecializer {
|
| const ShiftRightSpecializer();
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| - if (left.isUInt32(compiler)) return left.instructionType;
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + if (left.isUInt32(closedWorld)) return left.instructionType;
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - if (left.isNumber(compiler)) {
|
| - if (argumentLessThan32(right) && isPositive(left, compiler)) {
|
| - return newBuiltinVariant(instruction, compiler);
|
| + if (left.isNumber(closedWorld)) {
|
| + if (argumentLessThan32(right) && isPositive(left, closedWorld)) {
|
| + return newBuiltinVariant(instruction, compiler, closedWorld);
|
| }
|
| // Even if there is no builtin equivalent instruction, we know
|
| // the instruction does not have any side effect, and that it
|
| // can be GVN'ed.
|
| clearAllSideEffects(instruction);
|
| - if (isPositive(right, compiler) && isPositive(left, compiler)) {
|
| + if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) {
|
| instruction.selector = renameToOptimizedSelector(
|
| '_shrBothPositive', instruction.selector, compiler);
|
| - } else if (isPositive(left, compiler) && right.isNumber(compiler)) {
|
| + } else if (isPositive(left, closedWorld) && right.isNumber(closedWorld)) {
|
| instruction.selector = renameToOptimizedSelector(
|
| '_shrReceiverPositive', instruction.selector, compiler);
|
| - } else if (isPositive(right, compiler)) {
|
| + } else if (isPositive(right, closedWorld)) {
|
| instruction.selector = renameToOptimizedSelector(
|
| '_shrOtherPositive', instruction.selector, compiler);
|
| }
|
| @@ -523,9 +533,12 @@ class ShiftRightSpecializer extends BinaryBitOpSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HShiftRight(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HShiftRight(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
|
|
| BinaryOperation operation(ConstantSystem constantSystem) {
|
| @@ -541,20 +554,22 @@ class BitOrSpecializer extends BinaryBitOpSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
|
| - return backend.uint31Type;
|
| + if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) {
|
| + return closedWorld.commonMasks.uint31Type;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HBitOr(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HBitOr(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -566,21 +581,23 @@ class BitAndSpecializer extends BinaryBitOpSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (left.isPrimitiveOrNull(compiler) &&
|
| - (left.isUInt31(compiler) || right.isUInt31(compiler))) {
|
| - return backend.uint31Type;
|
| + if (left.isPrimitiveOrNull(closedWorld) &&
|
| + (left.isUInt31(closedWorld) || right.isUInt31(closedWorld))) {
|
| + return closedWorld.commonMasks.uint31Type;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HBitAnd(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HBitAnd(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -592,20 +609,22 @@ class BitXorSpecializer extends BinaryBitOpSpecializer {
|
| }
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
|
| - return backend.uint31Type;
|
| + if (left.isUInt31(closedWorld) && right.isUInt31(closedWorld)) {
|
| + return closedWorld.commonMasks.uint31Type;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - return new HBitXor(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, computeTypeFromInputTypes(instruction, compiler));
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + return new HBitXor(
|
| + instruction.inputs[1],
|
| + instruction.inputs[2],
|
| + instruction.selector,
|
| + computeTypeFromInputTypes(instruction, compiler, closedWorld));
|
| }
|
| }
|
|
|
| @@ -613,47 +632,46 @@ abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
|
| const RelationalSpecializer();
|
|
|
| TypeMask computeTypeFromInputTypes(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| - if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
|
| - return backend.boolType;
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| + if (instruction.inputs[1].isPrimitiveOrNull(closedWorld)) {
|
| + return closedWorld.commonMasks.boolType;
|
| }
|
| - return super.computeTypeFromInputTypes(instruction, compiler);
|
| + return super.computeTypeFromInputTypes(instruction, compiler, closedWorld);
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| - if (left.isNumber(compiler) && right.isNumber(compiler)) {
|
| - return newBuiltinVariant(instruction, compiler);
|
| + if (left.isNumber(closedWorld) && right.isNumber(closedWorld)) {
|
| + return newBuiltinVariant(instruction, closedWorld);
|
| }
|
| return null;
|
| }
|
|
|
| - HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);
|
| + HInstruction newBuiltinVariant(
|
| + HInvokeDynamic instruction, ClosedWorld closedWorld);
|
| }
|
|
|
| class EqualsSpecializer extends RelationalSpecializer {
|
| const EqualsSpecializer();
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction left = instruction.inputs[1];
|
| HInstruction right = instruction.inputs[2];
|
| TypeMask instructionType = left.instructionType;
|
| - if (right.isConstantNull() || left.isPrimitiveOrNull(compiler)) {
|
| - return newBuiltinVariant(instruction, compiler);
|
| + if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) {
|
| + return newBuiltinVariant(instruction, closedWorld);
|
| }
|
| - ClosedWorld world = compiler.closedWorld;
|
| - JavaScriptBackend backend = compiler.backend;
|
| Iterable<Element> matches =
|
| - world.allFunctions.filter(instruction.selector, instructionType);
|
| + closedWorld.allFunctions.filter(instruction.selector, instructionType);
|
| // This test relies the on `Object.==` and `Interceptor.==` always being
|
| // implemented because if the selector matches by subtype, it still will be
|
| // a regular object or an interceptor.
|
| - if (matches.every(backend.isDefaultEqualityImplementation)) {
|
| - return newBuiltinVariant(instruction, compiler);
|
| + if (matches
|
| + .every(closedWorld.backendClasses.isDefaultEqualityImplementation)) {
|
| + return newBuiltinVariant(instruction, closedWorld);
|
| }
|
| return null;
|
| }
|
| @@ -663,10 +681,9 @@ class EqualsSpecializer extends RelationalSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| + HInvokeDynamic instruction, ClosedWorld closedWorld) {
|
| return new HIdentity(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, backend.boolType);
|
| + instruction.selector, closedWorld.commonMasks.boolType);
|
| }
|
| }
|
|
|
| @@ -678,10 +695,9 @@ class LessSpecializer extends RelationalSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| + HInvokeDynamic instruction, ClosedWorld closedWorld) {
|
| return new HLess(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, backend.boolType);
|
| + instruction.selector, closedWorld.commonMasks.boolType);
|
| }
|
| }
|
|
|
| @@ -693,10 +709,9 @@ class GreaterSpecializer extends RelationalSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| + HInvokeDynamic instruction, ClosedWorld closedWorld) {
|
| return new HGreater(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, backend.boolType);
|
| + instruction.selector, closedWorld.commonMasks.boolType);
|
| }
|
| }
|
|
|
| @@ -708,10 +723,9 @@ class GreaterEqualSpecializer extends RelationalSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| + HInvokeDynamic instruction, ClosedWorld closedWorld) {
|
| return new HGreaterEqual(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, backend.boolType);
|
| + instruction.selector, closedWorld.commonMasks.boolType);
|
| }
|
| }
|
|
|
| @@ -723,10 +737,9 @@ class LessEqualSpecializer extends RelationalSpecializer {
|
| }
|
|
|
| HInstruction newBuiltinVariant(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| - JavaScriptBackend backend = compiler.backend;
|
| + HInvokeDynamic instruction, ClosedWorld closedWorld) {
|
| return new HLessEqual(instruction.inputs[1], instruction.inputs[2],
|
| - instruction.selector, backend.boolType);
|
| + instruction.selector, closedWorld.commonMasks.boolType);
|
| }
|
| }
|
|
|
| @@ -738,11 +751,11 @@ class CodeUnitAtSpecializer extends InvokeDynamicSpecializer {
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index
|
| // bounds checking optimizations as for HIndex.
|
| HInstruction receiver = instruction.getDartReceiver(compiler);
|
| - if (receiver.isStringOrNull(compiler)) {
|
| + if (receiver.isStringOrNull(closedWorld)) {
|
| // Even if there is no builtin equivalent instruction, we know
|
| // String.codeUnitAt does not have any side effect (other than throwing),
|
| // and that it can be GVN'ed.
|
| @@ -760,9 +773,9 @@ class RoundSpecializer extends InvokeDynamicSpecializer {
|
| }
|
|
|
| HInstruction tryConvertToBuiltin(
|
| - HInvokeDynamic instruction, Compiler compiler) {
|
| + HInvokeDynamic instruction, Compiler compiler, ClosedWorld closedWorld) {
|
| HInstruction receiver = instruction.getDartReceiver(compiler);
|
| - if (receiver.isNumberOrNull(compiler)) {
|
| + if (receiver.isNumberOrNull(closedWorld)) {
|
| // Even if there is no builtin equivalent instruction, we know the
|
| // instruction does not have any side effect, and that it can be GVN'ed.
|
| clearAllSideEffects(instruction);
|
|
|