| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart2js.cps_ir.redundant_join_elimination; | 5 library dart2js.cps_ir.redundant_join_elimination; |
| 6 | 6 |
| 7 import 'cps_ir_nodes.dart'; | 7 import 'cps_ir_nodes.dart'; |
| 8 import 'optimizers.dart'; | 8 import 'optimizers.dart'; |
| 9 | 9 |
| 10 /// Eliminates redundant join points. | 10 /// Eliminates redundant join points. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 // of times each branch is hit. | 102 // of times each branch is hit. |
| 103 // We know all callers are InvokeContinuations because they are the only | 103 // We know all callers are InvokeContinuations because they are the only |
| 104 // valid uses of a multi-use continuation. | 104 // valid uses of a multi-use continuation. |
| 105 int trueHits = 0, falseHits = 0; | 105 int trueHits = 0, falseHits = 0; |
| 106 InvokeContinuation trueCall, falseCall; | 106 InvokeContinuation trueCall, falseCall; |
| 107 for (Reference ref = branchCont.firstRef; ref != null; ref = ref.next) { | 107 for (Reference ref = branchCont.firstRef; ref != null; ref = ref.next) { |
| 108 InvokeContinuation invoke = ref.parent; | 108 InvokeContinuation invoke = ref.parent; |
| 109 Primitive argument = invoke.arguments[parameterIndex].definition; | 109 Primitive argument = invoke.arguments[parameterIndex].definition; |
| 110 if (argument is! Constant) return; // Branching condition is unknown. | 110 if (argument is! Constant) return; // Branching condition is unknown. |
| 111 Constant constant = argument; | 111 Constant constant = argument; |
| 112 if (isFalsyConstant(constant.value)) { | 112 if (isTruthyConstant(constant.value, strict: branch.isStrictCheck)) { |
| 113 ++trueHits; |
| 114 trueCall = invoke; |
| 115 } else { |
| 113 ++falseHits; | 116 ++falseHits; |
| 114 falseCall = invoke; | 117 falseCall = invoke; |
| 115 } else { | |
| 116 ++trueHits; | |
| 117 trueCall = invoke; | |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 // The optimization is now known to be safe, but it only pays off if | 121 // The optimization is now known to be safe, but it only pays off if |
| 122 // one of the callers can inline its target, since otherwise we end up | 122 // one of the callers can inline its target, since otherwise we end up |
| 123 // replacing a boolean variable with a labeled break. | 123 // replacing a boolean variable with a labeled break. |
| 124 // TODO(asgerf): The labeled break might be better? Evaluate. | 124 // TODO(asgerf): The labeled break might be better? Evaluate. |
| 125 if (!(trueHits == 1 && !trueCall.isEscapingTry || | 125 if (!(trueHits == 1 && !trueCall.isEscapingTry || |
| 126 falseHits == 1 && !falseCall.isEscapingTry)) { | 126 falseHits == 1 && !falseCall.isEscapingTry)) { |
| 127 return; | 127 return; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 // Rewrite every invocation of branchCont to call either the true or false | 175 // Rewrite every invocation of branchCont to call either the true or false |
| 176 // branch directly. Since these were lifted out above branchCont, they are | 176 // branch directly. Since these were lifted out above branchCont, they are |
| 177 // now in scope. | 177 // now in scope. |
| 178 // Since trueCont and falseCont were branch targets, they originally | 178 // Since trueCont and falseCont were branch targets, they originally |
| 179 // had no parameters, and so after the lifting, their parameters are | 179 // had no parameters, and so after the lifting, their parameters are |
| 180 // exactly the same as those accepted by branchCont. | 180 // exactly the same as those accepted by branchCont. |
| 181 while (branchCont.firstRef != null) { | 181 while (branchCont.firstRef != null) { |
| 182 Reference reference = branchCont.firstRef; | 182 Reference reference = branchCont.firstRef; |
| 183 InvokeContinuation invoke = branchCont.firstRef.parent; | 183 InvokeContinuation invoke = branchCont.firstRef.parent; |
| 184 Constant condition = invoke.arguments[parameterIndex].definition; | 184 Constant condition = invoke.arguments[parameterIndex].definition; |
| 185 if (isFalsyConstant(condition.value)) { | 185 if (isTruthyConstant(condition.value, strict: branch.isStrictCheck)) { |
| 186 invoke.continuation.changeTo(trueCont); |
| 187 } else { |
| 186 invoke.continuation.changeTo(falseCont); | 188 invoke.continuation.changeTo(falseCont); |
| 187 } else { | |
| 188 invoke.continuation.changeTo(trueCont); | |
| 189 } | 189 } |
| 190 assert(branchCont.firstRef != reference); | 190 assert(branchCont.firstRef != reference); |
| 191 } | 191 } |
| 192 | 192 |
| 193 // Remove the now-unused branchCont continuation. | 193 // Remove the now-unused branchCont continuation. |
| 194 assert(branchCont.hasNoUses); | 194 assert(branchCont.hasNoUses); |
| 195 branch.trueContinuation.unlink(); | 195 branch.trueContinuation.unlink(); |
| 196 branch.falseContinuation.unlink(); | 196 branch.falseContinuation.unlink(); |
| 197 outerLetCont.continuations.remove(branchCont); | 197 outerLetCont.continuations.remove(branchCont); |
| 198 if (outerLetCont.continuations.isEmpty) { | 198 if (outerLetCont.continuations.isEmpty) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 }); | 265 }); |
| 266 } | 266 } |
| 267 | 267 |
| 268 processReference(Reference ref) { | 268 processReference(Reference ref) { |
| 269 Parameter target = renaming[ref.definition]; | 269 Parameter target = renaming[ref.definition]; |
| 270 if (target != null) { | 270 if (target != null) { |
| 271 ref.changeTo(target); | 271 ref.changeTo(target); |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 } | 274 } |
| OLD | NEW |