Chromium Code Reviews| Index: pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart |
| diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart |
| index 61a72fa0641ea908ad5e458cb068dc313423fa8a..73ac95416433b50b0c191ec5f0b935e56b114bc4 100644 |
| --- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart |
| +++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart |
| @@ -263,12 +263,20 @@ bool _isBetaContLin(Continuation cont) { |
| return false; |
| } |
| - if (cont.firstRef.parent is InvokeContinuation) { |
| - InvokeContinuation invoke = cont.firstRef.parent; |
| - return (cont == invoke.continuation.definition); |
| - } |
| + if (cont.firstRef.parent is! InvokeContinuation) return false; |
| + |
| + InvokeContinuation invoke = cont.firstRef.parent; |
| + if (cont != invoke.continuation.definition) return false; |
| - return false; |
| + // Beta-reduction will move the continuation's body to its unique invocation |
| + // site. This is not safe if the body is moved inside an exception handler |
|
karlklose
2015/02/16 10:15:48
'inside' -> 'into'?
Kevin Millikin (Google)
2015/02/25 11:06:35
Thanks.
|
| + // binding. |
| + Node current = invoke.parent; |
| + while (current != cont.parent) { |
| + if (current is LetHandler) return false; |
| + current = current.parent; |
| + } |
| + return true; |
| } |
| /// Returns true iff the continuation consists of a continuation |
| @@ -357,6 +365,12 @@ bool _isDeadParameter(Parameter parameter) { |
| return false; |
| } |
| + // We cannot remove exception handler parameters, they have a fixed arity |
| + // of two (TODO(kmillikin): is that true?). |
|
asgerf
2015/02/20 10:10:07
I agree that they should have two parameters. Plea
Kevin Millikin (Google)
2015/02/25 11:06:36
Done.
|
| + if (parameter.parent.parent is LetHandler) { |
| + return false; |
| + } |
| + |
| // We cannot remove the parameter to a call continuation, because the |
| // resulting expression will not be well-formed (call continuations have |
| // exactly one argument). The return continuation is a call continuation, so |
| @@ -386,6 +400,11 @@ class _RedexVisitor extends RecursiveVisitor { |
| } |
| void processContinuation(Continuation node) { |
| + // While it would be nice to remove exception handlers that are provably |
| + // unnecessary (e.g., the body cannot throw), that takes more sophisticated |
| + // analysis than we do in this pass. |
| + if (node.parent is LetHandler) return; |
| + |
| // Continuation beta- and eta-redexes can overlap, namely when an eta-redex |
| // is invoked exactly once. We prioritize continuation beta-redexes over |
| // eta-redexes because some reductions (e.g., dead parameter elimination) |
| @@ -512,6 +531,11 @@ class ParentVisitor extends RecursiveVisitor { |
| node.body.parent = node; |
| } |
| + processLetHandler(LetHandler node) { |
| + node.handler.parent = node; |
| + node.body.parent = node; |
| + } |
| + |
| processLetMutable(LetMutable node) { |
| node.variable.parent = node; |
| node.value.parent = node; |