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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 11361100: Remove hack around aborting loop body in the case of for loops and while loops. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 part of ssa; 5 part of ssa;
6 6
7 class Interceptors { 7 class Interceptors {
8 Compiler compiler; 8 Compiler compiler;
9 Interceptors(Compiler this.compiler); 9 Interceptors(Compiler this.compiler);
10 10
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 // In all other cases a new box will be created when entering the body of 658 // In all other cases a new box will be created when entering the body of
659 // the next iteration. 659 // the next iteration.
660 ClosureScope scopeData = closureData.capturingScopes[node]; 660 ClosureScope scopeData = closureData.capturingScopes[node];
661 if (scopeData == null) return; 661 if (scopeData == null) return;
662 if (scopeData.hasBoxedLoopVariables()) { 662 if (scopeData.hasBoxedLoopVariables()) {
663 updateCaptureBox(scopeData.boxElement, scopeData.boxedLoopVariables); 663 updateCaptureBox(scopeData.boxElement, scopeData.boxedLoopVariables);
664 } 664 }
665 } 665 }
666 666
667 void endLoop(HBasicBlock loopEntry) { 667 void endLoop(HBasicBlock loopEntry) {
668 // If the loop has an aborting body, we don't update the loop
669 // phis.
670 if (loopEntry.predecessors.length == 1) return;
668 loopEntry.forEachPhi((HPhi phi) { 671 loopEntry.forEachPhi((HPhi phi) {
669 Element element = phi.sourceElement; 672 Element element = phi.sourceElement;
670 HInstruction postLoopDefinition = directLocals[element]; 673 HInstruction postLoopDefinition = directLocals[element];
671 phi.addInput(postLoopDefinition); 674 phi.addInput(postLoopDefinition);
672 }); 675 });
673 } 676 }
674 677
675 /** 678 /**
676 * Merge [otherLocals] into this locals handler, creating phi-nodes when 679 * Merge [otherLocals] into this locals handler, creating phi-nodes when
677 * there is a conflict. 680 * there is a conflict.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 763
761 abstract class JumpHandler { 764 abstract class JumpHandler {
762 factory JumpHandler(SsaBuilder builder, TargetElement target) { 765 factory JumpHandler(SsaBuilder builder, TargetElement target) {
763 return new TargetJumpHandler(builder, target); 766 return new TargetJumpHandler(builder, target);
764 } 767 }
765 void generateBreak([LabelElement label]); 768 void generateBreak([LabelElement label]);
766 void generateContinue([LabelElement label]); 769 void generateContinue([LabelElement label]);
767 void forEachBreak(void action(HBreak instruction, LocalsHandler locals)); 770 void forEachBreak(void action(HBreak instruction, LocalsHandler locals));
768 void forEachContinue(void action(HContinue instruction, 771 void forEachContinue(void action(HContinue instruction,
769 LocalsHandler locals)); 772 LocalsHandler locals));
773 bool hasAnyContinue();
770 void close(); 774 void close();
771 final TargetElement target; 775 final TargetElement target;
772 List<LabelElement> labels(); 776 List<LabelElement> labels();
773 } 777 }
774 778
775 // Insert break handler used to avoid null checks when a target isn't 779 // Insert break handler used to avoid null checks when a target isn't
776 // used as the target of a break, and therefore doesn't need a break 780 // used as the target of a break, and therefore doesn't need a break
777 // handler associated with it. 781 // handler associated with it.
778 class NullJumpHandler implements JumpHandler { 782 class NullJumpHandler implements JumpHandler {
779 final Compiler compiler; 783 final Compiler compiler;
780 784
781 NullJumpHandler(this.compiler); 785 NullJumpHandler(this.compiler);
782 786
783 void generateBreak([LabelElement label]) { 787 void generateBreak([LabelElement label]) {
784 compiler.internalError('generateBreak should not be called'); 788 compiler.internalError('generateBreak should not be called');
785 } 789 }
786 790
787 void generateContinue([LabelElement label]) { 791 void generateContinue([LabelElement label]) {
788 compiler.internalError('generateContinue should not be called'); 792 compiler.internalError('generateContinue should not be called');
789 } 793 }
790 794
791 void forEachBreak(Function ignored) { } 795 void forEachBreak(Function ignored) { }
792 void forEachContinue(Function ignored) { } 796 void forEachContinue(Function ignored) { }
793 void close() { } 797 void close() { }
798 bool hasAnyContinue() => false;
794 799
795 List<LabelElement> labels() => const <LabelElement>[]; 800 List<LabelElement> labels() => const <LabelElement>[];
796 TargetElement get target => null; 801 TargetElement get target => null;
797 } 802 }
798 803
799 // Records breaks until a target block is available. 804 // Records breaks until a target block is available.
800 // Breaks are always forward jumps. 805 // Breaks are always forward jumps.
801 // Continues in loops are implemented as breaks of the body. 806 // Continues in loops are implemented as breaks of the body.
802 // Continues in switches is currently not handled. 807 // Continues in switches is currently not handled.
803 class TargetJumpHandler implements JumpHandler { 808 class TargetJumpHandler implements JumpHandler {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 if (entry.isBreak()) action(entry.jumpInstruction, entry.locals); 846 if (entry.isBreak()) action(entry.jumpInstruction, entry.locals);
842 } 847 }
843 } 848 }
844 849
845 void forEachContinue(Function action) { 850 void forEachContinue(Function action) {
846 for (JumpHandlerEntry entry in jumps) { 851 for (JumpHandlerEntry entry in jumps) {
847 if (entry.isContinue()) action(entry.jumpInstruction, entry.locals); 852 if (entry.isContinue()) action(entry.jumpInstruction, entry.locals);
848 } 853 }
849 } 854 }
850 855
856 bool hasAnyContinue() {
857 for (JumpHandlerEntry entry in jumps) {
858 if (entry.isContinue()) return true;
859 }
860 return false;
861 }
862
851 void close() { 863 void close() {
852 // The mapping from TargetElement to JumpHandler is no longer needed. 864 // The mapping from TargetElement to JumpHandler is no longer needed.
853 builder.jumpTargets.remove(target); 865 builder.jumpTargets.remove(target);
854 } 866 }
855 867
856 List<LabelElement> labels() { 868 List<LabelElement> labels() {
857 List<LabelElement> result = null; 869 List<LabelElement> result = null;
858 for (LabelElement element in target.labels) { 870 for (LabelElement element in target.labels) {
859 if (result == null) result = <LabelElement>[]; 871 if (result == null) result = <LabelElement>[];
860 result.add(element); 872 result.add(element);
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 new SubExpression(conditionBlock, conditionExitBlock); 1798 new SubExpression(conditionBlock, conditionExitBlock);
1787 1799
1788 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1800 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1789 1801
1790 // The body. 1802 // The body.
1791 HBasicBlock beginBodyBlock = addNewBlock(); 1803 HBasicBlock beginBodyBlock = addNewBlock();
1792 conditionExitBlock.addSuccessor(beginBodyBlock); 1804 conditionExitBlock.addSuccessor(beginBodyBlock);
1793 open(beginBodyBlock); 1805 open(beginBodyBlock);
1794 1806
1795 localsHandler.enterLoopBody(loop); 1807 localsHandler.enterLoopBody(loop);
1796 hackAroundPossiblyAbortingBody(loop, body); 1808 body();
1797 1809
1798 SubGraph bodyGraph = new SubGraph(beginBodyBlock, current); 1810 SubGraph bodyGraph = new SubGraph(beginBodyBlock, lastOpenedBlock);
1799 HBasicBlock bodyBlock = close(new HGoto()); 1811 HBasicBlock bodyBlock = current;
1812 if (current != null) close(new HGoto());
1800 1813
1801 // Update. 1814 SubExpression updateGraph;
1802 // We create an update block, even when we are in a while loop. There the
1803 // update block is the jump-target for continue statements. We could avoid
1804 // the creation if there is no continue, but for now we always create it.
1805 HBasicBlock updateBlock = addNewBlock();
1806 1815
1807 List<LocalsHandler> continueLocals = <LocalsHandler>[]; 1816 // Check that the loop has at least one back-edge.
1808 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { 1817 if (jumpHandler.hasAnyContinue() || bodyBlock != null) {
1809 instruction.block.addSuccessor(updateBlock); 1818 // Update.
1810 continueLocals.add(locals); 1819 // We create an update block, even when we are in a while loop. There the
1811 }); 1820 // update block is the jump-target for continue statements. We could avoid
floitsch 2012/11/05 17:36:09 It seems trivial to avoid the creation of the bloc
ngeoffray 2012/11/06 08:55:27 Will do in another CL.
1812 bodyBlock.addSuccessor(updateBlock); 1821 // the creation if there is no continue, but for now we always create it.
1813 continueLocals.add(localsHandler); 1822 HBasicBlock updateBlock = addNewBlock();
1814 1823
1815 open(updateBlock); 1824 List<LocalsHandler> continueLocals = <LocalsHandler>[];
1825 jumpHandler.forEachContinue((HContinue instruction,
1826 LocalsHandler locals) {
1827 instruction.block.addSuccessor(updateBlock);
1828 continueLocals.add(locals);
1829 });
1816 1830
1817 localsHandler = localsHandler.mergeMultiple(continueLocals, updateBlock);
1818 1831
1819 HLabeledBlockInformation labelInfo; 1832 if (bodyBlock != null) {
1820 List<LabelElement> labels = jumpHandler.labels(); 1833 continueLocals.add(localsHandler);
1821 TargetElement target = elements[loop]; 1834 bodyBlock.addSuccessor(updateBlock);
1822 if (!labels.isEmpty) { 1835 }
1823 beginBodyBlock.setBlockFlow( 1836
1824 new HLabeledBlockInformation( 1837 open(updateBlock);
1825 new HSubGraphBlockInformation(bodyGraph), 1838 localsHandler =
1826 jumpHandler.labels(), 1839 continueLocals[0].mergeMultiple(continueLocals, updateBlock);
1827 isContinue: true), 1840
1828 updateBlock); 1841 HLabeledBlockInformation labelInfo;
1829 } else if (target != null && target.isContinueTarget) { 1842 List<LabelElement> labels = jumpHandler.labels();
1830 beginBodyBlock.setBlockFlow( 1843 TargetElement target = elements[loop];
1831 new HLabeledBlockInformation.implicit( 1844 if (!labels.isEmpty) {
1832 new HSubGraphBlockInformation(bodyGraph), 1845 beginBodyBlock.setBlockFlow(
1833 target, 1846 new HLabeledBlockInformation(
1834 isContinue: true), 1847 new HSubGraphBlockInformation(bodyGraph),
1835 updateBlock); 1848 jumpHandler.labels(),
1849 isContinue: true),
1850 updateBlock);
1851 } else if (target != null && target.isContinueTarget) {
1852 beginBodyBlock.setBlockFlow(
1853 new HLabeledBlockInformation.implicit(
1854 new HSubGraphBlockInformation(bodyGraph),
1855 target,
1856 isContinue: true),
1857 updateBlock);
1858 }
1859
1860 localsHandler.enterLoopUpdates(loop);
1861
1862 update();
1863
1864 HBasicBlock updateEndBlock = close(new HGoto());
1865 // The back-edge completing the cycle.
1866 updateEndBlock.addSuccessor(conditionBlock);
1867 updateGraph = new SubExpression(updateBlock, updateEndBlock);
1836 } 1868 }
1837 1869
1838 localsHandler.enterLoopUpdates(loop);
1839
1840 update();
1841
1842 HBasicBlock updateEndBlock = close(new HGoto());
1843 // The back-edge completing the cycle.
1844 updateEndBlock.addSuccessor(conditionBlock);
1845 conditionBlock.postProcessLoopHeader(); 1870 conditionBlock.postProcessLoopHeader();
1846 SubExpression updateGraph = new SubExpression(updateBlock, updateEndBlock);
1847 1871
1848 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); 1872 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals);
1849 HLoopBlockInformation info = 1873 HLoopBlockInformation info =
1850 new HLoopBlockInformation( 1874 new HLoopBlockInformation(
1851 HLoopBlockInformation.loopType(loop), 1875 HLoopBlockInformation.loopType(loop),
1852 wrapExpressionGraph(initializerGraph), 1876 wrapExpressionGraph(initializerGraph),
1853 wrapExpressionGraph(conditionExpression), 1877 wrapExpressionGraph(conditionExpression),
1854 wrapStatementGraph(bodyGraph), 1878 wrapStatementGraph(bodyGraph),
1855 wrapExpressionGraph(updateGraph), 1879 wrapExpressionGraph(updateGraph),
1856 conditionBlock.loopInformation.target, 1880 conditionBlock.loopInformation.target,
(...skipping 2822 matching lines...) Expand 10 before | Expand all | Expand 10 after
4679 new HSubGraphBlockInformation(elseBranch.graph)); 4703 new HSubGraphBlockInformation(elseBranch.graph));
4680 4704
4681 HBasicBlock conditionStartBlock = conditionBranch.block; 4705 HBasicBlock conditionStartBlock = conditionBranch.block;
4682 conditionStartBlock.setBlockFlow(info, joinBlock); 4706 conditionStartBlock.setBlockFlow(info, joinBlock);
4683 SubGraph conditionGraph = conditionBranch.graph; 4707 SubGraph conditionGraph = conditionBranch.graph;
4684 HIf branch = conditionGraph.end.last; 4708 HIf branch = conditionGraph.end.last;
4685 assert(branch is HIf); 4709 assert(branch is HIf);
4686 branch.blockInformation = conditionStartBlock.blockFlow; 4710 branch.blockInformation = conditionStartBlock.blockFlow;
4687 } 4711 }
4688 } 4712 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698