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 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |