| 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 final SourceInformationStrategy sourceInformationFactory; | 10 final SourceInformationStrategy sourceInformationFactory; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 currentContainer = new js.Block.empty(), | 145 currentContainer = new js.Block.empty(), |
| 146 parameters = <js.Parameter>[], | 146 parameters = <js.Parameter>[], |
| 147 expressionStack = <js.Expression>[], | 147 expressionStack = <js.Expression>[], |
| 148 oldContainerStack = <js.Block>[], | 148 oldContainerStack = <js.Block>[], |
| 149 generateAtUseSite = new Set<HInstruction>(), | 149 generateAtUseSite = new Set<HInstruction>(), |
| 150 controlFlowOperators = new Set<HInstruction>(), | 150 controlFlowOperators = new Set<HInstruction>(), |
| 151 breakAction = new Map<Entity, EntityAction>(), | 151 breakAction = new Map<Entity, EntityAction>(), |
| 152 continueAction = new Map<Entity, EntityAction>(); | 152 continueAction = new Map<Entity, EntityAction>(); |
| 153 | 153 |
| 154 Compiler get compiler => backend.compiler; | 154 Compiler get compiler => backend.compiler; |
| 155 |
| 155 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter; | 156 NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter; |
| 157 |
| 156 CodegenRegistry get registry => work.registry; | 158 CodegenRegistry get registry => work.registry; |
| 159 |
| 157 native.NativeEnqueuer get nativeEnqueuer { | 160 native.NativeEnqueuer get nativeEnqueuer { |
| 158 return compiler.enqueuer.codegen.nativeEnqueuer; | 161 return compiler.enqueuer.codegen.nativeEnqueuer; |
| 159 } | 162 } |
| 160 | 163 |
| 164 DiagnosticReporter get reporter => compiler.reporter; |
| 165 |
| 161 bool isGenerateAtUseSite(HInstruction instruction) { | 166 bool isGenerateAtUseSite(HInstruction instruction) { |
| 162 return generateAtUseSite.contains(instruction); | 167 return generateAtUseSite.contains(instruction); |
| 163 } | 168 } |
| 164 | 169 |
| 165 bool hasNonBitOpUser(HInstruction instruction, Set<HPhi> phiSet) { | 170 bool hasNonBitOpUser(HInstruction instruction, Set<HPhi> phiSet) { |
| 166 for (HInstruction user in instruction.usedBy) { | 171 for (HInstruction user in instruction.usedBy) { |
| 167 if (user is HPhi) { | 172 if (user is HPhi) { |
| 168 if (!phiSet.contains(user)) { | 173 if (!phiSet.contains(user)) { |
| 169 phiSet.add(user); | 174 phiSet.add(user); |
| 170 if (hasNonBitOpUser(user, phiSet)) return true; | 175 if (hasNonBitOpUser(user, phiSet)) return true; |
| (...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 body.statements.add( | 933 body.statements.add( |
| 929 new js.If(jsCondition, updateBody, exitLoop)); | 934 new js.If(jsCondition, updateBody, exitLoop)); |
| 930 jsCondition = newLiteralBool(true, info.sourceInformation); | 935 jsCondition = newLiteralBool(true, info.sourceInformation); |
| 931 } | 936 } |
| 932 loop = new js.Do(unwrapStatement(body), jsCondition) | 937 loop = new js.Do(unwrapStatement(body), jsCondition) |
| 933 .withSourceInformation(info.sourceInformation); | 938 .withSourceInformation(info.sourceInformation); |
| 934 } | 939 } |
| 935 currentContainer = oldContainer; | 940 currentContainer = oldContainer; |
| 936 break; | 941 break; |
| 937 default: | 942 default: |
| 938 compiler.internalError(condition.conditionExpression, | 943 reporter.internalError(condition.conditionExpression, |
| 939 'Unexpected loop kind: ${info.kind}.'); | 944 'Unexpected loop kind: ${info.kind}.'); |
| 940 } | 945 } |
| 941 js.Statement result = loop; | 946 js.Statement result = loop; |
| 942 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) { | 947 if (info.kind == HLoopBlockInformation.SWITCH_CONTINUE_LOOP) { |
| 943 String continueLabelString = | 948 String continueLabelString = |
| 944 backend.namer.implicitContinueLabelName(info.target); | 949 backend.namer.implicitContinueLabelName(info.target); |
| 945 result = new js.LabeledStatement(continueLabelString, result); | 950 result = new js.LabeledStatement(continueLabelString, result); |
| 946 } | 951 } |
| 947 pushStatement(wrapIntoLabels(result, info.labels)); | 952 pushStatement(wrapIntoLabels(result, info.labels)); |
| 948 return true; | 953 return true; |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 HBasicBlock block = node.block; | 1334 HBasicBlock block = node.block; |
| 1330 assert(block.successors.length == 1); | 1335 assert(block.successors.length == 1); |
| 1331 List<HBasicBlock> dominated = block.dominatedBlocks; | 1336 List<HBasicBlock> dominated = block.dominatedBlocks; |
| 1332 // With the exception of the entry-node which dominates its successor | 1337 // With the exception of the entry-node which dominates its successor |
| 1333 // and the exit node, no block finishing with a 'goto' can have more than | 1338 // and the exit node, no block finishing with a 'goto' can have more than |
| 1334 // one dominated block (since it has only one successor). | 1339 // one dominated block (since it has only one successor). |
| 1335 // If the successor is dominated by another block, then the other block | 1340 // If the successor is dominated by another block, then the other block |
| 1336 // is responsible for visiting the successor. | 1341 // is responsible for visiting the successor. |
| 1337 if (dominated.isEmpty) return; | 1342 if (dominated.isEmpty) return; |
| 1338 if (dominated.length > 2) { | 1343 if (dominated.length > 2) { |
| 1339 compiler.internalError(node, 'dominated.length = ${dominated.length}'); | 1344 reporter.internalError(node, 'dominated.length = ${dominated.length}'); |
| 1340 } | 1345 } |
| 1341 if (dominated.length == 2 && block != currentGraph.entry) { | 1346 if (dominated.length == 2 && block != currentGraph.entry) { |
| 1342 compiler.internalError(node, 'node.block != currentGraph.entry'); | 1347 reporter.internalError(node, 'node.block != currentGraph.entry'); |
| 1343 } | 1348 } |
| 1344 assert(dominated[0] == block.successors[0]); | 1349 assert(dominated[0] == block.successors[0]); |
| 1345 visitBasicBlock(dominated[0]); | 1350 visitBasicBlock(dominated[0]); |
| 1346 } | 1351 } |
| 1347 | 1352 |
| 1348 visitLoopBranch(HLoopBranch node) { | 1353 visitLoopBranch(HLoopBranch node) { |
| 1349 assert(node.block == subGraph.end); | 1354 assert(node.block == subGraph.end); |
| 1350 // We are generating code for a loop condition. | 1355 // We are generating code for a loop condition. |
| 1351 // If we are generating the subgraph as an expression, the | 1356 // If we are generating the subgraph as an expression, the |
| 1352 // condition will be generated as the expression. | 1357 // condition will be generated as the expression. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1423 // try/catch block, ie the try body is always a predecessor | 1428 // try/catch block, ie the try body is always a predecessor |
| 1424 // of the catch and finally. Here, we continue visiting the try | 1429 // of the catch and finally. Here, we continue visiting the try |
| 1425 // body by visiting the block that contains the user-level control | 1430 // body by visiting the block that contains the user-level control |
| 1426 // flow instruction. | 1431 // flow instruction. |
| 1427 visitBasicBlock(node.bodyTrySuccessor); | 1432 visitBasicBlock(node.bodyTrySuccessor); |
| 1428 } | 1433 } |
| 1429 | 1434 |
| 1430 visitTry(HTry node) { | 1435 visitTry(HTry node) { |
| 1431 // We should never get here. Try/catch/finally is always handled using block | 1436 // We should never get here. Try/catch/finally is always handled using block |
| 1432 // information in [visitTryInfo]. | 1437 // information in [visitTryInfo]. |
| 1433 compiler.internalError(node, 'visitTry should not be called.'); | 1438 reporter.internalError(node, 'visitTry should not be called.'); |
| 1434 } | 1439 } |
| 1435 | 1440 |
| 1436 bool tryControlFlowOperation(HIf node) { | 1441 bool tryControlFlowOperation(HIf node) { |
| 1437 if (!controlFlowOperators.contains(node)) return false; | 1442 if (!controlFlowOperators.contains(node)) return false; |
| 1438 HPhi phi = node.joinBlock.phis.first; | 1443 HPhi phi = node.joinBlock.phis.first; |
| 1439 bool atUseSite = isGenerateAtUseSite(phi); | 1444 bool atUseSite = isGenerateAtUseSite(phi); |
| 1440 // Don't generate a conditional operator in this situation: | 1445 // Don't generate a conditional operator in this situation: |
| 1441 // i = condition ? bar() : i; | 1446 // i = condition ? bar() : i; |
| 1442 // But generate this instead: | 1447 // But generate this instead: |
| 1443 // if (condition) i = bar(); | 1448 // if (condition) i = bar(); |
| (...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2696 return pop(); | 2701 return pop(); |
| 2697 } else if (checkedType.containsOnlyBool(classWorld)) { | 2702 } else if (checkedType.containsOnlyBool(classWorld)) { |
| 2698 // input is !bool | 2703 // input is !bool |
| 2699 checkBool(input, '!==', input.sourceInformation); | 2704 checkBool(input, '!==', input.sourceInformation); |
| 2700 return pop(); | 2705 return pop(); |
| 2701 } else if (checkedType.containsOnlyString(classWorld)) { | 2706 } else if (checkedType.containsOnlyString(classWorld)) { |
| 2702 // input is !string | 2707 // input is !string |
| 2703 checkString(input, '!==', input.sourceInformation); | 2708 checkString(input, '!==', input.sourceInformation); |
| 2704 return pop(); | 2709 return pop(); |
| 2705 } | 2710 } |
| 2706 compiler.internalError(input, 'Unexpected check: $checkedType.'); | 2711 reporter.internalError(input, 'Unexpected check: $checkedType.'); |
| 2707 return null; | 2712 return null; |
| 2708 } | 2713 } |
| 2709 | 2714 |
| 2710 void visitTypeConversion(HTypeConversion node) { | 2715 void visitTypeConversion(HTypeConversion node) { |
| 2711 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { | 2716 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { |
| 2712 ClassWorld classWorld = compiler.world; | 2717 ClassWorld classWorld = compiler.world; |
| 2713 // An int check if the input is not int or null, is not | 2718 // An int check if the input is not int or null, is not |
| 2714 // sufficient for doing an argument or receiver check. | 2719 // sufficient for doing an argument or receiver check. |
| 2715 assert(compiler.trustTypeAnnotations || | 2720 assert(compiler.trustTypeAnnotations || |
| 2716 !node.checkedType.containsOnlyInt(classWorld) || | 2721 !node.checkedType.containsOnlyInt(classWorld) || |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2872 } | 2877 } |
| 2873 registry.registerStaticUse(helper); | 2878 registry.registerStaticUse(helper); |
| 2874 return backend.emitter.staticFunctionAccess(helper); | 2879 return backend.emitter.staticFunctionAccess(helper); |
| 2875 } | 2880 } |
| 2876 | 2881 |
| 2877 @override | 2882 @override |
| 2878 void visitRef(HRef node) { | 2883 void visitRef(HRef node) { |
| 2879 visit(node.value); | 2884 visit(node.value); |
| 2880 } | 2885 } |
| 2881 } | 2886 } |
| OLD | NEW |