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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 } | 286 } |
| 287 | 287 |
| 288 if (left.isNonPrimitive() && node.operation.isUserDefinable()) { | 288 if (left.isNonPrimitive() && node.operation.isUserDefinable()) { |
| 289 SourceString methodName = Elements.constructOperatorName( | 289 SourceString methodName = Elements.constructOperatorName( |
| 290 const SourceString('operator'), node.operation.name); | 290 const SourceString('operator'), node.operation.name); |
| 291 return fromInterceptorToDynamicInvocation(node, methodName); | 291 return fromInterceptorToDynamicInvocation(node, methodName); |
| 292 } | 292 } |
| 293 return node; | 293 return node; |
| 294 } | 294 } |
| 295 | 295 |
| 296 HInstruction handleIdentityCheck(HInvokeBinary node) { | |
|
Lasse Reichstein Nielsen
2012/04/26 07:24:02
With the new == semantics (which we haven't implem
ngeoffray
2012/04/26 09:25:19
True. Let's wait until we start implementing the n
| |
| 297 HInstruction left = node.left; | |
| 298 HInstruction right = node.right; | |
| 299 if (left.propagatedType.union(right.propagatedType) === HType.CONFLICTING) { | |
|
floitsch
2012/04/26 08:31:16
This should be intersection, except for numbers.
T
ngeoffray
2012/04/26 09:25:19
I used union because I was mostly thinking of the
| |
| 300 return graph.addConstantBool(false); | |
|
floitsch
2012/04/26 08:31:16
I don't think this is correct: A phi with inputs i
ngeoffray
2012/04/26 09:25:19
I'm not sure I understand how this relates to the
ngeoffray
2012/04/26 10:09:53
Actually, it looks like a phi never gets a conflic
| |
| 301 } | |
| 302 | |
| 303 if (left.isConstantBoolean() && right.isBoolean()) { | |
| 304 HConstant constant = left; | |
| 305 if (constant.constant.isTrue()) { | |
| 306 return right; | |
| 307 } else { | |
| 308 return new HNot(right); | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 if (right.isConstantBoolean() && left.isBoolean()) { | |
| 313 HConstant constant = right; | |
| 314 if (constant.constant.isTrue()) { | |
| 315 return left; | |
| 316 } else { | |
| 317 return new HNot(left); | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 return null; | |
| 322 } | |
| 323 | |
| 324 HInstruction visitIdentity(HIdentity node) { | |
| 325 HInstruction newInstruction = handleIdentityCheck(node); | |
| 326 return newInstruction === null ? super.visitIdentity(node) : newInstruction; | |
| 327 } | |
| 328 | |
| 329 HInstruction foldBuiltinEqualsCheck(HEquals node) { | |
| 330 // TODO(floitsch): cache interceptors. | |
| 331 HInstruction newInstruction = handleIdentityCheck(node); | |
| 332 if (newInstruction === null) { | |
| 333 HStatic target = new HStatic( | |
| 334 compiler.builder.interceptors.getTripleEqualsInterceptor()); | |
| 335 node.block.addBefore(node, target); | |
| 336 return new HIdentity(target, node.left, node.right); | |
| 337 } else { | |
| 338 return newInstruction; | |
| 339 } | |
| 340 } | |
| 341 | |
| 296 HInstruction visitEquals(HEquals node) { | 342 HInstruction visitEquals(HEquals node) { |
| 297 HInstruction left = node.left; | 343 HInstruction left = node.left; |
| 298 HInstruction right = node.right; | 344 HInstruction right = node.right; |
| 299 | 345 |
| 346 if (node.builtin) { | |
| 347 return foldBuiltinEqualsCheck(node); | |
| 348 } | |
| 349 | |
| 300 if (left.isConstant() && right.isConstant()) { | 350 if (left.isConstant() && right.isConstant()) { |
| 301 return visitInvokeBinary(node); | 351 return visitInvokeBinary(node); |
| 302 } | 352 } |
| 303 | 353 |
| 304 if (left.isNonPrimitive()) { | 354 if (left.isNonPrimitive()) { |
| 305 HNonPrimitiveType type = left.propagatedType; | 355 HNonPrimitiveType type = left.propagatedType; |
| 306 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); | 356 Element element = type.lookupMember(Namer.OPERATOR_EQUALS); |
| 307 if (element !== null) { | 357 if (element !== null) { |
| 308 // If the left-hand side is guaranteed to be a non-primitive | 358 // If the left-hand side is guaranteed to be a non-primitive |
| 309 // type and and it defines operator==, we emit a call to that | 359 // type and and it defines operator==, we emit a call to that |
| 310 // operator. | 360 // operator. |
| 311 return visitInvokeBinary(node); | 361 return visitInvokeBinary(node); |
| 312 } else if (right.isConstantNull()) { | 362 } else if (right.isConstantNull()) { |
| 313 return graph.addConstantBool(false); | 363 return graph.addConstantBool(false); |
| 314 } else { | 364 } else { |
| 315 // We can just emit an identity check because the type does | 365 // We can just emit an identity check because the type does |
| 316 // not implement operator=. | 366 // not implement operator=. |
| 317 // TODO(floitsch): cache interceptors. | 367 return foldBuiltinEqualsCheck(node); |
| 318 HStatic target = new HStatic( | |
| 319 compiler.builder.interceptors.getTripleEqualsInterceptor()); | |
| 320 node.block.addBefore(node, target); | |
| 321 return new HIdentity(target, left, right); | |
| 322 } | 368 } |
| 323 } | 369 } |
| 324 | 370 |
| 325 | |
| 326 if (right.isConstantNull()) { | 371 if (right.isConstantNull()) { |
| 327 if (left.propagatedType.isUseful()) { | 372 if (left.propagatedType.isUseful()) { |
| 328 return graph.addConstantBool(false); | 373 return graph.addConstantBool(false); |
| 329 } else { | 374 } else { |
| 330 // TODO(floitsch): cache interceptors. | 375 // TODO(floitsch): cache interceptors. |
| 331 HStatic target = new HStatic( | 376 HStatic target = new HStatic( |
| 332 compiler.builder.interceptors.getEqualsNullInterceptor()); | 377 compiler.builder.interceptors.getEqualsNullInterceptor()); |
| 333 node.block.addBefore(node, target); | 378 node.block.addBefore(node, target); |
| 334 return new HEquals(target, node.left, node.right); | 379 return new HEquals(target, node.left, node.right); |
| 335 } | 380 } |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 } | 910 } |
| 866 } | 911 } |
| 867 if (!canBeMoved) continue; | 912 if (!canBeMoved) continue; |
| 868 | 913 |
| 869 // This is safe because we are running after GVN. | 914 // This is safe because we are running after GVN. |
| 870 // TODO(ngeoffray): ensure GVN has been run. | 915 // TODO(ngeoffray): ensure GVN has been run. |
| 871 set_.add(current); | 916 set_.add(current); |
| 872 } | 917 } |
| 873 } | 918 } |
| 874 } | 919 } |
| OLD | NEW |