| OLD | NEW |
| 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 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); | 6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); |
| 7 String get name() => 'SSA code generator'; | 7 String get name() => 'SSA code generator'; |
| 8 | 8 |
| 9 | 9 |
| 10 String buildJavaScriptFunction(FunctionElement element, | 10 String buildJavaScriptFunction(FunctionElement element, |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 addIndented("}"); | 574 addIndented("}"); |
| 575 if (info.elseGraph !== null) { | 575 if (info.elseGraph !== null) { |
| 576 buffer.add(" else {\n"); | 576 buffer.add(" else {\n"); |
| 577 indent++; | 577 indent++; |
| 578 generateStatements(info.elseGraph); | 578 generateStatements(info.elseGraph); |
| 579 indent--; | 579 indent--; |
| 580 addIndented("}"); | 580 addIndented("}"); |
| 581 } | 581 } |
| 582 buffer.add("\n"); | 582 buffer.add("\n"); |
| 583 } | 583 } |
| 584 if (info.joinBlock !== null) { | |
| 585 visitBasicBlock(info.joinBlock); | |
| 586 } | |
| 587 return true; | 584 return true; |
| 588 } | 585 } |
| 589 | 586 |
| 587 bool visitSequenceInfo(HStatementSequenceInformation info) { |
| 588 return false; |
| 589 } |
| 590 |
| 590 bool visitSubGraphInfo(HSubGraphBlockInformation info) { | 591 bool visitSubGraphInfo(HSubGraphBlockInformation info) { |
| 591 visitSubGraph(info.subGraph); | 592 visitSubGraph(info.subGraph); |
| 592 // A [HSubGraphBlockInformation] is always part of another block | 593 // A [HSubGraphBlockInformation] is always part of another block |
| 593 // information structure, so it doesn't have a joinBlock. | 594 // information structure, so it doesn't have a joinBlock. |
| 594 } | 595 } |
| 595 | 596 |
| 596 bool visitSubExpressionInfo(HSubExpressionBlockInformation info) { | 597 bool visitSubExpressionInfo(HSubExpressionBlockInformation info) { |
| 597 return false; | 598 return false; |
| 598 } | 599 } |
| 599 | 600 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 620 addIndented('}'); | 621 addIndented('}'); |
| 621 } | 622 } |
| 622 if (info.finallyBlock != null) { | 623 if (info.finallyBlock != null) { |
| 623 buffer.add(" finally {\n"); | 624 buffer.add(" finally {\n"); |
| 624 indent++; | 625 indent++; |
| 625 generateStatements(info.finallyBlock); | 626 generateStatements(info.finallyBlock); |
| 626 indent--; | 627 indent--; |
| 627 addIndented("}"); | 628 addIndented("}"); |
| 628 } | 629 } |
| 629 buffer.add("\n"); | 630 buffer.add("\n"); |
| 630 visitBasicBlock(info.joinBlock); | |
| 631 return true; | 631 return true; |
| 632 } | 632 } |
| 633 | 633 |
| 634 bool visitLoopInfo(HLoopInformation info) { | 634 bool visitLoopInfo(HLoopBlockInformation info) { |
| 635 // We must look at the loop information only once, when visiting the | |
| 636 // initializer. After that, the initializer has been generated. | |
| 637 // The same block information is also put on the condition-block for | |
| 638 // the traditional code generation. | |
| 639 bool isInitializerBlock = (currentBlock !== info.header); | |
| 640 if (!isInitializerBlock && info.kind != HLoopInformation.DO_WHILE_LOOP) { | |
| 641 return false; | |
| 642 } | |
| 643 | |
| 644 HExpressionInformation condition = info.condition; | 635 HExpressionInformation condition = info.condition; |
| 645 bool isConditionExpression = isJSCondition(condition); | 636 bool isConditionExpression = isJSCondition(condition); |
| 646 | 637 |
| 647 void visitBodyIgnoreLabels() { | 638 void visitBodyIgnoreLabels() { |
| 648 if (info.body.start.isLabeledBlock()) { | 639 if (info.body.start.isLabeledBlock()) { |
| 649 HBlockInformation oldInfo = currentBlockInformation; | 640 HBlockInformation oldInfo = currentBlockInformation; |
| 650 currentBlockInformation = info.body.start.blockInformation; | 641 currentBlockInformation = info.body.start.blockInformation.body; |
| 651 generateStatements(info.body); | 642 generateStatements(info.body); |
| 652 currentBlockInformation = oldInfo; | 643 currentBlockInformation = oldInfo; |
| 653 } else { | 644 } else { |
| 654 generateStatements(info.body); | 645 generateStatements(info.body); |
| 655 } | 646 } |
| 656 } | 647 } |
| 657 | 648 |
| 658 switch (info.kind) { | 649 switch (info.kind) { |
| 659 // Treate all three "test-first" loops the same way. | 650 // Treate all three "test-first" loops the same way. |
| 660 case HLoopInformation.FOR_LOOP: | 651 case HLoopBlockInformation.FOR_LOOP: |
| 661 case HLoopInformation.WHILE_LOOP: | 652 case HLoopBlockInformation.WHILE_LOOP: |
| 662 case HLoopInformation.FOR_IN_LOOP: { | 653 case HLoopBlockInformation.FOR_IN_LOOP: { |
| 663 HBlockInformation initialization = info.initializer; | 654 HBlockInformation initialization = info.initializer; |
| 664 int initializationType = TYPE_STATEMENT; | 655 int initializationType = TYPE_STATEMENT; |
| 665 if (initialization !== null) { | 656 if (initialization !== null) { |
| 666 initializationType = expressionType(initialization); | 657 initializationType = expressionType(initialization); |
| 667 if (initializationType == TYPE_STATEMENT) { | 658 if (initializationType == TYPE_STATEMENT) { |
| 668 generateStatements(initialization); | 659 generateStatements(initialization); |
| 669 initialization = null; | 660 initialization = null; |
| 670 } | 661 } |
| 671 } | 662 } |
| 672 for (LabelElement label in info.labels) { | 663 for (LabelElement label in info.labels) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 wrapLoopBodyForContinue(info); | 714 wrapLoopBodyForContinue(info); |
| 724 generateStatements(info.updates); | 715 generateStatements(info.updates); |
| 725 } else { | 716 } else { |
| 726 visitBodyIgnoreLabels(); | 717 visitBodyIgnoreLabels(); |
| 727 } | 718 } |
| 728 indent--; | 719 indent--; |
| 729 } | 720 } |
| 730 addIndented("}\n"); | 721 addIndented("}\n"); |
| 731 break; | 722 break; |
| 732 } | 723 } |
| 733 case HLoopInformation.DO_WHILE_LOOP: { | 724 case HLoopBlockInformation.DO_WHILE_LOOP: { |
| 734 // Generate do-while loop in all cases. | 725 // Generate do-while loop in all cases. |
| 735 if (info.initializer !== null) { | 726 if (info.initializer !== null) { |
| 736 generateStatements(info.initializer); | 727 generateStatements(info.initializer); |
| 737 } | 728 } |
| 738 addIndentation(); | 729 addIndentation(); |
| 739 for (LabelElement label in info.labels) { | 730 for (LabelElement label in info.labels) { |
| 740 if (label.isTarget) { | 731 if (label.isTarget) { |
| 741 writeLabel(label); | 732 writeLabel(label); |
| 742 buffer.add(":"); | 733 buffer.add(":"); |
| 743 } | 734 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 764 use(condition.conditionExpression, JSPrecedence.PREFIX_PRECEDENCE); | 755 use(condition.conditionExpression, JSPrecedence.PREFIX_PRECEDENCE); |
| 765 buffer.add(");\n"); | 756 buffer.add(");\n"); |
| 766 } | 757 } |
| 767 break; | 758 break; |
| 768 } | 759 } |
| 769 default: | 760 default: |
| 770 compiler.internalError( | 761 compiler.internalError( |
| 771 'Unexpected loop kind: ${info.kind}', | 762 'Unexpected loop kind: ${info.kind}', |
| 772 instruction: condition.conditionExpression); | 763 instruction: condition.conditionExpression); |
| 773 } | 764 } |
| 774 visitBasicBlock(info.joinBlock); | |
| 775 return true; | 765 return true; |
| 776 } | 766 } |
| 777 | 767 |
| 778 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { | 768 bool visitLabeledBlockInfo(HLabeledBlockInformation labeledBlockInfo) { |
| 779 preLabeledBlock(labeledBlockInfo); | 769 preLabeledBlock(labeledBlockInfo); |
| 780 addIndentation(); | 770 addIndentation(); |
| 781 Link<Element> continueOverrides = const EmptyLink<Element>(); | 771 Link<Element> continueOverrides = const EmptyLink<Element>(); |
| 782 // If [labeledBlockInfo.isContinue], the block is an artificial | 772 // If [labeledBlockInfo.isContinue], the block is an artificial |
| 783 // block around the body of a loop with an update block, so that | 773 // block around the body of a loop with an update block, so that |
| 784 // continues of the loop can be written as breaks of the body | 774 // continues of the loop can be written as breaks of the body |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 buffer.add('{\n'); | 810 buffer.add('{\n'); |
| 821 indent++; | 811 indent++; |
| 822 | 812 |
| 823 startLabeledBlock(labeledBlockInfo); | 813 startLabeledBlock(labeledBlockInfo); |
| 824 generateStatements(labeledBlockInfo.body); | 814 generateStatements(labeledBlockInfo.body); |
| 825 endLabeledBlock(labeledBlockInfo); | 815 endLabeledBlock(labeledBlockInfo); |
| 826 | 816 |
| 827 indent--; | 817 indent--; |
| 828 addIndented('}\n'); | 818 addIndented('}\n'); |
| 829 | 819 |
| 830 if (labeledBlockInfo.joinBlock !== null) { | |
| 831 visitBasicBlock(labeledBlockInfo.joinBlock); | |
| 832 } | |
| 833 if (labeledBlockInfo.isContinue) { | 820 if (labeledBlockInfo.isContinue) { |
| 834 while (!continueOverrides.isEmpty()) { | 821 while (!continueOverrides.isEmpty()) { |
| 835 continueAction.remove(continueOverrides.head); | 822 continueAction.remove(continueOverrides.head); |
| 836 continueOverrides = continueOverrides.tail; | 823 continueOverrides = continueOverrides.tail; |
| 837 } | 824 } |
| 838 } else { | 825 } else { |
| 839 breakAction.remove(labeledBlockInfo.target); | 826 breakAction.remove(labeledBlockInfo.target); |
| 840 } | 827 } |
| 841 return true; | 828 return true; |
| 842 } | 829 } |
| 843 | 830 |
| 844 void emitLogicalOperation(HPhi node, String operation) { | 831 void emitLogicalOperation(HPhi node, String operation) { |
| 845 JSBinaryOperatorPrecedence operatorPrecedence = | 832 JSBinaryOperatorPrecedence operatorPrecedence = |
| 846 JSPrecedence.binary[operation]; | 833 JSPrecedence.binary[operation]; |
| 847 beginExpression(operatorPrecedence.precedence); | 834 beginExpression(operatorPrecedence.precedence); |
| 848 use(node.inputs[0], operatorPrecedence.left); | 835 use(node.inputs[0], operatorPrecedence.left); |
| 849 buffer.add(" $operation "); | 836 buffer.add(" $operation "); |
| 850 use(node.inputs[1], operatorPrecedence.right); | 837 use(node.inputs[1], operatorPrecedence.right); |
| 851 endExpression(operatorPrecedence.precedence); | 838 endExpression(operatorPrecedence.precedence); |
| 852 } | 839 } |
| 853 | 840 |
| 854 // Wraps a loop body in a block to make continues have a target to break | 841 // Wraps a loop body in a block to make continues have a target to break |
| 855 // to (if necessary). | 842 // to (if necessary). |
| 856 void wrapLoopBodyForContinue(HLoopInformation info) { | 843 void wrapLoopBodyForContinue(HLoopBlockInformation info) { |
| 857 TargetElement target = info.target; | 844 TargetElement target = info.target; |
| 858 if (target !== null && target.isContinueTarget) { | 845 if (target !== null && target.isContinueTarget) { |
| 859 addIndentation(); | 846 addIndentation(); |
| 860 for (LabelElement label in info.labels) { | 847 for (LabelElement label in info.labels) { |
| 861 if (label.isContinueTarget) { | 848 if (label.isContinueTarget) { |
| 862 writeContinueLabel(label); | 849 writeContinueLabel(label); |
| 863 buffer.add(":"); | 850 buffer.add(":"); |
| 864 continueAction[label] = continueAsBreak; | 851 continueAction[label] = continueAsBreak; |
| 865 } | 852 } |
| 866 } | 853 } |
| 867 writeImplicitContinueLabel(target); | 854 writeImplicitContinueLabel(target); |
| 868 buffer.add(":{\n"); | 855 buffer.add(":{\n"); |
| 869 continueAction[info.target] = implicitContinueAsBreak; | 856 continueAction[info.target] = implicitContinueAsBreak; |
| 870 indent++; | 857 indent++; |
| 871 generateStatements(info.body); | 858 generateStatements(info.body); |
| 872 indent--; | 859 indent--; |
| 873 addIndented("}\n"); | 860 addIndented("}\n"); |
| 874 continueAction.remove(info.target); | 861 continueAction.remove(info.target); |
| 875 for (LabelElement label in info.labels) { | 862 for (LabelElement label in info.labels) { |
| 876 if (label.isContinueTarget) { | 863 if (label.isContinueTarget) { |
| 877 continueAction.remove(label); | 864 continueAction.remove(label); |
| 878 } | 865 } |
| 879 } | 866 } |
| 880 } else { | 867 } else { |
| 881 // Loop body contains no continues, so we don't need a break target. | 868 // Loop body contains no continues, so we don't need a break target. |
| 882 generateStatements(info.body); | 869 generateStatements(info.body); |
| 883 } | 870 } |
| 884 } | 871 } |
| 885 | 872 |
| 873 bool handleBlockInfo(HBlockFlow block) { |
| 874 HBlockInformation info = block.body; |
| 875 // If we reach here again while handling the attached information, |
| 876 // e.g., because we call visitSubGraph on a subgraph starting on |
| 877 // the same block, don't handle it again. |
| 878 // When the structure graph is complete, we will be able to have |
| 879 // different structures starting on the same basic block (e.g., an |
| 880 // "if" and its condition). |
| 881 if (info === currentBlockInformation) return false; |
| 882 |
| 883 HBlockInformation oldBlockInformation = currentBlockInformation; |
| 884 currentBlockInformation = info; |
| 885 bool success = info.accept(this); |
| 886 currentBlockInformation = oldBlockInformation; |
| 887 if (success) { |
| 888 HBasicBlock continuation = block.continuation; |
| 889 if (continuation !== null) { |
| 890 visitBasicBlock(continuation); |
| 891 } |
| 892 } |
| 893 return success; |
| 894 } |
| 895 |
| 886 void visitBasicBlock(HBasicBlock node) { | 896 void visitBasicBlock(HBasicBlock node) { |
| 887 // Abort traversal if we are leaving the currently active sub-graph. | 897 // Abort traversal if we are leaving the currently active sub-graph. |
| 888 if (!subGraph.contains(node)) return; | 898 if (!subGraph.contains(node)) return; |
| 889 | 899 |
| 890 currentBlock = node; | 900 currentBlock = node; |
| 891 // If this node has special behavior attached, handle it. | 901 // If this node has block-structure based information attached, |
| 892 // If we reach here again while handling the attached information, | 902 // try using that to traverse from here. |
| 893 // e.g., because we call visitSubGraph on a subgraph starting here, | |
| 894 // don't handle it again. | |
| 895 if (node.blockInformation !== null && | 903 if (node.blockInformation !== null && |
| 896 node.blockInformation !== currentBlockInformation) { | 904 handleBlockInfo(node.blockInformation)) { |
| 897 HBlockInformation oldBlockInformation = currentBlockInformation; | 905 return; |
| 898 currentBlockInformation = node.blockInformation; | 906 } |
| 899 bool success = currentBlockInformation.accept(this); | 907 // Flow based traversal. |
| 900 currentBlockInformation = oldBlockInformation; | 908 if (node.isLoopHeader() && |
| 901 if (success) return; | 909 node.loopInformation.loopBlockInformation !== currentBlockInformation) { |
| 902 | 910 beginLoop(node); |
| 903 // If our special handling didn't succeed, we have to emit a generic | |
| 904 // version. This still requires special handling for loop-blocks | |
| 905 if (node.isLoopHeader()) { | |
| 906 beginLoop(node); | |
| 907 } | |
| 908 } | 911 } |
| 909 iterateBasicBlock(node); | 912 iterateBasicBlock(node); |
| 910 } | 913 } |
| 911 | 914 |
| 912 void iterateBasicBlock(HBasicBlock node) { | 915 void iterateBasicBlock(HBasicBlock node) { |
| 913 HInstruction instruction = node.first; | 916 HInstruction instruction = node.first; |
| 914 while (instruction != null) { | 917 while (instruction != null) { |
| 915 if (instruction === node.last) { | 918 if (instruction === node.last) { |
| 916 for (HBasicBlock successor in node.successors) { | 919 for (HBasicBlock successor in node.successors) { |
| 917 int index = successor.predecessors.indexOf(node); | 920 int index = successor.predecessors.indexOf(node); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 939 } | 942 } |
| 940 if (!temporaryExists(canonicalPhi)) { | 943 if (!temporaryExists(canonicalPhi)) { |
| 941 declareVariable(temporary(canonicalPhi)); | 944 declareVariable(temporary(canonicalPhi)); |
| 942 } else { | 945 } else { |
| 943 buffer.add(temporary(canonicalPhi)); | 946 buffer.add(temporary(canonicalPhi)); |
| 944 } | 947 } |
| 945 buffer.add(" = "); | 948 buffer.add(" = "); |
| 946 if (isLogicalOperation) { | 949 if (isLogicalOperation) { |
| 947 emitLogicalOperation(phi, logicalOperations[phi]); | 950 emitLogicalOperation(phi, logicalOperations[phi]); |
| 948 } else { | 951 } else { |
| 949 use(phi.inputs[index], JSPrecedence.ASSIGNMENT_PRECEDENCE); | 952 use(input, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 950 } | 953 } |
| 951 if (!isGeneratingExpression()) { | 954 if (!isGeneratingExpression()) { |
| 952 buffer.add(';\n'); | 955 buffer.add(';\n'); |
| 953 } | 956 } |
| 954 }); | 957 }); |
| 955 } | 958 } |
| 956 } | 959 } |
| 957 | 960 |
| 958 if (instruction is HGoto || instruction is HExit || instruction is HTry) { | 961 if (instruction is HGoto || instruction is HExit || instruction is HTry) { |
| 959 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 962 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 visitIf(HIf node) { | 1172 visitIf(HIf node) { |
| 1170 if (subGraph !== null && node.block === subGraph.end) { | 1173 if (subGraph !== null && node.block === subGraph.end) { |
| 1171 if (isGeneratingExpression()) { | 1174 if (isGeneratingExpression()) { |
| 1172 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); | 1175 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); |
| 1173 } | 1176 } |
| 1174 return; | 1177 return; |
| 1175 } | 1178 } |
| 1176 HInstruction condition = node.inputs[0]; | 1179 HInstruction condition = node.inputs[0]; |
| 1177 int preVisitedBlocks = 0; | 1180 int preVisitedBlocks = 0; |
| 1178 List<HBasicBlock> dominated = node.block.dominatedBlocks; | 1181 List<HBasicBlock> dominated = node.block.dominatedBlocks; |
| 1179 HIfBlockInformation info = node.blockInformation; | 1182 HIfBlockInformation info = node.blockInformation.body; |
| 1180 if (condition.isConstant()) { | 1183 if (condition.isConstant()) { |
| 1181 HConstant constant = condition; | 1184 HConstant constant = condition; |
| 1182 if (constant.constant.isTrue()) { | 1185 if (constant.constant.isTrue()) { |
| 1183 generateStatements(info.thenGraph); | 1186 generateStatements(info.thenGraph); |
| 1184 } else if (node.hasElse) { | 1187 } else if (node.hasElse) { |
| 1185 generateStatements(info.elseGraph); | 1188 generateStatements(info.elseGraph); |
| 1186 } | 1189 } |
| 1187 // We ignore the other branch, even if it isn't visited. | 1190 // We ignore the other branch, even if it isn't visited. |
| 1188 preVisitedBlocks = node.hasElse ? 2 : 1; | 1191 preVisitedBlocks = node.hasElse ? 2 : 1; |
| 1189 } else { | 1192 } else { |
| 1190 startIf(node); | 1193 startIf(node); |
| 1191 assert(!isGenerateAtUseSite(node)); | 1194 assert(!isGenerateAtUseSite(node)); |
| 1192 startThen(node); | 1195 startThen(node); |
| 1193 assert(node.thenBlock === dominated[0]); | 1196 assert(node.thenBlock === dominated[0]); |
| 1194 generateStatements(info.thenGraph); | 1197 generateStatements(info.thenGraph); |
| 1195 preVisitedBlocks++; | 1198 preVisitedBlocks++; |
| 1196 endThen(node); | 1199 endThen(node); |
| 1197 if (node.hasElse) { | 1200 if (node.hasElse) { |
| 1198 startElse(node); | 1201 startElse(node); |
| 1199 assert(node.elseBlock === dominated[1]); | 1202 assert(node.elseBlock === dominated[1]); |
| 1200 generateStatements(info.elseGraph); | 1203 generateStatements(info.elseGraph); |
| 1201 preVisitedBlocks++; | 1204 preVisitedBlocks++; |
| 1202 endElse(node); | 1205 endElse(node); |
| 1203 } | 1206 } |
| 1204 endIf(node); | 1207 endIf(node); |
| 1205 } | 1208 } |
| 1206 if (info.joinBlock !== null && info.joinBlock.dominator !== node.block) { | 1209 HBasicBlock joinBlock = node.joinBlock; |
| 1210 if (joinBlock !== null && joinBlock.dominator !== node.block) { |
| 1207 // The join block is dominated by a block in one of the branches. | 1211 // The join block is dominated by a block in one of the branches. |
| 1208 // The subgraph traversal never reached it, so we visit it here | 1212 // The subgraph traversal never reached it, so we visit it here |
| 1209 // instead. | 1213 // instead. |
| 1210 visitBasicBlock(info.joinBlock); | 1214 visitBasicBlock(joinBlock); |
| 1211 } | 1215 } |
| 1212 | 1216 |
| 1213 // Visit all the dominated blocks that are not part of the then or else | 1217 // Visit all the dominated blocks that are not part of the then or else |
| 1214 // branches, and is not the join block. | 1218 // branches, and is not the join block. |
| 1215 // Depending on how the then/else branches terminate | 1219 // Depending on how the then/else branches terminate |
| 1216 // (e.g., return/throw/break) there can be any number of these. | 1220 // (e.g., return/throw/break) there can be any number of these. |
| 1217 int dominatedCount = dominated.length; | 1221 int dominatedCount = dominated.length; |
| 1218 for (int i = preVisitedBlocks; i < dominatedCount; i++) { | 1222 for (int i = preVisitedBlocks; i < dominatedCount; i++) { |
| 1219 HBasicBlock dominatedBlock = dominated[i]; | 1223 HBasicBlock dominatedBlock = dominated[i]; |
| 1220 assert(dominatedBlock.dominator === node.block); | 1224 assert(dominatedBlock.dominator === node.block); |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2002 buffer.add(')) '); | 2006 buffer.add(')) '); |
| 2003 bailout(node, 'Not a string or array'); | 2007 bailout(node, 'Not a string or array'); |
| 2004 } else { | 2008 } else { |
| 2005 unreachable(); | 2009 unreachable(); |
| 2006 } | 2010 } |
| 2007 buffer.add(';\n'); | 2011 buffer.add(';\n'); |
| 2008 } | 2012 } |
| 2009 | 2013 |
| 2010 void beginLoop(HBasicBlock block) { | 2014 void beginLoop(HBasicBlock block) { |
| 2011 addIndentation(); | 2015 addIndentation(); |
| 2012 HLoopInformation info = block.blockInformation; | 2016 HLoopInformation info = block.loopInformation; |
| 2013 for (LabelElement label in info.labels) { | 2017 for (LabelElement label in info.labels) { |
| 2014 writeLabel(label); | 2018 writeLabel(label); |
| 2015 buffer.add(":"); | 2019 buffer.add(":"); |
| 2016 } | 2020 } |
| 2017 buffer.add('while (true) {\n'); | 2021 buffer.add('while (true) {\n'); |
| 2018 indent++; | 2022 indent++; |
| 2019 } | 2023 } |
| 2020 | 2024 |
| 2021 void endLoop(HBasicBlock block) { | 2025 void endLoop(HBasicBlock block) { |
| 2022 indent--; | 2026 indent--; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2126 } else if (argument is HTypeGuard) { | 2130 } else if (argument is HTypeGuard) { |
| 2127 HTypeGuard instruction = argument; | 2131 HTypeGuard instruction = argument; |
| 2128 return unwrap(instruction.guarded); | 2132 return unwrap(instruction.guarded); |
| 2129 } else { | 2133 } else { |
| 2130 return argument; | 2134 return argument; |
| 2131 } | 2135 } |
| 2132 } | 2136 } |
| 2133 | 2137 |
| 2134 bool visitAndOrInfo(HAndOrBlockInformation info) => false; | 2138 bool visitAndOrInfo(HAndOrBlockInformation info) => false; |
| 2135 bool visitIfInfo(HIfBlockInformation info) => false; | 2139 bool visitIfInfo(HIfBlockInformation info) => false; |
| 2136 bool visitLoopInfo(HLoopInformation info) => false; | 2140 bool visitLoopInfo(HLoopBlockInformation info) => false; |
| 2137 bool visitTryInfo(HTryBlockInformation info) => false; | 2141 bool visitTryInfo(HTryBlockInformation info) => false; |
| 2138 | 2142 bool visitSequenceInfo(HStatementSequenceInformation info) => false; |
| 2139 | 2143 |
| 2140 void visitTypeGuard(HTypeGuard node) { | 2144 void visitTypeGuard(HTypeGuard node) { |
| 2141 indent--; | 2145 indent--; |
| 2142 addIndented('case ${node.state}:\n'); | 2146 addIndented('case ${node.state}:\n'); |
| 2143 indent++; | 2147 indent++; |
| 2144 addIndented('state = 0;\n'); | 2148 addIndented('state = 0;\n'); |
| 2145 | 2149 |
| 2146 setup.add(' case ${node.state}:\n'); | 2150 setup.add(' case ${node.state}:\n'); |
| 2147 int i = 0; | 2151 int i = 0; |
| 2148 for (HInstruction input in node.inputs) { | 2152 for (HInstruction input in node.inputs) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2182 } | 2186 } |
| 2183 | 2187 |
| 2184 void beginLoop(HBasicBlock block) { | 2188 void beginLoop(HBasicBlock block) { |
| 2185 // TODO(ngeoffray): Don't put labels on loops that don't bailout. | 2189 // TODO(ngeoffray): Don't put labels on loops that don't bailout. |
| 2186 String newLabel = pushLabel(); | 2190 String newLabel = pushLabel(); |
| 2187 if (block.hasGuards()) { | 2191 if (block.hasGuards()) { |
| 2188 startBailoutCase(block.guards, const <HTypeGuard>[]); | 2192 startBailoutCase(block.guards, const <HTypeGuard>[]); |
| 2189 } | 2193 } |
| 2190 | 2194 |
| 2191 addIndentation(); | 2195 addIndentation(); |
| 2192 HLoopInformation loopInformation = block.blockInformation; | 2196 HLoopInformation loopInformation = block.loopInformation; |
| 2193 for (LabelElement label in loopInformation.labels) { | 2197 for (LabelElement label in loopInformation.labels) { |
| 2194 writeLabel(label); | 2198 writeLabel(label); |
| 2195 buffer.add(":"); | 2199 buffer.add(":"); |
| 2196 } | 2200 } |
| 2197 buffer.add('$newLabel: while (true) {\n'); | 2201 buffer.add('$newLabel: while (true) {\n'); |
| 2198 indent++; | 2202 indent++; |
| 2199 | 2203 |
| 2200 if (block.hasGuards()) { | 2204 if (block.hasGuards()) { |
| 2201 startBailoutSwitch(); | 2205 startBailoutSwitch(); |
| 2202 if (loopInformation.target !== null) { | 2206 if (loopInformation.target !== null) { |
| 2203 breakAction[loopInformation.target] = (TargetElement target) { | 2207 breakAction[loopInformation.target] = (TargetElement target) { |
| 2204 addIndented("break $newLabel;\n"); | 2208 addIndented("break $newLabel;\n"); |
| 2205 }; | 2209 }; |
| 2206 } | 2210 } |
| 2207 } | 2211 } |
| 2208 } | 2212 } |
| 2209 | 2213 |
| 2210 void endLoop(HBasicBlock block) { | 2214 void endLoop(HBasicBlock block) { |
| 2211 popLabel(); | 2215 popLabel(); |
| 2212 HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader; | 2216 HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader; |
| 2213 if (header.hasGuards()) { | 2217 if (header.hasGuards()) { |
| 2214 endBailoutSwitch(); | 2218 endBailoutSwitch(); |
| 2215 HLoopInformation info = header.blockInformation; | 2219 HLoopInformation info = header.loopInformation; |
| 2216 if (info.target != null) breakAction.remove(info.target); | 2220 if (info.target != null) breakAction.remove(info.target); |
| 2217 } | 2221 } |
| 2218 indent--; | 2222 indent--; |
| 2219 addIndented('}\n'); // Close 'while'. | 2223 addIndented('}\n'); // Close 'while'. |
| 2220 } | 2224 } |
| 2221 | 2225 |
| 2222 void handleLoopCondition(HLoopBranch node) { | 2226 void handleLoopCondition(HLoopBranch node) { |
| 2223 buffer.add('if (!'); | 2227 buffer.add('if (!'); |
| 2224 use(node.inputs[0], JSPrecedence.PREFIX_PRECEDENCE); | 2228 use(node.inputs[0], JSPrecedence.PREFIX_PRECEDENCE); |
| 2225 buffer.add(') break ${currentLabel()};\n'); | 2229 buffer.add(') break ${currentLabel()};\n'); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2299 startBailoutSwitch(); | 2303 startBailoutSwitch(); |
| 2300 } | 2304 } |
| 2301 } | 2305 } |
| 2302 | 2306 |
| 2303 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2307 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2304 if (labeledBlockInfo.body.start.hasGuards()) { | 2308 if (labeledBlockInfo.body.start.hasGuards()) { |
| 2305 endBailoutSwitch(); | 2309 endBailoutSwitch(); |
| 2306 } | 2310 } |
| 2307 } | 2311 } |
| 2308 } | 2312 } |
| OLD | NEW |