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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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
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 tree_ir_builder; 5 library tree_ir_builder;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../constants/values.dart'; 8 import '../constants/values.dart';
9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
10 import '../elements/elements.dart'; 10 import '../elements/elements.dart';
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 <cps_ir.Primitive, Variable>{}; 55 <cps_ir.Primitive, Variable>{};
56 final Map<cps_ir.MutableVariable, Variable> mutable2variable = 56 final Map<cps_ir.MutableVariable, Variable> mutable2variable =
57 <cps_ir.MutableVariable, Variable>{}; 57 <cps_ir.MutableVariable, Variable>{};
58 final Set<cps_ir.Constant> inlinedConstants = new Set<cps_ir.Constant>(); 58 final Set<cps_ir.Constant> inlinedConstants = new Set<cps_ir.Constant>();
59 59
60 // Continuations with more than one use are replaced with Tree labels. This 60 // Continuations with more than one use are replaced with Tree labels. This
61 // is the mapping from continuations to labels. 61 // is the mapping from continuations to labels.
62 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{}; 62 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
63 63
64 ExecutableElement currentElement; 64 ExecutableElement currentElement;
65
65 /// The parameter to be translated to 'this'. This can either be the receiver 66 /// The parameter to be translated to 'this'. This can either be the receiver
66 /// parameter, the interceptor parameter, or null if the method has neither. 67 /// parameter, the interceptor parameter, or null if the method has neither.
67 cps_ir.Parameter thisParameter; 68 cps_ir.Parameter thisParameter;
68 cps_ir.Continuation returnContinuation; 69 cps_ir.Continuation returnContinuation;
69 70
70 Builder(this.internalError, this.glue); 71 Builder(this.internalError, this.glue);
71 72
72 /// Variable used in [buildPhiAssignments] as a temporary when swapping 73 /// Variable used in [buildPhiAssignments] as a temporary when swapping
73 /// variables. 74 /// variables.
74 Variable phiTempVar; 75 Variable phiTempVar;
75 76
76 Variable addMutableVariable(cps_ir.MutableVariable irVariable) { 77 Variable addMutableVariable(cps_ir.MutableVariable irVariable) {
77 assert(!mutable2variable.containsKey(irVariable)); 78 assert(!mutable2variable.containsKey(irVariable));
78 Variable variable = new Variable(currentElement, irVariable.hint); 79 Variable variable = new Variable(currentElement, irVariable.hint);
79 mutable2variable[irVariable] = variable; 80 mutable2variable[irVariable] = variable;
80 return variable; 81 return variable;
81 } 82 }
82 83
83 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) { 84 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) {
84 return mutable2variable[mutableVariable]; 85 return mutable2variable[mutableVariable];
85 } 86 }
86 87
87 VariableUse getMutableVariableUse( 88 VariableUse getMutableVariableUse(
88 cps_ir.Reference<cps_ir.MutableVariable> reference, 89 cps_ir.Reference<cps_ir.MutableVariable> reference,
89 SourceInformation sourceInformation) { 90 SourceInformation sourceInformation) {
90 Variable variable = getMutableVariable(reference.definition); 91 Variable variable = getMutableVariable(reference.definition);
91 return new VariableUse(variable, sourceInformation: sourceInformation); 92 return new VariableUse(variable, sourceInformation: sourceInformation);
92 } 93 }
93 94
94 /// Obtains the variable representing the given primitive. Returns null for 95 /// Obtains the variable representing the given primitive. Returns null for
95 /// primitives that have no reference and do not need a variable. 96 /// primitives that have no reference and do not need a variable.
96 Variable getVariable(cps_ir.Primitive primitive) { 97 Variable getVariable(cps_ir.Primitive primitive) {
97 primitive = primitive.effectiveDefinition; 98 primitive = primitive.effectiveDefinition;
98 return primitive2variable.putIfAbsent(primitive, 99 return primitive2variable.putIfAbsent(
99 () => new Variable(currentElement, primitive.hint)); 100 primitive, () => new Variable(currentElement, primitive.hint));
100 } 101 }
101 102
102 /// Obtains a reference to the tree Variable corresponding to the IR primitive 103 /// Obtains a reference to the tree Variable corresponding to the IR primitive
103 /// referred to by [reference]. 104 /// referred to by [reference].
104 /// This increments the reference count for the given variable, so the 105 /// This increments the reference count for the given variable, so the
105 /// returned expression must be used in the tree. 106 /// returned expression must be used in the tree.
106 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference, 107 Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference,
107 {SourceInformation sourceInformation}) { 108 {SourceInformation sourceInformation}) {
108 cps_ir.Primitive prim = reference.definition.effectiveDefinition; 109 cps_ir.Primitive prim = reference.definition.effectiveDefinition;
109 if (prim is cps_ir.Constant && inlinedConstants.contains(prim)) { 110 if (prim is cps_ir.Constant && inlinedConstants.contains(prim)) {
110 return new Constant(prim.value); 111 return new Constant(prim.value);
111 } 112 }
112 if (thisParameter != null && prim == thisParameter) { 113 if (thisParameter != null && prim == thisParameter) {
113 return new This(); 114 return new This();
114 } 115 }
115 return new VariableUse( 116 return new VariableUse(getVariable(prim),
116 getVariable(prim), sourceInformation: sourceInformation); 117 sourceInformation: sourceInformation);
117 } 118 }
118 119
119 Expression getVariableUseOrNull( 120 Expression getVariableUseOrNull(
120 cps_ir.Reference<cps_ir.Primitive> reference) { 121 cps_ir.Reference<cps_ir.Primitive> reference) {
121 return reference == null ? null : getVariableUse(reference); 122 return reference == null ? null : getVariableUse(reference);
122 } 123 }
123 124
124 Label getLabel(cps_ir.Continuation cont) { 125 Label getLabel(cps_ir.Continuation cont) {
125 return labels.putIfAbsent(cont, () => new Label()); 126 return labels.putIfAbsent(cont, () => new Label());
126 } 127 }
127 128
128 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { 129 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
129 currentElement = node.element; 130 currentElement = node.element;
130 List<Variable> parameters = node.parameters.map(getVariable).toList(); 131 List<Variable> parameters = node.parameters.map(getVariable).toList();
(...skipping 13 matching lines...) Expand all
144 } 145 }
145 146
146 /// Returns a list of variables corresponding to the arguments to a method 147 /// Returns a list of variables corresponding to the arguments to a method
147 /// call or similar construct. 148 /// call or similar construct.
148 /// 149 ///
149 /// The `readCount` for these variables will be incremented. 150 /// The `readCount` for these variables will be incremented.
150 /// 151 ///
151 /// The list will be typed as a list of [Expression] to allow inplace updates 152 /// The list will be typed as a list of [Expression] to allow inplace updates
152 /// on the list during the rewrite phases. 153 /// on the list during the rewrite phases.
153 List<Expression> translateArguments(List<cps_ir.Reference> args) { 154 List<Expression> translateArguments(List<cps_ir.Reference> args) {
154 return new List<Expression>.generate(args.length, 155 return new List<Expression>.generate(
155 (int index) => getVariableUse(args[index]), 156 args.length, (int index) => getVariableUse(args[index]),
156 growable: false); 157 growable: false);
157 } 158 }
158 159
159 /// Simultaneously assigns each argument to the corresponding parameter, 160 /// Simultaneously assigns each argument to the corresponding parameter,
160 /// then continues at the statement created by [buildRest]. 161 /// then continues at the statement created by [buildRest].
161 Statement buildPhiAssignments( 162 Statement buildPhiAssignments(List<cps_ir.Parameter> parameters,
162 List<cps_ir.Parameter> parameters, 163 List<Expression> arguments, Statement buildRest()) {
163 List<Expression> arguments,
164 Statement buildRest()) {
165 assert(parameters.length == arguments.length); 164 assert(parameters.length == arguments.length);
166 // We want a parallel assignment to all parameters simultaneously. 165 // We want a parallel assignment to all parameters simultaneously.
167 // Since we do not have parallel assignments in dart_tree, we must linearize 166 // Since we do not have parallel assignments in dart_tree, we must linearize
168 // the assignments without attempting to read a previously-overwritten 167 // the assignments without attempting to read a previously-overwritten
169 // value. For example {x,y = y,x} cannot be linearized to {x = y; y = x}, 168 // value. For example {x,y = y,x} cannot be linearized to {x = y; y = x},
170 // for this we must introduce a temporary variable: {t = x; x = y; y = t}. 169 // for this we must introduce a temporary variable: {t = x; x = y; y = t}.
171 170
172 // [rightHand] is the inverse of [arguments], that is, it maps variables 171 // [rightHand] is the inverse of [arguments], that is, it maps variables
173 // to the assignments on which is occurs as the right-hand side. 172 // to the assignments on which is occurs as the right-hand side.
174 Map<Variable, List<int>> rightHand = <Variable, List<int>>{}; 173 Map<Variable, List<int>> rightHand = <Variable, List<int>>{};
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 Variable param = getVariable(parameters[i]); 209 Variable param = getVariable(parameters[i]);
211 Expression arg = arguments[i]; 210 Expression arg = arguments[i];
212 if (param == null || (arg is VariableUse && param == arg.variable)) { 211 if (param == null || (arg is VariableUse && param == arg.variable)) {
213 return; // No assignment necessary. 212 return; // No assignment necessary.
214 } 213 }
215 if (assignmentSrc[i] != null) { 214 if (assignmentSrc[i] != null) {
216 // Cycle found; store argument in a temporary variable. 215 // Cycle found; store argument in a temporary variable.
217 // The temporary will then be used as right-hand side when the 216 // The temporary will then be used as right-hand side when the
218 // assignment gets added. 217 // assignment gets added.
219 VariableUse source = assignmentSrc[i]; 218 VariableUse source = assignmentSrc[i];
220 if (source.variable != phiTempVar) { // Only move to temporary once. 219 if (source.variable != phiTempVar) {
220 // Only move to temporary once.
221 assignmentSrc[i] = new VariableUse(phiTempVar); 221 assignmentSrc[i] = new VariableUse(phiTempVar);
222 addAssignment(phiTempVar, arg); 222 addAssignment(phiTempVar, arg);
223 } 223 }
224 return; 224 return;
225 } 225 }
226 assignmentSrc[i] = arg; 226 assignmentSrc[i] = arg;
227 List<int> paramUses = rightHand[param]; 227 List<int> paramUses = rightHand[param];
228 if (paramUses != null) { 228 if (paramUses != null) {
229 for (int useIndex in paramUses) { 229 for (int useIndex in paramUses) {
230 visitAssignment(useIndex); 230 visitAssignment(useIndex);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // 357 //
358 // The continuation bodies are not always translated directly here because 358 // The continuation bodies are not always translated directly here because
359 // they may have been already translated: 359 // they may have been already translated:
360 // * For singly-used continuations, the continuation's body is 360 // * For singly-used continuations, the continuation's body is
361 // translated at the site of the continuation invocation. 361 // translated at the site of the continuation invocation.
362 // * For recursive continuations, there is a single non-recursive 362 // * For recursive continuations, there is a single non-recursive
363 // invocation. The continuation's body is translated at the site 363 // invocation. The continuation's body is translated at the site
364 // of the non-recursive continuation invocation. 364 // of the non-recursive continuation invocation.
365 // See [visitInvokeContinuation] for the implementation. 365 // See [visitInvokeContinuation] for the implementation.
366 NodeCallback visitLetCont(cps_ir.LetCont node) => (Statement next) { 366 NodeCallback visitLetCont(cps_ir.LetCont node) => (Statement next) {
367 for (cps_ir.Continuation continuation in node.continuations) { 367 for (cps_ir.Continuation continuation in node.continuations) {
368 // This happens after the body of the LetCont has been translated. 368 // This happens after the body of the LetCont has been translated.
369 // Labels are created on-demand if the continuation could not be inlined, 369 // Labels are created on-demand if the continuation could not be inlin ed,
370 // so the existence of the label indicates if a labeled statement should 370 // so the existence of the label indicates if a labeled statement shou ld
371 // be emitted. 371 // be emitted.
372 Label label = labels[continuation]; 372 Label label = labels[continuation];
373 if (label != null && !continuation.isRecursive) { 373 if (label != null && !continuation.isRecursive) {
374 // Recursively build the body. We only do this for join continuations, 374 // Recursively build the body. We only do this for join continuation s,
375 // so we should not risk overly deep recursion. 375 // so we should not risk overly deep recursion.
376 next = new LabeledStatement( 376 next = new LabeledStatement(
377 label, 377 label, next, translateExpression(continuation.body));
378 next, 378 }
379 translateExpression(continuation.body)); 379 }
380 } 380 return next;
381 } 381 };
382 return next;
383 };
384 382
385 NodeCallback visitLetHandler(cps_ir.LetHandler node) => (Statement next) { 383 NodeCallback visitLetHandler(cps_ir.LetHandler node) => (Statement next) {
386 List<Variable> catchParameters = 384 List<Variable> catchParameters =
387 node.handler.parameters.map(getVariable).toList(); 385 node.handler.parameters.map(getVariable).toList();
388 Statement catchBody = translateExpression(node.handler.body); 386 Statement catchBody = translateExpression(node.handler.body);
389 return new Try(next, catchParameters, catchBody); 387 return new Try(next, catchParameters, catchBody);
390 }; 388 };
391 389
392 NodeCallback visitLetMutable(cps_ir.LetMutable node) { 390 NodeCallback visitLetMutable(cps_ir.LetMutable node) {
393 Variable variable = addMutableVariable(node.variable); 391 Variable variable = addMutableVariable(node.variable);
394 Expression value = getVariableUse(node.valueRef); 392 Expression value = getVariableUse(node.valueRef);
395 return (Statement next) => Assign.makeStatement(variable, value, next); 393 return (Statement next) => Assign.makeStatement(variable, value, next);
396 } 394 }
397 395
398 /************************** TAIL EXPRESSIONS **************************/ 396 /************************** TAIL EXPRESSIONS **************************/
399 // 397 //
400 // Visit methods for tail expressions must return a statement directly 398 // Visit methods for tail expressions must return a statement directly
(...skipping 11 matching lines...) Expand all
412 Statement visitInvokeContinuation(cps_ir.InvokeContinuation node) { 410 Statement visitInvokeContinuation(cps_ir.InvokeContinuation node) {
413 // Invocations of the return continuation are translated to returns. 411 // Invocations of the return continuation are translated to returns.
414 // Other continuation invocations are replaced with assignments of the 412 // Other continuation invocations are replaced with assignments of the
415 // arguments to formal parameter variables, followed by the body if 413 // arguments to formal parameter variables, followed by the body if
416 // the continuation is singly reference or a break if it is multiply 414 // the continuation is singly reference or a break if it is multiply
417 // referenced. 415 // referenced.
418 cps_ir.Continuation cont = node.continuation; 416 cps_ir.Continuation cont = node.continuation;
419 if (cont == returnContinuation) { 417 if (cont == returnContinuation) {
420 assert(node.argumentRefs.length == 1); 418 assert(node.argumentRefs.length == 1);
421 return new Return(getVariableUse(node.argumentRefs.single), 419 return new Return(getVariableUse(node.argumentRefs.single),
422 sourceInformation: node.sourceInformation); 420 sourceInformation: node.sourceInformation);
423 } else { 421 } else {
424 List<Expression> arguments = translateArguments(node.argumentRefs); 422 List<Expression> arguments = translateArguments(node.argumentRefs);
425 return buildPhiAssignments(cont.parameters, arguments, 423 return buildPhiAssignments(cont.parameters, arguments, () {
426 () { 424 // Translate invocations of recursive and non-recursive
427 // Translate invocations of recursive and non-recursive 425 // continuations differently.
428 // continuations differently. 426 // * Non-recursive continuations
429 // * Non-recursive continuations 427 // - If there is one use, translate the continuation body
430 // - If there is one use, translate the continuation body 428 // inline at the invocation site.
431 // inline at the invocation site. 429 // - If there are multiple uses, translate to Break.
432 // - If there are multiple uses, translate to Break. 430 // * Recursive continuations
433 // * Recursive continuations 431 // - There is a single non-recursive invocation. Translate
434 // - There is a single non-recursive invocation. Translate 432 // the continuation body inline as a labeled loop at the
435 // the continuation body inline as a labeled loop at the 433 // invocation site.
436 // invocation site. 434 // - Translate the recursive invocations to Continue.
437 // - Translate the recursive invocations to Continue. 435 if (cont.isRecursive) {
438 if (cont.isRecursive) { 436 return node.isRecursive
439 return node.isRecursive 437 ? new Continue(getLabel(cont))
440 ? new Continue(getLabel(cont)) 438 : new WhileTrue(getLabel(cont), translateExpression(cont.body));
441 : new WhileTrue(getLabel(cont), 439 } else {
442 translateExpression(cont.body)); 440 return cont.hasExactlyOneUse && !node.isEscapingTry
443 } else { 441 ? translateExpression(cont.body)
444 return cont.hasExactlyOneUse && !node.isEscapingTry 442 : new Break(getLabel(cont));
445 ? translateExpression(cont.body) 443 }
446 : new Break(getLabel(cont)); 444 });
447 }
448 });
449 } 445 }
450 } 446 }
451 447
452 /// Translates a branch condition to a tree expression. 448 /// Translates a branch condition to a tree expression.
453 Expression translateCondition(cps_ir.Branch branch) { 449 Expression translateCondition(cps_ir.Branch branch) {
454 Expression value = getVariableUse( 450 Expression value = getVariableUse(branch.conditionRef,
455 branch.conditionRef, sourceInformation: branch.sourceInformation); 451 sourceInformation: branch.sourceInformation);
456 if (branch.isStrictCheck) { 452 if (branch.isStrictCheck) {
457 return new ApplyBuiltinOperator( 453 return new ApplyBuiltinOperator(
458 BuiltinOperator.StrictEq, 454 BuiltinOperator.StrictEq,
459 <Expression>[value, new Constant(new TrueConstantValue())], 455 <Expression>[value, new Constant(new TrueConstantValue())],
460 branch.sourceInformation); 456 branch.sourceInformation);
461 } else { 457 } else {
462 return value; 458 return value;
463 } 459 }
464 } 460 }
465 461
466 Statement visitBranch(cps_ir.Branch node) { 462 Statement visitBranch(cps_ir.Branch node) {
467 Expression condition = translateCondition(node); 463 Expression condition = translateCondition(node);
468 Statement thenStatement, elseStatement; 464 Statement thenStatement, elseStatement;
469 cps_ir.Continuation cont = node.trueContinuation; 465 cps_ir.Continuation cont = node.trueContinuation;
470 assert(cont.parameters.isEmpty); 466 assert(cont.parameters.isEmpty);
471 thenStatement = cont.hasExactlyOneUse 467 thenStatement = cont.hasExactlyOneUse
472 ? translateExpression(cont.body) 468 ? translateExpression(cont.body)
473 : new Break(labels[cont]); 469 : new Break(labels[cont]);
474 cont = node.falseContinuation; 470 cont = node.falseContinuation;
475 assert(cont.parameters.isEmpty); 471 assert(cont.parameters.isEmpty);
476 elseStatement = cont.hasExactlyOneUse 472 elseStatement = cont.hasExactlyOneUse
477 ? translateExpression(cont.body) 473 ? translateExpression(cont.body)
478 : new Break(labels[cont]); 474 : new Break(labels[cont]);
479 return new If( 475 return new If(
480 condition, thenStatement, elseStatement, node.sourceInformation); 476 condition, thenStatement, elseStatement, node.sourceInformation);
481 } 477 }
482 478
483
484 /************************** PRIMITIVES **************************/ 479 /************************** PRIMITIVES **************************/
485 // 480 //
486 // Visit methods for primitives must return an expression. 481 // Visit methods for primitives must return an expression.
487 // 482 //
488 483
489 Expression visitSetField(cps_ir.SetField node) { 484 Expression visitSetField(cps_ir.SetField node) {
490 return new SetField(getVariableUse(node.objectRef), 485 return new SetField(getVariableUse(node.objectRef), node.field,
491 node.field, 486 getVariableUse(node.valueRef), node.sourceInformation);
492 getVariableUse(node.valueRef),
493 node.sourceInformation);
494 } 487 }
495 488
496 Expression visitInterceptor(cps_ir.Interceptor node) { 489 Expression visitInterceptor(cps_ir.Interceptor node) {
497 return new Interceptor(getVariableUse(node.inputRef), 490 return new Interceptor(getVariableUse(node.inputRef),
498 node.interceptedClasses, 491 node.interceptedClasses, node.sourceInformation);
499 node.sourceInformation);
500 } 492 }
501 493
502 Expression visitCreateInstance(cps_ir.CreateInstance node) { 494 Expression visitCreateInstance(cps_ir.CreateInstance node) {
503 return new CreateInstance( 495 return new CreateInstance(
504 node.classElement, 496 node.classElement,
505 translateArguments(node.argumentRefs), 497 translateArguments(node.argumentRefs),
506 getVariableUseOrNull(node.typeInformationRef), 498 getVariableUseOrNull(node.typeInformationRef),
507 node.sourceInformation); 499 node.sourceInformation);
508 } 500 }
509 501
510 Expression visitGetField(cps_ir.GetField node) { 502 Expression visitGetField(cps_ir.GetField node) {
511 return new GetField(getVariableUse(node.objectRef), node.field, 503 return new GetField(
512 node.sourceInformation, objectIsNotNull: !node.object.type.isNullable); 504 getVariableUse(node.objectRef), node.field, node.sourceInformation,
505 objectIsNotNull: !node.object.type.isNullable);
513 } 506 }
514 507
515 Expression visitCreateBox(cps_ir.CreateBox node) { 508 Expression visitCreateBox(cps_ir.CreateBox node) {
516 return new CreateBox(); 509 return new CreateBox();
517 } 510 }
518 511
519 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) { 512 Expression visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
520 return new CreateInvocationMirror( 513 return new CreateInvocationMirror(
521 node.selector, 514 node.selector, translateArguments(node.argumentRefs));
522 translateArguments(node.argumentRefs));
523 } 515 }
524 516
525 Expression visitGetMutable(cps_ir.GetMutable node) { 517 Expression visitGetMutable(cps_ir.GetMutable node) {
526 return getMutableVariableUse(node.variableRef, node.sourceInformation); 518 return getMutableVariableUse(node.variableRef, node.sourceInformation);
527 } 519 }
528 520
529 Expression visitSetMutable(cps_ir.SetMutable node) { 521 Expression visitSetMutable(cps_ir.SetMutable node) {
530 Variable variable = getMutableVariable(node.variable); 522 Variable variable = getMutableVariable(node.variable);
531 Expression value = getVariableUse(node.valueRef); 523 Expression value = getVariableUse(node.valueRef);
532 return new Assign( 524 return new Assign(variable, value,
533 variable, value, sourceInformation: node.sourceInformation); 525 sourceInformation: node.sourceInformation);
534 } 526 }
535 527
536 Expression visitConstant(cps_ir.Constant node) { 528 Expression visitConstant(cps_ir.Constant node) {
537 return new Constant(node.value, sourceInformation: node.sourceInformation); 529 return new Constant(node.value, sourceInformation: node.sourceInformation);
538 } 530 }
539 531
540 Expression visitLiteralList(cps_ir.LiteralList node) { 532 Expression visitLiteralList(cps_ir.LiteralList node) {
541 return new LiteralList( 533 return new LiteralList(node.dartType, translateArguments(node.valueRefs));
542 node.dartType,
543 translateArguments(node.valueRefs));
544 } 534 }
545 535
546 Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) { 536 Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
547 return new ReifyRuntimeType( 537 return new ReifyRuntimeType(
548 getVariableUse(node.valueRef), node.sourceInformation); 538 getVariableUse(node.valueRef), node.sourceInformation);
549 } 539 }
550 540
551 Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) { 541 Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
552 return new ReadTypeVariable( 542 return new ReadTypeVariable(
553 node.variable, 543 node.variable, getVariableUse(node.targetRef), node.sourceInformation);
554 getVariableUse(node.targetRef),
555 node.sourceInformation);
556 } 544 }
557 545
558 Expression visitTypeExpression(cps_ir.TypeExpression node) { 546 Expression visitTypeExpression(cps_ir.TypeExpression node) {
559 return new TypeExpression( 547 return new TypeExpression(node.kind, node.dartType,
560 node.kind,
561 node.dartType,
562 node.argumentRefs.map(getVariableUse).toList()); 548 node.argumentRefs.map(getVariableUse).toList());
563 } 549 }
564 550
565 Expression visitTypeTest(cps_ir.TypeTest node) { 551 Expression visitTypeTest(cps_ir.TypeTest node) {
566 Expression value = getVariableUse(node.valueRef); 552 Expression value = getVariableUse(node.valueRef);
567 List<Expression> typeArgs = translateArguments(node.typeArgumentRefs); 553 List<Expression> typeArgs = translateArguments(node.typeArgumentRefs);
568 return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: true); 554 return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: true);
569 } 555 }
570 556
571 Expression visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) { 557 Expression visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
572 Expression value = getVariableUse(node.interceptorRef); 558 Expression value = getVariableUse(node.interceptorRef);
573 // TODO(sra): Move !! to cps_ir level. 559 // TODO(sra): Move !! to cps_ir level.
574 return new Not(new Not(new GetTypeTestProperty(value, node.dartType))); 560 return new Not(new Not(new GetTypeTestProperty(value, node.dartType)));
575 } 561 }
576 562
577 Expression visitGetStatic(cps_ir.GetStatic node) { 563 Expression visitGetStatic(cps_ir.GetStatic node) {
578 return new GetStatic(node.element, node.sourceInformation); 564 return new GetStatic(node.element, node.sourceInformation);
579 } 565 }
580 566
581 Expression visitSetStatic(cps_ir.SetStatic node) { 567 Expression visitSetStatic(cps_ir.SetStatic node) {
582 return new SetStatic( 568 return new SetStatic(
583 node.element, 569 node.element, getVariableUse(node.valueRef), node.sourceInformation);
584 getVariableUse(node.valueRef),
585 node.sourceInformation);
586 } 570 }
587 571
588 Expression visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) { 572 Expression visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
589 if (node.operator == BuiltinOperator.IsFalsy) { 573 if (node.operator == BuiltinOperator.IsFalsy) {
590 return new Not(getVariableUse(node.argumentRefs.single)); 574 return new Not(getVariableUse(node.argumentRefs.single));
591 } 575 }
592 return new ApplyBuiltinOperator( 576 return new ApplyBuiltinOperator(node.operator,
593 node.operator, 577 translateArguments(node.argumentRefs), node.sourceInformation);
594 translateArguments(node.argumentRefs),
595 node.sourceInformation);
596 } 578 }
597 579
598 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { 580 Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
599 return new ApplyBuiltinMethod(node.method, 581 return new ApplyBuiltinMethod(node.method, getVariableUse(node.receiverRef),
600 getVariableUse(node.receiverRef),
601 translateArguments(node.argumentRefs), 582 translateArguments(node.argumentRefs),
602 receiverIsNotNull: !node.receiver.type.isNullable); 583 receiverIsNotNull: !node.receiver.type.isNullable);
603 } 584 }
604 585
605 Expression visitGetLength(cps_ir.GetLength node) { 586 Expression visitGetLength(cps_ir.GetLength node) {
606 return new GetLength(getVariableUse(node.objectRef)); 587 return new GetLength(getVariableUse(node.objectRef));
607 } 588 }
608 589
609 Expression visitGetIndex(cps_ir.GetIndex node) { 590 Expression visitGetIndex(cps_ir.GetIndex node) {
610 return new GetIndex(getVariableUse(node.objectRef), 591 return new GetIndex(
611 getVariableUse(node.indexRef)); 592 getVariableUse(node.objectRef), getVariableUse(node.indexRef));
612 } 593 }
613 594
614 Expression visitSetIndex(cps_ir.SetIndex node) { 595 Expression visitSetIndex(cps_ir.SetIndex node) {
615 return new SetIndex(getVariableUse(node.objectRef), 596 return new SetIndex(getVariableUse(node.objectRef),
616 getVariableUse(node.indexRef), 597 getVariableUse(node.indexRef), getVariableUse(node.valueRef));
617 getVariableUse(node.valueRef));
618 } 598 }
619 599
620 Expression visitInvokeStatic(cps_ir.InvokeStatic node) { 600 Expression visitInvokeStatic(cps_ir.InvokeStatic node) {
621 List<Expression> arguments = translateArguments(node.argumentRefs); 601 List<Expression> arguments = translateArguments(node.argumentRefs);
622 return new InvokeStatic(node.target, node.selector, arguments, 602 return new InvokeStatic(
623 node.sourceInformation); 603 node.target, node.selector, arguments, node.sourceInformation);
624 } 604 }
625 605
626 List<Expression> insertReceiverArgument(Expression receiver, 606 List<Expression> insertReceiverArgument(
627 List<Expression> arguments) { 607 Expression receiver, List<Expression> arguments) {
628 return new List<Expression>.generate(arguments.length + 1, 608 return new List<Expression>.generate(
629 (n) => n == 0 ? receiver : arguments[n - 1], 609 arguments.length + 1, (n) => n == 0 ? receiver : arguments[n - 1],
630 growable: false); 610 growable: false);
631 } 611 }
632 612
633 Expression visitInvokeMethod(cps_ir.InvokeMethod node) { 613 Expression visitInvokeMethod(cps_ir.InvokeMethod node) {
634 switch (node.callingConvention) { 614 switch (node.callingConvention) {
635 case cps_ir.CallingConvention.Normal: 615 case cps_ir.CallingConvention.Normal:
636 InvokeMethod invoke = new InvokeMethod( 616 InvokeMethod invoke = new InvokeMethod(
637 getVariableUse(node.receiverRef), 617 getVariableUse(node.receiverRef),
638 node.selector, 618 node.selector,
639 node.mask, 619 node.mask,
(...skipping 12 matching lines...) Expand all
652 node.mask, 632 node.mask,
653 arguments, 633 arguments,
654 node.sourceInformation); 634 node.sourceInformation);
655 // Sometimes we know the Dart receiver is non-null because it has been 635 // Sometimes we know the Dart receiver is non-null because it has been
656 // refined, which implies that the JS receiver also can not be null at 636 // refined, which implies that the JS receiver also can not be null at
657 // the use-site. Interceptors are not refined, so this information is 637 // the use-site. Interceptors are not refined, so this information is
658 // not always available on the JS receiver. 638 // not always available on the JS receiver.
659 // Also check the JS receiver's type, however, because sometimes we know 639 // Also check the JS receiver's type, however, because sometimes we know
660 // an interceptor is non-null because it intercepts JSNull. 640 // an interceptor is non-null because it intercepts JSNull.
661 invoke.receiverIsNotNull = 641 invoke.receiverIsNotNull =
662 !node.receiver.type.isNullable || 642 !node.receiver.type.isNullable || !node.interceptor.type.isNullable;
663 !node.interceptor.type.isNullable;
664 return invoke; 643 return invoke;
665 644
666 case cps_ir.CallingConvention.DummyIntercepted: 645 case cps_ir.CallingConvention.DummyIntercepted:
667 List<Expression> arguments = insertReceiverArgument( 646 List<Expression> arguments = insertReceiverArgument(
668 new Constant(new IntConstantValue(0)), 647 new Constant(new IntConstantValue(0)),
669 translateArguments(node.argumentRefs)); 648 translateArguments(node.argumentRefs));
670 InvokeMethod invoke = new InvokeMethod( 649 InvokeMethod invoke = new InvokeMethod(getVariableUse(node.receiverRef),
671 getVariableUse(node.receiverRef), 650 node.selector, node.mask, arguments, node.sourceInformation);
672 node.selector,
673 node.mask,
674 arguments,
675 node.sourceInformation);
676 invoke.receiverIsNotNull = !node.receiver.type.isNullable; 651 invoke.receiverIsNotNull = !node.receiver.type.isNullable;
677 return invoke; 652 return invoke;
678 653
679 case cps_ir.CallingConvention.OneShotIntercepted: 654 case cps_ir.CallingConvention.OneShotIntercepted:
680 List<Expression> arguments = insertReceiverArgument( 655 List<Expression> arguments = insertReceiverArgument(
681 getVariableUse(node.receiverRef), 656 getVariableUse(node.receiverRef),
682 translateArguments(node.argumentRefs)); 657 translateArguments(node.argumentRefs));
683 return new OneShotInterceptor( 658 return new OneShotInterceptor(
684 node.selector, 659 node.selector, node.mask, arguments, node.sourceInformation);
685 node.mask,
686 arguments,
687 node.sourceInformation);
688 } 660 }
689 } 661 }
690 662
691 Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { 663 Expression visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
692 if (node.interceptorRef != null) { 664 if (node.interceptorRef != null) {
693 return new InvokeMethodDirectly(getVariableUse(node.interceptorRef), 665 return new InvokeMethodDirectly(
666 getVariableUse(node.interceptorRef),
694 node.target, 667 node.target,
695 node.selector, 668 node.selector,
696 insertReceiverArgument(getVariableUse(node.receiverRef), 669 insertReceiverArgument(getVariableUse(node.receiverRef),
697 translateArguments(node.argumentRefs)), 670 translateArguments(node.argumentRefs)),
698 node.sourceInformation); 671 node.sourceInformation);
699 } else { 672 } else {
700 return new InvokeMethodDirectly(getVariableUse(node.receiverRef), 673 return new InvokeMethodDirectly(
674 getVariableUse(node.receiverRef),
701 node.target, 675 node.target,
702 node.selector, 676 node.selector,
703 translateArguments(node.argumentRefs), 677 translateArguments(node.argumentRefs),
704 node.sourceInformation); 678 node.sourceInformation);
705 } 679 }
706 } 680 }
707 681
708 Expression visitTypeCast(cps_ir.TypeCast node) { 682 Expression visitTypeCast(cps_ir.TypeCast node) {
709 Expression value = getVariableUse(node.valueRef); 683 Expression value = getVariableUse(node.valueRef);
710 List<Expression> typeArgs = translateArguments(node.typeArgumentRefs); 684 List<Expression> typeArgs = translateArguments(node.typeArgumentRefs);
711 return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: false); 685 return new TypeOperator(value, node.dartType, typeArgs, isTypeTest: false);
712 } 686 }
713 687
714 Expression visitInvokeConstructor(cps_ir.InvokeConstructor node) { 688 Expression visitInvokeConstructor(cps_ir.InvokeConstructor node) {
715 List<Expression> arguments = translateArguments(node.argumentRefs); 689 List<Expression> arguments = translateArguments(node.argumentRefs);
716 return new InvokeConstructor( 690 return new InvokeConstructor(node.dartType, node.target, node.selector,
717 node.dartType, 691 arguments, node.sourceInformation);
718 node.target,
719 node.selector,
720 arguments,
721 node.sourceInformation);
722 } 692 }
723 693
724 visitForeignCode(cps_ir.ForeignCode node) { 694 visitForeignCode(cps_ir.ForeignCode node) {
725 List<Expression> arguments = 695 List<Expression> arguments =
726 node.argumentRefs.map(getVariableUse).toList(growable: false); 696 node.argumentRefs.map(getVariableUse).toList(growable: false);
727 List<bool> nullableArguments = node.argumentRefs 697 List<bool> nullableArguments = node.argumentRefs
728 .map((argument) => argument.definition.type.isNullable) 698 .map((argument) => argument.definition.type.isNullable)
729 .toList(growable: false); 699 .toList(growable: false);
730 if (node.codeTemplate.isExpression) { 700 if (node.codeTemplate.isExpression) {
731 return new ForeignExpression( 701 return new ForeignExpression(
(...skipping 13 matching lines...) Expand all
745 arguments, 715 arguments,
746 node.nativeBehavior, 716 node.nativeBehavior,
747 nullableArguments, 717 nullableArguments,
748 node.dependency, 718 node.dependency,
749 node.sourceInformation); 719 node.sourceInformation);
750 }; 720 };
751 } 721 }
752 } 722 }
753 723
754 visitReceiverCheck(cps_ir.ReceiverCheck node) => (Statement next) { 724 visitReceiverCheck(cps_ir.ReceiverCheck node) => (Statement next) {
755 // The CPS IR uses 'isNullCheck' because the semantics are important. 725 // The CPS IR uses 'isNullCheck' because the semantics are important.
756 // In the Tree IR, syntax is more important, so the receiver check uses 726 // In the Tree IR, syntax is more important, so the receiver check uses
757 // "useInvoke" to denote if an invocation should be emitted. 727 // "useInvoke" to denote if an invocation should be emitted.
758 return new ReceiverCheck( 728 return new ReceiverCheck(
759 condition: getVariableUseOrNull(node.conditionRef), 729 condition: getVariableUseOrNull(node.conditionRef),
760 value: getVariableUse(node.valueRef), 730 value: getVariableUse(node.valueRef),
761 selector: node.selector, 731 selector: node.selector,
762 useSelector: node.useSelector, 732 useSelector: node.useSelector,
763 useInvoke: !node.isNullCheck, 733 useInvoke: !node.isNullCheck,
764 next: next, 734 next: next,
765 sourceInformation: node.sourceInformation); 735 sourceInformation: node.sourceInformation);
766 }; 736 };
767 737
768 Expression visitGetLazyStatic(cps_ir.GetLazyStatic node) { 738 Expression visitGetLazyStatic(cps_ir.GetLazyStatic node) {
769 return new GetStatic.lazy(node.element, node.sourceInformation); 739 return new GetStatic.lazy(node.element, node.sourceInformation);
770 } 740 }
771 741
772 @override 742 @override
773 NodeCallback visitYield(cps_ir.Yield node) { 743 NodeCallback visitYield(cps_ir.Yield node) {
774 return (Statement next) { 744 return (Statement next) {
775 return new Yield(getVariableUse(node.inputRef), node.hasStar, next); 745 return new Yield(getVariableUse(node.inputRef), node.hasStar, next);
776 }; 746 };
(...skipping 11 matching lines...) Expand all
788 758
789 /********** UNUSED VISIT METHODS *************/ 759 /********** UNUSED VISIT METHODS *************/
790 760
791 unexpectedNode(cps_ir.Node node) { 761 unexpectedNode(cps_ir.Node node) {
792 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node'); 762 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node');
793 } 763 }
794 764
795 visitFunctionDefinition(cps_ir.FunctionDefinition node) { 765 visitFunctionDefinition(cps_ir.FunctionDefinition node) {
796 unexpectedNode(node); 766 unexpectedNode(node);
797 } 767 }
768
798 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); 769 visitParameter(cps_ir.Parameter node) => unexpectedNode(node);
799 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); 770 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node);
800 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); 771 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node);
801 visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node); 772 visitRethrow(cps_ir.Rethrow node) => unexpectedNode(node);
802 visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node); 773 visitBoundsCheck(cps_ir.BoundsCheck node) => unexpectedNode(node);
803 } 774 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698