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

Side by Side Diff: lib/compiler/implementation/ssa/codegen.dart

Issue 10669035: Don't lose the expected precedence during && compilation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/if_and_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 class SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 final JavaScriptBackend backend; 6 final JavaScriptBackend backend;
7 SsaCodeGeneratorTask(JavaScriptBackend backend) 7 SsaCodeGeneratorTask(JavaScriptBackend backend)
8 : this.backend = backend, 8 : this.backend = backend,
9 super(backend.compiler); 9 super(backend.compiler);
10 String get name() => 'SSA code generator'; 10 String get name() => 'SSA code generator';
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 386 }
387 generationState = oldState; 387 generationState = oldState;
388 } 388 }
389 389
390 /** 390 /**
391 * Generate expressions from block information. 391 * Generate expressions from block information.
392 */ 392 */
393 void generateExpression(HExpressionInformation expression) { 393 void generateExpression(HExpressionInformation expression) {
394 // Currently we only handle sub-expression graphs. 394 // Currently we only handle sub-expression graphs.
395 assert(expression is HSubExpressionBlockInformation); 395 assert(expression is HSubExpressionBlockInformation);
396 // [visitSubGraph] will reset the [expectedPrecedence]. Make sure we don't
397 // need parenthesis. I.e., this only expects to be called for top-level
398 // expressions, not sub-expressions.
399 assert(expectedPrecedence == JSPrecedence.STATEMENT_PRECEDENCE
400 || expectedPrecedence == JSPrecedence.EXPRESSION_PRECEDENCE);
401
396 HSubExpressionBlockInformation expressionSubGraph = expression; 402 HSubExpressionBlockInformation expressionSubGraph = expression;
397 403
398 int oldState = generationState; 404 int oldState = generationState;
399 generationState = STATE_FIRST_EXPRESSION; 405 generationState = STATE_FIRST_EXPRESSION;
400 visitSubGraph(expressionSubGraph.subExpression); 406 visitSubGraph(expressionSubGraph.subExpression);
401 generationState = oldState; 407 generationState = oldState;
402 } 408 }
403 409
404 void generateDeclaration(HExpressionInformation expression) { 410 void generateDeclaration(HExpressionInformation expression) {
405 // Currently we only handle sub-expression graphs. 411 // Currently we only handle sub-expression graphs.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 String inputName = variableNames.getName(instruction.checkedInput); 570 String inputName = variableNames.getName(instruction.checkedInput);
565 if (name != inputName) return false; 571 if (name != inputName) return false;
566 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); 572 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
567 return true; 573 return true;
568 } 574 }
569 575
570 void define(HInstruction instruction) { 576 void define(HInstruction instruction) {
571 if (isGeneratingExpression()) { 577 if (isGeneratingExpression()) {
572 addExpressionSeparator(); 578 addExpressionSeparator();
573 } else { 579 } else {
580 assert(expectedPrecedence == JSPrecedence.STATEMENT_PRECEDENCE);
574 addIndentation(); 581 addIndentation();
575 } 582 }
576 if (!instruction.isControlFlow() && variableNames.hasName(instruction)) { 583 if (!instruction.isControlFlow() && variableNames.hasName(instruction)) {
577 var name = variableNames.getName(instruction); 584 var name = variableNames.getName(instruction);
578 if (!handleSimpleUpdateDefinition(instruction, name) 585 if (!handleSimpleUpdateDefinition(instruction, name)
579 && !handleTypeConversion(instruction, name)) { 586 && !handleTypeConversion(instruction, name)) {
580 declareInstruction(instruction); 587 withPrecedence(JSPrecedence.ASSIGNMENT_PRECEDENCE, () {
sra1 2012/06/29 02:03:57 It bothers me that there are >200 places in this f
581 buffer.add(" = "); 588 declareInstruction(instruction);
582 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); 589 buffer.add(" = ");
590 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE);
591 });
583 } 592 }
584 } else { 593 } else {
585 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); 594 visit(instruction, expectedPrecedence);
586 } 595 }
587 if (!isGeneratingExpression()) buffer.add(';\n'); 596 if (!isGeneratingExpression()) buffer.add(';\n');
588 } 597 }
589 598
590 void use(HInstruction argument, int expectedPrecedenceForArgument) { 599 void use(HInstruction argument, int expectedPrecedenceForArgument) {
591 if (isGenerateAtUseSite(argument)) { 600 if (isGenerateAtUseSite(argument)) {
592 visit(argument, expectedPrecedenceForArgument); 601 visit(argument, expectedPrecedenceForArgument);
593 } else if (argument is HCheck && argument.isControlFlow()) { 602 } else if (argument is HCheck && argument.isControlFlow()) {
594 // A [HCheck] that has control flow can never be used as an 603 // A [HCheck] that has control flow can never be used as an
595 // expression and may not have a name. Therefore we just use the 604 // expression and may not have a name. Therefore we just use the
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 } 1113 }
1105 } 1114 }
1106 } 1115 }
1107 1116
1108 void iterateBasicBlock(HBasicBlock node) { 1117 void iterateBasicBlock(HBasicBlock node) {
1109 HInstruction instruction = node.first; 1118 HInstruction instruction = node.first;
1110 while (instruction !== node.last) { 1119 while (instruction !== node.last) {
1111 if (instruction is HTypeGuard) { 1120 if (instruction is HTypeGuard) {
1112 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); 1121 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
1113 } else if (!isGenerateAtUseSite(instruction)) { 1122 } else if (!isGenerateAtUseSite(instruction)) {
1123 expectedPrecedence = JSPrecedence.STATEMENT_PRECEDENCE;
1114 define(instruction); 1124 define(instruction);
1115 } 1125 }
1116 instruction = instruction.next; 1126 instruction = instruction.next;
1117 } 1127 }
1118 assignPhisOfSuccessors(node); 1128 assignPhisOfSuccessors(node);
1119 if (instruction is HLoopBranch && isGeneratingExpression()) { 1129 if (instruction is HLoopBranch && isGeneratingExpression()) {
1120 addExpressionSeparator(); 1130 addExpressionSeparator();
1121 } 1131 }
1122 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); 1132 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE);
1123 } 1133 }
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 int thenKind = analyzeGraphForCodegen(thenGraph); 1460 int thenKind = analyzeGraphForCodegen(thenGraph);
1451 int elseKind = analyzeGraphForCodegen(elseGraph); 1461 int elseKind = analyzeGraphForCodegen(elseGraph);
1452 1462
1453 void visitWithoutIndent(HStatementInformation toVisit) { 1463 void visitWithoutIndent(HStatementInformation toVisit) {
1454 int oldIndent = indent; 1464 int oldIndent = indent;
1455 indent = 0; 1465 indent = 0;
1456 generateStatements(toVisit); 1466 generateStatements(toVisit);
1457 indent = oldIndent; 1467 indent = oldIndent;
1458 } 1468 }
1459 1469
1470 void visitExpression(HStatementInformation toVisit) {
1471 // [generateExpression] only works if the [expectedPrecedence] is a
1472 // statement or an expression. We therefore have to duplicate some
1473 // work here.
1474 assert(toVisit.start == toVisit.end);
1475 assert(toVisit.start.last is HGoto);
1476 // Find the expression (there must only be one).
1477 HInstruction expression = toVisit.start.first;
1478 while (generateAtUseSite.contains(expression)) {
1479 expression = expression.next;
1480 }
1481 assert(() {
1482 HInstruction remaining = expression.next;
1483 while (remaining is !HGoto) {
1484 if (!generateAtUseSite.contains(remaining)) return false;
1485 remaining = remaining.next;
1486 }
1487 return true;
1488 });
1489
1490 int oldState = generationState;
1491 generationState = STATE_FIRST_EXPRESSION;
1492 define(expression);
1493 generationState = oldState;
1494 }
1495
1460 void visitWithIndent(HStatementInformation toVisit) { 1496 void visitWithIndent(HStatementInformation toVisit) {
1461 buffer.add('{\n'); 1497 buffer.add('{\n');
1462 indent++; 1498 indent++;
1463 generateStatements(toVisit); 1499 generateStatements(toVisit);
1464 indent--; 1500 indent--;
1465 addIndented('}'); 1501 addIndented('}');
1466 } 1502 }
1467 1503
1468 void emitIf() { 1504 void emitIf() {
1469 addIndented('if ('); 1505 addIndented('if (');
1470 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); 1506 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE);
1471 buffer.add(') '); 1507 buffer.add(') ');
1472 } 1508 }
1473 1509
1474 JSBinaryOperatorPrecedence operatorPrecedence = JSPrecedence.binary['&&']; 1510 JSBinaryOperatorPrecedence operatorPrecedence = JSPrecedence.binary['&&'];
1475 void generateAnd(HStatementInformation toVisit, Function condition) { 1511 void generateAnd(HStatementInformation toVisit, Function condition) {
1476 addIndentation(); 1512 addIndentation();
1477 beginExpression(operatorPrecedence.precedence); 1513 beginExpression(operatorPrecedence.precedence);
1514 var oldPrecedence = expectedPrecedence;
1515 expectedPrecedence = operatorPrecedence.left;
1478 condition(); 1516 condition();
1479 buffer.add(" && "); 1517 buffer.add(" && ");
1480 var oldPrecedence = expectedPrecedence;
1481 expectedPrecedence = operatorPrecedence.right; 1518 expectedPrecedence = operatorPrecedence.right;
1482 visitWithoutIndent(toVisit); 1519 visitExpression(toVisit);
1483 expectedPrecedence = oldPrecedence; 1520 expectedPrecedence = oldPrecedence;
1484 endExpression(operatorPrecedence.precedence); 1521 endExpression(operatorPrecedence.precedence);
1522 buffer.add(";\n");
1485 } 1523 }
1486 1524
1487 List<HBasicBlock> thenSuccessors = thenGraph.end.successors; 1525 List<HBasicBlock> thenSuccessors = thenGraph.end.successors;
1488 bool thenGraphHasSuccessor = thenSuccessors.length != 0 1526 bool thenGraphHasSuccessor = thenSuccessors.length != 0
1489 && thenSuccessors[0] !== currentGraph.exit; 1527 && thenSuccessors[0] !== currentGraph.exit;
1490 1528
1491 switch (thenKind) { 1529 switch (thenKind) {
1492 case EMPTY: 1530 case EMPTY:
1493 switch (elseKind) { 1531 switch (elseKind) {
1494 case EMPTY: 1532 case EMPTY:
(...skipping 1539 matching lines...) Expand 10 before | Expand all | Expand 10 after
3034 startBailoutSwitch(); 3072 startBailoutSwitch();
3035 } 3073 }
3036 } 3074 }
3037 3075
3038 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 3076 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
3039 if (labeledBlockInfo.body.start.hasGuards()) { 3077 if (labeledBlockInfo.body.start.hasGuards()) {
3040 endBailoutSwitch(); 3078 endBailoutSwitch();
3041 } 3079 }
3042 } 3080 }
3043 } 3081 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/if_and_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698