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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 } | 234 } |
| 235 | 235 |
| 236 if (left.isNonPrimitive() && node.operation.isUserDefinable()) { | 236 if (left.isNonPrimitive() && node.operation.isUserDefinable()) { |
| 237 SourceString methodName = Elements.constructOperatorName( | 237 SourceString methodName = Elements.constructOperatorName( |
| 238 const SourceString('operator'), node.operation.name); | 238 const SourceString('operator'), node.operation.name); |
| 239 return fromInterceptorToDynamicInvocation(node, methodName); | 239 return fromInterceptorToDynamicInvocation(node, methodName); |
| 240 } | 240 } |
| 241 return node; | 241 return node; |
| 242 } | 242 } |
| 243 | 243 |
| 244 HInstruction visitRelational(HRelational node) { | |
| 245 if (node.usedBy.length == 1 && node.usedBy[0] is HBoolify) { | |
|
ngeoffray
2012/04/25 11:48:08
I'd check if all the users are HBoolify instead.
floitsch
2012/04/25 16:01:49
Done.
| |
| 246 Interceptors interceptors = compiler.builder.interceptors; | |
| 247 HStatic oldTarget = node.target; | |
| 248 Element boolifiedInterceptor = | |
| 249 interceptors.getBoolifiedVersionOfInterceptor(oldTarget.element); | |
| 250 if (boolifiedInterceptor !== null) { | |
| 251 HStatic boolifiedTarget = new HStatic(boolifiedInterceptor); | |
| 252 // We don't remove the [oldTarget] in case it is used by other | |
| 253 // instructions. If it is unused it will be treated as dead code and | |
| 254 // discarded. | |
| 255 oldTarget.block.addAfter(oldTarget, boolifiedTarget); | |
| 256 // Remove us from the usedBy list of the old target. | |
|
ngeoffray
2012/04/25 11:48:08
Please move that code into the HInstruction class.
floitsch
2012/04/25 16:01:49
Moved into HBasicBlock class.
| |
| 257 if (oldTarget.usedBy.length == 1) { | |
| 258 oldTarget.usedBy.clear(); | |
| 259 } else { | |
| 260 List<HInstruction> users = oldTarget.usedBy; | |
| 261 int length = users.length; | |
| 262 for (int i = 0; i < length; i++) { | |
| 263 if (users[i] === node) { | |
| 264 users[i] = users[length - 1]; | |
| 265 users.length = length - 1; | |
| 266 } | |
| 267 } | |
| 268 } | |
| 269 // Replace old target with boolified target. | |
| 270 assert(node.target == node.inputs[0]); | |
| 271 node.inputs[0] = boolifiedTarget; | |
| 272 boolifiedTarget.usedBy.add(node); | |
| 273 node.usesBoolifiedInterceptor = true; | |
| 274 node.propagatedType = HType.BOOLEAN; | |
| 275 } | |
| 276 } | |
| 277 // This node stays the same, but the Boolify node will go away. | |
|
ngeoffray
2012/04/25 11:48:08
Move that comment one line up (in the if clause).
floitsch
2012/04/25 16:01:49
Done.
| |
| 278 // Note that we still have to call [super] to make sure that we end up | |
| 279 // in the remaining optimizations. | |
| 280 return super.visitRelational(node); | |
| 281 } | |
| 282 | |
| 244 HInstruction visitEquals(HEquals node) { | 283 HInstruction visitEquals(HEquals node) { |
| 245 HInstruction left = node.left; | 284 HInstruction left = node.left; |
| 246 HInstruction right = node.right; | 285 HInstruction right = node.right; |
| 247 | 286 |
| 248 if (left.isConstant() && right.isConstant()) { | 287 if (left.isConstant() && right.isConstant()) { |
| 249 return visitInvokeBinary(node); | 288 return visitInvokeBinary(node); |
|
ngeoffray
2012/04/25 11:48:08
Should that be changed to super.visitEquals(node)
floitsch
2012/04/25 16:01:49
Done.
| |
| 250 } | 289 } |
| 251 | 290 |
| 252 if (left.isNonPrimitive()) { | 291 if (left.isNonPrimitive()) { |
| 253 HNonPrimitiveType type = left.propagatedType; | 292 HNonPrimitiveType type = left.propagatedType; |
| 254 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); | 293 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); |
| 255 if (element !== null) { | 294 if (element !== null) { |
| 256 // If the left-hand side is guaranteed to be a non-primitive | 295 // If the left-hand side is guaranteed to be a non-primitive |
| 257 // type and and it defines operator==, we emit a call to that | 296 // type and and it defines operator==, we emit a call to that |
| 258 // operator. | 297 // operator. |
| 259 return visitInvokeBinary(node); | 298 return visitInvokeBinary(node); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 276 return graph.addConstantBool(false); | 315 return graph.addConstantBool(false); |
| 277 } else { | 316 } else { |
| 278 // TODO(floitsch): cache interceptors. | 317 // TODO(floitsch): cache interceptors. |
| 279 HStatic target = new HStatic( | 318 HStatic target = new HStatic( |
| 280 compiler.builder.interceptors.getEqualsNullInterceptor()); | 319 compiler.builder.interceptors.getEqualsNullInterceptor()); |
| 281 node.block.addBefore(node, target); | 320 node.block.addBefore(node, target); |
| 282 return new HEquals(target, node.left, node.right); | 321 return new HEquals(target, node.left, node.right); |
| 283 } | 322 } |
| 284 } | 323 } |
| 285 | 324 |
| 286 // All other cases are dealt with by the [visitInvokeBinary]. | 325 // All other cases are dealt with by the [visitRelational] and |
| 287 return visitInvokeBinary(node); | 326 // [visitInvokeBinary], which are visited by invoking the [super]'s |
| 327 // visit method. | |
| 328 return super.visitEquals(node); | |
| 288 } | 329 } |
| 289 | 330 |
| 290 HInstruction visitTypeGuard(HTypeGuard node) { | 331 HInstruction visitTypeGuard(HTypeGuard node) { |
| 291 HInstruction value = node.guarded; | 332 HInstruction value = node.guarded; |
| 292 HType combinedType = value.propagatedType.combine(node.guardedType); | 333 HType combinedType = value.propagatedType.combine(node.guardedType); |
| 293 return (combinedType == value.propagatedType) ? value : node; | 334 return (combinedType == value.propagatedType) ? value : node; |
| 294 } | 335 } |
| 295 | 336 |
| 296 HInstruction visitIntegerCheck(HIntegerCheck node) { | 337 HInstruction visitIntegerCheck(HIntegerCheck node) { |
| 297 HInstruction value = node.value; | 338 HInstruction value = node.value; |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 816 } | 857 } |
| 817 } | 858 } |
| 818 if (!canBeMoved) continue; | 859 if (!canBeMoved) continue; |
| 819 | 860 |
| 820 // This is safe because we are running after GVN. | 861 // This is safe because we are running after GVN. |
| 821 // TODO(ngeoffray): ensure GVN has been run. | 862 // TODO(ngeoffray): ensure GVN has been run. |
| 822 set_.add(current); | 863 set_.add(current); |
| 823 } | 864 } |
| 824 } | 865 } |
| 825 } | 866 } |
| OLD | NEW |