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 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 |