Chromium Code Reviews| 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(), |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
Is this tabs?
ngeoffray
2012/11/16 16:45:28
No.
| |
| 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 { | |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
Explain the empty else block.
ngeoffray
2012/11/16 16:45:28
Done.
| |
| 1934 // } | |
| 1935 // | |
| 1936 // If there is any break in the body, we attach a synthesized | |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
I prefer "synthetic".
ngeoffray
2012/11/16 16:45:28
Done.
| |
| 1937 // label to the if. | |
| 1938 HBasicBlock elseBlock = addNewBlock(); | |
| 1939 open(elseBlock); | |
| 1940 close(new HGoto()); | |
| 1941 endLoop(conditionBlock, null, jumpHandler, savedLocals); | |
| 1942 | |
| 1943 // [endLoop] will not create an exit block if there are no | |
| 1944 // breaks. | |
| 1945 if (current == null) open(addNewBlock()); | |
| 1946 elseBlock.addSuccessor(current); | |
| 1947 SubGraph elseGraph = new SubGraph(elseBlock, elseBlock); | |
| 1948 // Remove the loop information attached to the header. | |
| 1949 conditionBlock.loopInformation = null; | |
| 1950 | |
| 1951 // Remove the [HLoopBranch] instruction and replace it with | |
| 1952 // [HIf]. | |
| 1953 HInstruction condition = conditionExitBlock.last.inputs[0]; | |
| 1954 conditionExitBlock.addAtExit(new HIf(condition)); | |
| 1955 conditionExitBlock.addSuccessor(elseBlock); | |
| 1956 conditionExitBlock.remove(conditionExitBlock.last); | |
| 1957 HIfBlockInformation info = | |
| 1958 new HIfBlockInformation( | |
| 1919 wrapExpressionGraph(conditionExpression), | 1959 wrapExpressionGraph(conditionExpression), |
| 1920 wrapStatementGraph(bodyGraph), | 1960 wrapStatementGraph(bodyGraph), |
| 1921 wrapExpressionGraph(updateGraph), | 1961 wrapStatementGraph(elseGraph)); |
| 1922 conditionBlock.loopInformation.target, | |
| 1923 conditionBlock.loopInformation.labels, | |
| 1924 sourceFileLocationForBeginToken(loop), | |
| 1925 sourceFileLocationForEndToken(loop)); | |
| 1926 | 1962 |
| 1927 startBlock.setBlockFlow(info, current); | 1963 conditionBlock.setBlockFlow(info, current); |
| 1928 loopInfo.loopBlockInformation = info; | 1964 conditionBlock.last.blockInformation = conditionBlock.blockFlow; |
| 1965 | |
| 1966 // If the body has any break, attach a synthesized label to the | |
| 1967 // if block. | |
| 1968 if (jumpHandler.hasAnyBreak()) { | |
| 1969 TargetElement target = elements[loop]; | |
| 1970 LabelElement label = target.addLabel(null, 'loop'); | |
| 1971 label.isBreakTarget = true; | |
| 1972 SubGraph labelGraph = new SubGraph(conditionBlock, current); | |
| 1973 HLabeledBlockInformation labelInfo = new HLabeledBlockInformation( | |
| 1974 new HSubGraphBlockInformation(labelGraph), | |
| 1975 <LabelElement>[label]); | |
| 1976 | |
| 1977 conditionBlock.setBlockFlow(labelInfo, current); | |
| 1978 | |
| 1979 jumpHandler.forEachBreak((HBreak breakInstruction, _) { | |
| 1980 HBasicBlock block = breakInstruction.block; | |
| 1981 block.addAtExit(new HBreak.toLabel(label)); | |
| 1982 block.remove(breakInstruction); | |
| 1983 }); | |
| 1984 } | |
| 1985 } | |
| 1986 jumpHandler.close(); | |
| 1929 } | 1987 } |
| 1930 | 1988 |
| 1931 visitFor(For node) { | 1989 visitFor(For node) { |
| 1932 assert(node.body != null); | 1990 assert(node.body != null); |
| 1933 void buildInitializer() { | 1991 void buildInitializer() { |
| 1934 if (node.initializer == null) return; | 1992 if (node.initializer == null) return; |
| 1935 Node initializer = node.initializer; | 1993 Node initializer = node.initializer; |
| 1936 if (initializer != null) { | 1994 if (initializer != null) { |
| 1937 visit(initializer); | 1995 visit(initializer); |
| 1938 if (initializer.asExpression() != null) { | 1996 if (initializer.asExpression() != null) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2047 assert(!isAborted()); | 2105 assert(!isAborted()); |
| 2048 HInstruction conditionInstruction = popBoolified(); | 2106 HInstruction conditionInstruction = popBoolified(); |
| 2049 conditionEndBlock = close( | 2107 conditionEndBlock = close( |
| 2050 new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP)); | 2108 new HLoopBranch(conditionInstruction, HLoopBranch.DO_WHILE_LOOP)); |
| 2051 | 2109 |
| 2052 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge. | 2110 conditionEndBlock.addSuccessor(loopEntryBlock); // The back-edge. |
| 2053 conditionExpression = | 2111 conditionExpression = |
| 2054 new SubExpression(conditionBlock, conditionEndBlock); | 2112 new SubExpression(conditionBlock, conditionEndBlock); |
| 2055 } | 2113 } |
| 2056 | 2114 |
| 2057 loopEntryBlock.postProcessLoopHeader(); | 2115 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); |
| 2116 if (!isAbortingBody || hasContinues) { | |
| 2117 loopEntryBlock.postProcessLoopHeader(); | |
| 2118 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); | |
| 2119 HLoopBlockInformation loopBlockInfo = | |
| 2120 new HLoopBlockInformation( | |
| 2121 HLoopBlockInformation.DO_WHILE_LOOP, | |
| 2122 null, | |
| 2123 wrapExpressionGraph(conditionExpression), | |
| 2124 wrapStatementGraph(bodyGraph), | |
| 2125 null, | |
| 2126 loopEntryBlock.loopInformation.target, | |
| 2127 loopEntryBlock.loopInformation.labels, | |
| 2128 sourceFileLocationForBeginToken(node), | |
| 2129 sourceFileLocationForEndToken(node)); | |
| 2130 loopEntryBlock.setBlockFlow(loopBlockInfo, current); | |
| 2131 loopInfo.loopBlockInformation = loopBlockInfo; | |
| 2132 } else { | |
| 2133 // If the loop has no back edge, we remove the loop information | |
| 2134 // on the header. | |
| 2135 loopEntryBlock.loopInformation = null; | |
| 2058 | 2136 |
| 2059 endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler); | 2137 // If the body of the loop has any break, we attach a |
| 2138 // synthesized label to the body. | |
| 2139 if (jumpHandler.hasAnyBreak()) { | |
| 2140 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); | |
| 2141 TargetElement target = elements[node]; | |
| 2142 LabelElement label = target.addLabel(null, 'doWhile'); | |
|
Lasse Reichstein Nielsen
2012/11/16 15:09:11
This label is "doWhile" and the other one was "loo
ngeoffray
2012/11/16 16:45:28
Done.
| |
| 2143 label.isBreakTarget = true; | |
| 2144 HLabeledBlockInformation info = new HLabeledBlockInformation( | |
| 2145 new HSubGraphBlockInformation(bodyGraph), <LabelElement>[label]); | |
| 2146 loopEntryBlock.setBlockFlow(info, current); | |
| 2147 jumpHandler.forEachBreak((HBreak breakInstruction, _) { | |
| 2148 HBasicBlock block = breakInstruction.block; | |
| 2149 block.addAtExit(new HBreak.toLabel(label)); | |
| 2150 block.remove(breakInstruction); | |
| 2151 }); | |
| 2152 } | |
| 2153 } | |
| 2060 jumpHandler.close(); | 2154 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 } | 2155 } |
| 2078 | 2156 |
| 2079 visitFunctionExpression(FunctionExpression node) { | 2157 visitFunctionExpression(FunctionExpression node) { |
| 2080 ClosureClassMap nestedClosureData = | 2158 ClosureClassMap nestedClosureData = |
| 2081 compiler.closureToClassMapper.getMappingForNestedFunction(node); | 2159 compiler.closureToClassMapper.getMappingForNestedFunction(node); |
| 2082 assert(nestedClosureData != null); | 2160 assert(nestedClosureData != null); |
| 2083 assert(nestedClosureData.closureClassElement != null); | 2161 assert(nestedClosureData.closureClassElement != null); |
| 2084 ClassElement closureClassElement = | 2162 ClassElement closureClassElement = |
| 2085 nestedClosureData.closureClassElement; | 2163 nestedClosureData.closureClassElement; |
| 2086 FunctionElement callElement = nestedClosureData.callElement; | 2164 FunctionElement callElement = nestedClosureData.callElement; |
| (...skipping 2757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4844 new HSubGraphBlockInformation(elseBranch.graph)); | 4922 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4845 | 4923 |
| 4846 HBasicBlock conditionStartBlock = conditionBranch.block; | 4924 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4847 conditionStartBlock.setBlockFlow(info, joinBlock); | 4925 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4848 SubGraph conditionGraph = conditionBranch.graph; | 4926 SubGraph conditionGraph = conditionBranch.graph; |
| 4849 HIf branch = conditionGraph.end.last; | 4927 HIf branch = conditionGraph.end.last; |
| 4850 assert(branch is HIf); | 4928 assert(branch is HIf); |
| 4851 branch.blockInformation = conditionStartBlock.blockFlow; | 4929 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4852 } | 4930 } |
| 4853 } | 4931 } |
| OLD | NEW |