Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
index a06516a76a3003c7b732993184a2798d65ce64e4..6e2441a3b24f78e77df1e5cf520315c7e5ca7a2a 100644 |
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart |
@@ -567,9 +567,6 @@ class TransformingVisitor extends RecursiveVisitor { |
bool isAlwaysBoolified(Primitive prim) { |
for (Reference ref = prim.firstRef; ref != null; ref = ref.next) { |
Node use = ref.parent; |
- // Ignore uses in dead identical() nodes. |
- // This happens after rewriting identical(x, true) to x. |
- if (use is Identical && use.hasNoUses) continue; |
asgerf
2015/06/23 13:25:40
Now that unused primitives are not no-ops, it's ju
|
if (!isBoolifyingUse(ref)) return false; |
} |
return true; |
@@ -796,19 +793,6 @@ class TransformingVisitor extends RecursiveVisitor { |
return value == null ? new AbstractValue.nothing() : value; |
} |
- void visitIdentical(Identical node) { |
- Primitive left = node.left.definition; |
- Primitive right = node.right.definition; |
- AbstractValue leftValue = getValue(left); |
- AbstractValue rightValue = getValue(right); |
- // Replace identical(x, true) by x when x is known to be a boolean. |
- if (lattice.isDefinitelyBool(leftValue) && |
- rightValue.isConstant && |
- rightValue.constant.isTrue) { |
- left.substituteFor(node); |
- } |
- } |
- |
void insertLetPrim(Expression node, Primitive prim) { |
InteriorNode parent = node.parent; |
LetPrim let = new LetPrim(prim); |
@@ -863,6 +847,19 @@ class TransformingVisitor extends RecursiveVisitor { |
// rewriting the + operator to StringConcat. |
break; |
+ case BuiltinOperator.Identical: |
+ Primitive left = node.arguments[0].definition; |
+ Primitive right = node.arguments[1].definition; |
+ AbstractValue leftValue = getValue(left); |
+ AbstractValue rightValue = getValue(right); |
+ // Replace identical(x, true) by x when x is known to be a boolean. |
+ if (lattice.isDefinitelyBool(leftValue) && |
+ rightValue.isConstant && |
+ rightValue.constant.isTrue) { |
+ left.substituteFor(node); |
+ } |
+ break; |
+ |
default: |
} |
} |
@@ -915,6 +912,15 @@ class TransformingVisitor extends RecursiveVisitor { |
RemovalVisitor.remove(node.primitive); |
node.primitive = newPrim; |
} |
+ if (node.primitive.hasNoUses && node.primitive.isSafeForElimination) { |
+ // Remove unused primitives before entering the body. |
+ // This would also be done by shrinking reductions, but usage analyses |
+ // such as isAlwaysBoolified are more precise without the dead uses, so |
+ // we prefer to remove them early. |
+ RemovalVisitor.remove(node.primitive); |
+ node.parent.body = node.body; |
+ node.body.parent = node.parent; |
+ } |
} |
visit(node.body); |
} |
@@ -1205,6 +1211,37 @@ class TypePropagationVisitor implements Visitor { |
setValue(node, constantValue(new StringConstantValue(stringValue))); |
} |
break; |
+ |
+ case BuiltinOperator.Identical: |
+ AbstractValue leftConst = getValue(node.arguments[0].definition); |
+ AbstractValue rightConst = getValue(node.arguments[1].definition); |
+ ConstantValue leftValue = leftConst.constant; |
+ ConstantValue rightValue = rightConst.constant; |
+ if (leftConst.isNothing || rightConst.isNothing) { |
+ // Come back later. |
+ return; |
+ } else if (!leftConst.isConstant || !rightConst.isConstant) { |
+ TypeMask leftType = leftConst.type; |
+ TypeMask rightType = rightConst.type; |
+ if (typeSystem.areDisjoint(leftType, rightType)) { |
+ setValue(node, |
+ constantValue(new FalseConstantValue(), typeSystem.boolType)); |
+ } else { |
+ setValue(node, nonConstant(typeSystem.boolType)); |
+ } |
+ return; |
+ } else if (leftValue.isPrimitive && rightValue.isPrimitive) { |
+ assert(leftConst.isConstant && rightConst.isConstant); |
+ PrimitiveConstantValue left = leftValue; |
+ PrimitiveConstantValue right = rightValue; |
+ ConstantValue result = |
+ new BoolConstantValue(left.primitiveValue == right.primitiveValue); |
+ setValue(node, constantValue(result, typeSystem.boolType)); |
+ } else { |
+ setValue(node, nonConstant(typeSystem.boolType)); |
+ } |
+ break; |
+ |
default: |
setValue(node, nonConstant()); |
} |
@@ -1412,33 +1449,6 @@ class TypePropagationVisitor implements Visitor { |
visitBranch(branch); |
} |
- void visitIdentical(Identical node) { |
- AbstractValue leftConst = getValue(node.left.definition); |
- AbstractValue rightConst = getValue(node.right.definition); |
- ConstantValue leftValue = leftConst.constant; |
- ConstantValue rightValue = rightConst.constant; |
- if (leftConst.isNothing || rightConst.isNothing) { |
- // Come back later. |
- return; |
- } else if (!leftConst.isConstant || !rightConst.isConstant) { |
- TypeMask leftType = leftConst.type; |
- TypeMask rightType = rightConst.type; |
- if (typeSystem.areDisjoint(leftType, rightType)) { |
- setValue(node, |
- constantValue(new FalseConstantValue(), typeSystem.boolType)); |
- } else { |
- setValue(node, nonConstant(typeSystem.boolType)); |
- } |
- } else if (leftValue.isPrimitive && rightValue.isPrimitive) { |
- assert(leftConst.isConstant && rightConst.isConstant); |
- PrimitiveConstantValue left = leftValue; |
- PrimitiveConstantValue right = rightValue; |
- ConstantValue result = |
- new BoolConstantValue(left.primitiveValue == right.primitiveValue); |
- setValue(node, constantValue(result, typeSystem.boolType)); |
- } |
- } |
- |
void visitInterceptor(Interceptor node) { |
setReachable(node.input.definition); |
AbstractValue value = getValue(node.input.definition); |