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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart

Issue 233153002: Support assignment to parameters in the dart2dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart_tree; 5 library dart_tree;
6 6
7 import '../dart2jslib.dart' as dart2js; 7 import '../dart2jslib.dart' as dart2js;
8 import '../dart_types.dart'; 8 import '../dart_types.dart';
9 import '../util/util.dart'; 9 import '../util/util.dart';
10 import '../elements/elements.dart' 10 import '../elements/elements.dart'
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 accept(Visitor visitor) => visitor.visitSequence(this); 82 accept(Visitor visitor) => visitor.visitSequence(this);
83 } 83 }
84 84
85 /** 85 /**
86 * A local binding of a [Variable] to an [Expression]. 86 * A local binding of a [Variable] to an [Expression].
87 * 87 *
88 * In contrast to the CPS-based IR, non-primitive expressions can be named 88 * In contrast to the CPS-based IR, non-primitive expressions can be named
89 * with let. 89 * with let.
90 */ 90 */
91 class LetVal extends Expression { 91 class LetVal extends Expression {
92 final bool hasExactlyOneUse;
92 final Variable variable; 93 final Variable variable;
93 final Expression definition; 94 Expression definition;
94 final Expression body; 95 Expression body;
95 96
96 LetVal(this.variable, this.definition, this.body); 97 LetVal(this.hasExactlyOneUse, this.variable, this.definition, this.body);
floitsch 2014/04/10 17:24:46 I would put this last. It seems less important tha
Kevin Millikin (Google) 2014/04/11 08:31:23 Good reason, done.
97 98
98 bool get isPure => definition.isPure && body.isPure; 99 bool get isPure => definition.isPure && body.isPure;
99 100
100 accept(Visitor visitor) => visitor.visitLetVal(this); 101 accept(Visitor visitor) => visitor.visitLetVal(this);
101 } 102 }
102 103
103 /** 104 /**
104 * A call to a static target. 105 * A call to a static target.
105 * 106 *
106 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions. 107 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 function = new FunctionDefinition(parameters, node.body.accept(this)); 237 function = new FunctionDefinition(parameters, node.body.accept(this));
237 return null; 238 return null;
238 } 239 }
239 240
240 Expression visitLetPrim(ir.LetPrim node) { 241 Expression visitLetPrim(ir.LetPrim node) {
241 // LetPrim is translated to LetVal. 242 // LetPrim is translated to LetVal.
242 Expression definition = node.primitive.accept(this); 243 Expression definition = node.primitive.accept(this);
243 if (node.primitive.hasAtLeastOneUse) { 244 if (node.primitive.hasAtLeastOneUse) {
244 Variable variable = new Variable(null); 245 Variable variable = new Variable(null);
245 variables[node.primitive] = variable; 246 variables[node.primitive] = variable;
246 return new LetVal(variable, definition, node.body.accept(this)); 247 return new LetVal(node.primitive.hasExactlyOneUse, variable,
248 definition, node.body.accept(this));
247 } else { 249 } else {
248 return new Sequence([definition, node.body.accept(this)]); 250 return new Sequence([definition, node.body.accept(this)]);
249 } 251 }
250 } 252 }
251 253
252 Expression visitLetCont(ir.LetCont node) { 254 Expression visitLetCont(ir.LetCont node) {
253 // TODO(kmillikin): Allow continuations to have multiple uses. This could 255 // TODO(kmillikin): Allow continuations to have multiple uses. This could
254 // arise due to the representation of local control flow or due to 256 // arise due to the representation of local control flow or due to
255 // optimization. 257 // optimization.
256 assert(node.continuation.hasAtMostOneUse); 258 assert(node.continuation.hasAtMostOneUse);
257 return node.body.accept(this); 259 return node.body.accept(this);
258 } 260 }
259 261
260 Expression visitInvokeStatic(ir.InvokeStatic node) { 262 Expression visitInvokeStatic(ir.InvokeStatic node) {
261 // Calls are translated to direct style. 263 // Calls are translated to direct style.
262 List<Expression> arguments = translateArguments(node.arguments); 264 List<Expression> arguments = translateArguments(node.arguments);
263 Expression invoke = new InvokeStatic(node.target, arguments); 265 Expression invoke = new InvokeStatic(node.target, arguments);
264 ir.Continuation cont = node.continuation.definition; 266 ir.Continuation cont = node.continuation.definition;
265 if (cont == returnContinuation) { 267 if (cont == returnContinuation) {
266 return new Return(invoke); 268 return new Return(invoke);
267 } else { 269 } else {
268 assert(cont.hasExactlyOneUse); 270 assert(cont.hasExactlyOneUse);
269 if (cont.parameter.hasAtLeastOneUse) { 271 if (cont.parameter.hasAtLeastOneUse) {
270 Variable variable = new Variable(null); 272 Variable variable = new Variable(null);
271 variables[cont.parameter] = variable; 273 variables[cont.parameter] = variable;
272 return new LetVal(variable, invoke, cont.body.accept(this)); 274 return new LetVal(cont.parameter.hasExactlyOneUse, variable,
275 invoke, cont.body.accept(this));
273 } else { 276 } else {
274 return new Sequence([invoke, cont.body.accept(this)]); 277 return new Sequence([invoke, cont.body.accept(this)]);
275 } 278 }
276 } 279 }
277 } 280 }
278 281
279 Expression visitInvokeContinuation(ir.InvokeContinuation node) { 282 Expression visitInvokeContinuation(ir.InvokeContinuation node) {
280 // TODO(kmillikin): Support non-return continuations. These could arise 283 // TODO(kmillikin): Support non-return continuations. These could arise
281 // due to local control flow or due to inlining or other optimization. 284 // due to local control flow or due to inlining or other optimization.
282 assert(node.continuation.definition == returnContinuation); 285 assert(node.continuation.definition == returnContinuation);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 349
347 // TODO(kmillikin): It's not always beneficial to propagate pure 350 // TODO(kmillikin): It's not always beneficial to propagate pure
348 // definitions---it can prevent propagation of their inputs. Implement 351 // definitions---it can prevent propagation of their inputs. Implement
349 // a heuristic to avoid this. 352 // a heuristic to avoid this.
350 353
351 // TODO(kmillikin): Replace linear search with something faster in 354 // TODO(kmillikin): Replace linear search with something faster in
352 // practice. 355 // practice.
353 bool seenImpure = false; 356 bool seenImpure = false;
354 for (int i = environment.length - 1; i >= 0; --i) { 357 for (int i = environment.length - 1; i >= 0; --i) {
355 if (environment[i].variable == node) { 358 if (environment[i].variable == node) {
356 if (!seenImpure || environment[i].definition.isPure) { 359 if ((!seenImpure || environment[i].definition.isPure)
360 && environment[i].hasExactlyOneUse) {
357 // Use the definition if it is pure or if it is the first impure 361 // Use the definition if it is pure or if it is the first impure
358 // definition (i.e., propagating past only pure expressions). 362 // definition (i.e., propagating past only pure expressions).
359 return environment.removeAt(i).definition.accept(this); 363 return environment.removeAt(i).definition.accept(this);
360 } 364 }
361 break; 365 break;
362 } else if (!environment[i].definition.isPure) { 366 } else if (!environment[i].definition.isPure) {
363 // Once the first impure definition is seen, impure definitions should 367 // Once the first impure definition is seen, impure definitions should
364 // no longer be propagated. Continue searching for a pure definition. 368 // no longer be propagated. Continue searching for a pure definition.
365 seenImpure = true; 369 seenImpure = true;
366 } 370 }
367 } 371 }
368 // If the definition could not be propagated, leave the variable use. 372 // If the definition could not be propagated, leave the variable use.
369 return node; 373 return node;
370 } 374 }
371 375
372 Expression visitSequence(Sequence node) { 376 Expression visitSequence(Sequence node) {
373 for (int i = 0; i < node.expressions.length; ++i) { 377 for (int i = 0; i < node.expressions.length; ++i) {
374 node.expressions[i] = node.expressions[i].accept(this); 378 node.expressions[i] = node.expressions[i].accept(this);
375 } 379 }
376 return node; 380 return node;
377 } 381 }
378 382
379 Expression visitLetVal(LetVal node) { 383 Expression visitLetVal(LetVal node) {
380 environment.add(node); 384 environment.add(node);
381 Expression body = node.body.accept(this); 385 Expression body = node.body.accept(this);
382 386
383 // TODO(kmillikin): Allow definitions that are not propagated. Currently, 387 if (!environment.isEmpty && environment.last == node) {
384 // the only bindings are anonymous intermediate values (which only have one 388 // The definition could not be propagated. Residualize the let binding.
385 // use in the absence of optimizations) and they are not reordered. 389 node.body = body;
390 environment.removeLast();
391 node.definition = node.definition.accept(this);
392 return node;
393 }
386 assert(!environment.contains(node)); 394 assert(!environment.contains(node));
387 return body; 395 return body;
388 } 396 }
389 397
390 Expression visitInvokeStatic(InvokeStatic node) { 398 Expression visitInvokeStatic(InvokeStatic node) {
391 // Process arguments right-to-left, the opposite of evaluation order. 399 // Process arguments right-to-left, the opposite of evaluation order.
392 for (int i = node.arguments.length - 1; i >= 0; --i) { 400 for (int i = node.arguments.length - 1; i >= 0; --i) {
393 node.arguments[i] = node.arguments[i].accept(this); 401 node.arguments[i] = node.arguments[i].accept(this);
394 } 402 }
395 return node; 403 return node;
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 } 753 }
746 754
747 ast.Expression visitInterceptor(dart2js.InterceptorConstant constant) { 755 ast.Expression visitInterceptor(dart2js.InterceptorConstant constant) {
748 return unimplemented(); 756 return unimplemented();
749 } 757 }
750 758
751 ast.Expression visitDummy(dart2js.DummyConstant constant) { 759 ast.Expression visitDummy(dart2js.DummyConstant constant) {
752 return unimplemented(); 760 return unimplemented();
753 } 761 }
754 } 762 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698