| Index: sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4d978301082aa3ca87594d19e72401ebfc4e2ecf
|
| --- /dev/null
|
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
|
| @@ -0,0 +1,128 @@
|
| +// 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.
|
| +
|
| +part of ssa;
|
| +
|
| +class SsaFromIrBuilderTask extends CompilerTask {
|
| + SsaFromIrBuilderTask(Compiler compiler) : super(compiler);
|
| +
|
| + HGraph build(CodegenWorkItem work) {
|
| + return measure(() {
|
| + Element element = work.element.implementation;
|
| + return compiler.withCurrentElement(element, () {
|
| + HInstruction.idCounter = 0;
|
| + SsaFromIrBuilder builder = new SsaFromIrBuilder(compiler, element);
|
| +
|
| + HGraph graph;
|
| + ElementKind kind = element.kind;
|
| + if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
|
| + throw "Build HGraph for constructor from IR";
|
| +// graph = compileConstructor(builder, work);
|
| + } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
|
| + kind == ElementKind.FUNCTION ||
|
| + kind == ElementKind.GETTER ||
|
| + kind == ElementKind.SETTER) {
|
| + graph = builder.buildMethod();
|
| + } else if (kind == ElementKind.FIELD) {
|
| + throw "Build HGraph for field from IR";
|
| +// assert(!element.isInstanceMember());
|
| +// graph = builder.buildLazyInitializer(element);
|
| + } else {
|
| + compiler.internalErrorOnElement(element,
|
| + 'unexpected element kind $kind');
|
| + }
|
| + assert(graph.isValid());
|
| + // TODO(lry): for default arguments, register constants in backend.
|
| + // TODO(lry): tracing (factor out code in SsaBuilderTask).
|
| + return graph;
|
| + });
|
| + });
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * This builder generates SSA nodes for elements that have an IR representation.
|
| + * It mixes in [SsaGraphBuilderMixin] to share functionality with the
|
| + * [SsaBuilder] that creates SSA nodes from trees.
|
| + */
|
| +class SsaFromIrBuilder
|
| + extends IrNodesVisitor<HInstruction> with SsaGraphBuilderMixin {
|
| + final Compiler compiler;
|
| +
|
| + final Element sourceElement;
|
| +
|
| + SsaFromIrBuilder(this.compiler, this.sourceElement);
|
| +
|
| + /**
|
| + * Maps IR nodes ot the generated [HInstruction]. Because the IR is itself
|
| + * in an SSA form, the arguments of an [IrNode] have already been visited
|
| + * prior to the node. This map is used to obtain the corresponding generated
|
| + * SSA node.
|
| + */
|
| + final Map<IrNode, HInstruction> generated = new Map<IrNode, HInstruction>();
|
| +
|
| + HInstruction recordGenerated(IrNode irNode, HInstruction ssaNode) {
|
| + return generated[irNode] = ssaNode;
|
| + }
|
| +
|
| + HInstruction attachPosition(HInstruction target, IrNode node) {
|
| + target.sourcePosition = sourceFileLocation(node);
|
| + return target;
|
| + }
|
| +
|
| + SourceFileLocation sourceFileLocation(IrNode node) {
|
| + Element element = sourceElement;
|
| + // TODO(johnniwinther): remove the 'element.patch' hack.
|
| + if (element is FunctionElement) {
|
| + FunctionElement functionElement = element;
|
| + if (functionElement.patch != null) element = functionElement.patch;
|
| + }
|
| + Script script = element.getCompilationUnit().script;
|
| + SourceFile sourceFile = script.file;
|
| + SourceFileLocation location =
|
| + new OffsetSourceFileLocation(sourceFile, node.offset, node.sourceName);
|
| + if (!location.isValid()) {
|
| + throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
|
| + {'offset': node.offset,
|
| + 'fileName': sourceFile.filename,
|
| + 'length': sourceFile.length});
|
| + }
|
| + return location;
|
| + }
|
| +
|
| + HGraph buildMethod() {
|
| + graph.calledInLoop = compiler.world.isCalledInLoop(sourceElement);
|
| +
|
| + open(graph.entry);
|
| + HBasicBlock block = graph.addNewBlock();
|
| + close(new HGoto()).addSuccessor(block);
|
| + open(block);
|
| +
|
| + IrFunction function = compiler.irBuilder.getIr(sourceElement);
|
| + visitAll(function.statements);
|
| + if (!isAborted()) closeAndGotoExit(new HGoto());
|
| + graph.finalize();
|
| + return graph;
|
| + }
|
| +
|
| + HInstruction visitIrConstant(IrConstant node) {
|
| + return recordGenerated(node, graph.addConstant(node.value, compiler));
|
| + }
|
| +
|
| + HInstruction visitIrReturn(IrReturn node) {
|
| + assert(isReachable);
|
| + HInstruction value = generated[node.value];
|
| + // TODO(lry): add code for dynamic type check.
|
| + // value = potentiallyCheckType(value, returnType);
|
| + closeAndGotoExit(attachPosition(new HReturn(value), node));
|
| + }
|
| +
|
| + HInstruction visitNode(IrNode node) {
|
| + abort(node);
|
| + }
|
| +
|
| + void abort(IrNode node) {
|
| + throw 'Cannot build SSA from IR for $node';
|
| + }
|
| +}
|
|
|