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 SsaCodeGeneratorTask extends CompilerTask { | 7 class SsaCodeGeneratorTask extends CompilerTask { |
8 | 8 |
9 final JavaScriptBackend backend; | 9 final JavaScriptBackend backend; |
10 | 10 |
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1022 generateStatements(info.updates); | 1022 generateStatements(info.updates); |
1023 } else { | 1023 } else { |
1024 visitBodyIgnoreLabels(info); | 1024 visitBodyIgnoreLabels(info); |
1025 } | 1025 } |
1026 currentContainer = oldContainer; | 1026 currentContainer = oldContainer; |
1027 body = unwrapStatement(body); | 1027 body = unwrapStatement(body); |
1028 loop = new js.While(jsCondition, body); | 1028 loop = new js.While(jsCondition, body); |
1029 } | 1029 } |
1030 break; | 1030 break; |
1031 case HLoopBlockInformation.DO_WHILE_LOOP: | 1031 case HLoopBlockInformation.DO_WHILE_LOOP: |
1032 CopyHandler handler = variableNames.getCopyHandler(info.end); | |
floitsch
2012/11/07 09:59:04
Add comment explaining why this is necessary.
ngeoffray
2012/11/07 10:04:49
Done.
| |
1033 if (handler != null && !handler.isEmpty) return false; | |
1032 // Generate do-while loop in all cases. | 1034 // Generate do-while loop in all cases. |
floitsch
2012/11/07 09:59:04
Remove comment or:
Generate do-while loop in all o
ngeoffray
2012/11/07 10:04:49
Comment removed.
| |
1033 if (info.initializer != null) { | 1035 if (info.initializer != null) { |
1034 generateStatements(info.initializer); | 1036 generateStatements(info.initializer); |
1035 } | 1037 } |
1036 js.Block oldContainer = currentContainer; | 1038 js.Block oldContainer = currentContainer; |
1037 js.Statement body = new js.Block.empty(); | 1039 js.Statement body = new js.Block.empty(); |
1038 currentContainer = body; | 1040 currentContainer = body; |
1039 if (!isConditionExpression || info.updates != null) { | 1041 if (!isConditionExpression || info.updates != null) { |
1040 wrapLoopBodyForContinue(info); | 1042 wrapLoopBodyForContinue(info); |
1041 } else { | 1043 } else { |
1042 visitBodyIgnoreLabels(info); | 1044 visitBodyIgnoreLabels(info); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1319 void iterateBasicBlock(HBasicBlock node) { | 1321 void iterateBasicBlock(HBasicBlock node) { |
1320 HInstruction instruction = node.first; | 1322 HInstruction instruction = node.first; |
1321 while (!identical(instruction, node.last)) { | 1323 while (!identical(instruction, node.last)) { |
1322 if (instruction is HTypeGuard || instruction is HBailoutTarget) { | 1324 if (instruction is HTypeGuard || instruction is HBailoutTarget) { |
1323 visit(instruction); | 1325 visit(instruction); |
1324 } else if (!isGenerateAtUseSite(instruction)) { | 1326 } else if (!isGenerateAtUseSite(instruction)) { |
1325 define(instruction); | 1327 define(instruction); |
1326 } | 1328 } |
1327 instruction = instruction.next; | 1329 instruction = instruction.next; |
1328 } | 1330 } |
1329 assignPhisOfSuccessors(node); | 1331 if (instruction is HLoopBranch) { |
1332 HLoopBranch branch = instruction; | |
1333 // If the loop is a do/while loop, the phi updates must happen | |
1334 // after the evaluation of the condition. | |
1335 if (!branch.isDoWhile()) { | |
1336 assignPhisOfSuccessors(node); | |
1337 } | |
1338 } else { | |
1339 assignPhisOfSuccessors(node); | |
1340 } | |
1330 visit(instruction); | 1341 visit(instruction); |
1331 } | 1342 } |
1332 | 1343 |
1333 visitInvokeBinary(HInvokeBinary node, String op) { | 1344 visitInvokeBinary(HInvokeBinary node, String op) { |
1334 if (node.isBuiltin(types)) { | 1345 if (node.isBuiltin(types)) { |
1335 use(node.left); | 1346 use(node.left); |
1336 js.Expression jsLeft = pop(); | 1347 js.Expression jsLeft = pop(); |
1337 use(node.right); | 1348 use(node.right); |
1338 push(new js.Binary(op, jsLeft, pop()), node); | 1349 push(new js.Binary(op, jsLeft, pop()), node); |
1339 } else { | 1350 } else { |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1912 // to the code that called [visitSubGraph]. | 1923 // to the code that called [visitSubGraph]. |
1913 if (isGeneratingExpression) { | 1924 if (isGeneratingExpression) { |
1914 use(node.inputs[0]); | 1925 use(node.inputs[0]); |
1915 } | 1926 } |
1916 return; | 1927 return; |
1917 } | 1928 } |
1918 HBasicBlock branchBlock = currentBlock; | 1929 HBasicBlock branchBlock = currentBlock; |
1919 handleLoopCondition(node); | 1930 handleLoopCondition(node); |
1920 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; | 1931 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; |
1921 // For a do while loop, the body has already been visited. | 1932 // For a do while loop, the body has already been visited. |
1922 if (!node.isDoWhile()) { | 1933 if (!node.isDoWhile()) { |
floitsch
2012/11/07 09:59:04
Invert the test, so that we don't have the "!".
ngeoffray
2012/11/07 10:04:49
Done.
| |
1923 visitBasicBlock(dominated[0]); | 1934 visitBasicBlock(dominated[0]); |
1935 } else { | |
1936 // Now that the condition has been evaluated, we can update the | |
1937 // phis of a do/while loop. | |
1938 assignPhisOfSuccessors(node.block); | |
1924 } | 1939 } |
1925 endLoop(node.block); | 1940 endLoop(node.block); |
1926 | 1941 |
1927 // If the branch does not dominate the code after the loop, the | 1942 // If the branch does not dominate the code after the loop, the |
1928 // dominator will visit it. | 1943 // dominator will visit it. |
1929 if (!identical(branchBlock.successors[1].dominator, branchBlock)) return; | 1944 if (!identical(branchBlock.successors[1].dominator, branchBlock)) return; |
1930 | 1945 |
1931 visitBasicBlock(branchBlock.successors[1]); | 1946 visitBasicBlock(branchBlock.successors[1]); |
1932 // With labeled breaks we can have more dominated blocks. | 1947 // With labeled breaks we can have more dominated blocks. |
1933 if (dominated.length >= 3) { | 1948 if (dominated.length >= 3) { |
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2774 oldContainerStack.add(currentContainer); | 2789 oldContainerStack.add(currentContainer); |
2775 currentContainer = new js.Block.empty(); | 2790 currentContainer = new js.Block.empty(); |
2776 } | 2791 } |
2777 | 2792 |
2778 void endLoop(HBasicBlock block) { | 2793 void endLoop(HBasicBlock block) { |
2779 js.Statement body = currentContainer; | 2794 js.Statement body = currentContainer; |
2780 currentContainer = oldContainerStack.removeLast(); | 2795 currentContainer = oldContainerStack.removeLast(); |
2781 body = unwrapStatement(body); | 2796 body = unwrapStatement(body); |
2782 js.While loop = new js.While(newLiteralBool(true), body); | 2797 js.While loop = new js.While(newLiteralBool(true), body); |
2783 | 2798 |
2784 HLoopInformation info = block.loopInformation; | 2799 HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader; |
2800 HLoopInformation info = header.loopInformation; | |
2785 attachLocationRange(loop, | 2801 attachLocationRange(loop, |
2786 info.loopBlockInformation.sourcePosition, | 2802 info.loopBlockInformation.sourcePosition, |
2787 info.loopBlockInformation.endSourcePosition); | 2803 info.loopBlockInformation.endSourcePosition); |
2788 pushStatement(wrapIntoLabels(loop, info.labels)); | 2804 pushStatement(wrapIntoLabels(loop, info.labels)); |
2789 } | 2805 } |
2790 | 2806 |
2791 void handleLoopCondition(HLoopBranch node) { | 2807 void handleLoopCondition(HLoopBranch node) { |
2792 use(node.inputs[0]); | 2808 use(node.inputs[0]); |
2793 pushStatement(new js.If.noElse(pop(), new js.Break(null)), node); | 2809 js.Expression test = new js.Prefix('!', pop()); |
2810 js.Statement then = new js.Break(null); | |
2811 pushStatement(new js.If.noElse(test, then), node); | |
2794 } | 2812 } |
2795 | 2813 |
2796 | 2814 |
2797 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2815 void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
2798 } | 2816 } |
2799 | 2817 |
2800 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2818 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
2801 } | 2819 } |
2802 | 2820 |
2803 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2821 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3144 if (leftType.canBeNull() && rightType.canBeNull()) { | 3162 if (leftType.canBeNull() && rightType.canBeNull()) { |
3145 if (left.isConstantNull() || right.isConstantNull() || | 3163 if (left.isConstantNull() || right.isConstantNull() || |
3146 (leftType.isPrimitive() && leftType == rightType)) { | 3164 (leftType.isPrimitive() && leftType == rightType)) { |
3147 return '=='; | 3165 return '=='; |
3148 } | 3166 } |
3149 return null; | 3167 return null; |
3150 } else { | 3168 } else { |
3151 return '==='; | 3169 return '==='; |
3152 } | 3170 } |
3153 } | 3171 } |
OLD | NEW |