Index: lib/compiler/implementation/ssa/optimize.dart |
diff --git a/lib/compiler/implementation/ssa/optimize.dart b/lib/compiler/implementation/ssa/optimize.dart |
index b20e5a475052742f1f4011f244a0c52157520f93..8ae43a80a6662913f0f2b0c085c3b7565f880929 100644 |
--- a/lib/compiler/implementation/ssa/optimize.dart |
+++ b/lib/compiler/implementation/ssa/optimize.dart |
@@ -27,24 +27,25 @@ class SsaOptimizerTask extends CompilerTask { |
} |
void optimize(WorkItem work, HGraph graph) { |
+ ConstantSystem constantSystem = compiler.backend.constantSystem; |
JavaScriptItemCompilationContext context = work.compilationContext; |
HTypeMap types = context.types; |
measure(() { |
List<OptimizationPhase> phases = <OptimizationPhase>[ |
// Run trivial constant folding first to optimize |
// some patterns useful for type conversion. |
- new SsaConstantFolder(backend, work, types), |
+ new SsaConstantFolder(constantSystem, backend, work, types), |
new SsaTypeConversionInserter(compiler), |
new SsaTypePropagator(compiler, types), |
new SsaCheckInserter(backend, types), |
- new SsaConstantFolder(backend, work, types), |
+ new SsaConstantFolder(constantSystem, backend, work, types), |
new SsaRedundantPhiEliminator(), |
new SsaDeadPhiEliminator(), |
new SsaGlobalValueNumberer(compiler, types), |
new SsaCodeMotion(), |
// Previous optimizations may have generated new |
// opportunities for constant folding. |
- new SsaConstantFolder(backend, work, types), |
+ new SsaConstantFolder(constantSystem, backend, work, types), |
new SsaDeadCodeEliminator(types), |
new SsaRegisterRecompilationCandidates(backend, work, types)]; |
runPhases(graph, phases); |
@@ -110,11 +111,12 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
final String name = "SsaConstantFolder"; |
final JavaScriptBackend backend; |
final WorkItem work; |
+ final ConstantSystem constantSystem; |
final HTypeMap types; |
HGraph graph; |
Compiler get compiler => backend.compiler; |
- SsaConstantFolder(this.backend, this.work, this.types); |
+ SsaConstantFolder(this.constantSystem, this.backend, this.work, this.types); |
void visitGraph(HGraph visitee) { |
graph = visitee; |
@@ -161,7 +163,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
// All values !== true are boolified to false. |
DartType type = types[input].computeType(compiler); |
if (type !== null && type.element !== compiler.boolClass) { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
return node; |
} |
@@ -173,7 +175,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
if (input is HConstant) { |
HConstant constant = input; |
bool isTrue = constant.constant.isTrue(); |
- return graph.addConstantBool(!isTrue); |
+ return graph.addConstantBool(!isTrue, constantSystem); |
} else if (input is HNot) { |
return input.inputs[0]; |
} |
@@ -183,7 +185,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
HInstruction visitInvokeUnary(HInvokeUnary node) { |
HInstruction operand = node.operand; |
if (operand is HConstant) { |
- UnaryOperation operation = node.operation; |
+ UnaryOperation operation = node.operation(constantSystem); |
HConstant receiver = operand; |
Constant folded = operation.fold(receiver.constant); |
if (folded !== null) return graph.addConstant(folded); |
@@ -197,15 +199,15 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
if (input.isConstantString()) { |
HConstant constantInput = input; |
StringConstant constant = constantInput.constant; |
- return graph.addConstantInt(constant.length); |
+ return graph.addConstantInt(constant.length, constantSystem); |
} else if (input.isConstantList()) { |
HConstant constantInput = input; |
ListConstant constant = constantInput.constant; |
- return graph.addConstantInt(constant.length); |
+ return graph.addConstantInt(constant.length, constantSystem); |
} else if (input.isConstantMap()) { |
HConstant constantInput = input; |
MapConstant constant = constantInput.constant; |
- return graph.addConstantInt(constant.length); |
+ return graph.addConstantInt(constant.length, constantSystem); |
} |
} |
@@ -307,11 +309,12 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
HInstruction value = node.value; |
if (value.isInteger(types)) return value; |
if (value.isConstant()) { |
- assert((){ |
- HConstant constantInstruction = value; |
- return !constantInstruction.constant.isInt(); |
- }); |
- node.alwaysFalse = true; |
+ HConstant constantInstruction = value; |
+ assert(!constantInstruction.constant.isInt()); |
+ if (!constantSystem.isInt(constantInstruction.constant)) { |
+ // -0.0 is a double but will pass the runtime integer check. |
+ node.alwaysFalse = true; |
+ } |
} |
return node; |
} |
@@ -336,8 +339,8 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
HInstruction visitInvokeBinary(HInvokeBinary node) { |
HInstruction left = node.left; |
HInstruction right = node.right; |
+ BinaryOperation operation = node.operation(constantSystem); |
if (left is HConstant && right is HConstant) { |
- BinaryOperation operation = node.operation; |
HConstant op1 = left; |
HConstant op2 = right; |
Constant folded = operation.fold(op1.constant, op2.constant); |
@@ -345,10 +348,10 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
} |
if (!left.canBePrimitive(types) |
- && node.operation.isUserDefinable() |
+ && operation.isUserDefinable() |
// The equals operation is being optimized in visitEquals. |
- && node.operation !== const EqualsOperation()) { |
- Selector selector = new Selector.binaryOperator(node.operation.name); |
+ && node is! HEquals) { |
+ Selector selector = new Selector.binaryOperator(operation.name); |
return fromInterceptorToDynamicInvocation(node, selector); |
} |
return node; |
@@ -401,7 +404,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
// We don't optimize on numbers to preserve the runtime semantics. |
if (!(left.isNumber(types) && right.isNumber(types)) && |
leftType.intersection(rightType).isConflicting()) { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
if (left.isConstantBoolean() && right.isBoolean(types)) { |
@@ -465,7 +468,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
// operator. |
return super.visitEquals(node); |
} else if (right.isConstantNull()) { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} else { |
// We can just emit an identity check because the type does |
// not implement operator=. |
@@ -475,7 +478,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
if (right.isConstantNull()) { |
if (leftType.isPrimitive()) { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
} |
@@ -504,47 +507,47 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
HType expressionType = types[node.expression]; |
if (element === compiler.objectClass |
|| element === compiler.dynamicClass) { |
- return graph.addConstantBool(true); |
+ return graph.addConstantBool(true, constantSystem); |
} else if (expressionType.isInteger()) { |
if (element === compiler.intClass || element === compiler.numClass) { |
- return graph.addConstantBool(true); |
+ return graph.addConstantBool(true, constantSystem); |
} else if (element === compiler.doubleClass) { |
// We let the JS semantics decide for that check. Currently |
// the code we emit will always return true. |
return node; |
} else { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
} else if (expressionType.isDouble()) { |
if (element === compiler.doubleClass || element === compiler.numClass) { |
- return graph.addConstantBool(true); |
+ return graph.addConstantBool(true, constantSystem); |
} else if (element === compiler.intClass) { |
// We let the JS semantics decide for that check. Currently |
// the code we emit will return true for a double that can be |
- // represented as a 31-bit integer. |
+ // represented as a 31-bit integer and for -0.0. |
return node; |
} else { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
} else if (expressionType.isNumber()) { |
if (element === compiler.numClass) { |
- return graph.addConstantBool(true); |
+ return graph.addConstantBool(true, constantSystem); |
} |
// We cannot just return false, because the expression may be of |
// type int or double. |
} else if (expressionType.isString()) { |
if (element === compiler.stringClass |
|| Elements.isStringSupertype(element, compiler)) { |
- return graph.addConstantBool(true); |
+ return graph.addConstantBool(true, constantSystem); |
} else { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
} else if (expressionType.isArray()) { |
if (element === compiler.listClass |
|| Elements.isListSupertype(element, compiler)) { |
- return graph.addConstantBool(true); |
+ return graph.addConstantBool(true, constantSystem); |
} else { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
// TODO(karlklose): remove the hasTypeArguments check. |
} else if (expressionType.isUseful() |
@@ -553,9 +556,9 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
DartType receiverType = expressionType.computeType(compiler); |
if (receiverType !== null) { |
if (compiler.types.isSubtype(receiverType, type)) { |
- return graph.addConstantBool(true); |
+ return graph.addConstantBool(true, constantSystem); |
} else if (expressionType.isExact()) { |
- return graph.addConstantBool(false); |
+ return graph.addConstantBool(false, constantSystem); |
} |
} |
} |
@@ -634,7 +637,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
PrimitiveConstant primitive = constant.constant; |
folded = new DartString.concat(folded, primitive.toDartString()); |
} |
- return graph.addConstantString(folded, node.node); |
+ return graph.addConstant(constantSystem.createString(folded, node.node)); |
} |
} |