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

Unified Diff: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart
deleted file mode 100644
index 4ea9bebb5900e8c8b9236a5ab003c9ac7846253d..0000000000000000000000000000000000000000
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart
+++ /dev/null
@@ -1,954 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// IrNodes are kept in a separate library to have precise control over their
-// dependencies on other parts of the system.
-library dart2js.ir_nodes;
-
-import '../constants/expressions.dart';
-import '../constants/values.dart' as values show ConstantValue;
-import '../dart2jslib.dart' as dart2js show invariant;
-import '../elements/elements.dart';
-import '../universe/universe.dart' show Selector, SelectorKind;
-import '../dart_types.dart' show DartType, GenericType;
-
-abstract class Node {
- static int hashCount = 0;
- final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff;
-
- /// A pointer to the parent node. Is null until set by optimization passes.
- Node parent;
-
- accept(Visitor visitor);
-}
-
-abstract class Expression extends Node {
- Expression plug(Expression expr) => throw 'impossible';
-}
-
-/// The base class of things that variables can refer to: primitives,
-/// continuations, function and continuation parameters, etc.
-abstract class Definition extends Node {
- // The head of a linked-list of occurrences, in no particular order.
- Reference firstRef = null;
-
- bool get hasAtMostOneUse => firstRef == null || firstRef.next == null;
- bool get hasExactlyOneUse => firstRef != null && firstRef.next == null;
- bool get hasAtLeastOneUse => firstRef != null;
- bool get hasMultipleUses => !hasAtMostOneUse;
-
- void substituteFor(Definition other) {
- if (other.firstRef == null) return;
- Reference previous, current = other.firstRef;
- do {
- current.definition = this;
- previous = current;
- current = current.next;
- } while (current != null);
- previous.next = firstRef;
- if (firstRef != null) firstRef.previous = previous;
- firstRef = other.firstRef;
- }
-}
-
-/// An expression that cannot throw or diverge and has no side-effects.
-/// All primitives are named using the identity of the [Primitive] object.
-///
-/// Primitives may allocate objects, this is not considered side-effect here.
-///
-/// Although primitives may not mutate state, they may depend on state.
-abstract class Primitive extends Definition {
- /// The [VariableElement] or [ParameterElement] from which the primitive
- /// binding originated.
- Element hint;
-
- /// Register in which the variable binding this primitive can be allocated.
- /// Separate register spaces are used for primitives with different [element].
- /// Assigned by [RegisterAllocator], is null before that phase.
- int registerIndex;
-
- /// Use the given element as a hint for naming this primitive.
- ///
- /// Has no effect if this primitive already has a non-null [element].
- void useElementAsHint(Element hint) {
- if (this.hint == null) {
- this.hint = hint;
- }
- }
-}
-
-/// Operands to invocations and primitives are always variables. They point to
-/// their definition and are doubly-linked into a list of occurrences.
-class Reference {
- Definition definition;
- Reference previous = null;
- Reference next = null;
-
- /// A pointer to the parent node. Is null until set by optimization passes.
- Node parent;
-
- Reference(this.definition) {
- next = definition.firstRef;
- if (next != null) next.previous = this;
- definition.firstRef = this;
- }
-
- /// Unlinks this reference from the list of occurrences.
- void unlink() {
- if (previous == null) {
- assert(definition.firstRef == this);
- definition.firstRef = next;
- } else {
- previous.next = next;
- }
- if (next != null) next.previous = previous;
- }
-}
-
-/// Binding a value (primitive or constant): 'let val x = V in E'. The bound
-/// value is in scope in the body.
-/// During one-pass construction a LetVal with an empty body is used to
-/// represent one-level context 'let val x = V in []'.
-class LetPrim extends Expression implements InteriorNode {
- final Primitive primitive;
- Expression body = null;
-
- LetPrim(this.primitive);
-
- Expression plug(Expression expr) {
- assert(body == null);
- return body = expr;
- }
-
- accept(Visitor visitor) => visitor.visitLetPrim(this);
-}
-
-
-/// Binding a continuation: 'let cont k(v) = E in E'. The bound continuation
-/// is in scope in the body and the continuation parameter is in scope in the
-/// continuation body.
-/// During one-pass construction a LetCont with an empty continuation body is
-/// used to represent the one-level context 'let cont k(v) = [] in E'.
-class LetCont extends Expression implements InteriorNode {
- Continuation continuation;
- Expression body;
-
- LetCont(this.continuation, this.body);
-
- Expression plug(Expression expr) {
- assert(continuation != null && continuation.body == null);
- return continuation.body = expr;
- }
-
- accept(Visitor visitor) => visitor.visitLetCont(this);
-}
-
-abstract class Invoke {
- Selector get selector;
- List<Reference> get arguments;
-}
-
-/// Represents a node with a child node, which can be accessed through the
-/// `body` member. A typical usage is when removing a node from the CPS graph:
-///
-/// Node child = node.body;
-/// InteriorNode parent = node.parent;
-///
-/// child.parent = parent;
-/// parent.body = child;
-abstract class InteriorNode implements Node {
- Expression body;
-}
-
-/// Invoke a static function or static field getter/setter.
-class InvokeStatic extends Expression implements Invoke {
- /// [FunctionElement] or [FieldElement].
- final Entity target;
-
- /**
- * The selector encodes how the function is invoked: number of positional
- * arguments, names used in named arguments. This information is required
- * to build the [StaticCallSiteTypeInformation] for the inference graph.
- */
- final Selector selector;
-
- final Reference continuation;
- final List<Reference> arguments;
-
- InvokeStatic(this.target, this.selector, Continuation cont,
- List<Definition> args)
- : continuation = new Reference(cont),
- arguments = _referenceList(args) {
- assert(target is ErroneousElement || selector.name == target.name);
- }
-
- accept(Visitor visitor) => visitor.visitInvokeStatic(this);
-}
-
-/// Invoke a method, operator, getter, setter, or index getter/setter.
-/// Converting a method to a function object is treated as a getter invocation.
-class InvokeMethod extends Expression implements Invoke {
- final Reference receiver;
- final Selector selector;
- final Reference continuation;
- final List<Reference> arguments;
-
- InvokeMethod(Definition receiver,
- this.selector,
- Continuation cont,
- List<Definition> args)
- : receiver = new Reference(receiver),
- continuation = new Reference(cont),
- arguments = _referenceList(args) {
- assert(selector != null);
- assert(selector.kind == SelectorKind.CALL ||
- selector.kind == SelectorKind.OPERATOR ||
- (selector.kind == SelectorKind.GETTER && arguments.isEmpty) ||
- (selector.kind == SelectorKind.SETTER && arguments.length == 1) ||
- (selector.kind == SelectorKind.INDEX && arguments.length == 1) ||
- (selector.kind == SelectorKind.INDEX && arguments.length == 2));
- }
-
- accept(Visitor visitor) => visitor.visitInvokeMethod(this);
-}
-
-/// Invoke a method, operator, getter, setter, or index getter/setter from the
-/// super class in tail position.
-class InvokeSuperMethod extends Expression implements Invoke {
- final Selector selector;
- final Reference continuation;
- final List<Reference> arguments;
-
- InvokeSuperMethod(this.selector,
- Continuation cont,
- List<Definition> args)
- : continuation = new Reference(cont),
- arguments = _referenceList(args) {
- assert(selector != null);
- assert(selector.kind == SelectorKind.CALL ||
- selector.kind == SelectorKind.OPERATOR ||
- (selector.kind == SelectorKind.GETTER && arguments.isEmpty) ||
- (selector.kind == SelectorKind.SETTER && arguments.length == 1) ||
- (selector.kind == SelectorKind.INDEX && arguments.length == 1) ||
- (selector.kind == SelectorKind.INDEX && arguments.length == 2));
- }
-
- accept(Visitor visitor) => visitor.visitInvokeSuperMethod(this);
-}
-
-/// Non-const call to a constructor. The [target] may be a generative
-/// constructor, factory, or redirecting factory.
-class InvokeConstructor extends Expression implements Invoke {
- final DartType type;
- final FunctionElement target;
- final Reference continuation;
- final List<Reference> arguments;
- final Selector selector;
-
- /// The class being instantiated. This is the same as `target.enclosingClass`
- /// and `type.element`.
- ClassElement get targetClass => target.enclosingElement;
-
- /// True if this is an invocation of a factory constructor.
- bool get isFactory => target.isFactoryConstructor;
-
- InvokeConstructor(this.type,
- this.target,
- this.selector,
- Continuation cont,
- List<Definition> args)
- : continuation = new Reference(cont),
- arguments = _referenceList(args) {
- assert(dart2js.invariant(target,
- target.isErroneous || target.isConstructor,
- message: "Constructor invocation target is not a constructor: "
- "$target."));
- assert(dart2js.invariant(target,
- target.isErroneous ||
- type.isDynamic ||
- type.element == target.enclosingClass.declaration,
- message: "Constructor invocation type ${type} does not match enclosing "
- "class of target ${target}."));
- }
-
- accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
-}
-
-/// "as" casts and "is" checks.
-// We might want to turn "is"-checks into a [Primitive] as it can never diverge.
-// But then we need to special-case for is-checks with an erroneous .type as
-// these will throw.
-class TypeOperator extends Expression {
- final Reference receiver;
- final DartType type;
- final Reference continuation;
- // TODO(johnniwinther): Use `Operator` class to encapsule the operator type.
- final bool isTypeTest;
-
- TypeOperator(Primitive receiver,
- this.type,
- Continuation cont,
- {bool this.isTypeTest})
- : this.receiver = new Reference(receiver),
- this.continuation = new Reference(cont) {
- assert(isTypeTest != null);
- }
-
- bool get isTypeCast => !isTypeTest;
-
- accept(Visitor visitor) => visitor.visitTypeOperator(this);
-}
-
-/// Invoke [toString] on each argument and concatenate the results.
-class ConcatenateStrings extends Expression {
- final Reference continuation;
- final List<Reference> arguments;
-
- ConcatenateStrings(Continuation cont, List<Definition> args)
- : continuation = new Reference(cont),
- arguments = _referenceList(args);
-
- accept(Visitor visitor) => visitor.visitConcatenateStrings(this);
-}
-
-/// Gets the value from a closure variable. The identity of the variable is
-/// determined by a [Local].
-///
-/// Closure variables can be seen as ref cells that are not first-class values.
-/// A [LetPrim] with a [GetClosureVariable] can then be seen as:
-///
-/// let prim p = ![variable] in [body]
-///
-class GetClosureVariable extends Primitive {
- final Local variable;
-
- GetClosureVariable(this.variable) {
- assert(variable != null);
- }
-
- accept(Visitor visitor) => visitor.visitGetClosureVariable(this);
-}
-
-/// Assign or declare a closure variable. The identity of the variable is
-/// determined by a [Local].
-///
-/// Closure variables can be seen as ref cells that are not first-class values.
-/// If [isDeclaration], this can seen as a let binding:
-///
-/// let [variable] = ref [value] in [body]
-///
-/// And otherwise, it can be seen as a dereferencing assignment:
-///
-/// { ![variable] := [value]; [body] }
-///
-/// Closure variables without a declaring [SetClosureVariable] are implicitly
-/// declared at the entry to the [variable]'s enclosing function.
-class SetClosureVariable extends Expression implements InteriorNode {
- final Local variable;
- final Reference value;
- Expression body;
-
- /// If true, this declares a new copy of the closure variable. If so, all
- /// uses of the closure variable must occur in the [body].
- ///
- /// There can be at most one declaration per closure variable. If there is no
- /// declaration, only one copy exists (per function execution). It is best to
- /// avoid declaring closure variables if it is not necessary.
- final bool isDeclaration;
-
- SetClosureVariable(this.variable, Primitive value,
- {this.isDeclaration : false })
- : this.value = new Reference(value) {
- assert(variable != null);
- }
-
- accept(Visitor visitor) => visitor.visitSetClosureVariable(this);
-
- Expression plug(Expression expr) {
- assert(body == null);
- return body = expr;
- }
-}
-
-/// Create a potentially recursive function and store it in a closure variable.
-/// The function can access itself using [GetClosureVariable] on [variable].
-/// There must not exist a [SetClosureVariable] to [variable].
-///
-/// This can be seen as a let rec binding:
-///
-/// let rec [variable] = [definition] in [body]
-///
-class DeclareFunction extends Expression implements InteriorNode {
- final Local variable;
- final FunctionDefinition definition;
- Expression body;
-
- DeclareFunction(this.variable, this.definition);
-
- Expression plug(Expression expr) {
- assert(body == null);
- return body = expr;
- }
-
- accept(Visitor visitor) => visitor.visitDeclareFunction(this);
-}
-
-/// Invoke a continuation in tail position.
-class InvokeContinuation extends Expression {
- Reference continuation;
- List<Reference> arguments;
-
- // An invocation of a continuation is recursive if it occurs in the body of
- // the continuation itself.
- bool isRecursive;
-
- InvokeContinuation(Continuation cont, List<Definition> args,
- {recursive: false})
- : continuation = new Reference(cont),
- arguments = _referenceList(args),
- isRecursive = recursive {
- assert(cont.parameters == null ||
- cont.parameters.length == args.length);
- if (recursive) cont.isRecursive = true;
- }
-
- /// A continuation invocation whose target and arguments will be filled
- /// in later.
- ///
- /// Used as a placeholder for a jump whose target is not yet created
- /// (e.g., in the translation of break and continue).
- InvokeContinuation.uninitialized({recursive: false})
- : continuation = null,
- arguments = null,
- isRecursive = recursive;
-
- accept(Visitor visitor) => visitor.visitInvokeContinuation(this);
-}
-
-/// The base class of things which can be tested and branched on.
-abstract class Condition extends Node {
-}
-
-class IsTrue extends Condition {
- final Reference value;
-
- IsTrue(Definition val) : value = new Reference(val);
-
- accept(Visitor visitor) => visitor.visitIsTrue(this);
-}
-
-/// Choose between a pair of continuations based on a condition value.
-class Branch extends Expression {
- final Condition condition;
- final Reference trueContinuation;
- final Reference falseContinuation;
-
- Branch(this.condition, Continuation trueCont, Continuation falseCont)
- : trueContinuation = new Reference(trueCont),
- falseContinuation = new Reference(falseCont);
-
- accept(Visitor visitor) => visitor.visitBranch(this);
-}
-
-class Constant extends Primitive {
- final ConstantExpression expression;
-
- Constant(this.expression);
-
- values.ConstantValue get value => expression.value;
-
- accept(Visitor visitor) => visitor.visitConstant(this);
-}
-
-class This extends Primitive {
- This();
-
- accept(Visitor visitor) => visitor.visitThis(this);
-}
-
-/// Reify the given type variable as a [Type].
-/// This depends on the current binding of 'this'.
-class ReifyTypeVar extends Primitive {
- final TypeVariableElement typeVariable;
-
- ReifyTypeVar(this.typeVariable);
-
- values.ConstantValue get constant => null;
-
- accept(Visitor visitor) => visitor.visitReifyTypeVar(this);
-}
-
-class LiteralList extends Primitive {
- /// The List type being created; this is not the type argument.
- final GenericType type;
- final List<Reference> values;
-
- LiteralList(this.type, Iterable<Primitive> values)
- : this.values = _referenceList(values);
-
- accept(Visitor visitor) => visitor.visitLiteralList(this);
-}
-
-class LiteralMapEntry {
- final Reference key;
- final Reference value;
-
- LiteralMapEntry(Primitive key, Primitive value)
- : this.key = new Reference(key),
- this.value = new Reference(value);
-}
-
-class LiteralMap extends Primitive {
- final GenericType type;
- final List<LiteralMapEntry> entries;
-
- LiteralMap(this.type, this.entries);
-
- accept(Visitor visitor) => visitor.visitLiteralMap(this);
-}
-
-/// Create a non-recursive function.
-class CreateFunction extends Primitive {
- final FunctionDefinition definition;
-
- CreateFunction(this.definition);
-
- accept(Visitor visitor) => visitor.visitCreateFunction(this);
-}
-
-class Parameter extends Primitive {
- Parameter(Element element) {
- super.hint = element;
- }
-
- accept(Visitor visitor) => visitor.visitParameter(this);
-}
-
-/// Continuations are normally bound by 'let cont'. A continuation with one
-/// parameter and no body is used to represent a function's return continuation.
-/// The return continuation is bound by the Function, not by 'let cont'.
-class Continuation extends Definition implements InteriorNode {
- final List<Parameter> parameters;
- Expression body = null;
-
- // A continuation is recursive if it has any recursive invocations.
- bool isRecursive = false;
-
- bool get isReturnContinuation => body == null;
-
- Continuation(this.parameters);
-
- Continuation.retrn() : parameters = <Parameter>[new Parameter(null)];
-
- accept(Visitor visitor) => visitor.visitContinuation(this);
-}
-
-/// A function definition, consisting of parameters and a body. The parameters
-/// include a distinguished continuation parameter.
-class FunctionDefinition extends Node implements InteriorNode {
- final FunctionElement element;
- final Continuation returnContinuation;
- final List<Parameter> parameters;
- Expression body;
- final List<ConstDeclaration> localConstants;
-
- /// Values for optional parameters.
- final List<ConstantExpression> defaultParameterValues;
-
- FunctionDefinition(this.element, this.returnContinuation,
- this.parameters, this.body, this.localConstants,
- this.defaultParameterValues);
-
- FunctionDefinition.abstract(this.element,
- this.parameters,
- this.defaultParameterValues)
- : this.returnContinuation = null,
- this.localConstants = const <ConstDeclaration>[];
-
- accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
-
- /// Returns `true` if this function is abstract.
- ///
- /// If `true`, [body] and [returnContinuation] are `null` and [localConstants]
- /// is empty.
- bool get isAbstract => body == null;
-}
-
-List<Reference> _referenceList(Iterable<Definition> definitions) {
- return definitions.map((e) => new Reference(e)).toList();
-}
-
-abstract class Visitor<T> {
- T visit(Node node) => node.accept(this);
- // Abstract classes.
- T visitNode(Node node) => null;
- T visitExpression(Expression node) => visitNode(node);
- T visitDefinition(Definition node) => visitNode(node);
- T visitPrimitive(Primitive node) => visitDefinition(node);
- T visitCondition(Condition node) => visitNode(node);
-
- // Concrete classes.
- T visitFunctionDefinition(FunctionDefinition node) => visitNode(node);
-
- // Expressions.
- T visitLetPrim(LetPrim node) => visitExpression(node);
- T visitLetCont(LetCont node) => visitExpression(node);
- T visitInvokeStatic(InvokeStatic node) => visitExpression(node);
- T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node);
- T visitInvokeMethod(InvokeMethod node) => visitExpression(node);
- T visitInvokeSuperMethod(InvokeSuperMethod node) => visitExpression(node);
- T visitInvokeConstructor(InvokeConstructor node) => visitExpression(node);
- T visitConcatenateStrings(ConcatenateStrings node) => visitExpression(node);
- T visitBranch(Branch node) => visitExpression(node);
- T visitTypeOperator(TypeOperator node) => visitExpression(node);
- T visitSetClosureVariable(SetClosureVariable node) => visitExpression(node);
- T visitDeclareFunction(DeclareFunction node) => visitExpression(node);
-
- // Definitions.
- T visitLiteralList(LiteralList node) => visitPrimitive(node);
- T visitLiteralMap(LiteralMap node) => visitPrimitive(node);
- T visitConstant(Constant node) => visitPrimitive(node);
- T visitThis(This node) => visitPrimitive(node);
- T visitReifyTypeVar(ReifyTypeVar node) => visitPrimitive(node);
- T visitCreateFunction(CreateFunction node) => visitPrimitive(node);
- T visitGetClosureVariable(GetClosureVariable node) => visitPrimitive(node);
- T visitParameter(Parameter node) => visitPrimitive(node);
- T visitContinuation(Continuation node) => visitDefinition(node);
-
- // Conditions.
- T visitIsTrue(IsTrue node) => visitCondition(node);
-}
-
-/// Recursively visits the entire CPS term, and calls abstract `process*`
-/// (i.e. `processLetPrim`) functions in pre-order.
-abstract class RecursiveVisitor extends Visitor {
- // Ensures that RecursiveVisitor contains overrides for all relevant nodes.
- // As a rule of thumb, nodes with structure to traverse should be overridden
- // with the appropriate visits in this class (for example, visitLetCont),
- // while leaving other nodes for subclasses (i.e., visitLiteralList).
- visitNode(Node node) {
- throw "RecursiveVisitor is stale, add missing visit overrides";
- }
-
- processReference(Reference ref) {}
-
- processFunctionDefinition(FunctionDefinition node) {}
- visitFunctionDefinition(FunctionDefinition node) {
- processFunctionDefinition(node);
- node.parameters.forEach(visitParameter);
- visit(node.body);
- }
-
- // Expressions.
-
- processLetPrim(LetPrim node) {}
- visitLetPrim(LetPrim node) {
- processLetPrim(node);
- visit(node.primitive);
- visit(node.body);
- }
-
- processLetCont(LetCont node) {}
- visitLetCont(LetCont node) {
- processLetCont(node);
- visit(node.continuation);
- visit(node.body);
- }
-
- processInvokeStatic(InvokeStatic node) {}
- visitInvokeStatic(InvokeStatic node) {
- processInvokeStatic(node);
- processReference(node.continuation);
- node.arguments.forEach(processReference);
- }
-
- processInvokeContinuation(InvokeContinuation node) {}
- visitInvokeContinuation(InvokeContinuation node) {
- processInvokeContinuation(node);
- processReference(node.continuation);
- node.arguments.forEach(processReference);
- }
-
- processInvokeMethod(InvokeMethod node) {}
- visitInvokeMethod(InvokeMethod node) {
- processInvokeMethod(node);
- processReference(node.receiver);
- processReference(node.continuation);
- node.arguments.forEach(processReference);
- }
-
- processInvokeSuperMethod(InvokeSuperMethod node) {}
- visitInvokeSuperMethod(InvokeSuperMethod node) {
- processInvokeSuperMethod(node);
- processReference(node.continuation);
- node.arguments.forEach(processReference);
- }
-
- processInvokeConstructor(InvokeConstructor node) {}
- visitInvokeConstructor(InvokeConstructor node) {
- processInvokeConstructor(node);
- processReference(node.continuation);
- node.arguments.forEach(processReference);
- }
-
- processConcatenateStrings(ConcatenateStrings node) {}
- visitConcatenateStrings(ConcatenateStrings node) {
- processConcatenateStrings(node);
- processReference(node.continuation);
- node.arguments.forEach(processReference);
- }
-
-
- processBranch(Branch node) {}
- visitBranch(Branch node) {
- processBranch(node);
- processReference(node.trueContinuation);
- processReference(node.falseContinuation);
- visit(node.condition);
- }
-
- processTypeOperator(TypeOperator node) {}
- visitTypeOperator(TypeOperator node) {
- processTypeOperator(node);
- processReference(node.continuation);
- processReference(node.receiver);
- }
-
- processSetClosureVariable(SetClosureVariable node) {}
- visitSetClosureVariable(SetClosureVariable node) {
- processSetClosureVariable(node);
- processReference(node.value);
- visit(node.body);
- }
-
- processDeclareFunction(DeclareFunction node) {}
- visitDeclareFunction(DeclareFunction node) {
- processDeclareFunction(node);
- visit(node.definition);
- visit(node.body);
- }
-
- // Definitions.
-
- processLiteralList(LiteralList node) {}
- visitLiteralList(LiteralList node) {
- processLiteralList(node);
- node.values.forEach(processReference);
- }
-
- processLiteralMap(LiteralMap node) {}
- visitLiteralMap(LiteralMap node) {
- processLiteralMap(node);
- for (LiteralMapEntry entry in node.entries) {
- processReference(entry.key);
- processReference(entry.value);
- }
- }
-
- processConstant(Constant node) {}
- visitConstant(Constant node) => processConstant(node);
-
- processThis(This node) {}
- visitThis(This node) => processThis(node);
-
- processReifyTypeVar(ReifyTypeVar node) {}
- visitReifyTypeVar(ReifyTypeVar node) => processReifyTypeVar(node);
-
- processCreateFunction(CreateFunction node) {}
- visitCreateFunction(CreateFunction node) {
- processCreateFunction(node);
- visit(node.definition);
- }
-
- processGetClosureVariable(GetClosureVariable node) {}
- visitGetClosureVariable(GetClosureVariable node) =>
- processGetClosureVariable(node);
-
- processParameter(Parameter node) {}
- visitParameter(Parameter node) => processParameter(node);
-
- processContinuation(Continuation node) {}
- visitContinuation(Continuation node) {
- processContinuation(node);
- node.parameters.forEach(visitParameter);
- visit(node.body);
- }
-
- // Conditions.
-
- processIsTrue(IsTrue node) {}
- visitIsTrue(IsTrue node) {
- processIsTrue(node);
- processReference(node.value);
- }
-}
-
-/// Keeps track of currently unused register indices.
-class RegisterArray {
- int nextIndex = 0;
- final List<int> freeStack = <int>[];
-
- /// Returns an index that is currently unused.
- int makeIndex() {
- if (freeStack.isEmpty) {
- return nextIndex++;
- } else {
- return freeStack.removeLast();
- }
- }
-
- void releaseIndex(int index) {
- freeStack.add(index);
- }
-}
-
-/// Assigns indices to each primitive in the IR such that primitives that are
-/// live simultaneously never get assigned the same index.
-/// This information is used by the dart tree builder to generate fewer
-/// redundant variables.
-/// Currently, the liveness analysis is very simple and is often inadequate
-/// for removing all of the redundant variables.
-class RegisterAllocator extends Visitor {
- /// Separate register spaces for each source-level variable/parameter.
- /// Note that null is used as key for primitives without elements.
- final Map<Element, RegisterArray> elementRegisters =
- <Element, RegisterArray>{};
-
- RegisterArray getRegisterArray(Element element) {
- RegisterArray registers = elementRegisters[element];
- if (registers == null) {
- registers = new RegisterArray();
- elementRegisters[element] = registers;
- }
- return registers;
- }
-
- void allocate(Primitive primitive) {
- if (primitive.registerIndex == null) {
- primitive.registerIndex = getRegisterArray(primitive.hint).makeIndex();
- }
- }
-
- void release(Primitive primitive) {
- // Do not share indices for temporaries as this may obstruct inlining.
- if (primitive.hint == null) return;
- if (primitive.registerIndex != null) {
- getRegisterArray(primitive.hint).releaseIndex(primitive.registerIndex);
- }
- }
-
- void visitReference(Reference reference) {
- allocate(reference.definition);
- }
-
- void visitFunctionDefinition(FunctionDefinition node) {
- if (!node.isAbstract) {
- visit(node.body);
- }
- node.parameters.forEach(allocate); // Assign indices to unused parameters.
- elementRegisters.clear();
- }
-
- void visitLetPrim(LetPrim node) {
- visit(node.body);
- release(node.primitive);
- visit(node.primitive);
- }
-
- void visitLetCont(LetCont node) {
- visit(node.continuation);
- visit(node.body);
- }
-
- void visitInvokeStatic(InvokeStatic node) {
- node.arguments.forEach(visitReference);
- }
-
- void visitInvokeContinuation(InvokeContinuation node) {
- node.arguments.forEach(visitReference);
- }
-
- void visitInvokeMethod(InvokeMethod node) {
- visitReference(node.receiver);
- node.arguments.forEach(visitReference);
- }
-
- void visitInvokeSuperMethod(InvokeSuperMethod node) {
- node.arguments.forEach(visitReference);
- }
-
- void visitInvokeConstructor(InvokeConstructor node) {
- node.arguments.forEach(visitReference);
- }
-
- void visitConcatenateStrings(ConcatenateStrings node) {
- node.arguments.forEach(visitReference);
- }
-
- void visitBranch(Branch node) {
- visit(node.condition);
- }
-
- void visitLiteralList(LiteralList node) {
- node.values.forEach(visitReference);
- }
-
- void visitLiteralMap(LiteralMap node) {
- for (LiteralMapEntry entry in node.entries) {
- visitReference(entry.key);
- visitReference(entry.value);
- }
- }
-
- void visitTypeOperator(TypeOperator node) {
- visitReference(node.receiver);
- }
-
- void visitConstant(Constant node) {
- }
-
- void visitThis(This node) {
- }
-
- void visitReifyTypeVar(ReifyTypeVar node) {
- }
-
- void visitCreateFunction(CreateFunction node) {
- new RegisterAllocator().visit(node.definition);
- }
-
- void visitGetClosureVariable(GetClosureVariable node) {
- }
-
- void visitSetClosureVariable(SetClosureVariable node) {
- visit(node.body);
- visitReference(node.value);
- }
-
- void visitDeclareFunction(DeclareFunction node) {
- new RegisterAllocator().visit(node.definition);
- visit(node.body);
- }
-
- void visitParameter(Parameter node) {
- throw "Parameters should not be visited by RegisterAllocator";
- }
-
- void visitContinuation(Continuation node) {
- visit(node.body);
-
- // Arguments get allocated left-to-right, so we release parameters
- // right-to-left. This increases the likelihood that arguments can be
- // transferred without intermediate assignments.
- for (int i = node.parameters.length - 1; i >= 0; --i) {
- release(node.parameters[i]);
- }
- }
-
- void visitIsTrue(IsTrue node) {
- visitReference(node.value);
- }
-
-}
-

Powered by Google App Engine
This is Rietveld 408576698