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

Unified Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1398393002: Decouple SSA builder from codegen-work-item (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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/compiler/lib/src/native/ssa.dart ('k') | pkg/compiler/lib/src/ssa/ssa.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/ssa/builder.dart
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 080328ff34136702257fecf37bcf491592c6f7ba..604a6c34e7f7deb77aca6f551efa83d7af2e7369 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -66,40 +66,23 @@ class SsaBuilderTask extends CompilerTask {
return measure(() {
Element element = work.element.implementation;
return reporter.withCurrentElement(element, () {
- HInstruction.idCounter = 0;
SsaBuilder builder =
- new SsaBuilder(
- backend, work, emitter.nativeEmitter,
+ new SsaBuilder(work.element.implementation,
+ work.resolutionTree, work.compilationContext, work.registry,
+ backend, emitter.nativeEmitter,
sourceInformationFactory);
- HGraph graph;
- ElementKind kind = element.kind;
- if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
- graph = compileConstructor(builder, work);
- } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
- kind == ElementKind.FUNCTION ||
- kind == ElementKind.GETTER ||
- kind == ElementKind.SETTER) {
- graph = builder.buildMethod(element);
- } else if (kind == ElementKind.FIELD) {
- if (element.isInstanceMember) {
- assert(compiler.enableTypeAssertions);
- graph = builder.buildCheckedSetter(element);
- } else {
- graph = builder.buildLazyInitializer(element);
- }
- } else {
- reporter.internalError(element, 'Unexpected element kind $kind.');
- }
- assert(graph.isValid());
- if (!identical(kind, ElementKind.FIELD)) {
+ HGraph graph = builder.build();
+
+ // Default arguments are handled elsewhere, but we must ensure
+ // that the default values are computed during codegen.
+ if (!identical(element.kind, ElementKind.FIELD)) {
FunctionElement function = element;
FunctionSignature signature = function.functionSignature;
signature.forEachOptionalParameter((ParameterElement parameter) {
// This ensures the default value will be computed.
ConstantValue constant =
backend.constants.getConstantValueForVariable(parameter);
- CodegenRegistry registry = work.registry;
- registry.registerCompileTimeConstant(constant);
+ work.registry.registerCompileTimeConstant(constant);
});
}
if (compiler.tracer.isEnabled) {
@@ -123,9 +106,6 @@ class SsaBuilderTask extends CompilerTask {
});
}
- HGraph compileConstructor(SsaBuilder builder, CodegenWorkItem work) {
- return builder.buildFactory(work.element);
- }
}
/**
@@ -998,18 +978,44 @@ class SsaBuilder extends ast.Visitor
NewBulkMixin,
ErrorBulkMixin
implements SemanticSendVisitor {
+
+ /// The element for which this SSA builder is being used.
+ final Element target;
+
+ /// Reference to resolved elements in [target]'s AST.
+ TreeElements elements;
+
+ /// Used to report information about inlining (which occurs while building the
+ /// SSA graph), when dump-info is enabled.
+ final InfoReporter infoReporter;
+
+ /// If not null, the builder will store in [context] data that is used later
+ /// during the optimization phases.
+ final JavaScriptItemCompilationContext context;
+
+ /// Registry used to enqueue work during codegen, may be null to avoid
+ /// enqueing any work.
+ // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be
+ // able to return the impact as a result after building and avoid enqueing
+ // things here. Later the codegen task can decide whether to enqueue
+ // something. In the past this didn't matter as much because the SSA graph was
+ // used only for codegen, but currently we want to experiment using it for
+ // code-analysis too.
+ final CodegenRegistry registry;
final Compiler compiler;
final JavaScriptBackend backend;
final ConstantSystem constantSystem;
- final CodegenWorkItem work;
final RuntimeTypes rti;
- TreeElements elements;
+
SourceInformationBuilder sourceInformationBuilder;
+
bool inLazyInitializerExpression = false;
+ // TODO(sigmund): make all comments /// instead of /* */
/* This field is used by the native handler. */
final NativeEmitter nativeEmitter;
+ /// Holds the resulting SSA graph.
final HGraph graph = new HGraph();
/**
@@ -1089,22 +1095,21 @@ class SsaBuilder extends ast.Visitor
element.asyncMarker == AsyncMarker.ASYNC);
}
- SsaBuilder(JavaScriptBackend backend,
- CodegenWorkItem work,
- this.nativeEmitter,
- SourceInformationStrategy sourceInformationFactory)
+ // TODO(sigmund): make most args optional
+ SsaBuilder(this.target, this.elements, this.context, this.registry,
+ JavaScriptBackend backend, this.nativeEmitter,
+ SourceInformationStrategy sourceInformationFactory)
: this.compiler = backend.compiler,
+ this.infoReporter = backend.compiler.dumpInfoTask,
this.backend = backend,
this.constantSystem = backend.constantSystem,
- this.work = work,
- this.rti = backend.rti,
- this.elements = work.resolutionTree {
- graph.element = work.element;
- localsHandler = new LocalsHandler(this, work.element, null);
- sourceElementStack.add(work.element);
- sourceInformationBuilder =
- sourceInformationFactory.createBuilderForContext(
- work.element.implementation);
+ this.rti = backend.rti {
+ assert(target.isImplementation);
+ graph.element = target;
+ localsHandler = new LocalsHandler(this, target, null);
+ sourceElementStack.add(target);
+ sourceInformationBuilder = sourceInformationFactory.createBuilderForContext(
+ target);
}
BackendHelpers get helpers => backend.helpers;
@@ -1126,8 +1131,6 @@ class SsaBuilder extends ast.Visitor
node.accept(this);
}
- CodegenRegistry get registry => work.registry;
-
/// Returns the current source element.
///
/// The returned element is a declaration element.
@@ -1138,6 +1141,36 @@ class SsaBuilder extends ast.Visitor
bool get _checkOrTrustTypes =>
compiler.enableTypeAssertions || compiler.trustTypeAnnotations;
+ /// Build the graph for [target].
+ HGraph build() {
+ assert(invariant(target, target.isImplementation));
+ HInstruction.idCounter = 0;
+ ElementKind kind = target.kind;
+ // TODO(sigmund): remove `result` and return graph directly, need to ensure
+ // that it can never be null (see result in buildFactory for instance).
+ var result;
+ if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+ result = buildFactory(target);
+ } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
+ kind == ElementKind.FUNCTION ||
+ kind == ElementKind.GETTER ||
+ kind == ElementKind.SETTER) {
+ result = buildMethod(target);
+ } else if (kind == ElementKind.FIELD) {
+ if (target.isInstanceMember) {
+ assert(compiler.enableTypeAssertions);
+ result = buildCheckedSetter(target);
+ } else {
+ result = buildLazyInitializer(target);
+ }
+ } else {
+ reporter.internalError(target, 'Unexpected element kind $kind.');
+ }
+ assert(result.isValid());
+ return result;
+ }
+
+
HBasicBlock addNewBlock() {
HBasicBlock block = graph.addNewBlock();
// If adding a new block during building of an expression, it is due to
@@ -1480,9 +1513,8 @@ class SsaBuilder extends ast.Visitor
if (meetsHardConstraints() && heuristicSayGoodToGo()) {
doInlining();
- registry.registerInlining(
- element,
- compiler.currentElement);
+ infoReporter?.reportInlined(element,
+ inliningStack.isEmpty ? target : inliningStack.last.function);
return true;
}
@@ -1533,13 +1565,6 @@ class SsaBuilder extends ast.Visitor
}
}
- /**
- * Returns whether this builder is building code for [element].
- */
- bool isBuildingFor(Element element) {
- return work.element == element;
- }
-
/// A stack of [DartType]s the have been seen during inlining of factory
/// constructors. These types are preserved in [HInvokeStatic]s and
/// [HForeignNew]s inside the inline code and registered during code
@@ -1609,7 +1634,7 @@ class SsaBuilder extends ast.Visitor
graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
ast.FunctionExpression function = functionElement.node;
assert(function != null);
- assert(!function.modifiers.isExternal);
+ assert(invariant(functionElement, !function.modifiers.isExternal));
assert(elements.getFunctionDefinition(function) != null);
openFunction(functionElement, function);
String name = functionElement.name;
@@ -1680,10 +1705,10 @@ class SsaBuilder extends ast.Visitor
HGraph buildLazyInitializer(VariableElement variable) {
inLazyInitializerExpression = true;
- ast.VariableDefinitions node = variable.node;
- openFunction(variable, node);
assert(invariant(variable, variable.initializer != null,
message: "Non-constant variable $variable has no initializer."));
+ ast.VariableDefinitions node = variable.node;
+ openFunction(variable, node);
visit(variable.initializer);
HInstruction value = pop();
value = potentiallyCheckOrTrustType(value, variable.type);
@@ -2538,7 +2563,7 @@ class SsaBuilder extends ast.Visitor
assert(type != null);
type = localsHandler.substInContext(type);
HInstruction other = buildTypeConversion(original, type, kind);
- registry.registerIsCheck(type);
+ registry?.registerIsCheck(type);
return other;
}
@@ -2569,7 +2594,7 @@ class SsaBuilder extends ast.Visitor
messageInstruction];
HInstruction assertIsSubtype = new HInvokeStatic(
element, inputs, subtypeInstruction.instructionType);
- registry.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
+ registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
add(assertIsSubtype);
}
@@ -3184,7 +3209,7 @@ class SsaBuilder extends ast.Visitor
// TODO(ahe): This should be registered in codegen, not here.
// TODO(johnniwinther): Is [registerStaticUse] equivalent to
// [addToWorkList]?
- registry.registerStaticUse(callElement);
+ registry?.registerStaticUse(callElement);
List<HInstruction> capturedVariables = <HInstruction>[];
closureClassElement.closureFields.forEach((ClosureFieldElement field) {
@@ -3200,7 +3225,7 @@ class SsaBuilder extends ast.Visitor
..sourceInformation = sourceInformationBuilder.buildCreate(node));
Element methodElement = nestedClosureData.closureElement;
- registry.registerInstantiatedClosure(methodElement);
+ registry?.registerInstantiatedClosure(methodElement);
}
visitFunctionDeclaration(ast.FunctionDeclaration node) {
@@ -4392,7 +4417,7 @@ class SsaBuilder extends ast.Visitor
'"$name" does not handle closure with optional parameters.');
}
- registry.registerStaticUse(element);
+ registry?.registerStaticUse(element);
push(new HForeignCode(
js.js.expressionTemplateYielding(
backend.emitter.staticFunctionAccess(element)),
@@ -4499,7 +4524,7 @@ class SsaBuilder extends ast.Visitor
// class is _not_ the default implementation from [Object], in
// case the [noSuchMethod] implementation calls
// [JSInvocationMirror._invokeOn].
- registry.registerSelectorUse(selector);
+ registry?.registerSelectorUse(selector);
}
String publicName = name;
if (selector.isSetter) publicName += '=';
@@ -4878,9 +4903,9 @@ class SsaBuilder extends ast.Visitor
// When [member] is a field, we can be either
// generating a checked setter or inlining its
// initializer in a constructor. An initializer is
- // never built standalone, so [isBuildingFor] will
- // always return true when seeing one.
- (member.isField && !isBuildingFor(member))) {
+ // never built standalone, so in that case [target] is not
+ // the [member] itself.
+ (member.isField && member != target)) {
// The type variable is stored in a parameter of the method.
return localsHandler.readLocal(
typeVariableLocal, sourceInformation: sourceInformation);
@@ -4938,7 +4963,7 @@ class SsaBuilder extends ast.Visitor
inputs.add(analyzeTypeArgument(argument));
});
// TODO(15489): Register at codegen.
- registry.registerInstantiatedType(type);
+ registry?.registerInstantiatedType(type);
return callSetRuntimeTypeInfo(type.element, inputs, newObject);
}
@@ -5151,8 +5176,9 @@ class SsaBuilder extends ast.Visitor
// Overwrite the element type, in case the allocation site has
// been inlined.
newInstance.instructionType = elementType;
- JavaScriptItemCompilationContext context = work.compilationContext;
- context.allocatedFixedLists.add(newInstance);
+ if (context != null) {
+ context.allocatedFixedLists.add(newInstance);
+ }
}
// The List constructor forwards to a Dart static method that does
@@ -5697,7 +5723,7 @@ class SsaBuilder extends ast.Visitor
ConstructedConstantValue symbol = getConstantForNode(node);
StringConstantValue stringConstant = symbol.fields.values.single;
String nameString = stringConstant.toDartString().slowToString();
- registry.registerConstSymbol(nameString);
+ registry?.registerConstSymbol(nameString);
}
} else {
handleNewSend(node);
@@ -6877,7 +6903,7 @@ class SsaBuilder extends ast.Visitor
void visitLiteralSymbol(ast.LiteralSymbol node) {
stack.add(addConstant(node));
- registry.registerConstSymbol(node.slowNameString);
+ registry?.registerConstSymbol(node.slowNameString);
}
void visitStringJuxtaposition(ast.StringJuxtaposition node) {
@@ -7099,7 +7125,7 @@ class SsaBuilder extends ast.Visitor
arguments.add(analyzeTypeArgument(argument));
}
// TODO(15489): Register at codegen.
- registry.registerInstantiatedType(type);
+ registry?.registerInstantiatedType(type);
return callSetRuntimeTypeInfo(type.element, arguments, object);
}
« no previous file with comments | « pkg/compiler/lib/src/native/ssa.dart ('k') | pkg/compiler/lib/src/ssa/ssa.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698