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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart

Issue 57873002: Build new IR for functions returning a constant (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rename INode>IrNode. started working on inferencer Created 7 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright (c) 2013, 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 library ir_builder;
6
7 import 'ir_nodes.dart';
8 import '../elements/elements.dart';
9 import '../dart2jslib.dart';
10 import '../source_file.dart';
11 import '../tree/tree.dart';
12
13 class IrBuilderTask extends CompilerTask {
14 final Map<Element, IrNode> irNodes = new Map<Element, IrNode>();
karlklose 2013/11/06 09:11:28 How about calling this field 'nodes'?
lukas 2013/11/06 11:36:08 Done.
15
16 IrBuilderTask(Compiler compiler) : super(compiler);
17
18 String get name => 'IR builder';
19
20 void buildNodes() {
21 Map<Element, TreeElements> resolved =
22 compiler.enqueuer.resolution.resolvedElements;
23 resolved.forEach((Element element, TreeElements elementsMapping) {
24 element = element.implementation;
25
26 // @lry debug
27 if (element.name == 'noInline')
28 print(0);
29
30 SourceFile sourceFile = elementSourceFile(element);
31 IrNodeBuilderVisitor visitor =
32 new IrNodeBuilderVisitor(elementsMapping, compiler, sourceFile);
33 IrNode irNode;
34 ElementKind kind = element.kind;
35 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
36 // irNode = compileConstructor(builder, work);
37 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
38 kind == ElementKind.FUNCTION ||
39 kind == ElementKind.GETTER ||
40 kind == ElementKind.SETTER) {
41 irNode = visitor.buildMethod(element);
42 } else if (kind == ElementKind.FIELD) {
43 // @lry the below assertion holds in the ssa-builder, but not here.
44 // are instance fields never enqueued in the backend?
45 // compare to inferrer, which is not worklist-based but runs over all
46 // resolved elements
47 // assert(!element.isInstanceMember());
48 // irNode = builder.buildLazyInitializer(element);
49 } else {
50 compiler.internalErrorOnElement(element,
51 'unexpected element kind $kind');
52 }
53
54 if (irNode != null) {
55 irNodes[element] = irNode;
56 }
57
58 // @lry debug
59 if (element.name == 'noInline') {
60 // (element as dynamic).beginToken.next = null;
61 // (element as dynamic).cachedNode = null;
62 print(irNode);
63 }
64
65 });
66 }
67
68 SourceFile elementSourceFile(Element element) {
69 if (element is FunctionElement) {
70 FunctionElement functionElement = element;
71 if (functionElement.patch != null) element = functionElement.patch;
72 }
73 return element.getCompilationUnit().script.file;
74 }
75 }
76
77
78 class IrNodeBuilderVisitor extends ResolvedVisitor<IrNode> {
79 SourceFile sourceFile;
80
81 Context context;
82
83 IrNodeBuilderVisitor(TreeElements elements, Compiler compiler,
84 this.sourceFile) : super(elements, compiler) {
85 context = new Context(this);
86 }
87
88 IrNode buildMethod(FunctionElement functionElement) {
89 assert(invariant(functionElement, functionElement.isImplementation));
90 FunctionExpression function = functionElement.parseNode(compiler);
91 assert(function != null);
92 assert(!function.modifiers.isExternal());
93 assert(elements[function] != null);
94 return buildNode(function);
95 }
96
97 IrNode buildNode(Node node) {
98 try {
99 return node.accept(this);
100 } catch(e) {
101 if (e == ABORT_IRNODE_BUILDER) return null;
102 throw e;
103 }
104 }
105
106 ConstantSystem get constantSystem => compiler.backend.constantSystem;
107
108 int nodeOffset(Node node) {
109 return node.getBeginToken().charOffset;
110 }
111
112 IrNode visitFunctionExpression(FunctionExpression node) {
113 IrFunction result = new IrFunction(nodeOffset(node), const<IrNode>[]);
karlklose 2013/11/06 09:11:28 Initialize with <IrNode>[] (growable list) and fil
lukas 2013/11/06 11:36:08 Done.
114 context.openFunction(result);
115 IrNode body = node.body.accept(this);
116 if (context.statements.isNotEmpty) {
117 result.statements =
118 <IrNode>[]..addAll(context.constants)..addAll(context.statements);
119 }
120 context.closeFunction();
121 if (!context.isTopLevel()) {
122 context.enterStatement(result);
123 }
124 return result;
125 }
126
127 IrNode visitBlock(Block node) {
128 for (Node n in node.statements.nodes) {
129 n.accept(this);
130 }
131 return const IrNoValue();
132 }
133
134 IrNode visitReturn(Return node) {
135 IrNode value;
136 if (node.expression == null) {
137 value = context.enterConstant(constantSystem.createNull(), node);
138 } else {
139 value = node.expression.accept(this);
140 }
141 return context.enterStatement(
142 new IrReturn(nodeOffset(node), context.returnFunction, value));
143 }
144
145 IrConstant visitLiteralBool(LiteralBool node) =>
146 context.enterConstant(constantSystem.createBool(node.value), node);
147
148 IrConstant visitLiteralDouble(LiteralDouble node) =>
149 context.enterConstant(constantSystem.createDouble(node.value), node);
150
151 IrConstant visitLiteralInt(LiteralInt node) =>
152 context.enterConstant(constantSystem.createInt(node.value), node);
153
154 IrConstant visitLiteralString(LiteralString node) =>
155 context.enterConstant(
156 constantSystem.createString(node.dartString, node), node);
157
158 IrConstant visitLiteralNull(LiteralNull node) =>
159 context.enterConstant(constantSystem.createNull(), node);
160
161 // IrNode visitLiteralList(LiteralList node) => visitExpression(node);
162 // IrNode visitLiteralMap(LiteralMap node) => visitExpression(node);
163 // IrNode visitLiteralMapEntry(LiteralMapEntry node) => visitNode(node);
164 // IrNode visitLiteralSymbol(LiteralSymbol node) => visitExpression(node);
165
166
167 IrNode visitAssert(Send node) {
168 return giveup();
169 }
170
171 IrNode visitClosureSend(Send node) {
172 return giveup();
173 }
174
175 IrNode visitDynamicSend(Send node) {
176 return giveup();
177 }
178
179 IrNode visitGetterSend(Send node) {
180 return giveup();
181 }
182
183 IrNode visitOperatorSend(Send node) {
184 return giveup();
185 }
186
187 IrNode visitStaticSend(Send node) {
188 return giveup();
189 }
190
191 IrNode visitSuperSend(Send node) {
192 return giveup();
193 }
194
195 IrNode visitTypeReferenceSend(Send node) {
196 return giveup();
197 }
198
199 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
200
201 IrNode giveup() => throw ABORT_IRNODE_BUILDER;
202
203 void internalError(String reason, {Node node}) {
204 giveup();
205 }
206 }
207
208 class Context {
209 IrNodeBuilderVisitor visitor;
210 Context(this.visitor);
211
212 List<IrFunction> returnFunctionList = <IrFunction>[];
213 IrFunction get returnFunction => returnFunctionList.last;
214
215 List<List<IrNode>> statementsList = <List<IrNode>>[];
216 List<IrNode> get statements => statementsList.last;
217
218 List<List<IrConstant>> constantsList = <List<IrConstant>>[];
219 List<IrConstant> get constants => constantsList.last;
220
221 IrConstant enterConstant(Constant value, Node node) {
222 return constants.firstWhere((c) => c.value == value, orElse: () {
223 IrConstant c = new IrConstant(visitor.nodeOffset(node), value);
224 constants.add(c);
225 return c;
226 });
227 }
228
229 IrNode enterStatement(IrNode statement) {
230 statements.add(statement);
231 return statement;
232 }
233
234 void openFunction(IrFunction function) {
235 returnFunctionList.add(function);
236 statementsList.add(<IrNode>[]);
237 constantsList.add(<IrConstant>[]);
238 }
239
240 void closeFunction() {
241 returnFunctionList.removeLast();
242 statementsList.removeLast();
243 constantsList.removeLast();
244 }
245
246 void openContinuation() {
247 statementsList.add(<IrNode>[]);
248 }
249
250 void closeContinuation() {
251 statementsList.removeLast();
252 }
253
254 isTopLevel() => returnFunctionList.isEmpty;
255 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698