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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 2954463002: Refactoring to prepare for kernel based jump targets (Closed)
Patch Set: Updated cf. comments Created 3 years, 5 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
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 import 'dart:collection'; 5 import 'dart:collection';
6 6
7 import 'package:js_runtime/shared/embedded_names.dart'; 7 import 'package:js_runtime/shared/embedded_names.dart';
8 8
9 import '../closure.dart'; 9 import '../closure.dart';
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 1689 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 } 1700 }
1701 } 1701 }
1702 1702
1703 void buildBody() { 1703 void buildBody() {
1704 visit(node.body); 1704 visit(node.body);
1705 } 1705 }
1706 1706
1707 loopHandler.handleLoop( 1707 loopHandler.handleLoop(
1708 node, 1708 node,
1709 closureDataLookup.getClosureRepresentationInfoForLoop(node), 1709 closureDataLookup.getClosureRepresentationInfoForLoop(node),
1710 elements.getTargetDefinition(node),
1710 buildInitializer, 1711 buildInitializer,
1711 buildCondition, 1712 buildCondition,
1712 buildUpdate, 1713 buildUpdate,
1713 buildBody); 1714 buildBody);
1714 } 1715 }
1715 1716
1716 visitWhile(ast.While node) { 1717 visitWhile(ast.While node) {
1717 assert(isReachable); 1718 assert(isReachable);
1718 HInstruction buildCondition() { 1719 HInstruction buildCondition() {
1719 visit(node.condition); 1720 visit(node.condition);
1720 return popBoolified(); 1721 return popBoolified();
1721 } 1722 }
1722 1723
1723 loopHandler.handleLoop( 1724 loopHandler.handleLoop(
1724 node, 1725 node,
1725 closureDataLookup.getClosureRepresentationInfoForLoop(node), 1726 closureDataLookup.getClosureRepresentationInfoForLoop(node),
1727 elements.getTargetDefinition(node),
1726 () {}, 1728 () {},
1727 buildCondition, 1729 buildCondition,
1728 () {}, () { 1730 () {}, () {
1729 visit(node.body); 1731 visit(node.body);
1730 }); 1732 });
1731 } 1733 }
1732 1734
1733 visitDoWhile(ast.DoWhile node) { 1735 visitDoWhile(ast.DoWhile node) {
1734 assert(isReachable); 1736 assert(isReachable);
1735 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 1737 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
1736 var loopClosureInfo = 1738 var loopClosureInfo =
1737 closureDataLookup.getClosureRepresentationInfoForLoop(node); 1739 closureDataLookup.getClosureRepresentationInfoForLoop(node);
1738 localsHandler.startLoop(loopClosureInfo); 1740 localsHandler.startLoop(loopClosureInfo);
1739 loopDepth++; 1741 loopDepth++;
1740 JumpHandler jumpHandler = loopHandler.beginLoopHeader(node); 1742 JumpTarget target = elements.getTargetDefinition(node);
1743 JumpHandler jumpHandler = loopHandler.beginLoopHeader(node, target);
1741 HLoopInformation loopInfo = current.loopInformation; 1744 HLoopInformation loopInfo = current.loopInformation;
1742 HBasicBlock loopEntryBlock = current; 1745 HBasicBlock loopEntryBlock = current;
1743 HBasicBlock bodyEntryBlock = current; 1746 HBasicBlock bodyEntryBlock = current;
1744 JumpTarget target = elements.getTargetDefinition(node);
1745 bool hasContinues = target != null && target.isContinueTarget; 1747 bool hasContinues = target != null && target.isContinueTarget;
1746 if (hasContinues) { 1748 if (hasContinues) {
1747 // Add extra block to hang labels on. 1749 // Add extra block to hang labels on.
1748 // It doesn't currently work if they are on the same block as the 1750 // It doesn't currently work if they are on the same block as the
1749 // HLoopInfo. The handling of HLabeledBlockInformation will visit a 1751 // HLoopInfo. The handling of HLabeledBlockInformation will visit a
1750 // SubGraph that starts at the same block again, so the HLoopInfo is 1752 // SubGraph that starts at the same block again, so the HLoopInfo is
1751 // either handled twice, or it's handled after the labeled block info, 1753 // either handled twice, or it's handled after the labeled block info,
1752 // both of which generate the wrong code. 1754 // both of which generate the wrong code.
1753 // Using a separate block is just a simple workaround. 1755 // Using a separate block is just a simple workaround.
1754 bodyEntryBlock = openNewBlock(); 1756 bodyEntryBlock = openNewBlock();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 1849
1848 if (jumpHandler.hasAnyBreak()) { 1850 if (jumpHandler.hasAnyBreak()) {
1849 // Null branchBlock because the body of the do-while loop always aborts, 1851 // Null branchBlock because the body of the do-while loop always aborts,
1850 // so we never get to the condition. 1852 // so we never get to the condition.
1851 loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler); 1853 loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler);
1852 1854
1853 // Since the body of the loop has a break, we attach a synthesized label 1855 // Since the body of the loop has a break, we attach a synthesized label
1854 // to the body. 1856 // to the body.
1855 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock); 1857 SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
1856 JumpTarget target = elements.getTargetDefinition(node); 1858 JumpTarget target = elements.getTargetDefinition(node);
1857 LabelDefinition label = target.addLabel(null, 'loop'); 1859 LabelDefinition label =
1858 label.setBreakTarget(); 1860 target.addLabel(null, 'loop', isBreakTarget: true);
1859 HLabeledBlockInformation info = new HLabeledBlockInformation( 1861 HLabeledBlockInformation info = new HLabeledBlockInformation(
1860 new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]); 1862 new HSubGraphBlockInformation(bodyGraph), <LabelDefinition>[label]);
1861 loopEntryBlock.setBlockFlow(info, current); 1863 loopEntryBlock.setBlockFlow(info, current);
1862 jumpHandler.forEachBreak((HBreak breakInstruction, _) { 1864 jumpHandler.forEachBreak((HBreak breakInstruction, _) {
1863 HBasicBlock block = breakInstruction.block; 1865 HBasicBlock block = breakInstruction.block;
1864 block.addAtExit(new HBreak.toLabel(label)); 1866 block.addAtExit(new HBreak.toLabel(label));
1865 block.remove(breakInstruction); 1867 block.remove(breakInstruction);
1866 }); 1868 });
1867 } 1869 }
1868 } 1870 }
(...skipping 3502 matching lines...) Expand 10 before | Expand all | Expand 10 after
5371 5373
5372 /** 5374 /**
5373 * Creates a [JumpHandler] for a statement. The node must be a jump 5375 * Creates a [JumpHandler] for a statement. The node must be a jump
5374 * target. If there are no breaks or continues targeting the statement, 5376 * target. If there are no breaks or continues targeting the statement,
5375 * a special "null handler" is returned. 5377 * a special "null handler" is returned.
5376 * 5378 *
5377 * [isLoopJump] is [:true:] when the jump handler is for a loop. This is used 5379 * [isLoopJump] is [:true:] when the jump handler is for a loop. This is used
5378 * to distinguish the synthesized loop created for a switch statement with 5380 * to distinguish the synthesized loop created for a switch statement with
5379 * continue statements from simple switch statements. 5381 * continue statements from simple switch statements.
5380 */ 5382 */
5381 JumpHandler createJumpHandler(ast.Statement node, {bool isLoopJump}) { 5383 JumpHandler createJumpHandler(ast.Statement node, JumpTarget jumpTarget,
5382 JumpTarget element = elements.getTargetDefinition(node); 5384 {bool isLoopJump}) {
5383 if (element == null || !identical(element.statement, node)) { 5385 if (jumpTarget == null || !identical(jumpTarget.statement, node)) {
5384 // No breaks or continues to this node. 5386 // No breaks or continues to this node.
5385 return new NullJumpHandler(reporter); 5387 return new NullJumpHandler(reporter);
5386 } 5388 }
5387 if (isLoopJump && node is ast.SwitchStatement) { 5389 if (isLoopJump && node is ast.SwitchStatement) {
5388 // Create a special jump handler for loops created for switch statements 5390 // Create a special jump handler for loops created for switch statements
5389 // with continue statements. 5391 // with continue statements.
5390 return new AstSwitchCaseJumpHandler(this, element, node); 5392 return new AstSwitchCaseJumpHandler(this, jumpTarget, node);
5391 } 5393 }
5392 return new JumpHandler(this, element); 5394 return new JumpHandler(this, jumpTarget);
5393 } 5395 }
5394 5396
5395 visitAsyncForIn(ast.AsyncForIn node) { 5397 visitAsyncForIn(ast.AsyncForIn node) {
5396 // The async-for is implemented with a StreamIterator. 5398 // The async-for is implemented with a StreamIterator.
5397 HInstruction streamIterator; 5399 HInstruction streamIterator;
5398 5400
5399 visit(node.expression); 5401 visit(node.expression);
5400 HInstruction expression = pop(); 5402 HInstruction expression = pop();
5401 ConstructorElement constructor = commonElements.streamIteratorConstructor; 5403 ConstructorElement constructor = commonElements.streamIteratorConstructor;
5402 pushInvokeStatic( 5404 pushInvokeStatic(
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5438 5440
5439 visit(node.body); 5441 visit(node.body);
5440 } 5442 }
5441 5443
5442 void buildUpdate() {} 5444 void buildUpdate() {}
5443 5445
5444 buildProtectedByFinally(() { 5446 buildProtectedByFinally(() {
5445 loopHandler.handleLoop( 5447 loopHandler.handleLoop(
5446 node, 5448 node,
5447 closureDataLookup.getClosureRepresentationInfoForLoop(node), 5449 closureDataLookup.getClosureRepresentationInfoForLoop(node),
5450 elements.getTargetDefinition(node),
5448 buildInitializer, 5451 buildInitializer,
5449 buildCondition, 5452 buildCondition,
5450 buildUpdate, 5453 buildUpdate,
5451 buildBody); 5454 buildBody);
5452 }, () { 5455 }, () {
5453 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); 5456 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]);
5454 push(new HAwait(pop(), 5457 push(new HAwait(pop(),
5455 new TypeMask.subclass(commonElements.objectClass, closedWorld))); 5458 new TypeMask.subclass(commonElements.objectClass, closedWorld)));
5456 pop(); 5459 pop();
5457 }); 5460 });
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5510 Selector call = Selectors.current; 5513 Selector call = Selectors.current;
5511 TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node); 5514 TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node);
5512 pushInvokeDynamic(node, call, mask, [iterator]); 5515 pushInvokeDynamic(node, call, mask, [iterator]);
5513 buildAssignLoopVariable(node, pop()); 5516 buildAssignLoopVariable(node, pop());
5514 visit(node.body); 5517 visit(node.body);
5515 } 5518 }
5516 5519
5517 loopHandler.handleLoop( 5520 loopHandler.handleLoop(
5518 node, 5521 node,
5519 closureDataLookup.getClosureRepresentationInfoForLoop(node), 5522 closureDataLookup.getClosureRepresentationInfoForLoop(node),
5523 elements.getTargetDefinition(node),
5520 buildInitializer, 5524 buildInitializer,
5521 buildCondition, 5525 buildCondition,
5522 () {}, 5526 () {},
5523 buildBody); 5527 buildBody);
5524 } 5528 }
5525 5529
5526 buildAssignLoopVariable(ast.ForIn node, HInstruction value) { 5530 buildAssignLoopVariable(ast.ForIn node, HInstruction value) {
5527 ast.Node identifier = node.declaredIdentifier; 5531 ast.Node identifier = node.declaredIdentifier;
5528 Element variable = elements.getForInVariable(node); 5532 Element variable = elements.getForInVariable(node);
5529 Selector selector = elements.getSelector(identifier); 5533 Selector selector = elements.getSelector(identifier);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
5634 HInstruction one = graph.addConstantInt(1, closedWorld); 5638 HInstruction one = graph.addConstantInt(1, closedWorld);
5635 HInstruction addInstruction = 5639 HInstruction addInstruction =
5636 new HAdd(index, one, null, commonMasks.positiveIntType); 5640 new HAdd(index, one, null, commonMasks.positiveIntType);
5637 add(addInstruction); 5641 add(addInstruction);
5638 localsHandler.updateLocal(indexVariable, addInstruction); 5642 localsHandler.updateLocal(indexVariable, addInstruction);
5639 } 5643 }
5640 5644
5641 loopHandler.handleLoop( 5645 loopHandler.handleLoop(
5642 node, 5646 node,
5643 closureDataLookup.getClosureRepresentationInfoForLoop(node), 5647 closureDataLookup.getClosureRepresentationInfoForLoop(node),
5648 elements.getTargetDefinition(node),
5644 buildInitializer, 5649 buildInitializer,
5645 buildCondition, 5650 buildCondition,
5646 buildUpdate, 5651 buildUpdate,
5647 buildBody); 5652 buildBody);
5648 } 5653 }
5649 5654
5650 visitLabel(ast.Label node) { 5655 visitLabel(ast.Label node) {
5651 reporter.internalError(node, 'SsaFromAstMixin.visitLabel.'); 5656 reporter.internalError(node, 'SsaFromAstMixin.visitLabel.');
5652 } 5657 }
5653 5658
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
5833 buildComplexSwitchStatement(node, constants, caseIndex, hasDefault); 5838 buildComplexSwitchStatement(node, constants, caseIndex, hasDefault);
5834 } 5839 }
5835 } 5840 }
5836 5841
5837 /** 5842 /**
5838 * Builds a simple switch statement which does not handle uses of continue 5843 * Builds a simple switch statement which does not handle uses of continue
5839 * statements to labeled switch cases. 5844 * statements to labeled switch cases.
5840 */ 5845 */
5841 void buildSimpleSwitchStatement( 5846 void buildSimpleSwitchStatement(
5842 ast.SwitchStatement node, Map<ast.CaseMatch, ConstantValue> constants) { 5847 ast.SwitchStatement node, Map<ast.CaseMatch, ConstantValue> constants) {
5843 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); 5848 JumpHandler jumpHandler = createJumpHandler(
5849 node, elements.getTargetDefinition(node),
5850 isLoopJump: false);
5844 HInstruction buildExpression() { 5851 HInstruction buildExpression() {
5845 visit(node.expression); 5852 visit(node.expression);
5846 return pop(); 5853 return pop();
5847 } 5854 }
5848 5855
5849 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) { 5856 Iterable<ConstantValue> getConstants(ast.SwitchCase switchCase) {
5850 List<ConstantValue> constantList = <ConstantValue>[]; 5857 List<ConstantValue> constantList = <ConstantValue>[];
5851 for (ast.Node labelOrCase in switchCase.labelsAndCases) { 5858 for (ast.Node labelOrCase in switchCase.labelsAndCases) {
5852 if (labelOrCase is ast.CaseMatch) { 5859 if (labelOrCase is ast.CaseMatch) {
5853 constantList.add(constants[labelOrCase]); 5860 constantList.add(constants[labelOrCase]);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5903 // case 2: s_2; target = i; continue l; 5910 // case 2: s_2; target = i; continue l;
5904 // ... 5911 // ...
5905 // case n: s_n; target = j; continue l; 5912 // case n: s_n; target = j; continue l;
5906 // } 5913 // }
5907 // } 5914 // }
5908 5915
5909 JumpTarget switchTarget = elements.getTargetDefinition(node); 5916 JumpTarget switchTarget = elements.getTargetDefinition(node);
5910 HInstruction initialValue = graph.addConstantNull(closedWorld); 5917 HInstruction initialValue = graph.addConstantNull(closedWorld);
5911 localsHandler.updateLocal(switchTarget, initialValue); 5918 localsHandler.updateLocal(switchTarget, initialValue);
5912 5919
5913 JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: false); 5920 JumpHandler jumpHandler =
5921 createJumpHandler(node, switchTarget, isLoopJump: false);
5914 dynamic switchCases = node.cases; 5922 dynamic switchCases = node.cases;
5915 if (!hasDefault) { 5923 if (!hasDefault) {
5916 // Use [:null:] as the marker for a synthetic default clause. 5924 // Use [:null:] as the marker for a synthetic default clause.
5917 // The synthetic default is added because otherwise, there would be no 5925 // The synthetic default is added because otherwise, there would be no
5918 // good place to give a default value to the local. 5926 // good place to give a default value to the local.
5919 switchCases = node.cases.nodes.toList()..add(null); 5927 switchCases = node.cases.nodes.toList()..add(null);
5920 } 5928 }
5921 HInstruction buildExpression() { 5929 HInstruction buildExpression() {
5922 visit(node.expression); 5930 visit(node.expression);
5923 return pop(); 5931 return pop();
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
5987 node.cases, 5995 node.cases,
5988 getConstants, 5996 getConstants,
5989 (_) => false, // No case is default. 5997 (_) => false, // No case is default.
5990 buildSwitchCase); 5998 buildSwitchCase);
5991 } 5999 }
5992 6000
5993 void buildLoop() { 6001 void buildLoop() {
5994 loopHandler.handleLoop( 6002 loopHandler.handleLoop(
5995 node, 6003 node,
5996 closureDataLookup.getClosureRepresentationInfoForLoop(node), 6004 closureDataLookup.getClosureRepresentationInfoForLoop(node),
6005 switchTarget,
5997 () {}, 6006 () {},
5998 buildCondition, 6007 buildCondition,
5999 () {}, 6008 () {},
6000 buildSwitch); 6009 buildSwitch);
6001 } 6010 }
6002 6011
6003 if (hasDefault) { 6012 if (hasDefault) {
6004 buildLoop(); 6013 buildLoop();
6005 } else { 6014 } else {
6006 // If the switch statement has no default case, surround the loop with 6015 // If the switch statement has no default case, surround the loop with
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after
6849 this.oldReturnLocal, 6858 this.oldReturnLocal,
6850 this.oldReturnType, 6859 this.oldReturnType,
6851 this.oldResolvedAst, 6860 this.oldResolvedAst,
6852 this.oldStack, 6861 this.oldStack,
6853 this.oldLocalsHandler, 6862 this.oldLocalsHandler,
6854 this.inTryStatement, 6863 this.inTryStatement,
6855 this.allFunctionsCalledOnce, 6864 this.allFunctionsCalledOnce,
6856 this.oldElementInferenceResults) 6865 this.oldElementInferenceResults)
6857 : super(function); 6866 : super(function);
6858 } 6867 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart ('k') | pkg/compiler/lib/src/ssa/builder_kernel.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698