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

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1007103003: cps-ir: Merge variables based on set-based liveness and graph coloring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase Created 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer2dart/test/end2end_data.dart ('k') | pkg/compiler/lib/src/dart_backend/backend.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index f3d9f798b09f034d458ffd8dccafac6c5b2e708d..16cf74de280e6655628e0fb5ca2fc86bc71fdbeb 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -65,11 +65,6 @@ abstract class Primitive extends Definition<Primitive> {
/// binding originated.
Entity 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].
@@ -1030,8 +1025,10 @@ class RecursiveVisitor implements Visitor {
processConstructorDefinition(node);
if (node.thisParameter != null) visit(node.thisParameter);
node.parameters.forEach(visit);
- node.initializers.forEach(visit);
- visit(node.body);
+ if (!node.isAbstract) {
+ node.initializers.forEach(visit);
+ visit(node.body);
+ }
}
processFieldInitializer(FieldInitializer node) {}
@@ -1269,278 +1266,3 @@ class RecursiveVisitor implements Visitor {
node.arguments.forEach(processReference);
}
}
-
-/// 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 implements Visitor {
- final dart2js.InternalErrorFunction internalError;
-
- /// Separate register spaces for each source-level variable/parameter.
- /// Note that null is used as key for primitives without hints.
- final Map<Local, RegisterArray> elementRegisters = <Local, RegisterArray>{};
-
- RegisterAllocator(this.internalError);
-
- RegisterArray getRegisterArray(Local local) {
- RegisterArray registers = elementRegisters[local];
- if (registers == null) {
- registers = new RegisterArray();
- elementRegisters[local] = 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 visit(Node node) => node.accept(this);
-
- void visitReference(Reference reference) {
- allocate(reference.definition);
- }
-
- void visitFieldDefinition(FieldDefinition node) {
- if (node.hasInitializer) {
- visit(node.body);
- }
- }
-
- void visitRunnableBody(RunnableBody node) {
- visit(node.body);
- }
-
- void visitFunctionDefinition(FunctionDefinition node) {
- if (!node.isAbstract) {
- visit(node.body);
- }
- // Assign indices to unused parameters.
- for (Definition param in node.parameters) {
- if (param is Primitive) {
- allocate(param);
- }
- }
- }
-
- void visitConstructorDefinition(ConstructorDefinition node) {
- if (!node.isAbstract) {
- node.initializers.forEach(visit);
- visit(node.body);
- }
- // Assign indices to unused parameters.
- for (Definition param in node.parameters) {
- if (param is Primitive) {
- allocate(param);
- }
- }
- }
-
- void visitFieldInitializer(FieldInitializer node) {
- visit(node.body.body);
- }
-
- void visitSuperInitializer(SuperInitializer node) {
- node.arguments.forEach(visit);
- }
-
- void visitLetPrim(LetPrim node) {
- visit(node.body);
- release(node.primitive);
- visit(node.primitive);
- }
-
- void visitLetCont(LetCont node) {
- node.continuations.forEach(visit);
- visit(node.body);
- }
-
- void visitLetHandler(LetHandler node) {
- visit(node.handler);
- // Handler parameters that were not used in the handler body will not have
- // had register indexes assigned. Assign them here, otherwise they will
- // be eliminated later and they should not be (i.e., a catch clause that
- // does not use the exception parameter should not have the exception
- // parameter eliminated, because it would not be well-formed anymore).
- // In any case release the parameter indexes because the parameters are
- // not live in the try block.
- node.handler.parameters.forEach((Parameter parameter) {
- allocate(parameter);
- release(parameter);
- });
- visit(node.body);
- }
-
- void visitLetMutable(LetMutable node) {
- visit(node.body);
- visitReference(node.value);
- }
-
- 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 visitInvokeMethodDirectly(InvokeMethodDirectly node) {
- visitReference(node.receiver);
- 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 visitReifyTypeVar(ReifyTypeVar node) {
- }
-
- void visitCreateFunction(CreateFunction node) {
- new RegisterAllocator(internalError).visit(node.definition);
- }
-
- void visitGetMutableVariable(GetMutableVariable node) {
- }
-
- void visitSetMutableVariable(SetMutableVariable node) {
- visit(node.body);
- visitReference(node.value);
- }
-
- void visitDeclareFunction(DeclareFunction node) {
- new RegisterAllocator(internalError).visit(node.definition);
- visit(node.body);
- }
-
- void visitParameter(Parameter node) {
- // Parameters are handled differently depending on whether they are
- // function parameters, continuation parameters, exception handler
- // parameters, etc. Thus we do not call visitParameter directly and
- // handle them explicitly in their parent IR node.
- internalError(dart2js.CURRENT_ELEMENT_SPANNABLE,
- 'tried to allocate a parameter');
- }
-
- void visitMutableVariable(MutableVariable node) {}
-
- 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);
- }
-
- // JavaScript specific nodes.
-
- void visitSetField(SetField node) {
- visit(node.body);
- visitReference(node.value);
- visitReference(node.object);
- }
-
- void visitGetField(GetField node) {
- visitReference(node.object);
- }
-
- void visitCreateBox(CreateBox node) {
- }
-
- void visitCreateInstance(CreateInstance node) {
- node.arguments.forEach(visitReference);
- node.typeInformation.forEach(visitReference);
- }
-
- void visitIdentical(Identical node) {
- visitReference(node.left);
- visitReference(node.right);
- }
-
- void visitInterceptor(Interceptor node) {
- visitReference(node.input);
- }
-
- void visitReifyRuntimeType(ReifyRuntimeType node) {
- visitReference(node.value);
- }
-
- void visitReadTypeVariable(ReadTypeVariable node) {
- visitReference(node.target);
- }
-
- @override
- visitTypeExpression(TypeExpression node) {
- node.arguments.forEach(visitReference);
- }
-}
« no previous file with comments | « pkg/analyzer2dart/test/end2end_data.dart ('k') | pkg/compiler/lib/src/dart_backend/backend.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698