Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart

Issue 923013002: dart2dart: Implementation of simple try/catch. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed break/continue, incorporated comments. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 part of dart2js.cps_ir.optimizers; 5 part of dart2js.cps_ir.optimizers;
6 6
7 /** 7 /**
8 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described 8 * [ShrinkingReducer] applies shrinking reductions to CPS terms as described
9 * in 'Compiling with Continuations, Continued' by Andrew Kennedy. 9 * in 'Compiling with Continuations, Continued' by Andrew Kennedy.
10 */ 10 */
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 // There is a restriction on continuation eta-redexes that the body is not an 256 // There is a restriction on continuation eta-redexes that the body is not an
257 // invocation of the return continuation, because that leads to worse code 257 // invocation of the return continuation, because that leads to worse code
258 // when translating back to direct style (it duplicates returns). There is no 258 // when translating back to direct style (it duplicates returns). There is no
259 // such restriction here because continuation beta-reduction is only performed 259 // such restriction here because continuation beta-reduction is only performed
260 // for singly referenced continuations. Thus, there is no possibility of code 260 // for singly referenced continuations. Thus, there is no possibility of code
261 // duplication. 261 // duplication.
262 if (cont.isReturnContinuation || !cont.hasExactlyOneUse) { 262 if (cont.isReturnContinuation || !cont.hasExactlyOneUse) {
263 return false; 263 return false;
264 } 264 }
265 265
266 if (cont.firstRef.parent is InvokeContinuation) { 266 if (cont.firstRef.parent is! InvokeContinuation) return false;
267 InvokeContinuation invoke = cont.firstRef.parent; 267
268 return (cont == invoke.continuation.definition); 268 InvokeContinuation invoke = cont.firstRef.parent;
269 if (cont != invoke.continuation.definition) return false;
270
271 // Beta-reduction will move the continuation's body to its unique invocation
272 // site. This is not safe if the body is moved into an exception handler
273 // binding.
274 Node current = invoke.parent;
275 while (current != cont.parent) {
276 if (current is LetHandler) return false;
277 current = current.parent;
269 } 278 }
270 279 return true;
271 return false;
272 } 280 }
273 281
274 /// Returns true iff the continuation consists of a continuation 282 /// Returns true iff the continuation consists of a continuation
275 /// invocation, passing on all parameters. Special cases exist (see below). 283 /// invocation, passing on all parameters. Special cases exist (see below).
276 bool _isEtaCont(Continuation cont) { 284 bool _isEtaCont(Continuation cont) {
277 if (cont.isReturnContinuation || cont.body is! InvokeContinuation) { 285 if (cont.isReturnContinuation || cont.body is! InvokeContinuation) {
278 return false; 286 return false;
279 } 287 }
280 288
281 InvokeContinuation invoke = cont.body; 289 InvokeContinuation invoke = cont.body;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 358
351 return true; 359 return true;
352 } 360 }
353 361
354 bool _isDeadParameter(Parameter parameter) { 362 bool _isDeadParameter(Parameter parameter) {
355 // We cannot remove function parameters as an intraprocedural optimization. 363 // We cannot remove function parameters as an intraprocedural optimization.
356 if (parameter.parent is! Continuation || parameter.hasAtLeastOneUse) { 364 if (parameter.parent is! Continuation || parameter.hasAtLeastOneUse) {
357 return false; 365 return false;
358 } 366 }
359 367
368 // We cannot remove exception handler parameters, they have a fixed arity
369 // of two.
370 if (parameter.parent.parent is LetHandler) {
371 return false;
372 }
373
360 // We cannot remove the parameter to a call continuation, because the 374 // We cannot remove the parameter to a call continuation, because the
361 // resulting expression will not be well-formed (call continuations have 375 // resulting expression will not be well-formed (call continuations have
362 // exactly one argument). The return continuation is a call continuation, so 376 // exactly one argument). The return continuation is a call continuation, so
363 // we cannot remove its dummy parameter. 377 // we cannot remove its dummy parameter.
364 Continuation continuation = parameter.parent; 378 Continuation continuation = parameter.parent;
365 if (continuation.isReturnContinuation) return false; 379 if (continuation.isReturnContinuation) return false;
366 Reference<Continuation> current = continuation.firstRef; 380 Reference<Continuation> current = continuation.firstRef;
367 while (current != null) { 381 while (current != null) {
368 if (current.parent is! InvokeContinuation) return false; 382 if (current.parent is! InvokeContinuation) return false;
369 InvokeContinuation invoke = current.parent; 383 InvokeContinuation invoke = current.parent;
370 if (invoke.continuation.definition != continuation) return false; 384 if (invoke.continuation.definition != continuation) return false;
371 current = current.next; 385 current = current.next;
372 } 386 }
373 return true; 387 return true;
374 } 388 }
375 389
376 /// Traverses a term and adds any found redexes to the worklist. 390 /// Traverses a term and adds any found redexes to the worklist.
377 class _RedexVisitor extends RecursiveVisitor { 391 class _RedexVisitor extends RecursiveVisitor {
378 final Set<_ReductionTask> worklist; 392 final Set<_ReductionTask> worklist;
379 393
380 _RedexVisitor(this.worklist); 394 _RedexVisitor(this.worklist);
381 395
382 void processLetPrim(LetPrim node) { 396 void processLetPrim(LetPrim node) {
383 if (_isDeadVal(node)) { 397 if (_isDeadVal(node)) {
384 worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, node)); 398 worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, node));
385 } 399 }
386 } 400 }
387 401
388 void processContinuation(Continuation node) { 402 void processContinuation(Continuation node) {
403 // While it would be nice to remove exception handlers that are provably
404 // unnecessary (e.g., the body cannot throw), that takes more sophisticated
405 // analysis than we do in this pass.
406 if (node.parent is LetHandler) return;
407
389 // Continuation beta- and eta-redexes can overlap, namely when an eta-redex 408 // Continuation beta- and eta-redexes can overlap, namely when an eta-redex
390 // is invoked exactly once. We prioritize continuation beta-redexes over 409 // is invoked exactly once. We prioritize continuation beta-redexes over
391 // eta-redexes because some reductions (e.g., dead parameter elimination) 410 // eta-redexes because some reductions (e.g., dead parameter elimination)
392 // can destroy a continuation eta-redex. If we prioritized eta- over 411 // can destroy a continuation eta-redex. If we prioritized eta- over
393 // beta-redexes, this would implicitly "create" the corresponding beta-redex 412 // beta-redexes, this would implicitly "create" the corresponding beta-redex
394 // (in the sense that it would still apply) and the algorithm would not 413 // (in the sense that it would still apply) and the algorithm would not
395 // detect it. 414 // detect it.
396 if (_isDeadCont(node)) { 415 if (_isDeadCont(node)) {
397 worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, node)); 416 worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, node));
398 } else if (_isBetaContLin(node)){ 417 } else if (_isBetaContLin(node)){
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 524
506 processLetCont(LetCont node) { 525 processLetCont(LetCont node) {
507 int index = 0; 526 int index = 0;
508 node.continuations.forEach((Continuation continuation) { 527 node.continuations.forEach((Continuation continuation) {
509 continuation.parent = node; 528 continuation.parent = node;
510 continuation.parent_index = index++; 529 continuation.parent_index = index++;
511 }); 530 });
512 node.body.parent = node; 531 node.body.parent = node;
513 } 532 }
514 533
534 processLetHandler(LetHandler node) {
535 node.handler.parent = node;
536 node.body.parent = node;
537 }
538
515 processLetMutable(LetMutable node) { 539 processLetMutable(LetMutable node) {
516 node.variable.parent = node; 540 node.variable.parent = node;
517 node.value.parent = node; 541 node.value.parent = node;
518 node.body.parent = node; 542 node.body.parent = node;
519 } 543 }
520 544
521 processInvokeStatic(InvokeStatic node) { 545 processInvokeStatic(InvokeStatic node) {
522 node.arguments.forEach((Reference ref) => ref.parent = node); 546 node.arguments.forEach((Reference ref) => ref.parent = node);
523 node.continuation.parent = node; 547 node.continuation.parent = node;
524 } 548 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 } 699 }
676 700
677 String toString() => "$kind: $node"; 701 String toString() => "$kind: $node";
678 } 702 }
679 703
680 /// A dummy class used solely to mark nodes as deleted once they are removed 704 /// A dummy class used solely to mark nodes as deleted once they are removed
681 /// from a term. 705 /// from a term.
682 class _DeletedNode extends Node { 706 class _DeletedNode extends Node {
683 accept(_) => null; 707 accept(_) => null;
684 } 708 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698