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

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

Issue 10384027: Wrap block-informations when embedding them in the graph. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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) 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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698