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

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

Issue 1398393002: Decouple SSA builder from codegen-work-item (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « pkg/compiler/lib/src/native/ssa.dart ('k') | pkg/compiler/lib/src/ssa/ssa.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 class SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 final SsaCodeGeneratorTask generator; 8 final SsaCodeGeneratorTask generator;
9 final SsaBuilderTask builder; 9 final SsaBuilderTask builder;
10 final SsaOptimizerTask optimizer; 10 final SsaOptimizerTask optimizer;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 : emitter = backend.emitter, 59 : emitter = backend.emitter,
60 backend = backend, 60 backend = backend,
61 super(backend.compiler); 61 super(backend.compiler);
62 62
63 DiagnosticReporter get reporter => compiler.reporter; 63 DiagnosticReporter get reporter => compiler.reporter;
64 64
65 HGraph build(CodegenWorkItem work) { 65 HGraph build(CodegenWorkItem work) {
66 return measure(() { 66 return measure(() {
67 Element element = work.element.implementation; 67 Element element = work.element.implementation;
68 return reporter.withCurrentElement(element, () { 68 return reporter.withCurrentElement(element, () {
69 HInstruction.idCounter = 0;
70 SsaBuilder builder = 69 SsaBuilder builder =
71 new SsaBuilder( 70 new SsaBuilder(work.element.implementation,
72 backend, work, emitter.nativeEmitter, 71 work.resolutionTree, work.compilationContext, work.registry,
72 backend, emitter.nativeEmitter,
73 sourceInformationFactory); 73 sourceInformationFactory);
74 HGraph graph; 74 HGraph graph = builder.build();
75 ElementKind kind = element.kind; 75
76 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { 76 // Default arguments are handled elsewhere, but we must ensure
77 graph = compileConstructor(builder, work); 77 // that the default values are computed during codegen.
78 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || 78 if (!identical(element.kind, ElementKind.FIELD)) {
79 kind == ElementKind.FUNCTION ||
80 kind == ElementKind.GETTER ||
81 kind == ElementKind.SETTER) {
82 graph = builder.buildMethod(element);
83 } else if (kind == ElementKind.FIELD) {
84 if (element.isInstanceMember) {
85 assert(compiler.enableTypeAssertions);
86 graph = builder.buildCheckedSetter(element);
87 } else {
88 graph = builder.buildLazyInitializer(element);
89 }
90 } else {
91 reporter.internalError(element, 'Unexpected element kind $kind.');
92 }
93 assert(graph.isValid());
94 if (!identical(kind, ElementKind.FIELD)) {
95 FunctionElement function = element; 79 FunctionElement function = element;
96 FunctionSignature signature = function.functionSignature; 80 FunctionSignature signature = function.functionSignature;
97 signature.forEachOptionalParameter((ParameterElement parameter) { 81 signature.forEachOptionalParameter((ParameterElement parameter) {
98 // This ensures the default value will be computed. 82 // This ensures the default value will be computed.
99 ConstantValue constant = 83 ConstantValue constant =
100 backend.constants.getConstantValueForVariable(parameter); 84 backend.constants.getConstantValueForVariable(parameter);
101 CodegenRegistry registry = work.registry; 85 work.registry.registerCompileTimeConstant(constant);
102 registry.registerCompileTimeConstant(constant);
103 }); 86 });
104 } 87 }
105 if (compiler.tracer.isEnabled) { 88 if (compiler.tracer.isEnabled) {
106 String name; 89 String name;
107 if (element.isClassMember) { 90 if (element.isClassMember) {
108 String className = element.enclosingClass.name; 91 String className = element.enclosingClass.name;
109 String memberName = element.name; 92 String memberName = element.name;
110 name = "$className.$memberName"; 93 name = "$className.$memberName";
111 if (element.isGenerativeConstructorBody) { 94 if (element.isGenerativeConstructorBody) {
112 name = "$name (body)"; 95 name = "$name (body)";
113 } 96 }
114 } else { 97 } else {
115 name = "${element.name}"; 98 name = "${element.name}";
116 } 99 }
117 compiler.tracer.traceCompilation( 100 compiler.tracer.traceCompilation(
118 name, work.compilationContext); 101 name, work.compilationContext);
119 compiler.tracer.traceGraph('builder', graph); 102 compiler.tracer.traceGraph('builder', graph);
120 } 103 }
121 return graph; 104 return graph;
122 }); 105 });
123 }); 106 });
124 } 107 }
125 108
126 HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) {
127 return builder.buildFactory(work.element);
128 }
129 } 109 }
130 110
131 /** 111 /**
132 * Keeps track of locals (including parameters and phis) when building. The 112 * Keeps track of locals (including parameters and phis) when building. The
133 * 'this' reference is treated as parameter and hence handled by this class, 113 * 'this' reference is treated as parameter and hence handled by this class,
134 * too. 114 * too.
135 */ 115 */
136 class LocalsHandler { 116 class LocalsHandler {
137 /** 117 /**
138 * The values of locals that can be directly accessed (without redirections 118 * The values of locals that can be directly accessed (without redirections
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 * This class builds SSA nodes for functions represented in AST. 971 * This class builds SSA nodes for functions represented in AST.
992 */ 972 */
993 class SsaBuilder extends ast.Visitor 973 class SsaBuilder extends ast.Visitor
994 with BaseImplementationOfCompoundsMixin, 974 with BaseImplementationOfCompoundsMixin,
995 BaseImplementationOfSetIfNullsMixin, 975 BaseImplementationOfSetIfNullsMixin,
996 SendResolverMixin, 976 SendResolverMixin,
997 SemanticSendResolvedMixin, 977 SemanticSendResolvedMixin,
998 NewBulkMixin, 978 NewBulkMixin,
999 ErrorBulkMixin 979 ErrorBulkMixin
1000 implements SemanticSendVisitor { 980 implements SemanticSendVisitor {
981
982 /// The element for which this SSA builder is being used.
983 final Element target;
984
985 /// Reference to resolved elements in [target]'s AST.
986 TreeElements elements;
987
988 /// Used to report information about inlining (which occurs while building the
989 /// SSA graph), when dump-info is enabled.
990 final InfoReporter infoReporter;
991
992 /// If not null, the builder will store in [context] data that is used later
993 /// during the optimization phases.
994 final JavaScriptItemCompilationContext context;
995
996 /// Registry used to enqueue work during codegen, may be null to avoid
997 /// enqueing any work.
998 // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be
999 // able to return the impact as a result after building and avoid enqueing
1000 // things here. Later the codegen task can decide whether to enqueue
1001 // something. In the past this didn't matter as much because the SSA graph was
1002 // used only for codegen, but currently we want to experiment using it for
1003 // code-analysis too.
1004 final CodegenRegistry registry;
1001 final Compiler compiler; 1005 final Compiler compiler;
1002 final JavaScriptBackend backend; 1006 final JavaScriptBackend backend;
1003 final ConstantSystem constantSystem; 1007 final ConstantSystem constantSystem;
1004 final CodegenWorkItem work;
1005 final RuntimeTypes rti; 1008 final RuntimeTypes rti;
1006 TreeElements elements; 1009
1007 SourceInformationBuilder sourceInformationBuilder; 1010 SourceInformationBuilder sourceInformationBuilder;
1011
1008 bool inLazyInitializerExpression = false; 1012 bool inLazyInitializerExpression = false;
1009 1013
1014 // TODO(sigmund): make all comments /// instead of /* */
1010 /* This field is used by the native handler. */ 1015 /* This field is used by the native handler. */
1011 final NativeEmitter nativeEmitter; 1016 final NativeEmitter nativeEmitter;
1012 1017
1018 /// Holds the resulting SSA graph.
1013 final HGraph graph = new HGraph(); 1019 final HGraph graph = new HGraph();
1014 1020
1015 /** 1021 /**
1016 * The current block to add instructions to. Might be null, if we are 1022 * The current block to add instructions to. Might be null, if we are
1017 * visiting dead code, but see [isReachable]. 1023 * visiting dead code, but see [isReachable].
1018 */ 1024 */
1019 HBasicBlock _current; 1025 HBasicBlock _current;
1020 1026
1021 HBasicBlock get current => _current; 1027 HBasicBlock get current => _current;
1022 1028
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 // We build the Ssa graph by simulating a stack machine. 1088 // We build the Ssa graph by simulating a stack machine.
1083 List<HInstruction> stack = <HInstruction>[]; 1089 List<HInstruction> stack = <HInstruction>[];
1084 1090
1085 /// Returns `true` if the current element is an `async` function. 1091 /// Returns `true` if the current element is an `async` function.
1086 bool get isBuildingAsyncFunction { 1092 bool get isBuildingAsyncFunction {
1087 Element element = sourceElement; 1093 Element element = sourceElement;
1088 return (element is FunctionElement && 1094 return (element is FunctionElement &&
1089 element.asyncMarker == AsyncMarker.ASYNC); 1095 element.asyncMarker == AsyncMarker.ASYNC);
1090 } 1096 }
1091 1097
1092 SsaBuilder(JavaScriptBackend backend, 1098 // TODO(sigmund): make most args optional
1093 CodegenWorkItem work, 1099 SsaBuilder(this.target, this.elements, this.context, this.registry,
1094 this.nativeEmitter, 1100 JavaScriptBackend backend, this.nativeEmitter,
1095 SourceInformationStrategy sourceInformationFactory) 1101 SourceInformationStrategy sourceInformationFactory)
1096 : this.compiler = backend.compiler, 1102 : this.compiler = backend.compiler,
1103 this.infoReporter = backend.compiler.dumpInfoTask,
1097 this.backend = backend, 1104 this.backend = backend,
1098 this.constantSystem = backend.constantSystem, 1105 this.constantSystem = backend.constantSystem,
1099 this.work = work, 1106 this.rti = backend.rti {
1100 this.rti = backend.rti, 1107 assert(target.isImplementation);
1101 this.elements = work.resolutionTree { 1108 graph.element = target;
1102 graph.element = work.element; 1109 localsHandler = new LocalsHandler(this, target, null);
1103 localsHandler = new LocalsHandler(this, work.element, null); 1110 sourceElementStack.add(target);
1104 sourceElementStack.add(work.element); 1111 sourceInformationBuilder = sourceInformationFactory.createBuilderForContext(
1105 sourceInformationBuilder = 1112 target);
1106 sourceInformationFactory.createBuilderForContext(
1107 work.element.implementation);
1108 } 1113 }
1109 1114
1110 BackendHelpers get helpers => backend.helpers; 1115 BackendHelpers get helpers => backend.helpers;
1111 1116
1112 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; 1117 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder;
1113 1118
1114 DiagnosticReporter get reporter => compiler.reporter; 1119 DiagnosticReporter get reporter => compiler.reporter;
1115 1120
1116 @override 1121 @override
1117 SemanticSendVisitor get sendVisitor => this; 1122 SemanticSendVisitor get sendVisitor => this;
1118 1123
1119 @override 1124 @override
1120 void visitNode(ast.Node node) { 1125 void visitNode(ast.Node node) {
1121 internalError(node, "Unhandled node: $node"); 1126 internalError(node, "Unhandled node: $node");
1122 } 1127 }
1123 1128
1124 @override 1129 @override
1125 void apply(ast.Node node, [_]) { 1130 void apply(ast.Node node, [_]) {
1126 node.accept(this); 1131 node.accept(this);
1127 } 1132 }
1128 1133
1129 CodegenRegistry get registry => work.registry;
1130
1131 /// Returns the current source element. 1134 /// Returns the current source element.
1132 /// 1135 ///
1133 /// The returned element is a declaration element. 1136 /// The returned element is a declaration element.
1134 // TODO(johnniwinther): Check that all usages of sourceElement agree on 1137 // TODO(johnniwinther): Check that all usages of sourceElement agree on
1135 // implementation/declaration distinction. 1138 // implementation/declaration distinction.
1136 Element get sourceElement => sourceElementStack.last; 1139 Element get sourceElement => sourceElementStack.last;
1137 1140
1138 bool get _checkOrTrustTypes => 1141 bool get _checkOrTrustTypes =>
1139 compiler.enableTypeAssertions || compiler.trustTypeAnnotations; 1142 compiler.enableTypeAssertions || compiler.trustTypeAnnotations;
1140 1143
1144 /// Build the graph for [target].
1145 HGraph build() {
1146 assert(invariant(target, target.isImplementation));
1147 HInstruction.idCounter = 0;
1148 ElementKind kind = target.kind;
1149 // TODO(sigmund): remove `result` and return graph directly, need to ensure
1150 // that it can never be null (see result in buildFactory for instance).
1151 var result;
1152 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
1153 result = buildFactory(target);
1154 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
1155 kind == ElementKind.FUNCTION ||
1156 kind == ElementKind.GETTER ||
1157 kind == ElementKind.SETTER) {
1158 result = buildMethod(target);
1159 } else if (kind == ElementKind.FIELD) {
1160 if (target.isInstanceMember) {
1161 assert(compiler.enableTypeAssertions);
1162 result = buildCheckedSetter(target);
1163 } else {
1164 result = buildLazyInitializer(target);
1165 }
1166 } else {
1167 reporter.internalError(target, 'Unexpected element kind $kind.');
1168 }
1169 assert(result.isValid());
1170 return result;
1171 }
1172
1173
1141 HBasicBlock addNewBlock() { 1174 HBasicBlock addNewBlock() {
1142 HBasicBlock block = graph.addNewBlock(); 1175 HBasicBlock block = graph.addNewBlock();
1143 // If adding a new block during building of an expression, it is due to 1176 // If adding a new block during building of an expression, it is due to
1144 // conditional expressions or short-circuit logical operators. 1177 // conditional expressions or short-circuit logical operators.
1145 return block; 1178 return block;
1146 } 1179 }
1147 1180
1148 void open(HBasicBlock block) { 1181 void open(HBasicBlock block) {
1149 block.open(); 1182 block.open();
1150 current = block; 1183 current = block;
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 emitReturn(graph.addConstantNull(compiler), null); 1506 emitReturn(graph.addConstantNull(compiler), null);
1474 } else { 1507 } else {
1475 doInline(function); 1508 doInline(function);
1476 } 1509 }
1477 }); 1510 });
1478 leaveInlinedMethod(); 1511 leaveInlinedMethod();
1479 } 1512 }
1480 1513
1481 if (meetsHardConstraints() && heuristicSayGoodToGo()) { 1514 if (meetsHardConstraints() && heuristicSayGoodToGo()) {
1482 doInlining(); 1515 doInlining();
1483 registry.registerInlining( 1516 infoReporter?.reportInlined(element,
1484 element, 1517 inliningStack.isEmpty ? target : inliningStack.last.function);
1485 compiler.currentElement);
1486 return true; 1518 return true;
1487 } 1519 }
1488 1520
1489 return false; 1521 return false;
1490 } 1522 }
1491 1523
1492 bool get allInlinedFunctionsCalledOnce { 1524 bool get allInlinedFunctionsCalledOnce {
1493 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; 1525 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
1494 } 1526 }
1495 1527
(...skipping 30 matching lines...) Expand all
1526 Element get currentNonClosureClass { 1558 Element get currentNonClosureClass {
1527 ClassElement cls = sourceElement.enclosingClass; 1559 ClassElement cls = sourceElement.enclosingClass;
1528 if (cls != null && cls.isClosure) { 1560 if (cls != null && cls.isClosure) {
1529 var closureClass = cls; 1561 var closureClass = cls;
1530 return closureClass.methodElement.enclosingClass; 1562 return closureClass.methodElement.enclosingClass;
1531 } else { 1563 } else {
1532 return cls; 1564 return cls;
1533 } 1565 }
1534 } 1566 }
1535 1567
1536 /**
1537 * Returns whether this builder is building code for [element].
1538 */
1539 bool isBuildingFor(Element element) {
1540 return work.element == element;
1541 }
1542
1543 /// A stack of [DartType]s the have been seen during inlining of factory 1568 /// A stack of [DartType]s the have been seen during inlining of factory
1544 /// constructors. These types are preserved in [HInvokeStatic]s and 1569 /// constructors. These types are preserved in [HInvokeStatic]s and
1545 /// [HForeignNew]s inside the inline code and registered during code 1570 /// [HForeignNew]s inside the inline code and registered during code
1546 /// generation for these nodes. 1571 /// generation for these nodes.
1547 // TODO(karlklose): consider removing this and keeping the (substituted) 1572 // TODO(karlklose): consider removing this and keeping the (substituted)
1548 // types of the type variables in an environment (like the [LocalsHandler]). 1573 // types of the type variables in an environment (like the [LocalsHandler]).
1549 final List<DartType> currentInlinedInstantiations = <DartType>[]; 1574 final List<DartType> currentInlinedInstantiations = <DartType>[];
1550 1575
1551 final List<AstInliningState> inliningStack = <AstInliningState>[]; 1576 final List<AstInliningState> inliningStack = <AstInliningState>[];
1552 1577
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 /** 1627 /**
1603 * Documentation wanted -- johnniwinther 1628 * Documentation wanted -- johnniwinther
1604 * 1629 *
1605 * Invariant: [functionElement] must be an implementation element. 1630 * Invariant: [functionElement] must be an implementation element.
1606 */ 1631 */
1607 HGraph buildMethod(FunctionElement functionElement) { 1632 HGraph buildMethod(FunctionElement functionElement) {
1608 assert(invariant(functionElement, functionElement.isImplementation)); 1633 assert(invariant(functionElement, functionElement.isImplementation));
1609 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement); 1634 graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
1610 ast.FunctionExpression function = functionElement.node; 1635 ast.FunctionExpression function = functionElement.node;
1611 assert(function != null); 1636 assert(function != null);
1612 assert(!function.modifiers.isExternal); 1637 assert(invariant(functionElement, !function.modifiers.isExternal));
1613 assert(elements.getFunctionDefinition(function) != null); 1638 assert(elements.getFunctionDefinition(function) != null);
1614 openFunction(functionElement, function); 1639 openFunction(functionElement, function);
1615 String name = functionElement.name; 1640 String name = functionElement.name;
1616 // If [functionElement] is `operator==` we explicitely add a null check at 1641 // If [functionElement] is `operator==` we explicitely add a null check at
1617 // the beginning of the method. This is to avoid having call sites do the 1642 // the beginning of the method. This is to avoid having call sites do the
1618 // null check. 1643 // null check.
1619 if (name == '==') { 1644 if (name == '==') {
1620 if (!backend.operatorEqHandlesNullArgument(functionElement)) { 1645 if (!backend.operatorEqHandlesNullArgument(functionElement)) {
1621 handleIf( 1646 handleIf(
1622 function, 1647 function,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 // If the method is intercepted, we want the actual receiver 1698 // If the method is intercepted, we want the actual receiver
1674 // to be the first parameter. 1699 // to be the first parameter.
1675 graph.entry.addBefore(graph.entry.last, parameter); 1700 graph.entry.addBefore(graph.entry.last, parameter);
1676 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type); 1701 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type);
1677 add(new HFieldSet(field, thisInstruction, value)); 1702 add(new HFieldSet(field, thisInstruction, value));
1678 return closeFunction(); 1703 return closeFunction();
1679 } 1704 }
1680 1705
1681 HGraph buildLazyInitializer(VariableElement variable) { 1706 HGraph buildLazyInitializer(VariableElement variable) {
1682 inLazyInitializerExpression = true; 1707 inLazyInitializerExpression = true;
1708 assert(invariant(variable, variable.initializer != null,
1709 message: "Non-constant variable $variable has no initializer."));
1683 ast.VariableDefinitions node = variable.node; 1710 ast.VariableDefinitions node = variable.node;
1684 openFunction(variable, node); 1711 openFunction(variable, node);
1685 assert(invariant(variable, variable.initializer != null,
1686 message: "Non-constant variable $variable has no initializer."));
1687 visit(variable.initializer); 1712 visit(variable.initializer);
1688 HInstruction value = pop(); 1713 HInstruction value = pop();
1689 value = potentiallyCheckOrTrustType(value, variable.type); 1714 value = potentiallyCheckOrTrustType(value, variable.type);
1690 ast.SendSet sendSet = node.definitions.nodes.head; 1715 ast.SendSet sendSet = node.definitions.nodes.head;
1691 closeAndGotoExit(new HReturn(value, 1716 closeAndGotoExit(new HReturn(value,
1692 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator))); 1717 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)));
1693 return closeFunction(); 1718 return closeFunction();
1694 } 1719 }
1695 1720
1696 /** 1721 /**
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after
2531 if (element == compiler.objectClass) return original; 2556 if (element == compiler.objectClass) return original;
2532 TypeMask mask = new TypeMask.subtype(element, compiler.world); 2557 TypeMask mask = new TypeMask.subtype(element, compiler.world);
2533 return new HTypeKnown.pinned(mask, original); 2558 return new HTypeKnown.pinned(mask, original);
2534 } 2559 }
2535 2560
2536 HInstruction _checkType(HInstruction original, DartType type, int kind) { 2561 HInstruction _checkType(HInstruction original, DartType type, int kind) {
2537 assert(compiler.enableTypeAssertions); 2562 assert(compiler.enableTypeAssertions);
2538 assert(type != null); 2563 assert(type != null);
2539 type = localsHandler.substInContext(type); 2564 type = localsHandler.substInContext(type);
2540 HInstruction other = buildTypeConversion(original, type, kind); 2565 HInstruction other = buildTypeConversion(original, type, kind);
2541 registry.registerIsCheck(type); 2566 registry?.registerIsCheck(type);
2542 return other; 2567 return other;
2543 } 2568 }
2544 2569
2545 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type, 2570 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type,
2546 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 2571 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
2547 if (type == null) return original; 2572 if (type == null) return original;
2548 HInstruction checkedOrTrusted = original; 2573 HInstruction checkedOrTrusted = original;
2549 if (compiler.trustTypeAnnotations) { 2574 if (compiler.trustTypeAnnotations) {
2550 checkedOrTrusted = _trustType(original, type); 2575 checkedOrTrusted = _trustType(original, type);
2551 } else if (compiler.enableTypeAssertions) { 2576 } else if (compiler.enableTypeAssertions) {
(...skipping 10 matching lines...) Expand all
2562 analyzeTypeArgument(localsHandler.substInContext(subtype)); 2587 analyzeTypeArgument(localsHandler.substInContext(subtype));
2563 HInstruction supertypeInstruction = 2588 HInstruction supertypeInstruction =
2564 analyzeTypeArgument(localsHandler.substInContext(supertype)); 2589 analyzeTypeArgument(localsHandler.substInContext(supertype));
2565 HInstruction messageInstruction = 2590 HInstruction messageInstruction =
2566 graph.addConstantString(new ast.DartString.literal(message), compiler); 2591 graph.addConstantString(new ast.DartString.literal(message), compiler);
2567 Element element = helpers.assertIsSubtype; 2592 Element element = helpers.assertIsSubtype;
2568 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction, 2593 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction,
2569 messageInstruction]; 2594 messageInstruction];
2570 HInstruction assertIsSubtype = new HInvokeStatic( 2595 HInstruction assertIsSubtype = new HInvokeStatic(
2571 element, inputs, subtypeInstruction.instructionType); 2596 element, inputs, subtypeInstruction.instructionType);
2572 registry.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); 2597 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
2573 add(assertIsSubtype); 2598 add(assertIsSubtype);
2574 } 2599 }
2575 2600
2576 HGraph closeFunction() { 2601 HGraph closeFunction() {
2577 // TODO(kasperl): Make this goto an implicit return. 2602 // TODO(kasperl): Make this goto an implicit return.
2578 if (!isAborted()) closeAndGotoExit(new HGoto()); 2603 if (!isAborted()) closeAndGotoExit(new HGoto());
2579 graph.finalize(); 2604 graph.finalize();
2580 return graph; 2605 return graph;
2581 } 2606 }
2582 2607
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
3177 ClosureClassMap nestedClosureData = 3202 ClosureClassMap nestedClosureData =
3178 compiler.closureToClassMapper.getMappingForNestedFunction(node); 3203 compiler.closureToClassMapper.getMappingForNestedFunction(node);
3179 assert(nestedClosureData != null); 3204 assert(nestedClosureData != null);
3180 assert(nestedClosureData.closureClassElement != null); 3205 assert(nestedClosureData.closureClassElement != null);
3181 ClosureClassElement closureClassElement = 3206 ClosureClassElement closureClassElement =
3182 nestedClosureData.closureClassElement; 3207 nestedClosureData.closureClassElement;
3183 FunctionElement callElement = nestedClosureData.callElement; 3208 FunctionElement callElement = nestedClosureData.callElement;
3184 // TODO(ahe): This should be registered in codegen, not here. 3209 // TODO(ahe): This should be registered in codegen, not here.
3185 // TODO(johnniwinther): Is [registerStaticUse] equivalent to 3210 // TODO(johnniwinther): Is [registerStaticUse] equivalent to
3186 // [addToWorkList]? 3211 // [addToWorkList]?
3187 registry.registerStaticUse(callElement); 3212 registry?.registerStaticUse(callElement);
3188 3213
3189 List<HInstruction> capturedVariables = <HInstruction>[]; 3214 List<HInstruction> capturedVariables = <HInstruction>[];
3190 closureClassElement.closureFields.forEach((ClosureFieldElement field) { 3215 closureClassElement.closureFields.forEach((ClosureFieldElement field) {
3191 Local capturedLocal = 3216 Local capturedLocal =
3192 nestedClosureData.getLocalVariableForClosureField(field); 3217 nestedClosureData.getLocalVariableForClosureField(field);
3193 assert(capturedLocal != null); 3218 assert(capturedLocal != null);
3194 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 3219 capturedVariables.add(localsHandler.readLocal(capturedLocal));
3195 }); 3220 });
3196 3221
3197 TypeMask type = 3222 TypeMask type =
3198 new TypeMask.nonNullExact(compiler.functionClass, compiler.world); 3223 new TypeMask.nonNullExact(compiler.functionClass, compiler.world);
3199 push(new HForeignNew(closureClassElement, type, capturedVariables) 3224 push(new HForeignNew(closureClassElement, type, capturedVariables)
3200 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); 3225 ..sourceInformation = sourceInformationBuilder.buildCreate(node));
3201 3226
3202 Element methodElement = nestedClosureData.closureElement; 3227 Element methodElement = nestedClosureData.closureElement;
3203 registry.registerInstantiatedClosure(methodElement); 3228 registry?.registerInstantiatedClosure(methodElement);
3204 } 3229 }
3205 3230
3206 visitFunctionDeclaration(ast.FunctionDeclaration node) { 3231 visitFunctionDeclaration(ast.FunctionDeclaration node) {
3207 assert(isReachable); 3232 assert(isReachable);
3208 visit(node.function); 3233 visit(node.function);
3209 LocalFunctionElement localFunction = 3234 LocalFunctionElement localFunction =
3210 elements.getFunctionDefinition(node.function); 3235 elements.getFunctionDefinition(node.function);
3211 localsHandler.updateLocal(localFunction, pop()); 3236 localsHandler.updateLocal(localFunction, pop());
3212 } 3237 }
3213 3238
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
4385 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration 4410 // TODO(johnniwinther): Try to eliminate the need to distinguish declaration
4386 // and implementation signatures. Currently it is need because the 4411 // and implementation signatures. Currently it is need because the
4387 // signatures have different elements for parameters. 4412 // signatures have different elements for parameters.
4388 FunctionElement implementation = function.implementation; 4413 FunctionElement implementation = function.implementation;
4389 FunctionSignature params = implementation.functionSignature; 4414 FunctionSignature params = implementation.functionSignature;
4390 if (params.optionalParameterCount != 0) { 4415 if (params.optionalParameterCount != 0) {
4391 reporter.internalError(closure, 4416 reporter.internalError(closure,
4392 '"$name" does not handle closure with optional parameters.'); 4417 '"$name" does not handle closure with optional parameters.');
4393 } 4418 }
4394 4419
4395 registry.registerStaticUse(element); 4420 registry?.registerStaticUse(element);
4396 push(new HForeignCode( 4421 push(new HForeignCode(
4397 js.js.expressionTemplateYielding( 4422 js.js.expressionTemplateYielding(
4398 backend.emitter.staticFunctionAccess(element)), 4423 backend.emitter.staticFunctionAccess(element)),
4399 backend.dynamicType, 4424 backend.dynamicType,
4400 <HInstruction>[], 4425 <HInstruction>[],
4401 nativeBehavior: native.NativeBehavior.PURE)); 4426 nativeBehavior: native.NativeBehavior.PURE));
4402 return params; 4427 return params;
4403 } 4428 }
4404 4429
4405 void handleForeignDartClosureToJs(ast.Send node, String name) { 4430 void handleForeignDartClosureToJs(ast.Send node, String name) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
4492 String name = selector.name; 4517 String name = selector.name;
4493 4518
4494 ClassElement cls = currentNonClosureClass; 4519 ClassElement cls = currentNonClosureClass;
4495 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_); 4520 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
4496 if (compiler.enabledInvokeOn 4521 if (compiler.enabledInvokeOn
4497 && element.enclosingElement.declaration != compiler.objectClass) { 4522 && element.enclosingElement.declaration != compiler.objectClass) {
4498 // Register the call as dynamic if [noSuchMethod] on the super 4523 // Register the call as dynamic if [noSuchMethod] on the super
4499 // class is _not_ the default implementation from [Object], in 4524 // class is _not_ the default implementation from [Object], in
4500 // case the [noSuchMethod] implementation calls 4525 // case the [noSuchMethod] implementation calls
4501 // [JSInvocationMirror._invokeOn]. 4526 // [JSInvocationMirror._invokeOn].
4502 registry.registerSelectorUse(selector); 4527 registry?.registerSelectorUse(selector);
4503 } 4528 }
4504 String publicName = name; 4529 String publicName = name;
4505 if (selector.isSetter) publicName += '='; 4530 if (selector.isSetter) publicName += '=';
4506 4531
4507 ConstantValue nameConstant = constantSystem.createString( 4532 ConstantValue nameConstant = constantSystem.createString(
4508 new ast.DartString.literal(publicName)); 4533 new ast.DartString.literal(publicName));
4509 4534
4510 js.Name internalName = backend.namer.invocationName(selector); 4535 js.Name internalName = backend.namer.invocationName(selector);
4511 4536
4512 Element createInvocationMirror = helpers.createInvocationMirror; 4537 Element createInvocationMirror = helpers.createInvocationMirror;
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
4871 sourceInformation: sourceInformation); 4896 sourceInformation: sourceInformation);
4872 } else { 4897 } else {
4873 assert(member.isField); 4898 assert(member.isField);
4874 // The type variable is stored in a parameter of the method. 4899 // The type variable is stored in a parameter of the method.
4875 return localsHandler.readLocal(typeVariableLocal); 4900 return localsHandler.readLocal(typeVariableLocal);
4876 } 4901 }
4877 } else if (isInConstructorContext || 4902 } else if (isInConstructorContext ||
4878 // When [member] is a field, we can be either 4903 // When [member] is a field, we can be either
4879 // generating a checked setter or inlining its 4904 // generating a checked setter or inlining its
4880 // initializer in a constructor. An initializer is 4905 // initializer in a constructor. An initializer is
4881 // never built standalone, so [isBuildingFor] will 4906 // never built standalone, so in that case [target] is not
4882 // always return true when seeing one. 4907 // the [member] itself.
4883 (member.isField && !isBuildingFor(member))) { 4908 (member.isField && member != target)) {
4884 // The type variable is stored in a parameter of the method. 4909 // The type variable is stored in a parameter of the method.
4885 return localsHandler.readLocal( 4910 return localsHandler.readLocal(
4886 typeVariableLocal, sourceInformation: sourceInformation); 4911 typeVariableLocal, sourceInformation: sourceInformation);
4887 } else if (member.isInstanceMember) { 4912 } else if (member.isInstanceMember) {
4888 // The type variable is stored on the object. 4913 // The type variable is stored on the object.
4889 return readTypeVariable( 4914 return readTypeVariable(
4890 member.enclosingClass, 4915 member.enclosingClass,
4891 type.element, 4916 type.element,
4892 sourceInformation: sourceInformation); 4917 sourceInformation: sourceInformation);
4893 } else { 4918 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4931 HInstruction newObject) { 4956 HInstruction newObject) {
4932 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 4957 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
4933 return newObject; 4958 return newObject;
4934 } 4959 }
4935 List<HInstruction> inputs = <HInstruction>[]; 4960 List<HInstruction> inputs = <HInstruction>[];
4936 type = localsHandler.substInContext(type); 4961 type = localsHandler.substInContext(type);
4937 type.typeArguments.forEach((DartType argument) { 4962 type.typeArguments.forEach((DartType argument) {
4938 inputs.add(analyzeTypeArgument(argument)); 4963 inputs.add(analyzeTypeArgument(argument));
4939 }); 4964 });
4940 // TODO(15489): Register at codegen. 4965 // TODO(15489): Register at codegen.
4941 registry.registerInstantiatedType(type); 4966 registry?.registerInstantiatedType(type);
4942 return callSetRuntimeTypeInfo(type.element, inputs, newObject); 4967 return callSetRuntimeTypeInfo(type.element, inputs, newObject);
4943 } 4968 }
4944 4969
4945 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { 4970 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) {
4946 Element copyHelper = helpers.copyTypeArguments; 4971 Element copyHelper = helpers.copyTypeArguments;
4947 pushInvokeStatic(null, copyHelper, [source, target], 4972 pushInvokeStatic(null, copyHelper, [source, target],
4948 sourceInformation: target.sourceInformation); 4973 sourceInformation: target.sourceInformation);
4949 pop(); 4974 pop();
4950 } 4975 }
4951 4976
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
5144 typeMask: elementType, 5169 typeMask: elementType,
5145 instanceType: expectedType, 5170 instanceType: expectedType,
5146 sourceInformation: sourceInformation); 5171 sourceInformation: sourceInformation);
5147 removeInlinedInstantiation(expectedType); 5172 removeInlinedInstantiation(expectedType);
5148 } 5173 }
5149 HInstruction newInstance = stack.last; 5174 HInstruction newInstance = stack.last;
5150 if (isFixedList) { 5175 if (isFixedList) {
5151 // Overwrite the element type, in case the allocation site has 5176 // Overwrite the element type, in case the allocation site has
5152 // been inlined. 5177 // been inlined.
5153 newInstance.instructionType = elementType; 5178 newInstance.instructionType = elementType;
5154 JavaScriptItemCompilationContext context = work.compilationContext; 5179 if (context != null) {
5155 context.allocatedFixedLists.add(newInstance); 5180 context.allocatedFixedLists.add(newInstance);
5181 }
5156 } 5182 }
5157 5183
5158 // The List constructor forwards to a Dart static method that does 5184 // The List constructor forwards to a Dart static method that does
5159 // not know about the type argument. Therefore we special case 5185 // not know about the type argument. Therefore we special case
5160 // this constructor to have the setRuntimeTypeInfo called where 5186 // this constructor to have the setRuntimeTypeInfo called where
5161 // the 'new' is done. 5187 // the 'new' is done.
5162 if (backend.classNeedsRti(compiler.listClass) && 5188 if (backend.classNeedsRti(compiler.listClass) &&
5163 (isFixedListConstructorCall || isGrowableListConstructorCall || 5189 (isFixedListConstructorCall || isGrowableListConstructorCall ||
5164 isJSArrayTypedConstructor)) { 5190 isJSArrayTypedConstructor)) {
5165 newInstance = handleListConstructor(type, send, pop()); 5191 newInstance = handleListConstructor(type, send, pop());
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
5690 MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind]; 5716 MessageTemplate template = MessageTemplate.TEMPLATES[error.messageKind];
5691 Message message = template.message(error.messageArguments); 5717 Message message = template.message(error.messageArguments);
5692 generateRuntimeError(node.send, message.toString()); 5718 generateRuntimeError(node.send, message.toString());
5693 } 5719 }
5694 } else if (node.isConst) { 5720 } else if (node.isConst) {
5695 stack.add(addConstant(node)); 5721 stack.add(addConstant(node));
5696 if (isSymbolConstructor) { 5722 if (isSymbolConstructor) {
5697 ConstructedConstantValue symbol = getConstantForNode(node); 5723 ConstructedConstantValue symbol = getConstantForNode(node);
5698 StringConstantValue stringConstant = symbol.fields.values.single; 5724 StringConstantValue stringConstant = symbol.fields.values.single;
5699 String nameString = stringConstant.toDartString().slowToString(); 5725 String nameString = stringConstant.toDartString().slowToString();
5700 registry.registerConstSymbol(nameString); 5726 registry?.registerConstSymbol(nameString);
5701 } 5727 }
5702 } else { 5728 } else {
5703 handleNewSend(node); 5729 handleNewSend(node);
5704 } 5730 }
5705 } 5731 }
5706 5732
5707 @override 5733 @override
5708 void errorNonConstantConstructorInvoke( 5734 void errorNonConstantConstructorInvoke(
5709 ast.NewExpression node, 5735 ast.NewExpression node,
5710 Element element, 5736 Element element,
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
6870 void visitLiteralBool(ast.LiteralBool node) { 6896 void visitLiteralBool(ast.LiteralBool node) {
6871 stack.add(graph.addConstantBool(node.value, compiler)); 6897 stack.add(graph.addConstantBool(node.value, compiler));
6872 } 6898 }
6873 6899
6874 void visitLiteralString(ast.LiteralString node) { 6900 void visitLiteralString(ast.LiteralString node) {
6875 stack.add(graph.addConstantString(node.dartString, compiler)); 6901 stack.add(graph.addConstantString(node.dartString, compiler));
6876 } 6902 }
6877 6903
6878 void visitLiteralSymbol(ast.LiteralSymbol node) { 6904 void visitLiteralSymbol(ast.LiteralSymbol node) {
6879 stack.add(addConstant(node)); 6905 stack.add(addConstant(node));
6880 registry.registerConstSymbol(node.slowNameString); 6906 registry?.registerConstSymbol(node.slowNameString);
6881 } 6907 }
6882 6908
6883 void visitStringJuxtaposition(ast.StringJuxtaposition node) { 6909 void visitStringJuxtaposition(ast.StringJuxtaposition node) {
6884 if (!node.isInterpolation) { 6910 if (!node.isInterpolation) {
6885 // This is a simple string with no interpolations. 6911 // This is a simple string with no interpolations.
6886 stack.add(graph.addConstantString(node.dartString, compiler)); 6912 stack.add(graph.addConstantString(node.dartString, compiler));
6887 return; 6913 return;
6888 } 6914 }
6889 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); 6915 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
6890 stringBuilder.visit(node); 6916 stringBuilder.visit(node);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
7092 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { 7118 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) {
7093 InterfaceType type = localsHandler.substInContext(elements.getType(node)); 7119 InterfaceType type = localsHandler.substInContext(elements.getType(node));
7094 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 7120 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
7095 return object; 7121 return object;
7096 } 7122 }
7097 List<HInstruction> arguments = <HInstruction>[]; 7123 List<HInstruction> arguments = <HInstruction>[];
7098 for (DartType argument in type.typeArguments) { 7124 for (DartType argument in type.typeArguments) {
7099 arguments.add(analyzeTypeArgument(argument)); 7125 arguments.add(analyzeTypeArgument(argument));
7100 } 7126 }
7101 // TODO(15489): Register at codegen. 7127 // TODO(15489): Register at codegen.
7102 registry.registerInstantiatedType(type); 7128 registry?.registerInstantiatedType(type);
7103 return callSetRuntimeTypeInfo(type.element, arguments, object); 7129 return callSetRuntimeTypeInfo(type.element, arguments, object);
7104 } 7130 }
7105 7131
7106 visitLiteralList(ast.LiteralList node) { 7132 visitLiteralList(ast.LiteralList node) {
7107 HInstruction instruction; 7133 HInstruction instruction;
7108 7134
7109 if (node.isConst) { 7135 if (node.isConst) {
7110 instruction = addConstant(node); 7136 instruction = addConstant(node);
7111 } else { 7137 } else {
7112 List<HInstruction> inputs = <HInstruction>[]; 7138 List<HInstruction> inputs = <HInstruction>[];
(...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after
8995 if (unaliased is TypedefType) throw 'unable to unalias $type'; 9021 if (unaliased is TypedefType) throw 'unable to unalias $type';
8996 unaliased.accept(this, builder); 9022 unaliased.accept(this, builder);
8997 } 9023 }
8998 9024
8999 void visitDynamicType(DynamicType type, SsaBuilder builder) { 9025 void visitDynamicType(DynamicType type, SsaBuilder builder) {
9000 JavaScriptBackend backend = builder.compiler.backend; 9026 JavaScriptBackend backend = builder.compiler.backend;
9001 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 9027 ClassElement cls = backend.findHelper('DynamicRuntimeType');
9002 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 9028 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
9003 } 9029 }
9004 } 9030 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/ssa.dart ('k') | pkg/compiler/lib/src/ssa/ssa.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698