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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart

Issue 1251083002: dart2js cps: Avoid deep recursion using trampolines and basic blocks. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase Created 5 years, 4 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
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 library tree_ir.optimization.statement_rewriter; 5 library tree_ir.optimization.statement_rewriter;
6 6
7 import 'optimization.dart' show Pass; 7 import 'optimization.dart' show Pass;
8 import '../tree_ir_nodes.dart'; 8 import '../tree_ir_nodes.dart';
9 import '../../io/source_information.dart'; 9 import '../../io/source_information.dart';
10 10
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 exp is VariableUse && constantEnvironment.containsKey(exp.variable); 361 exp is VariableUse && constantEnvironment.containsKey(exp.variable);
362 } 362 }
363 363
364 /// True if [node] is an assignment that can be propagated as a constant. 364 /// True if [node] is an assignment that can be propagated as a constant.
365 bool isEffectivelyConstantAssignment(Expression node) { 365 bool isEffectivelyConstantAssignment(Expression node) {
366 return node is Assign && 366 return node is Assign &&
367 node.variable.writeCount == 1 && 367 node.variable.writeCount == 1 &&
368 isEffectivelyConstant(node.value); 368 isEffectivelyConstant(node.value);
369 } 369 }
370 370
371 Statement visitExpressionStatement(ExpressionStatement stmt) { 371 Statement visitExpressionStatement(ExpressionStatement inputNode) {
372 // Analyze chains of expression statements.
373 // To avoid deep recursion, [processExpressionStatement] returns a callback
374 // to invoke after its successor node has been processed.
375 // These callbacks are stored in a list and invoked in reverse at the end.
376 List<Function> stack = [];
377 Statement node = inputNode;
378 while (node is ExpressionStatement) {
379 stack.add(processExpressionStatement(node));
380 node = node.next;
381 }
382 Statement result = visitStatement(node);
383 for (Function fun in stack.reversed) {
384 result = fun(result);
385 }
386 return result;
387 }
388
389 /// Attempts to propagate an assignment in an expression statement.
390 ///
391 /// Returns a callback to be invoked after the sucessor statement has
392 /// been processed.
393 Function processExpressionStatement(ExpressionStatement stmt) {
372 Variable leftHand = getLeftHand(stmt.expression); 394 Variable leftHand = getLeftHand(stmt.expression);
373 pushDominatingAssignment(leftHand); 395 pushDominatingAssignment(leftHand);
374 if (isEffectivelyConstantAssignment(stmt.expression) && 396 if (isEffectivelyConstantAssignment(stmt.expression) &&
375 !usesRecentlyAssignedVariable(stmt.expression)) { 397 !usesRecentlyAssignedVariable(stmt.expression)) {
376 Assign assign = stmt.expression; 398 Assign assign = stmt.expression;
377 // Handle constant assignments specially. 399 // Handle constant assignments specially.
378 // They are always safe to propagate (though we should avoid duplication). 400 // They are always safe to propagate (though we should avoid duplication).
379 // Moreover, they should not prevent other expressions from propagating. 401 // Moreover, they should not prevent other expressions from propagating.
380 if (assign.variable.readCount == 1) { 402 if (assign.variable.readCount == 1) {
381 // A single-use constant should always be propagated to its use site. 403 // A single-use constant should always be propagated to its use site.
382 constantEnvironment[assign.variable] = assign.value; 404 constantEnvironment[assign.variable] = assign.value;
383 Statement next = visitStatement(stmt.next); 405 return (Statement next) {
384 popDominatingAssignment(leftHand); 406 popDominatingAssignment(leftHand);
385 if (assign.variable.readCount > 0) { 407 if (assign.variable.readCount > 0) {
386 // The assignment could not be propagated into the successor, either 408 // The assignment could not be propagated into the successor,
387 // because it has an unsafe variable use (see [hasUnsafeVariableUse]) 409 // either because it [hasUnsafeVariableUse] or because the
388 // or because the use is outside the current try block, and we do 410 // use is outside the current try block, and we do not currently
389 // not currently support constant propagation out of a try block. 411 // support constant propagation out of a try block.
390 constantEnvironment.remove(assign.variable); 412 constantEnvironment.remove(assign.variable);
391 assign.value = visitExpression(assign.value); 413 assign.value = visitExpression(assign.value);
392 stmt.next = next; 414 stmt.next = next;
393 return stmt; 415 return stmt;
394 } else { 416 } else {
395 --assign.variable.writeCount; 417 --assign.variable.writeCount;
396 return next; 418 return next;
397 } 419 }
420 };
398 } else { 421 } else {
399 // With more than one use, we cannot propagate the constant. 422 // With more than one use, we cannot propagate the constant.
400 // Visit the following statement without polluting [environment] so 423 // Visit the following statement without polluting [environment] so
401 // that any preceding non-constant assignments might still propagate. 424 // that any preceding non-constant assignments might still propagate.
402 stmt.next = visitStatement(stmt.next); 425 return (Statement next) {
426 stmt.next = next;
427 popDominatingAssignment(leftHand);
428 assign.value = visitExpression(assign.value);
429 return stmt;
430 };
431 }
432 } else {
433 // Try to propagate the expression, and block previous impure expressions
434 // until this has propagated.
435 environment.add(stmt.expression);
436 return (Statement next) {
437 stmt.next = next;
403 popDominatingAssignment(leftHand); 438 popDominatingAssignment(leftHand);
404 assign.value = visitExpression(assign.value); 439 if (!environment.isEmpty && environment.last == stmt.expression) {
405 return stmt; 440 // Retain the expression statement.
406 } 441 environment.removeLast();
407 } 442 stmt.expression = visitExpression(stmt.expression);
408 // Try to propagate the expression, and block previous impure expressions 443 return stmt;
409 // until this has propagated. 444 } else {
410 environment.add(stmt.expression); 445 // Expression was propagated into the successor.
411 stmt.next = visitStatement(stmt.next); 446 return stmt.next;
412 popDominatingAssignment(leftHand); 447 }
413 if (!environment.isEmpty && environment.last == stmt.expression) { 448 };
414 // Retain the expression statement.
415 environment.removeLast();
416 stmt.expression = visitExpression(stmt.expression);
417 return stmt;
418 } else {
419 // Expression was propagated into the successor.
420 return stmt.next;
421 } 449 }
422 } 450 }
423 451
424 Expression visitAssign(Assign node) { 452 Expression visitAssign(Assign node) {
425 node.value = visitExpression(node.value); 453 node.value = visitExpression(node.value);
426 // Remove assignments to variables without any uses. This can happen 454 // Remove assignments to variables without any uses. This can happen
427 // because the assignment was propagated into its use, e.g: 455 // because the assignment was propagated into its use, e.g:
428 // 456 //
429 // { x = foo(); bar(x) } ==> bar(x = foo()) ==> bar(foo()) 457 // { x = foo(); bar(x) } ==> bar(x = foo()) ==> bar(foo())
430 // 458 //
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 VariableUseVisitor(this.callback); 1197 VariableUseVisitor(this.callback);
1170 1198
1171 visitVariableUse(VariableUse use) => callback(use); 1199 visitVariableUse(VariableUse use) => callback(use);
1172 1200
1173 visitInnerFunction(FunctionDefinition node) {} 1201 visitInnerFunction(FunctionDefinition node) {}
1174 1202
1175 static void visit(Expression node, VariableUseCallback callback) { 1203 static void visit(Expression node, VariableUseCallback callback) {
1176 new VariableUseVisitor(callback).visitExpression(node); 1204 new VariableUseVisitor(callback).visitExpression(node);
1177 } 1205 }
1178 } 1206 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/unsugar.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698