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

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

Issue 11359068: Do not use hack around aborting loop body for a do/while. (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
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.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 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 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 abstract class JumpHandler { 764 abstract class JumpHandler {
765 factory JumpHandler(SsaBuilder builder, TargetElement target) { 765 factory JumpHandler(SsaBuilder builder, TargetElement target) {
766 return new TargetJumpHandler(builder, target); 766 return new TargetJumpHandler(builder, target);
767 } 767 }
768 void generateBreak([LabelElement label]); 768 void generateBreak([LabelElement label]);
769 void generateContinue([LabelElement label]); 769 void generateContinue([LabelElement label]);
770 void forEachBreak(void action(HBreak instruction, LocalsHandler locals)); 770 void forEachBreak(void action(HBreak instruction, LocalsHandler locals));
771 void forEachContinue(void action(HContinue instruction, 771 void forEachContinue(void action(HContinue instruction,
772 LocalsHandler locals)); 772 LocalsHandler locals));
773 bool hasAnyContinue(); 773 bool hasAnyContinue();
774 bool hasAnyBreak();
774 void close(); 775 void close();
775 final TargetElement target; 776 final TargetElement target;
776 List<LabelElement> labels(); 777 List<LabelElement> labels();
777 } 778 }
778 779
779 // Insert break handler used to avoid null checks when a target isn't 780 // Insert break handler used to avoid null checks when a target isn't
780 // used as the target of a break, and therefore doesn't need a break 781 // used as the target of a break, and therefore doesn't need a break
781 // handler associated with it. 782 // handler associated with it.
782 class NullJumpHandler implements JumpHandler { 783 class NullJumpHandler implements JumpHandler {
783 final Compiler compiler; 784 final Compiler compiler;
784 785
785 NullJumpHandler(this.compiler); 786 NullJumpHandler(this.compiler);
786 787
787 void generateBreak([LabelElement label]) { 788 void generateBreak([LabelElement label]) {
788 compiler.internalError('generateBreak should not be called'); 789 compiler.internalError('generateBreak should not be called');
789 } 790 }
790 791
791 void generateContinue([LabelElement label]) { 792 void generateContinue([LabelElement label]) {
792 compiler.internalError('generateContinue should not be called'); 793 compiler.internalError('generateContinue should not be called');
793 } 794 }
794 795
795 void forEachBreak(Function ignored) { } 796 void forEachBreak(Function ignored) { }
796 void forEachContinue(Function ignored) { } 797 void forEachContinue(Function ignored) { }
797 void close() { } 798 void close() { }
798 bool hasAnyContinue() => false; 799 bool hasAnyContinue() => false;
800 bool hasAnyBreak() => false;
799 801
800 List<LabelElement> labels() => const <LabelElement>[]; 802 List<LabelElement> labels() => const <LabelElement>[];
801 TargetElement get target => null; 803 TargetElement get target => null;
802 } 804 }
803 805
804 // Records breaks until a target block is available. 806 // Records breaks until a target block is available.
805 // Breaks are always forward jumps. 807 // Breaks are always forward jumps.
806 // Continues in loops are implemented as breaks of the body. 808 // Continues in loops are implemented as breaks of the body.
807 // Continues in switches is currently not handled. 809 // Continues in switches is currently not handled.
808 class TargetJumpHandler implements JumpHandler { 810 class TargetJumpHandler implements JumpHandler {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 } 855 }
854 } 856 }
855 857
856 bool hasAnyContinue() { 858 bool hasAnyContinue() {
857 for (JumpHandlerEntry entry in jumps) { 859 for (JumpHandlerEntry entry in jumps) {
858 if (entry.isContinue()) return true; 860 if (entry.isContinue()) return true;
859 } 861 }
860 return false; 862 return false;
861 } 863 }
862 864
865 bool hasAnyBreak() {
866 for (JumpHandlerEntry entry in jumps) {
867 if (entry.isBreak()) return true;
868 }
869 return false;
870 }
871
863 void close() { 872 void close() {
864 // The mapping from TargetElement to JumpHandler is no longer needed. 873 // The mapping from TargetElement to JumpHandler is no longer needed.
865 builder.jumpTargets.remove(target); 874 builder.jumpTargets.remove(target);
866 } 875 }
867 876
868 List<LabelElement> labels() { 877 List<LabelElement> labels() {
869 List<LabelElement> result = null; 878 List<LabelElement> result = null;
870 for (LabelElement element in target.labels) { 879 for (LabelElement element in target.labels) {
871 if (result == null) result = <LabelElement>[]; 880 if (result == null) result = <LabelElement>[];
872 result.add(element); 881 result.add(element);
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 /** 1730 /**
1722 * Ends the loop: 1731 * Ends the loop:
1723 * - creates a new block and adds it as successor to the [branchBlock]. 1732 * - creates a new block and adds it as successor to the [branchBlock].
1724 * - opens the new block (setting as [current]). 1733 * - opens the new block (setting as [current]).
1725 * - notifies the locals handler that we're exiting a loop. 1734 * - notifies the locals handler that we're exiting a loop.
1726 */ 1735 */
1727 void endLoop(HBasicBlock loopEntry, 1736 void endLoop(HBasicBlock loopEntry,
1728 HBasicBlock branchBlock, 1737 HBasicBlock branchBlock,
1729 JumpHandler jumpHandler, 1738 JumpHandler jumpHandler,
1730 LocalsHandler savedLocals) { 1739 LocalsHandler savedLocals) {
1740 if (branchBlock == null && !jumpHandler.hasAnyBreak()) return;
1741
1731 HBasicBlock loopExitBlock = addNewBlock(); 1742 HBasicBlock loopExitBlock = addNewBlock();
1732 assert(branchBlock.successors.length == 1); 1743 assert(branchBlock == null || branchBlock.successors.length == 1);
1733 List<LocalsHandler> breakLocals = <LocalsHandler>[]; 1744 List<LocalsHandler> breakLocals = <LocalsHandler>[];
1734 jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { 1745 jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
1735 breakInstruction.block.addSuccessor(loopExitBlock); 1746 breakInstruction.block.addSuccessor(loopExitBlock);
1736 breakLocals.add(locals); 1747 breakLocals.add(locals);
1737 }); 1748 });
1738 branchBlock.addSuccessor(loopExitBlock); 1749 if (branchBlock != null) {
1750 branchBlock.addSuccessor(loopExitBlock);
1751 }
1739 open(loopExitBlock); 1752 open(loopExitBlock);
1740 localsHandler.endLoop(loopEntry); 1753 localsHandler.endLoop(loopEntry);
1741 if (!breakLocals.isEmpty) { 1754 if (!breakLocals.isEmpty) {
1742 breakLocals.add(savedLocals); 1755 breakLocals.add(savedLocals);
1743 localsHandler = savedLocals.mergeMultiple(breakLocals, loopExitBlock); 1756 localsHandler = savedLocals.mergeMultiple(breakLocals, loopExitBlock);
1744 } else { 1757 } else {
1745 localsHandler = savedLocals; 1758 localsHandler = savedLocals;
1746 } 1759 }
1747 } 1760 }
1748 1761
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 // Add extra block to hang labels on. 1959 // Add extra block to hang labels on.
1947 // It doesn't currently work if they are on the same block as the 1960 // It doesn't currently work if they are on the same block as the
1948 // HLoopInfo. The handling of HLabeledBlockInformation will visit a 1961 // HLoopInfo. The handling of HLabeledBlockInformation will visit a
1949 // SubGraph that starts at the same block again, so the HLoopInfo is 1962 // SubGraph that starts at the same block again, so the HLoopInfo is
1950 // either handled twice, or it's handled after the labeled block info, 1963 // either handled twice, or it's handled after the labeled block info,
1951 // both of which generate the wrong code. 1964 // both of which generate the wrong code.
1952 // Using a separate block is just a simple workaround. 1965 // Using a separate block is just a simple workaround.
1953 bodyEntryBlock = openNewBlock(); 1966 bodyEntryBlock = openNewBlock();
1954 } 1967 }
1955 localsHandler.enterLoopBody(node); 1968 localsHandler.enterLoopBody(node);
1956 hackAroundPossiblyAbortingBody(node, () { visit(node.body); }); 1969 visit(node.body);
1957 1970
1958 // If there are no continues we could avoid the creation of the condition 1971 // If there are no continues we could avoid the creation of the condition
1959 // block. This could also lead to a block having multiple entries and exits. 1972 // block. This could also lead to a block having multiple entries and exits.
1960 HBasicBlock bodyExitBlock = close(new HGoto()); 1973 HBasicBlock bodyExitBlock;
1961 HBasicBlock conditionBlock = addNewBlock(); 1974 bool isAbortingBody = false;
1975 if (current != null) {
1976 bodyExitBlock = close(new HGoto());
1977 } else {
1978 isAbortingBody = true;
1979 bodyExitBlock = lastOpenedBlock;
1980 }
1962 1981
1963 List<LocalsHandler> continueLocals = <LocalsHandler>[]; 1982 SubExpression conditionExpression;
1964 jumpHandler.forEachContinue((HContinue instruction, LocalsHandler locals) { 1983 HBasicBlock conditionEndBlock;
1965 instruction.block.addSuccessor(conditionBlock); 1984 if (!isAbortingBody || hasContinues) {
1966 continueLocals.add(locals); 1985 HBasicBlock conditionBlock = addNewBlock();
1967 }); 1986
1968 bodyExitBlock.addSuccessor(conditionBlock); 1987 List<LocalsHandler> continueLocals = <LocalsHandler>[];
1969 if (!continueLocals.isEmpty) { 1988 jumpHandler.forEachContinue((HContinue instruction,
1970 continueLocals.add(localsHandler); 1989 LocalsHandler locals) {
1971 localsHandler = savedLocals.mergeMultiple(continueLocals, conditionBlock); 1990 instruction.block.addSuccessor(conditionBlock);
1972 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); 1991 continueLocals.add(locals);
1973 List<LabelElement> labels = jumpHandler.labels(); 1992 });
1974 HSubGraphBlockInformation bodyInfo = 1993
1975 new HSubGraphBlockInformation(bodyGraph); 1994 if (!isAbortingBody) {
1976 HLabeledBlockInformation info; 1995 bodyExitBlock.addSuccessor(conditionBlock);
1977 if (!labels.isEmpty) {
1978 info = new HLabeledBlockInformation(bodyInfo, labels, isContinue: true);
1979 } else {
1980 info = new HLabeledBlockInformation.implicit(bodyInfo, target,
1981 isContinue: true);
1982 } 1996 }
1983 bodyEntryBlock.setBlockFlow(info, conditionBlock); 1997
1998 if (!continueLocals.isEmpty) {
1999 if (!isAbortingBody) continueLocals.add(localsHandler);
2000 localsHandler =
2001 savedLocals.mergeMultiple(continueLocals, conditionBlock);
2002 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
2003 List<LabelElement> labels = jumpHandler.labels();
2004 HSubGraphBlockInformation bodyInfo =
2005 new HSubGraphBlockInformation(bodyGraph);
2006 HLabeledBlockInformation info;
2007 if (!labels.isEmpty) {
2008 info = new HLabeledBlockInformation(bodyInfo, labels,
2009 isContinue: true);
2010 } else {
2011 info = new HLabeledBlockInformation.implicit(bodyInfo, target,
2012 isContinue: true);
2013 }
2014 bodyEntryBlock.setBlockFlow(info, conditionBlock);
2015 }
2016 open(conditionBlock);
2017
2018 visit(node.condition);
2019 assert(!isAborted());
2020 HInstruction conditionInstruction = popBoolified();
2021 conditionEndBlock = close(
2022 new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
2023
2024 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge.
2025 conditionExpression =
2026 new SubExpression(conditionBlock, conditionEndBlock);
1984 } 2027 }
1985 open(conditionBlock);
1986 2028
1987 visit(node.condition);
1988 assert(!isAborted());
1989 HInstruction conditionInstruction = popBoolified();
1990 HBasicBlock conditionEndBlock =
1991 close(new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP));
1992
1993 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge.
1994 loopEntryBlock.postProcessLoopHeader(); 2029 loopEntryBlock.postProcessLoopHeader();
1995 2030
1996 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); 2031 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler);
1997 jumpHandler.close(); 2032 jumpHandler.close();
1998 2033
1999 SubExpression conditionExpression =
2000 new SubExpression(conditionBlock, conditionEndBlock);
2001 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); 2034 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
2002 2035
2003 HLoopBlockInformation loopBlockInfo = 2036 HLoopBlockInformation loopBlockInfo =
2004 new HLoopBlockInformation( 2037 new HLoopBlockInformation(
2005 HLoopBlockInformation.DO_WHILE_LOOP, 2038 HLoopBlockInformation.DO_WHILE_LOOP,
2006 null, 2039 null,
2007 wrapExpressionGraph(conditionExpression), 2040 wrapExpressionGraph(conditionExpression),
2008 wrapStatementGraph(bodyGraph), 2041 wrapStatementGraph(bodyGraph),
2009 null, 2042 null,
2010 loopEntryBlock.loopInformation.target, 2043 loopEntryBlock.loopInformation.target,
(...skipping 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after
4742 new HSubGraphBlockInformation(elseBranch.graph)); 4775 new HSubGraphBlockInformation(elseBranch.graph));
4743 4776
4744 HBasicBlock conditionStartBlock = conditionBranch.block; 4777 HBasicBlock conditionStartBlock = conditionBranch.block;
4745 conditionStartBlock.setBlockFlow(info, joinBlock); 4778 conditionStartBlock.setBlockFlow(info, joinBlock);
4746 SubGraph conditionGraph = conditionBranch.graph; 4779 SubGraph conditionGraph = conditionBranch.graph;
4747 HIf branch = conditionGraph.end.last; 4780 HIf branch = conditionGraph.end.last;
4748 assert(branch is HIf); 4781 assert(branch is HIf);
4749 branch.blockInformation = conditionStartBlock.blockFlow; 4782 branch.blockInformation = conditionStartBlock.blockFlow;
4750 } 4783 }
4751 } 4784 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698