Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 14071003: Fix first part on liveness analysis of bug https://code.google.com/p/dart/issues/detail?id=9687: a … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 if (name == const SourceString('==')) { 933 if (name == const SourceString('==')) {
934 if (!backend.operatorEqHandlesNullArgument(functionElement)) { 934 if (!backend.operatorEqHandlesNullArgument(functionElement)) {
935 handleIf( 935 handleIf(
936 function, 936 function,
937 () { 937 () {
938 HParameterValue parameter = parameters.values.first; 938 HParameterValue parameter = parameters.values.first;
939 push(new HIdentity( 939 push(new HIdentity(
940 parameter, graph.addConstantNull(constantSystem))); 940 parameter, graph.addConstantNull(constantSystem)));
941 }, 941 },
942 () { 942 () {
943 HReturn ret = new HReturn( 943 closeAndGotoExit(new HReturn(
944 graph.addConstantBool(false, constantSystem)); 944 graph.addConstantBool(false, constantSystem)));
945 close(ret).addSuccessor(graph.exit);
946 }, 945 },
947 null); 946 null);
948 } 947 }
949 } 948 }
950 function.body.accept(this); 949 function.body.accept(this);
951 return closeFunction(); 950 return closeFunction();
952 } 951 }
953 952
954 HGraph buildLazyInitializer(VariableElement variable) { 953 HGraph buildLazyInitializer(VariableElement variable) {
955 SendSet node = variable.parseNode(compiler); 954 SendSet node = variable.parseNode(compiler);
956 openFunction(variable, node); 955 openFunction(variable, node);
957 Link<Node> link = node.arguments; 956 Link<Node> link = node.arguments;
958 assert(!link.isEmpty && link.tail.isEmpty); 957 assert(!link.isEmpty && link.tail.isEmpty);
959 visit(link.head); 958 visit(link.head);
960 HInstruction value = pop(); 959 HInstruction value = pop();
961 value = potentiallyCheckType(value, variable.computeType(compiler)); 960 value = potentiallyCheckType(value, variable.computeType(compiler));
962 close(new HReturn(value)).addSuccessor(graph.exit); 961 closeAndGotoExit(new HReturn(value));
963 return closeFunction(); 962 return closeFunction();
964 } 963 }
965 964
966 /** 965 /**
967 * Returns the constructor body associated with the given constructor or 966 * Returns the constructor body associated with the given constructor or
968 * creates a new constructor body, if none can be found. 967 * creates a new constructor body, if none can be found.
969 * 968 *
970 * Returns [:null:] if the constructor does not have a body. 969 * Returns [:null:] if the constructor does not have a body.
971 */ 970 */
972 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 971 ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 // these selectors. Maybe the resolver can do more of the work 1528 // these selectors. Maybe the resolver can do more of the work
1530 // for us here? 1529 // for us here?
1531 LibraryElement library = body.getLibrary(); 1530 LibraryElement library = body.getLibrary();
1532 Selector selector = new Selector.call( 1531 Selector selector = new Selector.call(
1533 name, library, bodyCallInputs.length - 1); 1532 name, library, bodyCallInputs.length - 1);
1534 HInvokeDynamic invoke = 1533 HInvokeDynamic invoke =
1535 new HInvokeDynamicMethod(selector, bodyCallInputs); 1534 new HInvokeDynamicMethod(selector, bodyCallInputs);
1536 invoke.element = body; 1535 invoke.element = body;
1537 add(invoke); 1536 add(invoke);
1538 } 1537 }
1539 close(new HReturn(newObject)).addSuccessor(graph.exit); 1538 closeAndGotoExit(new HReturn(newObject));
1540 return closeFunction(); 1539 return closeFunction();
1541 } 1540 }
1542 1541
1543 void addParameterCheckInstruction(Element element) { 1542 void addParameterCheckInstruction(Element element) {
1544 HInstruction check; 1543 HInstruction check;
1545 Element checkResultElement = 1544 Element checkResultElement =
1546 localsHandler.closureData.parametersWithSentinel[element]; 1545 localsHandler.closureData.parametersWithSentinel[element];
1547 if (currentElement.isGenerativeConstructorBody()) { 1546 if (currentElement.isGenerativeConstructorBody()) {
1548 // A generative constructor body receives extra parameters that 1547 // A generative constructor body receives extra parameters that
1549 // indicate if a parameter was passed to the factory. 1548 // indicate if a parameter was passed to the factory.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1657 HInstruction original, DartType type, 1656 HInstruction original, DartType type,
1658 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 1657 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
1659 if (!compiler.enableTypeAssertions) return original; 1658 if (!compiler.enableTypeAssertions) return original;
1660 HInstruction other = original.convertType(compiler, type, kind); 1659 HInstruction other = original.convertType(compiler, type, kind);
1661 if (other != original) add(other); 1660 if (other != original) add(other);
1662 return other; 1661 return other;
1663 } 1662 }
1664 1663
1665 HGraph closeFunction() { 1664 HGraph closeFunction() {
1666 // TODO(kasperl): Make this goto an implicit return. 1665 // TODO(kasperl): Make this goto an implicit return.
1667 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); 1666 if (!isAborted()) closeAndGotoExit(new HGoto());
1668 graph.finalize(); 1667 graph.finalize();
1669 return graph; 1668 return graph;
1670 } 1669 }
1671 1670
1672 HBasicBlock addNewBlock() { 1671 HBasicBlock addNewBlock() {
1673 HBasicBlock block = graph.addNewBlock(); 1672 HBasicBlock block = graph.addNewBlock();
1674 // If adding a new block during building of an expression, it is due to 1673 // If adding a new block during building of an expression, it is due to
1675 // conditional expressions or short-circuit logical operators. 1674 // conditional expressions or short-circuit logical operators.
1676 return block; 1675 return block;
1677 } 1676 }
1678 1677
1679 void open(HBasicBlock block) { 1678 void open(HBasicBlock block) {
1680 block.open(); 1679 block.open();
1681 current = block; 1680 current = block;
1682 lastOpenedBlock = block; 1681 lastOpenedBlock = block;
1683 } 1682 }
1684 1683
1685 HBasicBlock close(HControlFlow end) { 1684 HBasicBlock close(HControlFlow end) {
1686 HBasicBlock result = current; 1685 HBasicBlock result = current;
1687 current.close(end); 1686 current.close(end);
1688 current = null; 1687 current = null;
1689 return result; 1688 return result;
1690 } 1689 }
1691 1690
1691 HBasicBlock closeAndGotoExit(HControlFlow end) {
1692 HBasicBlock result = current;
1693 current.close(end);
1694 current = null;
1695 result.addSuccessor(graph.exit);
1696 return result;
1697 }
1698
1692 void goto(HBasicBlock from, HBasicBlock to) { 1699 void goto(HBasicBlock from, HBasicBlock to) {
1693 from.close(new HGoto()); 1700 from.close(new HGoto());
1694 from.addSuccessor(to); 1701 from.addSuccessor(to);
1695 } 1702 }
1696 1703
1697 bool isAborted() { 1704 bool isAborted() {
1698 return _current == null; 1705 return _current == null;
1699 } 1706 }
1700 1707
1701 /** 1708 /**
(...skipping 2218 matching lines...) Expand 10 before | Expand all | Expand 10 after
3920 visit(node.expression); 3927 visit(node.expression);
3921 value = pop(); 3928 value = pop();
3922 value = potentiallyCheckType(value, returnType); 3929 value = potentiallyCheckType(value, returnType);
3923 } 3930 }
3924 3931
3925 handleInTryStatement(); 3932 handleInTryStatement();
3926 3933
3927 if (!inliningStack.isEmpty) { 3934 if (!inliningStack.isEmpty) {
3928 localsHandler.updateLocal(returnElement, value); 3935 localsHandler.updateLocal(returnElement, value);
3929 } else { 3936 } else {
3930 close(attachPosition(new HReturn(value), node)).addSuccessor(graph.exit); 3937 closeAndGotoExit(attachPosition(new HReturn(value), node));
3931 } 3938 }
3932 } 3939 }
3933 3940
3934 visitThrow(Throw node) { 3941 visitThrow(Throw node) {
3935 if (node.expression == null) { 3942 if (node.expression == null) {
3936 HInstruction exception = rethrowableException; 3943 HInstruction exception = rethrowableException;
3937 if (exception == null) { 3944 if (exception == null) {
3938 exception = graph.addConstantNull(constantSystem); 3945 exception = graph.addConstantNull(constantSystem);
3939 compiler.internalError( 3946 compiler.internalError(
3940 'rethrowableException should not be null', node: node); 3947 'rethrowableException should not be null', node: node);
3941 } 3948 }
3942 close(new HThrow(exception, isRethrow: true)); 3949 handleInTryStatement();
3950 closeAndGotoExit(new HThrow(exception, isRethrow: true));
3943 } else { 3951 } else {
3952 visit(node.expression);
3953 handleInTryStatement();
3944 if (inliningStack.isEmpty) { 3954 if (inliningStack.isEmpty) {
3945 visit(node.expression); 3955 closeAndGotoExit(new HThrow(pop()));
3946 close(new HThrow(pop()));
3947 } else if (isReachable) { 3956 } else if (isReachable) {
3948 // We don't close the block when we are inlining, because we could be 3957 // We don't close the block when we are inlining, because we could be
3949 // inside an expression, and it is rather complicated to close the 3958 // inside an expression, and it is rather complicated to close the
3950 // block at an arbitrary place in an expression. 3959 // block at an arbitrary place in an expression.
3951 visit(node.expression);
3952 add(new HThrowExpression(pop())); 3960 add(new HThrowExpression(pop()));
3953 isReachable = false; 3961 isReachable = false;
3954 } 3962 }
3955 } 3963 }
3956 } 3964 }
3957 3965
3958 visitTypeAnnotation(TypeAnnotation node) { 3966 visitTypeAnnotation(TypeAnnotation node) {
3959 compiler.internalError('visiting type annotation in SSA builder', 3967 compiler.internalError('visiting type annotation in SSA builder',
3960 node: node); 3968 node: node);
3961 } 3969 }
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
4357 // default case. 4365 // default case.
4358 expressionBlock.addSuccessor(block); 4366 expressionBlock.addSuccessor(block);
4359 hasDefault = true; 4367 hasDefault = true;
4360 } 4368 }
4361 open(block); 4369 open(block);
4362 localsHandler = new LocalsHandler.from(savedLocals); 4370 localsHandler = new LocalsHandler.from(savedLocals);
4363 visit(switchCase.statements); 4371 visit(switchCase.statements);
4364 if (!isAborted() && caseIterator.hasNext) { 4372 if (!isAborted() && caseIterator.hasNext) {
4365 pushInvokeHelper0(getFallThroughErrorElement, HType.UNKNOWN); 4373 pushInvokeHelper0(getFallThroughErrorElement, HType.UNKNOWN);
4366 HInstruction error = pop(); 4374 HInstruction error = pop();
4367 close(new HThrow(error)); 4375 closeAndGotoExit(new HThrow(error));
4368 } 4376 }
4369 statements.add( 4377 statements.add(
4370 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); 4378 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock)));
4371 } 4379 }
4372 4380
4373 // Add a join-block if necessary. 4381 // Add a join-block if necessary.
4374 // We create [joinBlock] early, and then go through the cases that might 4382 // We create [joinBlock] early, and then go through the cases that might
4375 // want to jump to it. In each case, if we add [joinBlock] as a successor 4383 // want to jump to it. In each case, if we add [joinBlock] as a successor
4376 // of another block, we also add an element to [caseHandlers] that is used 4384 // of another block, we also add an element to [caseHandlers] that is used
4377 // to create the phis in [joinBlock]. 4385 // to create the phis in [joinBlock].
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
4474 // Called for the statements on all but the last case block. 4482 // Called for the statements on all but the last case block.
4475 // Ensures that a user expecting a fallthrough gets an error. 4483 // Ensures that a user expecting a fallthrough gets an error.
4476 void visitStatementsAndAbort() { 4484 void visitStatementsAndAbort() {
4477 visit(node.statements); 4485 visit(node.statements);
4478 if (!isAborted()) { 4486 if (!isAborted()) {
4479 compiler.reportWarning(node, 'Missing break at end of switch case'); 4487 compiler.reportWarning(node, 'Missing break at end of switch case');
4480 Element element = 4488 Element element =
4481 compiler.findHelper(const SourceString("getFallThroughError")); 4489 compiler.findHelper(const SourceString("getFallThroughError"));
4482 pushInvokeHelper0(element, HType.UNKNOWN); 4490 pushInvokeHelper0(element, HType.UNKNOWN);
4483 HInstruction error = pop(); 4491 HInstruction error = pop();
4484 close(new HThrow(error)); 4492 closeAndGotoExit(new HThrow(error));
4485 } 4493 }
4486 } 4494 }
4487 4495
4488 Link<Node> skipLabels(Link<Node> labelsAndCases) { 4496 Link<Node> skipLabels(Link<Node> labelsAndCases) {
4489 while (!labelsAndCases.isEmpty && labelsAndCases.head is Label) { 4497 while (!labelsAndCases.isEmpty && labelsAndCases.head is Label) {
4490 labelsAndCases = labelsAndCases.tail; 4498 labelsAndCases = labelsAndCases.tail;
4491 } 4499 }
4492 return labelsAndCases; 4500 return labelsAndCases;
4493 } 4501 }
4494 4502
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
4690 pushInvokeHelper1( 4698 pushInvokeHelper1(
4691 backend.getTraceFromException(), exception, HType.UNKNOWN); 4699 backend.getTraceFromException(), exception, HType.UNKNOWN);
4692 HInstruction traceInstruction = pop(); 4700 HInstruction traceInstruction = pop();
4693 localsHandler.updateLocal(elements[trace], traceInstruction); 4701 localsHandler.updateLocal(elements[trace], traceInstruction);
4694 } 4702 }
4695 visit(catchBlock); 4703 visit(catchBlock);
4696 } 4704 }
4697 4705
4698 void visitElse() { 4706 void visitElse() {
4699 if (link.isEmpty) { 4707 if (link.isEmpty) {
4700 close(new HThrow(exception, isRethrow: true)); 4708 closeAndGotoExit(new HThrow(exception, isRethrow: true));
4701 } else { 4709 } else {
4702 CatchBlock newBlock = link.head; 4710 CatchBlock newBlock = link.head;
4703 handleIf(node, 4711 handleIf(node,
4704 () { pushCondition(newBlock); }, 4712 () { pushCondition(newBlock); },
4705 visitThen, visitElse); 4713 visitThen, visitElse);
4706 } 4714 }
4707 } 4715 }
4708 4716
4709 CatchBlock firstBlock = link.head; 4717 CatchBlock firstBlock = link.head;
4710 handleIf(node, () { pushCondition(firstBlock); }, visitThen, visitElse); 4718 handleIf(node, () { pushCondition(firstBlock); }, visitThen, visitElse);
(...skipping 21 matching lines...) Expand all
4732 addExitTrySuccessor(successor) { 4740 addExitTrySuccessor(successor) {
4733 if (successor == null) return; 4741 if (successor == null) return;
4734 // Iterate over all blocks created inside this try/catch, and 4742 // Iterate over all blocks created inside this try/catch, and
4735 // attach successor information to blocks that end with 4743 // attach successor information to blocks that end with
4736 // [HExitTry]. 4744 // [HExitTry].
4737 for (int i = startTryBlock.id; i < successor.id; i++) { 4745 for (int i = startTryBlock.id; i < successor.id; i++) {
4738 HBasicBlock block = graph.blocks[i]; 4746 HBasicBlock block = graph.blocks[i];
4739 var last = block.last; 4747 var last = block.last;
4740 if (last is HExitTry) { 4748 if (last is HExitTry) {
4741 block.addSuccessor(successor); 4749 block.addSuccessor(successor);
4742 } else if (last is HTry) {
4743 // Skip all blocks inside this nested try/catch.
4744 i = last.joinBlock.id;
4745 } 4750 }
4746 } 4751 }
4747 } 4752 }
4748 4753
4749 // Setup all successors. The entry block that contains the [HTry] 4754 // Setup all successors. The entry block that contains the [HTry]
4750 // has 1) the body, 2) the catch, 3) the finally, and 4) the exit 4755 // has 1) the body, 2) the catch, 3) the finally, and 4) the exit
4751 // blocks as successors. 4756 // blocks as successors.
4752 enterBlock.addSuccessor(startTryBlock); 4757 enterBlock.addSuccessor(startTryBlock);
4753 addOptionalSuccessor(enterBlock, startCatchBlock); 4758 addOptionalSuccessor(enterBlock, startCatchBlock);
4754 addOptionalSuccessor(enterBlock, startFinallyBlock); 4759 addOptionalSuccessor(enterBlock, startFinallyBlock);
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
5214 new HSubGraphBlockInformation(elseBranch.graph)); 5219 new HSubGraphBlockInformation(elseBranch.graph));
5215 5220
5216 HBasicBlock conditionStartBlock = conditionBranch.block; 5221 HBasicBlock conditionStartBlock = conditionBranch.block;
5217 conditionStartBlock.setBlockFlow(info, joinBlock); 5222 conditionStartBlock.setBlockFlow(info, joinBlock);
5218 SubGraph conditionGraph = conditionBranch.graph; 5223 SubGraph conditionGraph = conditionBranch.graph;
5219 HIf branch = conditionGraph.end.last; 5224 HIf branch = conditionGraph.end.last;
5220 assert(branch is HIf); 5225 assert(branch is HIf);
5221 branch.blockInformation = conditionStartBlock.blockFlow; 5226 branch.blockInformation = conditionStartBlock.blockFlow;
5222 } 5227 }
5223 } 5228 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698