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'; |
+ } |
+} |