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 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 generateStatements(info.updates); | 936 generateStatements(info.updates); |
937 } else { | 937 } else { |
938 visitBodyIgnoreLabels(info); | 938 visitBodyIgnoreLabels(info); |
939 } | 939 } |
940 currentContainer = oldContainer; | 940 currentContainer = oldContainer; |
941 body = unwrapStatement(body); | 941 body = unwrapStatement(body); |
942 loop = new js.While(jsCondition, body); | 942 loop = new js.While(jsCondition, body); |
943 } | 943 } |
944 break; | 944 break; |
945 case HLoopBlockInformation.DO_WHILE_LOOP: | 945 case HLoopBlockInformation.DO_WHILE_LOOP: |
946 // If there are phi copies after the condition, we cannot emit | |
947 // a pretty do/while loop, se we fallback to the generic | |
948 // emission of a loop. | |
949 CopyHandler handler = variableNames.getCopyHandler(info.end); | |
950 if (handler != null && !handler.isEmpty) return false; | |
951 if (info.initializer != null) { | 946 if (info.initializer != null) { |
952 generateStatements(info.initializer); | 947 generateStatements(info.initializer); |
953 } | 948 } |
954 js.Block oldContainer = currentContainer; | 949 js.Block oldContainer = currentContainer; |
955 js.Statement body = new js.Block.empty(); | 950 js.Statement body = new js.Block.empty(); |
| 951 // If there are phi copies in the block that jumps to the |
| 952 // loop entry, we must emit the condition like this: |
| 953 // do { |
| 954 // body; |
| 955 // if (condition) { |
| 956 // phi updates; |
| 957 // continue; |
| 958 // } else { |
| 959 // break; |
| 960 // } |
| 961 // } while (true); |
| 962 HBasicBlock avoidEdge = info.end.successors[0]; |
| 963 js.Statement updateBody = new js.Block.empty(); |
| 964 currentContainer = updateBody; |
| 965 assignPhisOfSuccessors(avoidEdge); |
| 966 bool hasPhiUpdates = !updateBody.statements.isEmpty; |
956 currentContainer = body; | 967 currentContainer = body; |
957 if (!isConditionExpression || info.updates != null) { | 968 if (hasPhiUpdates || !isConditionExpression || info.updates != null) { |
958 wrapLoopBodyForContinue(info); | 969 wrapLoopBodyForContinue(info); |
959 } else { | 970 } else { |
960 visitBodyIgnoreLabels(info); | 971 visitBodyIgnoreLabels(info); |
961 } | 972 } |
962 if (info.updates != null) { | 973 if (info.updates != null) { |
963 generateStatements(info.updates); | 974 generateStatements(info.updates); |
964 } | 975 } |
965 if (condition == null) { | 976 if (condition == null) { |
966 push(newLiteralBool(false)); | 977 push(newLiteralBool(false)); |
967 } else if (isConditionExpression) { | 978 } else if (isConditionExpression) { |
968 push(generateExpression(condition)); | 979 push(generateExpression(condition)); |
969 } else { | 980 } else { |
970 generateStatements(condition); | 981 generateStatements(condition); |
971 use(condition.conditionExpression); | 982 use(condition.conditionExpression); |
972 } | 983 } |
973 js.Expression jsCondition = pop(); | 984 js.Expression jsCondition = pop(); |
| 985 if (hasPhiUpdates) { |
| 986 updateBody.statements.add(new js.Continue(null)); |
| 987 body.statements.add( |
| 988 new js.If(jsCondition, updateBody, new js.Break(null))); |
| 989 } |
| 990 loop = new js.Do(unwrapStatement(body), jsCondition); |
974 currentContainer = oldContainer; | 991 currentContainer = oldContainer; |
975 body = unwrapStatement(body); | |
976 loop = new js.Do(body, jsCondition); | |
977 break; | 992 break; |
978 default: | 993 default: |
979 compiler.internalError( | 994 compiler.internalError( |
980 'Unexpected loop kind: ${info.kind}', | 995 'Unexpected loop kind: ${info.kind}', |
981 instruction: condition.conditionExpression); | 996 instruction: condition.conditionExpression); |
982 } | 997 } |
983 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition); | 998 attachLocationRange(loop, info.sourcePosition, info.endSourcePosition); |
984 pushStatement(wrapIntoLabels(loop, info.labels)); | 999 pushStatement(wrapIntoLabels(loop, info.labels)); |
985 return true; | 1000 return true; |
986 } | 1001 } |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 void iterateBasicBlock(HBasicBlock node) { | 1252 void iterateBasicBlock(HBasicBlock node) { |
1238 HInstruction instruction = node.first; | 1253 HInstruction instruction = node.first; |
1239 while (!identical(instruction, node.last)) { | 1254 while (!identical(instruction, node.last)) { |
1240 if (instruction is HTypeGuard || instruction is HBailoutTarget) { | 1255 if (instruction is HTypeGuard || instruction is HBailoutTarget) { |
1241 visit(instruction); | 1256 visit(instruction); |
1242 } else if (!isGenerateAtUseSite(instruction)) { | 1257 } else if (!isGenerateAtUseSite(instruction)) { |
1243 define(instruction); | 1258 define(instruction); |
1244 } | 1259 } |
1245 instruction = instruction.next; | 1260 instruction = instruction.next; |
1246 } | 1261 } |
1247 if (instruction is HLoopBranch) { | 1262 assignPhisOfSuccessors(node); |
1248 HLoopBranch branch = instruction; | |
1249 // If the loop is a do/while loop, the phi updates must happen | |
1250 // after the evaluation of the condition. | |
1251 if (!branch.isDoWhile()) { | |
1252 assignPhisOfSuccessors(node); | |
1253 } | |
1254 } else { | |
1255 assignPhisOfSuccessors(node); | |
1256 } | |
1257 visit(instruction); | 1263 visit(instruction); |
1258 } | 1264 } |
1259 | 1265 |
1260 visitInvokeBinary(HInvokeBinary node, String op) { | 1266 visitInvokeBinary(HInvokeBinary node, String op) { |
1261 if (node.isBuiltin(types)) { | 1267 if (node.isBuiltin(types)) { |
1262 use(node.left); | 1268 use(node.left); |
1263 js.Expression jsLeft = pop(); | 1269 js.Expression jsLeft = pop(); |
1264 use(node.right); | 1270 use(node.right); |
1265 push(new js.Binary(op, jsLeft, pop()), node); | 1271 push(new js.Binary(op, jsLeft, pop()), node); |
1266 } else { | 1272 } else { |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1863 // Otherwise, we don't generate the expression, and leave that | 1869 // Otherwise, we don't generate the expression, and leave that |
1864 // to the code that called [visitSubGraph]. | 1870 // to the code that called [visitSubGraph]. |
1865 if (isGeneratingExpression) { | 1871 if (isGeneratingExpression) { |
1866 use(node.inputs[0]); | 1872 use(node.inputs[0]); |
1867 } | 1873 } |
1868 return; | 1874 return; |
1869 } | 1875 } |
1870 HBasicBlock branchBlock = currentBlock; | 1876 HBasicBlock branchBlock = currentBlock; |
1871 handleLoopCondition(node); | 1877 handleLoopCondition(node); |
1872 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; | 1878 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; |
1873 if (node.isDoWhile()) { | 1879 if (!node.isDoWhile()) { |
1874 // Now that the condition has been evaluated, we can update the | |
1875 // phis of a do/while loop. | |
1876 assignPhisOfSuccessors(node.block); | |
1877 } else { | |
1878 // For a do while loop, the body has already been visited. | 1880 // For a do while loop, the body has already been visited. |
1879 visitBasicBlock(dominated[0]); | 1881 visitBasicBlock(dominated[0]); |
1880 } | 1882 } |
1881 endLoop(node.block); | 1883 endLoop(node.block); |
1882 | 1884 |
1883 // If the branch does not dominate the code after the loop, the | 1885 // If the branch does not dominate the code after the loop, the |
1884 // dominator will visit it. | 1886 // dominator will visit it. |
1885 if (!identical(branchBlock.successors[1].dominator, branchBlock)) return; | 1887 if (!identical(branchBlock.successors[1].dominator, branchBlock)) return; |
1886 | 1888 |
1887 visitBasicBlock(branchBlock.successors[1]); | 1889 visitBasicBlock(branchBlock.successors[1]); |
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3103 if (leftType.canBeNull() && rightType.canBeNull()) { | 3105 if (leftType.canBeNull() && rightType.canBeNull()) { |
3104 if (left.isConstantNull() || right.isConstantNull() || | 3106 if (left.isConstantNull() || right.isConstantNull() || |
3105 (leftType.isPrimitive() && leftType == rightType)) { | 3107 (leftType.isPrimitive() && leftType == rightType)) { |
3106 return '=='; | 3108 return '=='; |
3107 } | 3109 } |
3108 return null; | 3110 return null; |
3109 } else { | 3111 } else { |
3110 return '==='; | 3112 return '==='; |
3111 } | 3113 } |
3112 } | 3114 } |
OLD | NEW |