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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.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, 10 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 tree_ir.optimization; 5 part of tree_ir.optimization;
6 6
7 /** 7 /**
8 * Performs the following transformations on the tree: 8 * Performs the following transformations on the tree:
9 * - Assignment propagation 9 * - Assignment propagation
10 * - If-to-conditional conversion 10 * - If-to-conditional conversion
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 /// for a break to L' if L maps to L'. 104 /// for a break to L' if L maps to L'.
105 Map<Label, Jump> labelRedirects = <Label, Jump>{}; 105 Map<Label, Jump> labelRedirects = <Label, Jump>{};
106 106
107 /// Rewriter for methods. 107 /// Rewriter for methods.
108 StatementRewriter() : constantEnvironment = <Variable, Expression>{}; 108 StatementRewriter() : constantEnvironment = <Variable, Expression>{};
109 109
110 /// Rewriter for nested functions. 110 /// Rewriter for nested functions.
111 StatementRewriter.nested(StatementRewriter parent) 111 StatementRewriter.nested(StatementRewriter parent)
112 : constantEnvironment = parent.constantEnvironment; 112 : constantEnvironment = parent.constantEnvironment;
113 113
114 /// Returns the redirect target of [label] or [label] itself if it should not 114 /// A set of labels that can be safely inlined at their use.
115 ///
116 /// The successor statements for labeled statements that have only one break
117 /// from them are normally rewritten inline at the site of the break. This
118 /// is not safe if the code would be moved inside the scope of an exception
119 /// handler (i.e., if the code would be moved into a try from outside it).
120 Set<Label> safeForInlining = new Set<Label>();
121
122 /// Returns the redirect target of [jump] or [jump] itself if it should not
115 /// be redirected. 123 /// be redirected.
116 Jump redirect(Jump jump) { 124 Jump redirect(Jump jump) {
117 Jump newJump = labelRedirects[jump.target]; 125 Jump newJump = labelRedirects[jump.target];
118 return newJump != null ? newJump : jump; 126 return newJump != null ? newJump : jump;
119 } 127 }
120 128
121 rewriteExecutableDefinition(ExecutableDefinition definition) { 129 rewriteExecutableDefinition(ExecutableDefinition definition) {
122 inEmptyEnvironment(() { 130 inEmptyEnvironment(() {
123 definition.body = visitStatement(definition.body); 131 definition.body = visitStatement(definition.body);
124 }); 132 });
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 node.value = visitExpression(node.value); 311 node.value = visitExpression(node.value);
304 return node; 312 return node;
305 } 313 }
306 314
307 315
308 Statement visitBreak(Break node) { 316 Statement visitBreak(Break node) {
309 // Redirect through chain of breaks. 317 // Redirect through chain of breaks.
310 // Note that useCount was accounted for at visitLabeledStatement. 318 // Note that useCount was accounted for at visitLabeledStatement.
311 // Note redirect may return either a Break or Continue statement. 319 // Note redirect may return either a Break or Continue statement.
312 Jump jump = redirect(node); 320 Jump jump = redirect(node);
313 if (jump is Break && jump.target.useCount == 1) { 321 if (jump is Break &&
322 jump.target.useCount == 1 &&
323 safeForInlining.contains(jump.target)) {
314 --jump.target.useCount; 324 --jump.target.useCount;
315 return visitStatement(jump.target.binding.next); 325 return visitStatement(jump.target.binding.next);
316 } 326 }
317 return jump; 327 return jump;
318 } 328 }
319 329
320 Statement visitContinue(Continue node) { 330 Statement visitContinue(Continue node) {
321 return node; 331 return node;
322 } 332 }
323 333
324 Statement visitLabeledStatement(LabeledStatement node) { 334 Statement visitLabeledStatement(LabeledStatement node) {
325 if (node.next is Jump) { 335 if (node.next is Jump) {
326 // Eliminate label if next is a break or continue statement 336 // Eliminate label if next is a break or continue statement
327 // Breaks to this label are redirected to the outer label. 337 // Breaks to this label are redirected to the outer label.
328 // Note that breakCount for the two labels is updated proactively here 338 // Note that breakCount for the two labels is updated proactively here
329 // so breaks can reliably tell if they should inline their target. 339 // so breaks can reliably tell if they should inline their target.
330 Jump next = node.next; 340 Jump next = node.next;
331 Jump newJump = redirect(next); 341 Jump newJump = redirect(next);
332 labelRedirects[node.label] = newJump; 342 labelRedirects[node.label] = newJump;
333 newJump.target.useCount += node.label.useCount - 1; 343 newJump.target.useCount += node.label.useCount - 1;
334 node.label.useCount = 0; 344 node.label.useCount = 0;
335 Statement result = visitStatement(node.body); 345 Statement result = visitStatement(node.body);
336 labelRedirects.remove(node.label); // Save some space. 346 labelRedirects.remove(node.label); // Save some space.
337 return result; 347 return result;
338 } 348 }
339 349
350 safeForInlining.add(node.label);
340 node.body = visitStatement(node.body); 351 node.body = visitStatement(node.body);
352 safeForInlining.remove(node.label);
341 353
342 if (node.label.useCount == 0) { 354 if (node.label.useCount == 0) {
343 // Eliminate the label if next was inlined at a break 355 // Eliminate the label if next was inlined at a break
344 return node.body; 356 return node.body;
345 } 357 }
346 358
347 // Do not propagate assignments into the successor statements, since they 359 // Do not propagate assignments into the successor statements, since they
348 // may be overwritten by assignments in the body. 360 // may be overwritten by assignments in the body.
349 inEmptyEnvironment(() { 361 inEmptyEnvironment(() {
350 node.next = visitStatement(node.next); 362 node.next = visitStatement(node.next);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 node.body = visitStatement(node.body); 402 node.body = visitStatement(node.body);
391 }); 403 });
392 return node; 404 return node;
393 } 405 }
394 406
395 Statement visitWhileCondition(WhileCondition node) { 407 Statement visitWhileCondition(WhileCondition node) {
396 // Not introduced yet 408 // Not introduced yet
397 throw "Unexpected WhileCondition in StatementRewriter"; 409 throw "Unexpected WhileCondition in StatementRewriter";
398 } 410 }
399 411
412 Statement visitTry(Try node) {
413 Set<Label> saved = safeForInlining;
414 safeForInlining = new Set<Label>();
415 node.tryBody = visitStatement(node.tryBody);
416 safeForInlining = saved;
417 node.catchBody = visitStatement(node.catchBody);
418 return node;
419 }
420
400 Expression visitConstant(Constant node) { 421 Expression visitConstant(Constant node) {
401 return node; 422 return node;
402 } 423 }
403 424
404 Expression visitThis(This node) { 425 Expression visitThis(This node) {
405 return node; 426 return node;
406 } 427 }
407 428
408 Expression visitReifyTypeVar(ReifyTypeVar node) { 429 Expression visitReifyTypeVar(ReifyTypeVar node) {
409 return node; 430 return node;
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 } 646 }
626 647
627 Expression makeCondition(Expression e, bool polarity) { 648 Expression makeCondition(Expression e, bool polarity) {
628 return polarity ? e : new Not(e); 649 return polarity ? e : new Not(e);
629 } 650 }
630 651
631 Statement getBranch(If node, bool polarity) { 652 Statement getBranch(If node, bool polarity) {
632 return polarity ? node.thenStatement : node.elseStatement; 653 return polarity ? node.thenStatement : node.elseStatement;
633 } 654 }
634 } 655 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698