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