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

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

Issue 795933005: Create a Tree IR builder for JavaScript specific nodes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Move identicalFunction. Created 6 years 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
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/task.dart ('k') | no next file » | 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) 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 '../dart2jslib.dart' as dart2js; 7 import '../dart2jslib.dart' as dart2js;
8 import '../dart_types.dart'; 8 import '../dart_types.dart';
9 import '../elements/elements.dart'; 9 import '../elements/elements.dart';
10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; 10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
11 import '../util/util.dart' show CURRENT_ELEMENT_SPANNABLE; 11 import '../util/util.dart' show CURRENT_ELEMENT_SPANNABLE;
12 import 'tree_ir_nodes.dart'; 12 import 'tree_ir_nodes.dart';
13 import '../js_backend/codegen/glue.dart';
14 13
15 /** 14 /**
16 * Builder translates from CPS-based IR to direct-style Tree. 15 * Builder translates from CPS-based IR to direct-style Tree.
17 * 16 *
18 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced 17 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced
19 * non-exit continuation `Cont(v, body)` is translated into a direct-style call 18 * non-exit continuation `Cont(v, body)` is translated into a direct-style call
20 * whose value is bound in the continuation body: 19 * whose value is bound in the continuation body:
21 * 20 *
22 * `LetVal(v, Invoke(fun, args), body)` 21 * `LetVal(v, Invoke(fun, args), body)`
23 * 22 *
(...skipping 15 matching lines...) Expand all
39 * Block arguments are later replaced with data flow during the Tree-to-Tree 38 * Block arguments are later replaced with data flow during the Tree-to-Tree
40 * translation out of SSA. Jumps are eliminated during the Tree-to-Tree 39 * translation out of SSA. Jumps are eliminated during the Tree-to-Tree
41 * control-flow recognition. 40 * control-flow recognition.
42 * 41 *
43 * Otherwise, the output of Builder looks very much like the input. In 42 * Otherwise, the output of Builder looks very much like the input. In
44 * particular, intermediate values and blocks used for local control flow are 43 * particular, intermediate values and blocks used for local control flow are
45 * still all named. 44 * still all named.
46 */ 45 */
47 class Builder extends cps_ir.Visitor<Node> { 46 class Builder extends cps_ir.Visitor<Node> {
48 final dart2js.InternalErrorFunction internalError; 47 final dart2js.InternalErrorFunction internalError;
49 final Element identicalFunction;
50 final Glue glue;
51 48
52 /// Maps variable/parameter elements to the Tree variables that represent it. 49 /// Maps variable/parameter elements to the Tree variables that represent it.
53 final Map<Element, List<Variable>> element2variables = 50 final Map<Element, List<Variable>> element2variables =
54 <Element,List<Variable>>{}; 51 <Element,List<Variable>>{};
55 52
56 /// Like [element2variables], except for closure variables. 53 /// Like [element2variables], except for closure variables.
57 final Map<cps_ir.ClosureVariable, Variable> local2closure = 54 final Map<cps_ir.ClosureVariable, Variable> local2closure =
58 <cps_ir.ClosureVariable, Variable>{}; 55 <cps_ir.ClosureVariable, Variable>{};
59 56
60 // Continuations with more than one use are replaced with Tree labels. This 57 // Continuations with more than one use are replaced with Tree labels. This
61 // is the mapping from continuations to labels. 58 // is the mapping from continuations to labels.
62 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{}; 59 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
63 60
64 ExecutableElement currentElement; 61 ExecutableElement currentElement;
65 cps_ir.Continuation returnContinuation; 62 cps_ir.Continuation returnContinuation;
66 63
67 Builder parent; 64 Builder parent;
68 65
69 Builder(this.glue, this.internalError, this.identicalFunction); 66 Builder(this.internalError, [this.parent]);
70 67
71 Builder.inner(Builder parent) 68 Builder createInnerBuilder() {
72 : this.parent = parent, 69 return new Builder(internalError, this);
73 this.glue = parent.glue, 70 }
74 this.internalError = parent.internalError,
75 this.identicalFunction = parent.identicalFunction;
76 71
77 /// Variable used in [buildPhiAssignments] as a temporary when swapping 72 /// Variable used in [buildPhiAssignments] as a temporary when swapping
78 /// variables. 73 /// variables.
79 Variable phiTempVar; 74 Variable phiTempVar;
80 75
81 Variable getClosureVariable(cps_ir.ClosureVariable irVariable) { 76 Variable getClosureVariable(cps_ir.ClosureVariable irVariable) {
82 if (irVariable.host != currentElement) { 77 if (irVariable.host != currentElement) {
83 return parent.getClosureVariable(irVariable); 78 return parent.getClosureVariable(irVariable);
84 } 79 }
85 return local2closure.putIfAbsent(irVariable, 80 return local2closure.putIfAbsent(irVariable,
(...skipping 25 matching lines...) Expand all
111 CURRENT_ELEMENT_SPANNABLE, 106 CURRENT_ELEMENT_SPANNABLE,
112 "Reference to ${reference.definition} has no register"); 107 "Reference to ${reference.definition} has no register");
113 } 108 }
114 ++variable.readCount; 109 ++variable.readCount;
115 return variable; 110 return variable;
116 } 111 }
117 112
118 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { 113 ExecutableDefinition build(cps_ir.ExecutableDefinition node) {
119 if (node is cps_ir.FieldDefinition) { 114 if (node is cps_ir.FieldDefinition) {
120 return buildField(node); 115 return buildField(node);
121 } else if (node is cps_ir.FunctionDefinition) { 116 } else {
117 assert(dart2js.invariant(
118 currentElement,
119 node is cps_ir.FunctionDefinition,
120 message: 'expected FunctionDefinition or FieldDefinition, '
121 ' found $node'));
122 return buildFunction(node); 122 return buildFunction(node);
123 } 123 }
124 assert(false);
125 } 124 }
126 125
127 FieldDefinition buildField(cps_ir.FieldDefinition node) { 126 FieldDefinition buildField(cps_ir.FieldDefinition node) {
128 Statement body; 127 Statement body;
129 if (node.hasInitializer) { 128 if (node.hasInitializer) {
130 currentElement = node.element; 129 currentElement = node.element;
131 returnContinuation = node.returnContinuation; 130 returnContinuation = node.returnContinuation;
132 131
133 phiTempVar = new Variable(node.element, null); 132 phiTempVar = new Variable(node.element, null);
134 133
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 } 268 }
270 269
271 if (first == null) { 270 if (first == null) {
272 first = buildRest(); 271 first = buildRest();
273 } else { 272 } else {
274 current.next = buildRest(); 273 current.next = buildRest();
275 } 274 }
276 return first; 275 return first;
277 } 276 }
278 277
279 visitNode(cps_ir.Node node) => throw "Unhandled node: $node"; 278 visitNode(cps_ir.Node node) {
279 if (node is cps_ir.JsSpecificNode) {
280 throw "Cannot handle JS specific IR nodes in this visitor";
281 } else {
282 throw "Unhandled node: $node";
283 }
284 }
280 285
281 Statement visitLetPrim(cps_ir.LetPrim node) { 286 Statement visitLetPrim(cps_ir.LetPrim node) {
282 Variable variable = getVariable(node.primitive); 287 Variable variable = getVariable(node.primitive);
283 288
284 // Don't translate unused primitives. 289 // Don't translate unused primitives.
285 if (variable == null) return visit(node.body); 290 if (variable == null) return visit(node.body);
286 291
287 Node definition = visit(node.primitive); 292 Node definition = visit(node.primitive);
288 293
289 // visitPrimitive returns a Statement without successor if it cannot occur 294 // visitPrimitive returns a Statement without successor if it cannot occur
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 node.type, 466 node.type,
462 new List<LiteralMapEntry>.generate(node.entries.length, (int index) { 467 new List<LiteralMapEntry>.generate(node.entries.length, (int index) {
463 return new LiteralMapEntry( 468 return new LiteralMapEntry(
464 getVariableReference(node.entries[index].key), 469 getVariableReference(node.entries[index].key),
465 getVariableReference(node.entries[index].value)); 470 getVariableReference(node.entries[index].value));
466 }) 471 })
467 ); 472 );
468 } 473 }
469 474
470 FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) { 475 FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) {
471 return new Builder.inner(this).buildFunction(function); 476 return createInnerBuilder().buildFunction(function);
472 } 477 }
473 478
474 Node visitCreateFunction(cps_ir.CreateFunction node) { 479 Node visitCreateFunction(cps_ir.CreateFunction node) {
475 FunctionDefinition def = makeSubFunction(node.definition); 480 FunctionDefinition def = makeSubFunction(node.definition);
476 FunctionType type = node.definition.element.type; 481 FunctionType type = node.definition.element.type;
477 bool hasReturnType = !type.returnType.treatAsDynamic; 482 bool hasReturnType = !type.returnType.treatAsDynamic;
478 if (hasReturnType) { 483 if (hasReturnType) {
479 // This function cannot occur in expression context. 484 // This function cannot occur in expression context.
480 // The successor will be filled in by visitLetPrim. 485 // The successor will be filled in by visitLetPrim.
481 return new FunctionDeclaration(getVariable(node), def, null); 486 return new FunctionDeclaration(getVariable(node), def, null);
(...skipping 12 matching lines...) Expand all
494 Expression visitContinuation(cps_ir.Continuation node) { 499 Expression visitContinuation(cps_ir.Continuation node) {
495 // Until continuations with multiple uses are supported, they are not 500 // Until continuations with multiple uses are supported, they are not
496 // visited. 501 // visited.
497 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); 502 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.');
498 return null; 503 return null;
499 } 504 }
500 505
501 Expression visitIsTrue(cps_ir.IsTrue node) { 506 Expression visitIsTrue(cps_ir.IsTrue node) {
502 return getVariableReference(node.value); 507 return getVariableReference(node.value);
503 } 508 }
504
505 dart2js.Selector get identicalSelector {
506 return new dart2js.Selector.call('identical', null, 2);
507 }
508
509 Expression visitIdentical(cps_ir.Identical node) {
510 return new InvokeStatic(
511 identicalFunction,
512 identicalSelector,
513 <Expression>[getVariableReference(node.left),
514 getVariableReference(node.right)]);
515 }
516
517 Expression visitInterceptor(cps_ir.Interceptor node) {
518 Element getInterceptor = glue.getInterceptorMethod;
519 glue.registerUseInterceptorInCodegen();
520 return new InvokeStatic(
521 getInterceptor,
522 new dart2js.Selector.fromElement(getInterceptor),
523 <Expression>[getVariableReference(node.input)]);
524 }
525 } 509 }
526 510
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/task.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698