| Index: lib/compiler/implementation/ssa/optimize.dart
|
| diff --git a/lib/compiler/implementation/ssa/optimize.dart b/lib/compiler/implementation/ssa/optimize.dart
|
| index b4eee8611116d9f37a58f8dfd44cc719220d12ab..b93e18428ca2f76741f98a1cf5f652773166576e 100644
|
| --- a/lib/compiler/implementation/ssa/optimize.dart
|
| +++ b/lib/compiler/implementation/ssa/optimize.dart
|
| @@ -293,6 +293,43 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase {
|
| return node;
|
| }
|
|
|
| + bool allUsersAreBoolifies(HInstruction instruction) {
|
| + List<HInstruction> users = instruction.usedBy;
|
| + int length = users.length;
|
| + for (int i = 0; i < length; i++) {
|
| + if (users[i] is! HBoolify) return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + HInstruction visitRelational(HRelational node) {
|
| + if (allUsersAreBoolifies(node)) {
|
| + Interceptors interceptors = compiler.builder.interceptors;
|
| + HStatic oldTarget = node.target;
|
| + Element boolifiedInterceptor =
|
| + interceptors.getBoolifiedVersionOf(oldTarget.element);
|
| + if (boolifiedInterceptor !== null) {
|
| + HStatic boolifiedTarget = new HStatic(boolifiedInterceptor);
|
| + // We don't remove the [oldTarget] in case it is used by other
|
| + // instructions. If it is unused it will be treated as dead code and
|
| + // discarded.
|
| + oldTarget.block.addAfter(oldTarget, boolifiedTarget);
|
| + // Remove us as user from the [oldTarget].
|
| + HBasicBlock.removeUser(oldTarget, node);
|
| + // Replace old target with boolified target.
|
| + assert(node.target == node.inputs[0]);
|
| + node.inputs[0] = boolifiedTarget;
|
| + boolifiedTarget.usedBy.add(node);
|
| + node.usesBoolifiedInterceptor = true;
|
| + node.propagatedType = HType.BOOLEAN;
|
| + }
|
| + // This node stays the same, but the Boolify node will go away.
|
| + }
|
| + // Note that we still have to call [super] to make sure that we end up
|
| + // in the remaining optimizations.
|
| + return super.visitRelational(node);
|
| + }
|
| +
|
| HInstruction handleIdentityCheck(HInvokeBinary node) {
|
| HInstruction left = node.left;
|
| HInstruction right = node.right;
|
| @@ -354,7 +391,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase {
|
| }
|
|
|
| if (left.isConstant() && right.isConstant()) {
|
| - return visitInvokeBinary(node);
|
| + return super.visitEquals(node);
|
| }
|
|
|
| if (left.isNonPrimitive()) {
|
| @@ -364,7 +401,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase {
|
| // If the left-hand side is guaranteed to be a non-primitive
|
| // type and and it defines operator==, we emit a call to that
|
| // operator.
|
| - return visitInvokeBinary(node);
|
| + return super.visitEquals(node);
|
| } else if (right.isConstantNull()) {
|
| return graph.addConstantBool(false);
|
| } else {
|
| @@ -379,15 +416,27 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase {
|
| return graph.addConstantBool(false);
|
| } else {
|
| // TODO(floitsch): cache interceptors.
|
| - HStatic target = new HStatic(
|
| - compiler.builder.interceptors.getEqualsNullInterceptor());
|
| + Interceptors interceptors = compiler.builder.interceptors;
|
| + Element targetElement = interceptors.getEqualsNullInterceptor();
|
| + bool onlyUsedInBoolify = allUsersAreBoolifies(node);
|
| + if (onlyUsedInBoolify) {
|
| + targetElement = interceptors.getBoolifiedVersionOf(targetElement);
|
| + }
|
| + HStatic target = new HStatic(targetElement);
|
| node.block.addBefore(node, target);
|
| - return new HEquals(target, node.left, node.right);
|
| + HEquals result = new HEquals(target, node.left, node.right);
|
| + if (onlyUsedInBoolify) {
|
| + result.usesBoolifiedInterceptor = true;
|
| + result.propagatedType = HType.BOOLEAN;
|
| + }
|
| + return result;
|
| }
|
| }
|
|
|
| - // All other cases are dealt with by the [visitInvokeBinary].
|
| - return visitInvokeBinary(node);
|
| + // All other cases are dealt with by the [visitRelational] and
|
| + // [visitInvokeBinary], which are visited by invoking the [super]'s
|
| + // visit method.
|
| + return super.visitEquals(node);
|
| }
|
|
|
| HInstruction visitTypeGuard(HTypeGuard node) {
|
|
|