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

Side by Side Diff: pkg/compiler/lib/src/inferrer/builder_kernel.dart

Issue 2746293006: Pulling the element model out of global type inference. (Closed)
Patch Set: . Created 3 years, 9 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
(Empty)
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
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.
4
5 import 'package:kernel/ast.dart' as ir;
6
7 import '../closure.dart';
8 import '../compiler.dart';
9 import '../elements/elements.dart';
10 import '../elements/entities.dart';
11 import '../kernel/kernel.dart';
12 import '../ssa/kernel_ast_adapter.dart';
13 import '../tree/tree.dart' as ast;
14 import '../types/types.dart' show TypeMask;
15 import '../universe/side_effects.dart' show SideEffects;
16 import 'inferrer_engine.dart';
17 import 'locals_handler.dart';
18 import 'type_graph_nodes.dart';
19 import 'type_system.dart';
20
21 /// [KernelTypeGraphBuilder] can be thought of as a type-inference graph
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 BTW - we should be able to update these comments a
Emily Fortuna 2017/03/17 01:03:02 Done.
22 /// builder for a single element.
23 ///
24 /// Calling [run] will start the work of visiting the body of the code to
25 /// construct a set of infernece-nodes that abstractly represent what the code
26 /// is doing.
27 ///
28 /// This visitor is parameterized by an [InferenceEngine], which internally
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 similarly note the engine parameter is now gone (J
Emily Fortuna 2017/03/17 01:03:01 Done.
29 /// decides how to represent inference nodes.
30 class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
31 final Compiler compiler;
32 final AstElement originalElement;
33 // TODO(efortuna): Remove this.
34 final Element outermostElement;
35 ir.Node analyzedNode;
36 final ResolvedAst resolvedAst;
37 final TypeSystem types;
38 LocalsHandler locals;
39 final InferrerEngine inferrer;
40 SideEffects sideEffects = new SideEffects.empty();
41 int loopLevel = 0;
42 final Set<Entity> capturedVariables = new Set<Entity>();
43
44 KernelAstAdapter astAdapter;
45
46 bool get inLoop => loopLevel > 0;
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 nit: I'd move htis up next to loopLevel (it mixes
Emily Fortuna 2017/03/17 01:03:02 Done.
47
48 KernelTypeGraphBuilder.internal(this.originalElement, this.resolvedAst,
49 this.outermostElement, this.inferrer, this.compiler, this.locals)
50 : this.types = inferrer.types {
51 if (locals != null) return;
52
53 Kernel kernel = compiler.backend.kernelTask.kernel;
54 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend,
Siggi Cherem (dart-lang) 2017/03/16 00:37:45 it might not be worth making this change because t
Emily Fortuna 2017/03/17 01:03:02 Done.
55 resolvedAst, kernel.nodeToAst, kernel.nodeToElement);
56
57 analyzedNode = astAdapter.getInitialKernelNode(originalElement);
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 will analyzerNode ever change? If not, then maybe
Emily Fortuna 2017/03/17 01:03:02 Done.
58
59 ast.Node node;
Siggi Cherem (dart-lang) 2017/03/16 00:37:45 I'm guessing the idea is this will be replaced by
Emily Fortuna 2017/03/17 01:03:01 yep. The list of things to do grows very quickly!
60 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
61 node = resolvedAst.node;
62 }
63 FieldInitializationScope fieldScope = (analyzedNode is ir.Constructor)
64 ? new FieldInitializationScope(types)
65 : null;
66 locals =
67 new LocalsHandler(inferrer, types, compiler.options, node, fieldScope);
68 }
69
70 KernelTypeGraphBuilder(Element element, ResolvedAst resolvedAst,
71 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler])
72 : this.internal(
73 element,
74 resolvedAst,
75 element.outermostEnclosingMemberOrTopLevel.implementation,
76 inferrer,
77 compiler,
78 handler);
79
80 TypeInformation run() {
81 ir.Expression initializer;
82 if (analyzedNode is ir.Field) {
83 initializer = (analyzedNode as ir.Field).initializer;
Siggi Cherem (dart-lang) 2017/03/16 00:37:45 If we can make analyzerNode final above, then this
Emily Fortuna 2017/03/17 01:03:02 Hmm I made this change complete with the finals, a
Siggi Cherem (dart-lang) 2017/03/17 21:10:17 interesting - I think I understand why now - this
84 if (initializer == null) {
85 // Eagerly bailout, because computing the closure data only
86 // works for functions and field assignments.
87 return types.nullType;
88 }
89 }
90
91 // Update the locals that are boxed in [locals]. These locals will
92 // be handled specially, in that we are computing their LUB at
93 // each update, and reading them yields the type that was found in a
94 // previous analysis of [outermostElement].
95 ClosureClassMap closureData =
96 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
97 closureData.forEachCapturedVariable((variable, field) {
98 locals.setCaptured(variable, field);
99 });
100 closureData.forEachBoxedVariable((variable, field) {
101 locals.setCapturedAndBoxed(variable, field);
102 });
103
104 if (analyzedNode is ir.Field) {
105 return initializer.accept(this);
106 }
107 return _processFunctionNode(analyzedNode);
108 }
109
110 TypeInformation _processFunctionNode(ir.FunctionNode funcNode) {
111 // TODO(efortuna): Implement.
112 return types.dynamicType;
113 }
114
115 @override
116 TypeInformation defaultExpression(ir.Expression expression) {
117 // TODO(efortuna): Remove when more is implemented.
118 return types.dynamicType;
119 }
120
121 @override
122 TypeInformation visitNullLiteral(ir.NullLiteral literal) {
123 return types.nullType;
124 }
125
126 @override
127 TypeInformation visitBlock(ir.Block block) {
128 for (ir.Statement statement in block.statements) {
129 statement.accept(this);
130 if (locals.aborts) break;
131 }
132 return null;
133 }
134
135 @override
136 TypeInformation visitListLiteral(ir.ListLiteral listLiteral) {
137 // We only set the type once. We don't need to re-visit the children
138 // when re-analyzing the node.
139 return inferrer.concreteKernelTypes.putIfAbsent(listLiteral, () {
140 TypeInformation elementType;
141 int length = 0;
142 for (ir.Expression element in listLiteral.expressions) {
143 TypeInformation type = element.accept(this);
144 elementType = elementType == null
145 ? types.allocatePhi(null, null, type)
146 : types.addPhiInput(null, elementType, type);
147 length++;
148 }
149 elementType = elementType == null
150 ? types.nonNullEmpty()
151 : types.simplifyPhi(null, null, elementType);
152 TypeInformation containerType =
153 listLiteral.isConst ? types.constListType : types.growableListType;
154 // TODO(efortuna): Change signature of allocateList and the rest of
155 // type_system to deal with Kernel elements.
156 return types.allocateList(containerType, astAdapter.getNode(listLiteral),
157 outermostElement, elementType, length);
158 });
159 }
160 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698