Chromium Code Reviews| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 if (operand is HConstant) { | 140 if (operand is HConstant) { |
| 141 UnaryOperation operation = node.operation; | 141 UnaryOperation operation = node.operation; |
| 142 HConstant receiver = operand; | 142 HConstant receiver = operand; |
| 143 Constant folded = operation.fold(receiver.constant); | 143 Constant folded = operation.fold(receiver.constant); |
| 144 if (folded !== null) return graph.addConstant(folded); | 144 if (folded !== null) return graph.addConstant(folded); |
| 145 } | 145 } |
| 146 return node; | 146 return node; |
| 147 } | 147 } |
| 148 | 148 |
| 149 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { | 149 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { |
| 150 if (node.name == const SourceString('length') && | 150 if (node.isLengthGetter()) { |
| 151 node.inputs[1].isConstantString()) { | 151 HInstruction input = node.inputs[1]; |
| 152 HConstant input = node.inputs[1]; | 152 if (input.isConstantString()) { |
| 153 StringConstant constant = input.constant; | 153 StringConstant constant = input.constant; |
| 154 DartString string = constant.value; | 154 return graph.addConstantInt(constant.length); |
| 155 return graph.addConstantInt(string.length); | 155 } else if (input.isConstantList()) { |
| 156 ListConstant constant = input.constant; | |
| 157 return graph.addConstantInt(constant.length); | |
| 158 } else if (input.isConstantMap()) { | |
| 159 MapConstant constant = input.constant; | |
| 160 return graph.addConstantInt(constant.length); | |
| 161 } | |
| 162 } | |
| 163 return node; | |
| 164 } | |
| 165 | |
| 166 HInstruction visitInvokeDynamic(HInvokeDynamic node) { | |
| 167 HType receiverType = node.receiver.propagatedType; | |
| 168 if (receiverType.isNonPrimitive()) { | |
| 169 HNonPrimitiveType type = receiverType; | |
| 170 Element element = type.lookupMember(node.name); | |
| 171 // TODO(ngeoffray): Also fold if it's a getter or variable. | |
| 172 if (element != null && element.isFunction()) { | |
| 173 FunctionElement method = element; | |
| 174 FunctionParameters parameters = method.computeParameters(compiler); | |
| 175 if (node.selector.applies(parameters)) { | |
|
floitsch
2012/04/18 19:18:48
Even if the function doesn't apply we should set t
ngeoffray
2012/04/19 08:09:33
Why? There is no need to compile the function sinc
| |
| 176 if (parameters.optionalParameterCount == 0) { | |
| 177 node.element = element; | |
| 178 } | |
| 179 // TODO(ngeoffray): If the method has optional parameters, | |
| 180 // we should pass the default values here. | |
| 181 } | |
| 182 } | |
| 183 } | |
| 184 return node; | |
| 185 } | |
| 186 | |
| 187 HInstruction visitIndex(HIndex node) { | |
|
kasperl
2012/04/19 06:46:19
This looks like this could be refactored with a he
ngeoffray
2012/04/19 08:09:33
Done.
| |
| 188 if (node.receiver.isNonPrimitive()) { | |
| 189 return new HInvokeDynamicMethod( | |
| 190 node.selector, | |
| 191 Elements.constructOperatorName( | |
| 192 const SourceString('operator'), | |
| 193 const SourceString('[]')), | |
| 194 node.inputs.getRange(1, node.inputs.length - 1)); | |
| 195 } | |
| 196 return node; | |
| 197 } | |
| 198 | |
| 199 HInstruction visitIndexAssign(HIndexAssign node) { | |
| 200 if (node.receiver.isNonPrimitive()) { | |
| 201 return new HInvokeDynamicMethod( | |
| 202 node.selector, | |
| 203 Elements.constructOperatorName( | |
| 204 const SourceString('operator'), | |
| 205 const SourceString('[]=')), | |
| 206 node.inputs.getRange(1, node.inputs.length - 1)); | |
| 156 } | 207 } |
| 157 return node; | 208 return node; |
| 158 } | 209 } |
| 159 | 210 |
| 160 HInstruction visitInvokeBinary(HInvokeBinary node) { | 211 HInstruction visitInvokeBinary(HInvokeBinary node) { |
| 161 HInstruction left = node.left; | 212 HInstruction left = node.left; |
| 162 HInstruction right = node.right; | 213 HInstruction right = node.right; |
| 163 if (left is HConstant && right is HConstant) { | 214 if (left is HConstant && right is HConstant) { |
| 164 BinaryOperation operation = node.operation; | 215 BinaryOperation operation = node.operation; |
| 165 HConstant op1 = left; | 216 HConstant op1 = left; |
| 166 HConstant op2 = right; | 217 HConstant op2 = right; |
| 167 Constant folded = operation.fold(op1.constant, op2.constant); | 218 Constant folded = operation.fold(op1.constant, op2.constant); |
| 168 if (folded !== null) return graph.addConstant(folded); | 219 if (folded !== null) return graph.addConstant(folded); |
| 169 } | 220 } |
| 221 | |
| 222 if (left.isNonPrimitive() && node.operation.isUserDefinable()) { | |
| 223 return new HInvokeDynamicMethod( | |
| 224 node.selector, | |
| 225 Elements.constructOperatorName( | |
| 226 const SourceString('operator'), | |
| 227 node.operation.name), | |
| 228 node.inputs.getRange(1, node.inputs.length - 1)); | |
| 229 } | |
| 170 return node; | 230 return node; |
| 171 } | 231 } |
| 172 | 232 |
| 173 HInstruction visitEquals(HEquals node) { | 233 HInstruction visitEquals(HEquals node) { |
| 174 HInstruction left = node.left; | 234 HInstruction left = node.left; |
| 175 HInstruction right = node.right; | 235 HInstruction right = node.right; |
| 176 if (!left.isConstant() && right.isConstantNull()) { | 236 if (!left.isConstant() && right.isConstantNull()) { |
| 177 // TODO(floitsch): cache interceptors. | 237 // TODO(floitsch): cache interceptors. |
| 178 HStatic target = new HStatic( | 238 HStatic target = new HStatic( |
| 179 compiler.builder.interceptors.getEqualsNullInterceptor()); | 239 compiler.builder.interceptors.getEqualsNullInterceptor()); |
| 180 node.block.addBefore(node,target); | 240 node.block.addBefore(node,target); |
| 181 return new HEquals(target, node.left, node.right); | 241 return new HEquals(target, node.left, node.right); |
| 182 } | 242 } |
| 243 | |
| 244 if (left.isNonPrimitive()) { | |
|
kasperl
2012/04/19 06:46:19
Add a comment here that explains what this does. E
| |
| 245 HNonPrimitiveType type = left.propagatedType; | |
| 246 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); | |
| 247 if (element === null) { | |
| 248 // TODO(floitsch): cache interceptors. | |
| 249 HStatic target = new HStatic( | |
| 250 compiler.builder.interceptors.getTripleEqualsInterceptor()); | |
| 251 return new HIdentity(target, left, right); | |
| 252 } | |
| 253 } | |
| 254 | |
| 183 // All other cases are dealt with by the [visitInvokeBinary]. | 255 // All other cases are dealt with by the [visitInvokeBinary]. |
| 184 return visitInvokeBinary(node); | 256 return visitInvokeBinary(node); |
| 185 } | 257 } |
| 186 | 258 |
| 187 HInstruction visitTypeGuard(HTypeGuard node) { | 259 HInstruction visitTypeGuard(HTypeGuard node) { |
| 188 HInstruction value = node.guarded; | 260 HInstruction value = node.guarded; |
| 189 HType combinedType = value.propagatedType.combine(node.propagatedType); | 261 HType combinedType = value.propagatedType.combine(node.propagatedType); |
| 190 return (combinedType == value.propagatedType) ? value : node; | 262 return (combinedType == value.propagatedType) ? value : node; |
| 191 } | 263 } |
| 192 | 264 |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 713 } | 785 } |
| 714 } | 786 } |
| 715 if (!canBeMoved) continue; | 787 if (!canBeMoved) continue; |
| 716 | 788 |
| 717 // This is safe because we are running after GVN. | 789 // This is safe because we are running after GVN. |
| 718 // TODO(ngeoffray): ensure GVN has been run. | 790 // TODO(ngeoffray): ensure GVN has been run. |
| 719 set_.add(current); | 791 set_.add(current); |
| 720 } | 792 } |
| 721 } | 793 } |
| 722 } | 794 } |
| OLD | NEW |