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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
6 final JavaScriptBackend backend; | 6 final JavaScriptBackend backend; |
7 SsaCodeGeneratorTask(JavaScriptBackend backend) | 7 SsaCodeGeneratorTask(JavaScriptBackend backend) |
8 : this.backend = backend, | 8 : this.backend = backend, |
9 super(backend.compiler); | 9 super(backend.compiler); |
10 String get name() => 'SSA code generator'; | 10 String get name() => 'SSA code generator'; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 static final int TYPE_STATEMENT = 0; | 140 static final int TYPE_STATEMENT = 0; |
141 static final int TYPE_EXPRESSION = 1; | 141 static final int TYPE_EXPRESSION = 1; |
142 static final int TYPE_DECLARATION = 2; | 142 static final int TYPE_DECLARATION = 2; |
143 | 143 |
144 final JavaScriptBackend backend; | 144 final JavaScriptBackend backend; |
145 final WorkItem work; | 145 final WorkItem work; |
146 final StringBuffer buffer; | 146 final StringBuffer buffer; |
147 final String parameters; | 147 final String parameters; |
148 | 148 |
149 final Set<HInstruction> generateAtUseSite; | 149 final Set<HInstruction> generateAtUseSite; |
150 final Map<HPhi, String> logicalOperations; | 150 final Set<HInstruction> logicalOperations; |
151 final Map<Element, ElementAction> breakAction; | 151 final Map<Element, ElementAction> breakAction; |
152 final Map<Element, ElementAction> continueAction; | 152 final Map<Element, ElementAction> continueAction; |
153 final Map<Element, String> parameterNames; | 153 final Map<Element, String> parameterNames; |
154 | 154 |
155 /** | 155 /** |
156 * Contains the names of the instructions, as well as the parallel | 156 * Contains the names of the instructions, as well as the parallel |
157 * copies to perform on block transitioning. | 157 * copies to perform on block transitioning. |
158 */ | 158 */ |
159 VariableNames variableNames; | 159 VariableNames variableNames; |
160 | 160 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 } | 199 } |
200 | 200 |
201 SsaCodeGenerator(this.backend, | 201 SsaCodeGenerator(this.backend, |
202 this.work, | 202 this.work, |
203 this.parameters, | 203 this.parameters, |
204 this.parameterNames) | 204 this.parameterNames) |
205 : declaredVariables = new Set<String>(), | 205 : declaredVariables = new Set<String>(), |
206 delayedVariablesDeclaration = new List<String>(), | 206 delayedVariablesDeclaration = new List<String>(), |
207 buffer = new StringBuffer(), | 207 buffer = new StringBuffer(), |
208 generateAtUseSite = new Set<HInstruction>(), | 208 generateAtUseSite = new Set<HInstruction>(), |
209 logicalOperations = new Map<HPhi, String>(), | 209 logicalOperations = new Set<HInstruction>(), |
210 breakAction = new Map<Element, ElementAction>(), | 210 breakAction = new Map<Element, ElementAction>(), |
211 continueAction = new Map<Element, ElementAction>(), | 211 continueAction = new Map<Element, ElementAction>(), |
212 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] { | 212 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] { |
213 | 213 |
214 Interceptors interceptors = backend.builder.interceptors; | 214 Interceptors interceptors = backend.builder.interceptors; |
215 equalsNullElement = interceptors.getEqualsNullInterceptor(); | 215 equalsNullElement = interceptors.getEqualsNullInterceptor(); |
216 boolifiedEqualsNullElement = | 216 boolifiedEqualsNullElement = |
217 interceptors.getBoolifiedVersionOf(equalsNullElement); | 217 interceptors.getBoolifiedVersionOf(equalsNullElement); |
218 } | 218 } |
219 | 219 |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 buffer.add("var "); | 480 buffer.add("var "); |
481 } | 481 } |
482 buffer.add(variableName); | 482 buffer.add(variableName); |
483 } | 483 } |
484 | 484 |
485 void declareInstruction(HInstruction instruction) { | 485 void declareInstruction(HInstruction instruction) { |
486 declareVariable(variableNames.getName(instruction)); | 486 declareVariable(variableNames.getName(instruction)); |
487 } | 487 } |
488 | 488 |
489 void define(HInstruction instruction) { | 489 void define(HInstruction instruction) { |
| 490 if (isGeneratingExpression()) { |
| 491 addExpressionSeparator(); |
| 492 } else { |
| 493 addIndentation(); |
| 494 } |
490 if (instruction is !HCheck && variableNames.hasName(instruction)) { | 495 if (instruction is !HCheck && variableNames.hasName(instruction)) { |
491 declareInstruction(instruction); | 496 declareInstruction(instruction); |
492 buffer.add(" = "); | 497 buffer.add(" = "); |
493 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 498 visit(instruction, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
494 } else { | 499 } else { |
495 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 500 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
496 } | 501 } |
| 502 if (!isGeneratingExpression()) buffer.add(';\n'); |
497 } | 503 } |
498 | 504 |
499 void use(HInstruction argument, int expectedPrecedenceForArgument) { | 505 void use(HInstruction argument, int expectedPrecedenceForArgument) { |
500 if (isGenerateAtUseSite(argument)) { | 506 if (isGenerateAtUseSite(argument)) { |
501 visit(argument, expectedPrecedenceForArgument); | 507 visit(argument, expectedPrecedenceForArgument); |
502 } else if (argument is HCheck) { | 508 } else if (argument is HCheck) { |
503 HCheck check = argument; | 509 HCheck check = argument; |
504 use(argument.checkedInput, expectedPrecedenceForArgument); | 510 use(argument.checkedInput, expectedPrecedenceForArgument); |
505 } else { | 511 } else { |
506 buffer.add(variableNames.getName(argument)); | 512 buffer.add(variableNames.getName(argument)); |
(...skipping 19 matching lines...) Expand all Loading... |
526 buffer.add(";\n"); | 532 buffer.add(";\n"); |
527 } | 533 } |
528 | 534 |
529 void implicitBreakWithLabel(TargetElement target) { | 535 void implicitBreakWithLabel(TargetElement target) { |
530 addIndented("break "); | 536 addIndented("break "); |
531 writeImplicitLabel(target); | 537 writeImplicitLabel(target); |
532 buffer.add(";\n"); | 538 buffer.add(";\n"); |
533 } | 539 } |
534 | 540 |
535 bool visitIfInfo(HIfBlockInformation info) { | 541 bool visitIfInfo(HIfBlockInformation info) { |
| 542 // If the [HIf] instruction is actually a logical operation, we |
| 543 // let the flow-based traversal handle it. |
| 544 if (logicalOperations.contains(info.condition.end.last)) return false; |
536 HInstruction condition = info.condition.conditionExpression; | 545 HInstruction condition = info.condition.conditionExpression; |
537 if (condition.isConstant()) { | 546 if (condition.isConstant()) { |
538 // If the condition is constant, only generate one branch (if any). | 547 // If the condition is constant, only generate one branch (if any). |
539 HConstant constantCondition = condition; | 548 HConstant constantCondition = condition; |
540 Constant constant = constantCondition.constant; | 549 Constant constant = constantCondition.constant; |
541 generateStatements(info.condition); | 550 generateStatements(info.condition); |
542 if (constant.isTrue()) { | 551 if (constant.isTrue()) { |
543 generateStatements(info.thenGraph); | 552 generateStatements(info.thenGraph); |
544 } else if (info.elseGraph !== null) { | 553 } else if (info.elseGraph !== null) { |
545 generateStatements(info.elseGraph); | 554 generateStatements(info.elseGraph); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 while (!continueOverrides.isEmpty()) { | 811 while (!continueOverrides.isEmpty()) { |
803 continueAction.remove(continueOverrides.head); | 812 continueAction.remove(continueOverrides.head); |
804 continueOverrides = continueOverrides.tail; | 813 continueOverrides = continueOverrides.tail; |
805 } | 814 } |
806 } else { | 815 } else { |
807 breakAction.remove(labeledBlockInfo.target); | 816 breakAction.remove(labeledBlockInfo.target); |
808 } | 817 } |
809 return true; | 818 return true; |
810 } | 819 } |
811 | 820 |
812 void emitLogicalOperation(HPhi node, String operation) { | |
813 JSBinaryOperatorPrecedence operatorPrecedence = | |
814 JSPrecedence.binary[operation]; | |
815 beginExpression(operatorPrecedence.precedence); | |
816 use(node.inputs[0], operatorPrecedence.left); | |
817 buffer.add(" $operation "); | |
818 use(node.inputs[1], operatorPrecedence.right); | |
819 endExpression(operatorPrecedence.precedence); | |
820 } | |
821 | |
822 // Wraps a loop body in a block to make continues have a target to break | 821 // Wraps a loop body in a block to make continues have a target to break |
823 // to (if necessary). | 822 // to (if necessary). |
824 void wrapLoopBodyForContinue(HLoopBlockInformation info) { | 823 void wrapLoopBodyForContinue(HLoopBlockInformation info) { |
825 TargetElement target = info.target; | 824 TargetElement target = info.target; |
826 if (target !== null && target.isContinueTarget) { | 825 if (target !== null && target.isContinueTarget) { |
827 addIndentation(); | 826 addIndentation(); |
828 for (LabelElement label in info.labels) { | 827 for (LabelElement label in info.labels) { |
829 if (label.isContinueTarget) { | 828 if (label.isContinueTarget) { |
830 writeContinueLabel(label); | 829 writeContinueLabel(label); |
831 buffer.add(":"); | 830 buffer.add(":"); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 buffer.add(' = '); | 1004 buffer.add(' = '); |
1006 use(copy.source, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 1005 use(copy.source, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
1007 if (!isGeneratingExpression()) { | 1006 if (!isGeneratingExpression()) { |
1008 buffer.add(';\n'); | 1007 buffer.add(';\n'); |
1009 } | 1008 } |
1010 } | 1009 } |
1011 } | 1010 } |
1012 | 1011 |
1013 void iterateBasicBlock(HBasicBlock node) { | 1012 void iterateBasicBlock(HBasicBlock node) { |
1014 HInstruction instruction = node.first; | 1013 HInstruction instruction = node.first; |
1015 while (instruction != null) { | 1014 while (instruction !== node.last) { |
1016 if (instruction === node.last) { | 1015 if (instruction is HTypeGuard) { |
1017 assignPhisOfSuccessors(node); | |
1018 } | |
1019 | |
1020 if (isGenerateAtUseSite(instruction)) { | |
1021 if (instruction is HIf) { | |
1022 HIf hif = instruction; | |
1023 // The "if" is implementing part of a logical expression. | |
1024 // Skip directly forward to to its latest successor, since everything | |
1025 // in-between must also be generateAtUseSite. | |
1026 assert(hif.trueBranch.id < hif.falseBranch.id); | |
1027 visitBasicBlock(hif.falseBranch); | |
1028 } | |
1029 } else if (instruction is HControlFlow) { | |
1030 if (instruction is HLoopBranch && isGeneratingExpression()) { | |
1031 addExpressionSeparator(); | |
1032 } | |
1033 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | 1016 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
1034 } else if (instruction is HTypeGuard) { | 1017 } else if (!isGenerateAtUseSite(instruction)) { |
1035 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); | |
1036 } else { | |
1037 if (isGeneratingExpression()) { | |
1038 addExpressionSeparator(); | |
1039 } else { | |
1040 addIndentation(); | |
1041 } | |
1042 define(instruction); | 1018 define(instruction); |
1043 if (!isGeneratingExpression()) buffer.add(';\n'); | |
1044 } | 1019 } |
1045 instruction = instruction.next; | 1020 instruction = instruction.next; |
1046 } | 1021 } |
| 1022 assignPhisOfSuccessors(node); |
| 1023 if (instruction is HLoopBranch && isGeneratingExpression()) { |
| 1024 addExpressionSeparator(); |
| 1025 } |
| 1026 visit(instruction, JSPrecedence.STATEMENT_PRECEDENCE); |
1047 } | 1027 } |
1048 | 1028 |
1049 visitInvokeBinary(HInvokeBinary node, String op) { | 1029 visitInvokeBinary(HInvokeBinary node, String op) { |
1050 if (node.builtin) { | 1030 if (node.builtin) { |
1051 JSBinaryOperatorPrecedence operatorPrecedences = JSPrecedence.binary[op]; | 1031 JSBinaryOperatorPrecedence operatorPrecedences = JSPrecedence.binary[op]; |
1052 beginExpression(operatorPrecedences.precedence); | 1032 beginExpression(operatorPrecedences.precedence); |
1053 use(node.left, operatorPrecedences.left); | 1033 use(node.left, operatorPrecedences.left); |
1054 buffer.add(' $op '); | 1034 buffer.add(' $op '); |
1055 use(node.right, operatorPrecedences.right); | 1035 use(node.right, operatorPrecedences.right); |
1056 endExpression(operatorPrecedences.precedence); | 1036 endExpression(operatorPrecedences.precedence); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 compiler.internalError('visitTry should not be called', instruction: node); | 1236 compiler.internalError('visitTry should not be called', instruction: node); |
1257 } | 1237 } |
1258 | 1238 |
1259 bool isEmptyElse(HBasicBlock start, HBasicBlock end) { | 1239 bool isEmptyElse(HBasicBlock start, HBasicBlock end) { |
1260 if (start !== end) return false; | 1240 if (start !== end) return false; |
1261 if (start.last is !HGoto | 1241 if (start.last is !HGoto |
1262 || start.last is HBreak | 1242 || start.last is HBreak |
1263 || start.last is HContinue) { | 1243 || start.last is HContinue) { |
1264 return false; | 1244 return false; |
1265 } | 1245 } |
1266 HInstruction instruction = start.first; | |
1267 for (HInstruction instruction = start.first; | 1246 for (HInstruction instruction = start.first; |
1268 instruction != start.last; | 1247 instruction != start.last; |
1269 instruction = instruction.next) { | 1248 instruction = instruction.next) { |
1270 // Instructions generated at use site are okay because they do | 1249 // Instructions generated at use site are okay because they do |
1271 // not generate code in this else block. | 1250 // not generate code in this else block. |
1272 if (!isGenerateAtUseSite(instruction)) return false; | 1251 if (!isGenerateAtUseSite(instruction)) return false; |
1273 } | 1252 } |
1274 CopyHandler handler = variableNames.getCopyHandler(start); | 1253 CopyHandler handler = variableNames.getCopyHandler(start); |
1275 if (handler == null || handler.isEmpty()) return true; | 1254 if (handler == null || handler.isEmpty()) return true; |
1276 if (!handler.assignments.isEmpty()) return false; | 1255 if (!handler.assignments.isEmpty()) return false; |
1277 // If the block has a copy where the destination and source are | 1256 // If the block has a copy where the destination and source are |
1278 // different, we will emit that copy, and therefore the block is | 1257 // different, we will emit that copy, and therefore the block is |
1279 // not empty. | 1258 // not empty. |
1280 for (Copy copy in handler.copies) { | 1259 for (Copy copy in handler.copies) { |
1281 String sourceName = variableNames.getName(copy.source); | 1260 String sourceName = variableNames.getName(copy.source); |
1282 String destinationName = variableNames.getName(copy.destination); | 1261 String destinationName = variableNames.getName(copy.destination); |
1283 if (sourceName != destinationName) return false; | 1262 if (sourceName != destinationName) return false; |
1284 } | 1263 } |
1285 return true; | 1264 return true; |
1286 } | 1265 } |
1287 | 1266 |
1288 visitIf(HIf node) { | 1267 visitIf(HIf node) { |
| 1268 if (logicalOperations.contains(node)) { |
| 1269 HPhi phi = node.joinBlock.phis.first; |
| 1270 if (!isGenerateAtUseSite(phi)) define(phi); |
| 1271 visitBasicBlock(node.joinBlock); |
| 1272 return; |
| 1273 } |
| 1274 |
1289 if (subGraph !== null && node.block === subGraph.end) { | 1275 if (subGraph !== null && node.block === subGraph.end) { |
1290 if (isGeneratingExpression()) { | 1276 if (isGeneratingExpression()) { |
1291 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); | 1277 use(node.inputs[0], JSPrecedence.EXPRESSION_PRECEDENCE); |
1292 } | 1278 } |
1293 return; | 1279 return; |
1294 } | 1280 } |
| 1281 |
1295 HInstruction condition = node.inputs[0]; | 1282 HInstruction condition = node.inputs[0]; |
1296 int preVisitedBlocks = 0; | 1283 int preVisitedBlocks = 0; |
1297 List<HBasicBlock> dominated = node.block.dominatedBlocks; | 1284 List<HBasicBlock> dominated = node.block.dominatedBlocks; |
1298 HIfBlockInformation info = node.blockInformation.body; | 1285 HIfBlockInformation info = node.blockInformation.body; |
1299 HBasicBlock joinBlock = node.joinBlock; | 1286 HBasicBlock joinBlock = node.joinBlock; |
1300 if (condition.isConstant()) { | 1287 if (condition.isConstant()) { |
1301 HConstant constant = condition; | 1288 HConstant constant = condition; |
1302 if (constant.constant.isTrue()) { | 1289 if (constant.constant.isTrue()) { |
1303 generateStatements(info.thenGraph); | 1290 generateStatements(info.thenGraph); |
1304 } else if (node.hasElse) { | 1291 } else if (node.hasElse) { |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 visitBasicBlock(branchBlock.successors[1]); | 1567 visitBasicBlock(branchBlock.successors[1]); |
1581 // With labeled breaks we can have more dominated blocks. | 1568 // With labeled breaks we can have more dominated blocks. |
1582 if (dominated.length >= 3) { | 1569 if (dominated.length >= 3) { |
1583 for (int i = 2; i < dominated.length; i++) { | 1570 for (int i = 2; i < dominated.length; i++) { |
1584 visitBasicBlock(dominated[i]); | 1571 visitBasicBlock(dominated[i]); |
1585 } | 1572 } |
1586 } | 1573 } |
1587 } | 1574 } |
1588 | 1575 |
1589 visitNot(HNot node) { | 1576 visitNot(HNot node) { |
| 1577 assert(node.inputs.length == 1); |
| 1578 generateNot(node.inputs[0]); |
| 1579 } |
| 1580 |
| 1581 |
| 1582 void generateNot(HInstruction input) { |
1590 bool isBuiltinRelational(HInstruction instruction) { | 1583 bool isBuiltinRelational(HInstruction instruction) { |
1591 if (instruction is !HRelational) return false; | 1584 if (instruction is !HRelational) return false; |
1592 HRelational relational = instruction; | 1585 HRelational relational = instruction; |
1593 return relational.builtin; | 1586 return relational.builtin; |
1594 } | 1587 } |
1595 | 1588 |
1596 assert(node.inputs.length == 1); | |
1597 HInstruction input = node.inputs[0]; | |
1598 if (input is HBoolify && isGenerateAtUseSite(input)) { | 1589 if (input is HBoolify && isGenerateAtUseSite(input)) { |
1599 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); | 1590 beginExpression(JSPrecedence.EQUALITY_PRECEDENCE); |
1600 assert(node.inputs.length == 1); | |
1601 use(input.inputs[0], JSPrecedence.EQUALITY_PRECEDENCE); | 1591 use(input.inputs[0], JSPrecedence.EQUALITY_PRECEDENCE); |
1602 buffer.add(' !== true'); | 1592 buffer.add(' !== true'); |
1603 endExpression(JSPrecedence.EQUALITY_PRECEDENCE); | 1593 endExpression(JSPrecedence.EQUALITY_PRECEDENCE); |
1604 } else if (isBuiltinRelational(input) && | 1594 } else if (isBuiltinRelational(input) && |
1605 isGenerateAtUseSite(input) && | 1595 isGenerateAtUseSite(input) && |
1606 input.inputs[0].propagatedType.isUseful() && | 1596 input.inputs[0].propagatedType.isUseful() && |
1607 !input.inputs[0].isDouble() && | 1597 !input.inputs[0].isDouble() && |
1608 input.inputs[1].propagatedType.isUseful() && | 1598 input.inputs[1].propagatedType.isUseful() && |
1609 !input.inputs[1].isDouble()) { | 1599 !input.inputs[1].isDouble()) { |
1610 // This optimization doesn't work for NaN, so we only do it if the | 1600 // This optimization doesn't work for NaN, so we only do it if the |
(...skipping 18 matching lines...) Expand all Loading... |
1629 endExpression(JSPrecedence.PREFIX_PRECEDENCE); | 1619 endExpression(JSPrecedence.PREFIX_PRECEDENCE); |
1630 } | 1620 } |
1631 } | 1621 } |
1632 | 1622 |
1633 visitParameterValue(HParameterValue node) { | 1623 visitParameterValue(HParameterValue node) { |
1634 assert(isGenerateAtUseSite(node)); | 1624 assert(isGenerateAtUseSite(node)); |
1635 buffer.add(variableNames.getName(node)); | 1625 buffer.add(variableNames.getName(node)); |
1636 } | 1626 } |
1637 | 1627 |
1638 visitPhi(HPhi node) { | 1628 visitPhi(HPhi node) { |
1639 String operation = logicalOperations[node]; | 1629 HBasicBlock ifBlock = node.block.predecessors[0].predecessors[0]; |
1640 if (operation !== null) { | 1630 // This method is only called for phis that are generated at use |
1641 emitLogicalOperation(node, operation); | 1631 // site. A phi can be generated at use site only if it is the |
| 1632 // result of a logical operation. |
| 1633 assert(logicalOperations.contains(ifBlock.last)); |
| 1634 HInstruction input = ifBlock.last.inputs[0]; |
| 1635 if (input.isConstantFalse()) { |
| 1636 use(node.inputs[1], expectedPrecedence); |
| 1637 } else if (input.isConstantTrue()) { |
| 1638 use(node.inputs[0], expectedPrecedence); |
1642 } else { | 1639 } else { |
1643 buffer.add('${variableNames.getName(node)}'); | 1640 String operation = node.inputs[1].isConstantFalse() ? '&&' : '||'; |
| 1641 JSBinaryOperatorPrecedence operatorPrecedence = |
| 1642 JSPrecedence.binary[operation]; |
| 1643 beginExpression(operatorPrecedence.precedence); |
| 1644 if (operation == '||') { |
| 1645 if (input is HNot) { |
| 1646 use(input.inputs[0], operatorPrecedence.left); |
| 1647 } else { |
| 1648 generateNot(input); |
| 1649 } |
| 1650 } else { |
| 1651 use(input, operatorPrecedence.left); |
| 1652 } |
| 1653 buffer.add(" $operation "); |
| 1654 use(node.inputs[0], operatorPrecedence.right); |
| 1655 endExpression(operatorPrecedence.precedence); |
1644 } | 1656 } |
1645 } | 1657 } |
1646 | 1658 |
1647 visitReturn(HReturn node) { | 1659 visitReturn(HReturn node) { |
1648 addIndentation(); | 1660 addIndentation(); |
1649 assert(node.inputs.length == 1); | 1661 assert(node.inputs.length == 1); |
1650 HInstruction input = node.inputs[0]; | 1662 HInstruction input = node.inputs[0]; |
1651 if (input.isConstantNull()) { | 1663 if (input.isConstantNull()) { |
1652 buffer.add('return;\n'); | 1664 buffer.add('return;\n'); |
1653 } else { | 1665 } else { |
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2505 startBailoutSwitch(); | 2517 startBailoutSwitch(); |
2506 } | 2518 } |
2507 } | 2519 } |
2508 | 2520 |
2509 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2521 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
2510 if (labeledBlockInfo.body.start.hasGuards()) { | 2522 if (labeledBlockInfo.body.start.hasGuards()) { |
2511 endBailoutSwitch(); | 2523 endBailoutSwitch(); |
2512 } | 2524 } |
2513 } | 2525 } |
2514 } | 2526 } |
OLD | NEW |