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 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 1782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1793 } | 1793 } |
1794 | 1794 |
1795 HSubExpressionBlockInformation wrapExpressionGraph(SubExpression expression) { | 1795 HSubExpressionBlockInformation wrapExpressionGraph(SubExpression expression) { |
1796 if (expression == null) return null; | 1796 if (expression == null) return null; |
1797 return new HSubExpressionBlockInformation(expression); | 1797 return new HSubExpressionBlockInformation(expression); |
1798 } | 1798 } |
1799 | 1799 |
1800 // For while loops, initializer and update are null. | 1800 // For while loops, initializer and update are null. |
1801 // The condition function must return a boolean result. | 1801 // The condition function must return a boolean result. |
1802 // None of the functions must leave anything on the stack. | 1802 // None of the functions must leave anything on the stack. |
1803 handleLoop(Node loop, | 1803 void handleLoop(Node loop, |
1804 void initialize(), | 1804 void initialize(), |
1805 HInstruction condition(), | 1805 HInstruction condition(), |
1806 void update(), | 1806 void update(), |
1807 void body()) { | 1807 void body()) { |
1808 // Generate: | 1808 // Generate: |
1809 // <initializer> | 1809 // <initializer> |
1810 // loop-entry: | 1810 // loop-entry: |
1811 // if (!<condition>) goto loop-exit; | 1811 // if (!<condition>) goto loop-exit; |
1812 // <body> | 1812 // <body> |
1813 // <updates> | 1813 // <updates> |
1814 // goto loop-entry; | 1814 // goto loop-entry; |
1815 // loop-exit: | 1815 // loop-exit: |
1816 | 1816 |
1817 localsHandler.startLoop(loop); | 1817 localsHandler.startLoop(loop); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1902 localsHandler.enterLoopUpdates(loop); | 1902 localsHandler.enterLoopUpdates(loop); |
1903 | 1903 |
1904 update(); | 1904 update(); |
1905 | 1905 |
1906 HBasicBlock updateEndBlock = close(new HGoto()); | 1906 HBasicBlock updateEndBlock = close(new HGoto()); |
1907 // The back-edge completing the cycle. | 1907 // The back-edge completing the cycle. |
1908 updateEndBlock.addSuccessor(conditionBlock); | 1908 updateEndBlock.addSuccessor(conditionBlock); |
1909 updateGraph = new SubExpression(updateBlock, updateEndBlock); | 1909 updateGraph = new SubExpression(updateBlock, updateEndBlock); |
1910 } | 1910 } |
1911 | 1911 |
1912 conditionBlock.postProcessLoopHeader(); | 1912 if (jumpHandler.hasAnyContinue() || bodyBlock != null) { |
| 1913 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); |
| 1914 conditionBlock.postProcessLoopHeader(); |
| 1915 HLoopBlockInformation info = |
| 1916 new HLoopBlockInformation( |
| 1917 HLoopBlockInformation.loopType(loop), |
| 1918 wrapExpressionGraph(initializerGraph), |
| 1919 wrapExpressionGraph(conditionExpression), |
| 1920 wrapStatementGraph(bodyGraph), |
| 1921 wrapExpressionGraph(updateGraph), |
| 1922 conditionBlock.loopInformation.target, |
| 1923 conditionBlock.loopInformation.labels, |
| 1924 sourceFileLocationForBeginToken(loop), |
| 1925 sourceFileLocationForEndToken(loop)); |
1913 | 1926 |
1914 endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals); | 1927 startBlock.setBlockFlow(info, current); |
1915 HLoopBlockInformation info = | 1928 loopInfo.loopBlockInformation = info; |
1916 new HLoopBlockInformation( | 1929 } else { |
1917 HLoopBlockInformation.loopType(loop), | 1930 // There is no back edge for the loop, so we turn the code into: |
1918 wrapExpressionGraph(initializerGraph), | 1931 // if (condition) { |
| 1932 // body; |
| 1933 // } else { |
| 1934 // // We always create an empty else block to avoid critical edges. |
| 1935 // } |
| 1936 // |
| 1937 // If there is any break in the body, we attach a synthetic |
| 1938 // label to the if. |
| 1939 HBasicBlock elseBlock = addNewBlock(); |
| 1940 open(elseBlock); |
| 1941 close(new HGoto()); |
| 1942 endLoop(conditionBlock, null, jumpHandler, savedLocals); |
| 1943 |
| 1944 // [endLoop] will not create an exit block if there are no |
| 1945 // breaks. |
| 1946 if (current == null) open(addNewBlock()); |
| 1947 elseBlock.addSuccessor(current); |
| 1948 SubGraph elseGraph = new SubGraph(elseBlock, elseBlock); |
| 1949 // Remove the loop information attached to the header. |
| 1950 conditionBlock.loopInformation = null; |
| 1951 |
| 1952 // Remove the [HLoopBranch] instruction and replace it with |
| 1953 // [HIf]. |
| 1954 HInstruction condition = conditionExitBlock.last.inputs[0]; |
| 1955 conditionExitBlock.addAtExit(new HIf(condition)); |
| 1956 conditionExitBlock.addSuccessor(elseBlock); |
| 1957 conditionExitBlock.remove(conditionExitBlock.last); |
| 1958 HIfBlockInformation info = |
| 1959 new HIfBlockInformation( |
1919 wrapExpressionGraph(conditionExpression), | 1960 wrapExpressionGraph(conditionExpression), |
1920 wrapStatementGraph(bodyGraph), | 1961 wrapStatementGraph(bodyGraph), |
1921 wrapExpressionGraph(updateGraph), | 1962 wrapStatementGraph(elseGraph)); |
1922 conditionBlock.loopInformation.target, | |
1923 conditionBlock.loopInformation.labels, | |
1924 sourceFileLocationForBeginToken(loop), | |
1925 sourceFileLocationForEndToken(loop)); | |
1926 | 1963 |
1927 startBlock.setBlockFlow(info, current); | 1964 conditionBlock.setBlockFlow(info, current); |
1928 loopInfo.loopBlockInformation = info; | 1965 conditionBlock.last.blockInformation = conditionBlock.blockFlow; |
| 1966 |
| 1967 // If the body has any break, attach a synthesized label to the |
| 1968 // if block. |
| 1969 if (jumpHandler.hasAnyBreak()) { |
| 1970 TargetElement target = elements[loop]; |
| 1971 LabelElement label = target.addLabel(null, 'loop'); |
| 1972 label.isBreakTarget = true; |
| 1973 SubGraph labelGraph = new SubGraph(conditionBlock, current); |
| 1974 HLabeledBlockInformation labelInfo = new HLabeledBlockInformation( |
| 1975 new HSubGraphBlockInformation(labelGraph), |
| 1976 <LabelElement>[label]); |
| 1977 |
| 1978 conditionBlock.setBlockFlow(labelInfo, current); |
| 1979 |
| 1980 jumpHandler.forEachBreak((HBreak breakInstruction, _) { |
| 1981 HBasicBlock block = breakInstruction.block; |
| 1982 block.addAtExit(new HBreak.toLabel(label)); |
| 1983 block.remove(breakInstruction); |
| 1984 }); |
| 1985 } |
| 1986 } |
| 1987 jumpHandler.close(); |
1929 } | 1988 } |
1930 | 1989 |
1931 visitFor(For node) { | 1990 visitFor(For node) { |
1932 assert(node.body != null); | 1991 assert(node.body != null); |
1933 void buildInitializer() { | 1992 void buildInitializer() { |
1934 if (node.initializer == null) return; | 1993 if (node.initializer == null) return; |
1935 Node initializer = node.initializer; | 1994 Node initializer = node.initializer; |
1936 if (initializer != null) { | 1995 if (initializer != null) { |
1937 visit(initializer); | 1996 visit(initializer); |
1938 if (initializer.asExpression() != null) { | 1997 if (initializer.asExpression() != null) { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2047 assert(!isAborted()); | 2106 assert(!isAborted()); |
2048 HInstruction conditionInstruction = popBoolified(); | 2107 HInstruction conditionInstruction = popBoolified(); |
2049 conditionEndBlock = close( | 2108 conditionEndBlock = close( |
2050 new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP)); | 2109 new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP)); |
2051 | 2110 |
2052 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge. | 2111 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge. |
2053 conditionExpression = | 2112 conditionExpression = |
2054 new SubExpression(conditionBlock, conditionEndBlock); | 2113 new SubExpression(conditionBlock, conditionEndBlock); |
2055 } | 2114 } |
2056 | 2115 |
2057 loopEntryBlock.postProcessLoopHeader(); | 2116 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); |
| 2117 if (!isAbortingBody || hasContinues) { |
| 2118 loopEntryBlock.postProcessLoopHeader(); |
| 2119 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| 2120 HLoopBlockInformation loopBlockInfo = |
| 2121 new HLoopBlockInformation( |
| 2122 HLoopBlockInformation.DO_WHILE_LOOP, |
| 2123 null, |
| 2124 wrapExpressionGraph(conditionExpression), |
| 2125 wrapStatementGraph(bodyGraph), |
| 2126 null, |
| 2127 loopEntryBlock.loopInformation.target, |
| 2128 loopEntryBlock.loopInformation.labels, |
| 2129 sourceFileLocationForBeginToken(node), |
| 2130 sourceFileLocationForEndToken(node)); |
| 2131 loopEntryBlock.setBlockFlow(loopBlockInfo, current); |
| 2132 loopInfo.loopBlockInformation = loopBlockInfo; |
| 2133 } else { |
| 2134 // If the loop has no back edge, we remove the loop information |
| 2135 // on the header. |
| 2136 loopEntryBlock.loopInformation = null; |
2058 | 2137 |
2059 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); | 2138 // If the body of the loop has any break, we attach a |
| 2139 // synthesized label to the body. |
| 2140 if (jumpHandler.hasAnyBreak()) { |
| 2141 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); |
| 2142 TargetElement target = elements[node]; |
| 2143 LabelElement label = target.addLabel(null, 'loop'); |
| 2144 label.isBreakTarget = true; |
| 2145 HLabeledBlockInformation info = new HLabeledBlockInformation( |
| 2146 new HSubGraphBlockInformation(bodyGraph), <LabelElement>[label]); |
| 2147 loopEntryBlock.setBlockFlow(info, current); |
| 2148 jumpHandler.forEachBreak((HBreak breakInstruction, _) { |
| 2149 HBasicBlock block = breakInstruction.block; |
| 2150 block.addAtExit(new HBreak.toLabel(label)); |
| 2151 block.remove(breakInstruction); |
| 2152 }); |
| 2153 } |
| 2154 } |
2060 jumpHandler.close(); | 2155 jumpHandler.close(); |
2061 | |
2062 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); | |
2063 | |
2064 HLoopBlockInformation loopBlockInfo = | |
2065 new HLoopBlockInformation( | |
2066 HLoopBlockInformation.DO_WHILE_LOOP, | |
2067 null, | |
2068 wrapExpressionGraph(conditionExpression), | |
2069 wrapStatementGraph(bodyGraph), | |
2070 null, | |
2071 loopEntryBlock.loopInformation.target, | |
2072 loopEntryBlock.loopInformation.labels, | |
2073 sourceFileLocationForBeginToken(node), | |
2074 sourceFileLocationForEndToken(node)); | |
2075 loopEntryBlock.setBlockFlow(loopBlockInfo, current); | |
2076 loopInfo.loopBlockInformation = loopBlockInfo; | |
2077 } | 2156 } |
2078 | 2157 |
2079 visitFunctionExpression(FunctionExpression node) { | 2158 visitFunctionExpression(FunctionExpression node) { |
2080 ClosureClassMap nestedClosureData = | 2159 ClosureClassMap nestedClosureData = |
2081 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 2160 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
2082 assert(nestedClosureData != null); | 2161 assert(nestedClosureData != null); |
2083 assert(nestedClosureData.closureClassElement != null); | 2162 assert(nestedClosureData.closureClassElement != null); |
2084 ClassElement closureClassElement = | 2163 ClassElement closureClassElement = |
2085 nestedClosureData.closureClassElement; | 2164 nestedClosureData.closureClassElement; |
2086 FunctionElement callElement = nestedClosureData.callElement; | 2165 FunctionElement callElement = nestedClosureData.callElement; |
(...skipping 2757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4844 new HSubGraphBlockInformation(elseBranch.graph)); | 4923 new HSubGraphBlockInformation(elseBranch.graph)); |
4845 | 4924 |
4846 HBasicBlock conditionStartBlock = conditionBranch.block; | 4925 HBasicBlock conditionStartBlock = conditionBranch.block; |
4847 conditionStartBlock.setBlockFlow(info, joinBlock); | 4926 conditionStartBlock.setBlockFlow(info, joinBlock); |
4848 SubGraph conditionGraph = conditionBranch.graph; | 4927 SubGraph conditionGraph = conditionBranch.graph; |
4849 HIf branch = conditionGraph.end.last; | 4928 HIf branch = conditionGraph.end.last; |
4850 assert(branch is HIf); | 4929 assert(branch is HIf); |
4851 branch.blockInformation = conditionStartBlock.blockFlow; | 4930 branch.blockInformation = conditionStartBlock.blockFlow; |
4852 } | 4931 } |
4853 } | 4932 } |
OLD | NEW |