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

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: Fix a comment Created 5 years, 5 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) {
floitsch 2015/07/22 14:21:42 Add comment, what this function does (and/or on an
asgerf 2015/07/22 14:32:25 Done. Also renamed analyze->process since it has s
372 List<Function> stack = [];
373 Statement node = inputNode;
374 while (node is ExpressionStatement) {
375 stack.add(analyzeExpressionStatement(node));
376 node = node.next;
377 }
378 Statement result = visitStatement(node);
379 for (Function fun in stack.reversed) {
380 result = fun(result);
381 }
382 return result;
383 }
384
385 Function analyzeExpressionStatement(ExpressionStatement stmt) {
372 Variable leftHand = getLeftHand(stmt.expression); 386 Variable leftHand = getLeftHand(stmt.expression);
373 pushDominatingAssignment(leftHand); 387 pushDominatingAssignment(leftHand);
374 if (isEffectivelyConstantAssignment(stmt.expression) && 388 if (isEffectivelyConstantAssignment(stmt.expression) &&
375 !usesRecentlyAssignedVariable(stmt.expression)) { 389 !usesRecentlyAssignedVariable(stmt.expression)) {
376 Assign assign = stmt.expression; 390 Assign assign = stmt.expression;
377 // Handle constant assignments specially. 391 // Handle constant assignments specially.
378 // They are always safe to propagate (though we should avoid duplication). 392 // They are always safe to propagate (though we should avoid duplication).
379 // Moreover, they should not prevent other expressions from propagating. 393 // Moreover, they should not prevent other expressions from propagating.
380 if (assign.variable.readCount == 1) { 394 if (assign.variable.readCount == 1) {
381 // A single-use constant should always be propagated to its use site. 395 // A single-use constant should always be propagated to its use site.
382 constantEnvironment[assign.variable] = assign.value; 396 constantEnvironment[assign.variable] = assign.value;
383 Statement next = visitStatement(stmt.next); 397 return (Statement next) {
384 popDominatingAssignment(leftHand); 398 popDominatingAssignment(leftHand);
385 if (assign.variable.readCount > 0) { 399 if (assign.variable.readCount > 0) {
386 // The assignment could not be propagated into the successor, either 400 // The assignment could not be propagated into the successor, either
387 // because it has an unsafe variable use (see [hasUnsafeVariableUse]) 401 // because it has an unsafe variable use (see [hasUnsafeVariableUse] )
floitsch 2015/07/22 14:21:42 long line.
asgerf 2015/07/22 14:32:25 Done.
388 // or because the use is outside the current try block, and we do 402 // or because the use is outside the current try block, and we do
389 // not currently support constant propagation out of a try block. 403 // not currently support constant propagation out of a try block.
390 constantEnvironment.remove(assign.variable); 404 constantEnvironment.remove(assign.variable);
391 assign.value = visitExpression(assign.value); 405 assign.value = visitExpression(assign.value);
392 stmt.next = next; 406 stmt.next = next;
393 return stmt; 407 return stmt;
394 } else { 408 } else {
395 --assign.variable.writeCount; 409 --assign.variable.writeCount;
396 return next; 410 return next;
397 } 411 }
412 };
398 } else { 413 } else {
399 // With more than one use, we cannot propagate the constant. 414 // With more than one use, we cannot propagate the constant.
400 // Visit the following statement without polluting [environment] so 415 // Visit the following statement without polluting [environment] so
401 // that any preceding non-constant assignments might still propagate. 416 // that any preceding non-constant assignments might still propagate.
402 stmt.next = visitStatement(stmt.next); 417 return (Statement next) {
418 stmt.next = next;
419 popDominatingAssignment(leftHand);
420 assign.value = visitExpression(assign.value);
421 return stmt;
422 };
423 }
424 } else {
425 // Try to propagate the expression, and block previous impure expressions
426 // until this has propagated.
427 environment.add(stmt.expression);
428 return (Statement next) {
429 stmt.next = next;
403 popDominatingAssignment(leftHand); 430 popDominatingAssignment(leftHand);
404 assign.value = visitExpression(assign.value); 431 if (!environment.isEmpty && environment.last == stmt.expression) {
405 return stmt; 432 // Retain the expression statement.
406 } 433 environment.removeLast();
407 } 434 stmt.expression = visitExpression(stmt.expression);
408 // Try to propagate the expression, and block previous impure expressions 435 return stmt;
409 // until this has propagated. 436 } else {
410 environment.add(stmt.expression); 437 // Expression was propagated into the successor.
411 stmt.next = visitStatement(stmt.next); 438 return stmt.next;
412 popDominatingAssignment(leftHand); 439 }
413 if (!environment.isEmpty && environment.last == stmt.expression) { 440 };
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 } 441 }
422 } 442 }
423 443
424 Expression visitAssign(Assign node) { 444 Expression visitAssign(Assign node) {
425 node.value = visitExpression(node.value); 445 node.value = visitExpression(node.value);
426 // Remove assignments to variables without any uses. This can happen 446 // Remove assignments to variables without any uses. This can happen
427 // because the assignment was propagated into its use, e.g: 447 // because the assignment was propagated into its use, e.g:
428 // 448 //
429 // { x = foo(); bar(x) } ==> bar(x = foo()) ==> bar(foo()) 449 // { x = foo(); bar(x) } ==> bar(x = foo()) ==> bar(foo())
430 // 450 //
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 VariableUseVisitor(this.callback); 1189 VariableUseVisitor(this.callback);
1170 1190
1171 visitVariableUse(VariableUse use) => callback(use); 1191 visitVariableUse(VariableUse use) => callback(use);
1172 1192
1173 visitInnerFunction(FunctionDefinition node) {} 1193 visitInnerFunction(FunctionDefinition node) {}
1174 1194
1175 static void visit(Expression node, VariableUseCallback callback) { 1195 static void visit(Expression node, VariableUseCallback callback) {
1176 new VariableUseVisitor(callback).visitExpression(node); 1196 new VariableUseVisitor(callback).visitExpression(node);
1177 } 1197 }
1178 } 1198 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698