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 hasCopies = !updateBody.statements.isEmpty; | |
floitsch
2012/11/16 14:05:43
hasPhiUpdates ?
ngeoffray
2012/11/16 14:14:59
Done.
| |
956 currentContainer = body; | 967 currentContainer = body; |
957 if (!isConditionExpression || info.updates != null) { | 968 if (hasCopies || !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 (hasCopies) { | |
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 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1862 // Otherwise, we don't generate the expression, and leave that | 1868 // Otherwise, we don't generate the expression, and leave that |
1863 // to the code that called [visitSubGraph]. | 1869 // to the code that called [visitSubGraph]. |
1864 if (isGeneratingExpression) { | 1870 if (isGeneratingExpression) { |
1865 use(node.inputs[0]); | 1871 use(node.inputs[0]); |
1866 } | 1872 } |
1867 return; | 1873 return; |
1868 } | 1874 } |
1869 HBasicBlock branchBlock = currentBlock; | 1875 HBasicBlock branchBlock = currentBlock; |
1870 handleLoopCondition(node); | 1876 handleLoopCondition(node); |
1871 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; | 1877 List<HBasicBlock> dominated = currentBlock.dominatedBlocks; |
1872 if (node.isDoWhile()) { | 1878 if (!node.isDoWhile()) { |
1873 // Now that the condition has been evaluated, we can update the | |
1874 // phis of a do/while loop. | |
1875 assignPhisOfSuccessors(node.block); | |
1876 } else { | |
1877 // For a do while loop, the body has already been visited. | 1879 // For a do while loop, the body has already been visited. |
1878 visitBasicBlock(dominated[0]); | 1880 visitBasicBlock(dominated[0]); |
1879 } | 1881 } |
1880 endLoop(node.block); | 1882 endLoop(node.block); |
1881 | 1883 |
1882 // If the branch does not dominate the code after the loop, the | 1884 // If the branch does not dominate the code after the loop, the |
1883 // dominator will visit it. | 1885 // dominator will visit it. |
1884 if (!identical(branchBlock.successors[1].dominator, branchBlock)) return; | 1886 if (!identical(branchBlock.successors[1].dominator, branchBlock)) return; |
1885 | 1887 |
1886 visitBasicBlock(branchBlock.successors[1]); | 1888 visitBasicBlock(branchBlock.successors[1]); |
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3104 if (leftType.canBeNull() && rightType.canBeNull()) { | 3106 if (leftType.canBeNull() && rightType.canBeNull()) { |
3105 if (left.isConstantNull() || right.isConstantNull() || | 3107 if (left.isConstantNull() || right.isConstantNull() || |
3106 (leftType.isPrimitive() && leftType == rightType)) { | 3108 (leftType.isPrimitive() && leftType == rightType)) { |
3107 return '=='; | 3109 return '=='; |
3108 } | 3110 } |
3109 return null; | 3111 return null; |
3110 } else { | 3112 } else { |
3111 return '==='; | 3113 return '==='; |
3112 } | 3114 } |
3113 } | 3115 } |
OLD | NEW |