| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 interface OptimizationPhase { | 5 interface OptimizationPhase { |
| 6 String get name(); | 6 String get name(); |
| 7 void visitGraph(HGraph graph); | 7 void visitGraph(HGraph graph); |
| 8 } | 8 } |
| 9 | 9 |
| 10 class SsaOptimizerTask extends CompilerTask { | 10 class SsaOptimizerTask extends CompilerTask { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 HInstruction visitInstruction(HInstruction node) { | 83 HInstruction visitInstruction(HInstruction node) { |
| 84 return node; | 84 return node; |
| 85 } | 85 } |
| 86 | 86 |
| 87 HInstruction visitBoolify(HBoolify node) { | 87 HInstruction visitBoolify(HBoolify node) { |
| 88 List<HInstruction> inputs = node.inputs; | 88 List<HInstruction> inputs = node.inputs; |
| 89 assert(inputs.length == 1); | 89 assert(inputs.length == 1); |
| 90 HInstruction input = inputs[0]; | 90 HInstruction input = inputs[0]; |
| 91 if (input.isBoolean()) return input; | 91 if (input.isBoolean()) return input; |
| 92 // All values !== true are boolified to false. | 92 // All values !== true are boolified to false. |
| 93 if (input.type.isKnown()) return graph.addNewLiteralFalse(); | 93 if (input.type.isKnown()) { |
| 94 return graph.addConstantBool(false); |
| 95 } |
| 94 return node; | 96 return node; |
| 95 } | 97 } |
| 96 | 98 |
| 97 HInstruction visitNot(HNot node) { | 99 HInstruction visitNot(HNot node) { |
| 98 List<HInstruction> inputs = node.inputs; | 100 List<HInstruction> inputs = node.inputs; |
| 99 assert(inputs.length == 1); | 101 assert(inputs.length == 1); |
| 100 HInstruction input = inputs[0]; | 102 HInstruction input = inputs[0]; |
| 101 if (input is HLiteral) { | 103 if (input is HConstant) { |
| 102 HLiteral literal = input; | 104 HConstant constant = input; |
| 103 return graph.addNewLiteralBool(literal.value !== true); | 105 bool isTrue = constant.constant.isTrue(); |
| 106 return graph.addConstantBool(!isTrue); |
| 104 } | 107 } |
| 105 return node; | 108 return node; |
| 106 } | 109 } |
| 107 | 110 |
| 108 HInstruction visitInvokeBinary(HInvokeBinary node) => node.fold(graph); | 111 HInstruction visitInvokeBinary(HInvokeBinary node) => node.fold(graph); |
| 109 HInstruction visitInvokeUnary(HInvokeUnary node) => node.fold(graph); | 112 HInstruction visitInvokeUnary(HInvokeUnary node) => node.fold(graph); |
| 110 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) | 113 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) |
| 111 => node.fold(graph); | 114 => node.fold(graph); |
| 112 | 115 |
| 113 HInstruction visitAdd(HAdd node) { | 116 HInstruction visitAdd(HAdd node) { |
| 117 // TODO(floitsch): move this code into the compile-time constant handler. |
| 118 |
| 114 // String + is defined for all literals. We don't need to know which | 119 // String + is defined for all literals. We don't need to know which |
| 115 // literal type the right-hand side is. | 120 // type the right-hand side is. |
| 116 | 121 |
| 117 if (node.left.isString()) { | 122 if (node.left.isString()) { |
| 118 // First try to eliminate adding the empty string to a string. | 123 // First try to eliminate adding the empty string to a string. |
| 119 if (node.right.isLiteralString()) { | 124 if (node.right.isConstantString()) { |
| 120 HLiteral right = node.right; | 125 HConstant right = node.right; |
| 121 DartString rightString = right.value; | 126 Constant rightStringConstant = right.constant; |
| 127 DartString rightString = rightStringConstant.value; |
| 122 if (rightString.isEmpty()) { | 128 if (rightString.isEmpty()) { |
| 123 // String has no content, i.e., it's the empty string. | 129 // String has no content, i.e., it's the empty string. |
| 124 return node.left; | 130 return node.left; |
| 125 } | 131 } |
| 126 } | 132 } |
| 127 // Then, if both are literals, try to do the concatenation statically. | 133 // Then, if both are constants, try to do the concatenation statically. |
| 128 if (node.left.isLiteralString()) { | 134 if (node.left.isConstantString()) { |
| 129 HLiteral left = node.left; | 135 HConstant left = node.left; |
| 130 DartString leftString = left.value; | 136 Constant leftStringConstant = left.constant; |
| 137 DartString leftString = leftStringConstant.value; |
| 131 if (leftString.isEmpty()) { | 138 if (leftString.isEmpty()) { |
| 132 // Left is empty String. | 139 // Left is empty String. |
| 133 if (node.right.isString()) { | 140 if (node.right.isString()) { |
| 134 // Right is already a String, just return that. | 141 // Right is already a String, just return that. |
| 135 return node.right; | 142 return node.right; |
| 136 } | 143 } |
| 137 if (node.right is HLiteral) { | 144 if (node.right is HConstant) { |
| 138 HLiteral right = node.right; | 145 HConstant right = node.right; |
| 139 // Right is a literal, so we can statically convert it to String | 146 // Right is a constant, so we can statically convert it to String |
| 140 // and return that. | 147 // and return that. |
| 141 // Remaining literal types are represented by their Dart value. | 148 // Remaining literal types are represented by their Dart value. |
| 142 assert(right.isLiteralBoolean() || | 149 if (right.isConstantBoolean() || |
| 143 right.isLiteralNumber() || | 150 right.isConstantNumber() || |
| 144 right.isLiteralNull()); | 151 right.isConstantNull()) { |
| 145 String str = right.value.toString(); | 152 PrimitiveConstant rightConstant = right.constant; |
| 146 return graph.addNewLiteralString(new DartString.literal(str)); | 153 String str = rightConstant.value.toString(); |
| 154 return graph.addConstantString(new DartString.literal(str)); |
| 155 } |
| 147 } | 156 } |
| 148 } | 157 } |
| 149 // TODO(lrn): Perform concatenation in Dart. | 158 // TODO(lrn): Perform concatenation in Dart. |
| 150 } | 159 } |
| 151 } | 160 } |
| 152 return visitInvokeBinary(node); | 161 return visitInvokeBinary(node); |
| 153 } | 162 } |
| 154 | 163 |
| 155 HInstruction visitEquals(HEquals node) { | 164 HInstruction visitEquals(HEquals node) { |
| 156 if (node.left is HLiteral && node.right is HLiteral) { | 165 HInstruction left = node.left; |
| 157 HLiteral op1 = node.left; | 166 HInstruction right = node.right; |
| 158 HLiteral op2 = node.right; | 167 if (!left.isConstant() && right.isConstantNull()) { |
| 159 if (op1.isLiteralString()) { | 168 // TODO(floitsch): cache interceptors. |
| 160 if (op2.isLiteralString() && op1.value.definitelyEquals(op2.value)) { | |
| 161 return graph.addNewLiteralTrue(); | |
| 162 } | |
| 163 } else { | |
| 164 return graph.addNewLiteralBool(op1.value == op2.value); | |
| 165 } | |
| 166 } else if (node.right.isLiteralNull()) { | |
| 167 HStatic target = new HStatic( | 169 HStatic target = new HStatic( |
| 168 compiler.builder.interceptors.getEqualsNullInterceptor()); | 170 compiler.builder.interceptors.getEqualsNullInterceptor()); |
| 169 node.block.addBefore(node, target); | 171 node.block.addBefore(node,target); |
| 170 return new HEquals(target, node.left, node.right); | 172 return new HEquals(target, node.left, node.right); |
| 171 } | 173 } |
| 172 return node; | 174 // All other cases are dealt with by the [visitInvokeBinary]. |
| 175 return visitInvokeBinary(node); |
| 173 } | 176 } |
| 174 | 177 |
| 175 HInstruction visitTypeGuard(HTypeGuard node) { | 178 HInstruction visitTypeGuard(HTypeGuard node) { |
| 176 HInstruction value = node.guarded; | 179 HInstruction value = node.guarded; |
| 177 return (value.type.combine(node.type) == value.type) ? value : node; | 180 return (value.type.combine(node.type) == value.type) ? value : node; |
| 178 } | 181 } |
| 179 | 182 |
| 180 HInstruction visitIntegerCheck(HIntegerCheck node) { | 183 HInstruction visitIntegerCheck(HIntegerCheck node) { |
| 181 HInstruction value = node.value; | 184 HInstruction value = node.value; |
| 182 return value.isInteger() ? value : node; | 185 return value.isInteger() ? value : node; |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 } | 641 } |
| 639 } | 642 } |
| 640 if (!canBeMoved) continue; | 643 if (!canBeMoved) continue; |
| 641 | 644 |
| 642 // This is safe because we are running after GVN. | 645 // This is safe because we are running after GVN. |
| 643 // TODO(ngeoffray): ensure GVN has been run. | 646 // TODO(ngeoffray): ensure GVN has been run. |
| 644 set_.add(current); | 647 set_.add(current); |
| 645 } | 648 } |
| 646 } | 649 } |
| 647 } | 650 } |
| OLD | NEW |