Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 class SsaBuilderTask extends CompilerTask { | 5 class SsaBuilderTask extends CompilerTask { |
| 6 SsaBuilderTask(Compiler compiler) : super(compiler); | 6 SsaBuilderTask(Compiler compiler) : super(compiler); |
| 7 String get name() => 'SSA builder'; | 7 String get name() => 'SSA builder'; |
| 8 | 8 |
| 9 HGraph build(FunctionElement element, TreeElements elements) { | 9 HGraph build(FunctionElement element, TreeElements elements) { |
| 10 return measure(() { | 10 return measure(() { |
| 11 FunctionExpression function = element.node; | 11 FunctionExpression function = element.node; |
| 12 HInstruction.idCounter = 0; | 12 HInstruction.idCounter = 0; |
| 13 HGraph graph = | 13 SsaBuilder builder = new SsaBuilder(compiler, elements); |
| 14 compileMethod(function.parameters, function.body, elements); | 14 HGraph graph; |
| 15 switch (element.kind) { | |
| 16 case ElementKind.CONSTRUCTOR: | |
| 17 graph = compileConstructor(builder, function, element, elements); | |
|
ngeoffray
2011/12/08 16:01:40
I wouuld have the same API between compileConstruc
floitsch
2011/12/08 16:36:00
Done.
| |
| 18 break; | |
| 19 case ElementKind.CONSTRUCTOR_BODY: | |
| 20 graph = compileConstructorBody(builder, function); | |
| 21 break; | |
| 22 case ElementKind.FUNCTION: | |
| 23 graph = compileMethod(builder, function); | |
| 24 break; | |
| 25 } | |
| 15 assert(graph.isValid()); | 26 assert(graph.isValid()); |
| 16 if (GENERATE_SSA_TRACE) { | 27 if (GENERATE_SSA_TRACE) { |
| 17 Identifier name = function.name; | 28 Identifier name = function.name; |
| 18 new HTracer.singleton().traceCompilation(name.source.toString()); | 29 new HTracer.singleton().traceCompilation(name.source.toString()); |
| 19 new HTracer.singleton().traceGraph('builder', graph); | 30 new HTracer.singleton().traceGraph('builder', graph); |
| 20 } | 31 } |
| 21 return graph; | 32 return graph; |
| 22 }); | 33 }); |
| 23 } | 34 } |
| 24 | 35 |
| 25 HGraph compileMethod(NodeList parameters, | 36 HGraph compileConstructor(SsaBuilder builder, |
| 26 Node body, | 37 FunctionExpression function, |
| 27 TreeElements elements) { | 38 FunctionElement element, |
| 28 SsaBuilder builder = new SsaBuilder(compiler, elements); | 39 TreeElements elements) { |
| 29 HGraph graph = builder.build(parameters, body); | 40 // The body of the constructor will be generated in a separate function. |
| 30 return graph; | 41 ConstructorBodyElement bodyElement = new ConstructorBodyElement(element); |
| 42 compiler.worklist.add(new WorkElement.toCodegen(bodyElement, elements)); | |
| 43 ClassElement classElement = element.enclosingElement; | |
| 44 classElement.backendMembers.add(bodyElement); | |
| 45 // TODO(floitsch): pass initializer-list to builder. | |
| 46 return builder.buildFactory(classElement, bodyElement, function.parameters); | |
| 47 } | |
| 48 | |
| 49 HGraph compileConstructorBody(SsaBuilder builder, | |
| 50 FunctionExpression function) { | |
| 51 // TODO(floitsch): find super call and pass it to the builder. | |
| 52 return builder.buildConstructorBody(null, | |
| 53 function.parameters, | |
| 54 function.body); | |
| 55 } | |
| 56 | |
| 57 HGraph compileMethod(SsaBuilder builder, FunctionExpression function) { | |
| 58 return builder.buildMethod(function.parameters, function.body); | |
| 31 } | 59 } |
| 32 } | 60 } |
| 33 | 61 |
| 34 class SsaBuilder implements Visitor { | 62 class SsaBuilder implements Visitor { |
| 35 final Compiler compiler; | 63 final Compiler compiler; |
| 36 final TreeElements elements; | 64 final TreeElements elements; |
| 37 HGraph graph; | 65 HGraph graph; |
| 38 | 66 |
| 39 // We build the Ssa graph by simulating a stack machine. | 67 // We build the Ssa graph by simulating a stack machine. |
| 40 List<HInstruction> stack; | 68 List<HInstruction> stack; |
| 41 | 69 |
| 42 Map<Element, HInstruction> definitions; | 70 Map<Element, HInstruction> definitions; |
| 43 | 71 |
| 44 // The current block to add instructions to. Might be null, if we are | 72 // The current block to add instructions to. Might be null, if we are |
| 45 // visiting dead code. | 73 // visiting dead code. |
| 46 HBasicBlock current; | 74 HBasicBlock current; |
| 47 // Whether we are currently processing a condition expression (e.g., from | 75 // Whether we are currently processing a condition expression (e.g., from |
| 48 // an if, while, do-while, or for statement, or the conditional expression. | 76 // an if, while, do-while, or for statement, or the conditional expression. |
| 49 // (Currently, only if-statements are processed this way). | 77 // (Currently, only if-statements are processed this way). |
| 50 bool isConditionExpression = false; | 78 bool isConditionExpression = false; |
| 51 | 79 |
| 52 SsaBuilder(this.compiler, this.elements); | 80 SsaBuilder(this.compiler, this.elements); |
| 53 | 81 |
| 54 HGraph build(NodeList parameters, Node body) { | 82 HGraph buildMethod(NodeList parameters, Node body) { |
| 83 openFunction(parameters); | |
| 84 body.accept(this); | |
| 85 return closeFunction(); | |
| 86 } | |
| 87 | |
| 88 HGraph buildFactory(ClassElement classElement, | |
| 89 ConstructorBodyElement bodyElement, | |
| 90 NodeList parameters) { | |
| 91 openFunction(parameters); | |
| 92 HForeignNew newObject = new HForeignNew(classElement, []); | |
| 93 add(newObject); | |
| 94 String methodName = | |
| 95 compiler.namer.constructorBodyName(bodyElement.constructor); | |
| 96 List bodyCallInputs = <HInstruction>[]; | |
| 97 bodyCallInputs.add(newObject); | |
| 98 Link link = parameters.nodes; | |
| 99 for (; !link.isEmpty(); link = link.tail) { | |
| 100 Element parameterElement = elements[link.head]; | |
| 101 HInstruction currentValue = definitions[parameterElement]; | |
| 102 bodyCallInputs.add(currentValue); | |
| 103 } | |
| 104 add(new HInvokeDynamic(methodName, bodyCallInputs)); | |
| 105 close(new HReturn(newObject)).addSuccessor(graph.exit); | |
| 106 return closeFunction(); | |
| 107 } | |
| 108 | |
| 109 HGraph buildConstructorBody(Send superInvocation, | |
| 110 NodeList parameters, | |
| 111 Node body) { | |
| 112 openFunction(parameters); | |
| 113 if (superInvocation !== null) { | |
|
ngeoffray
2011/12/08 16:01:40
I'm not really fund of having code that we know is
floitsch
2011/12/08 16:36:00
Done.
| |
| 114 Element superElement = elements[superInvocation]; | |
| 115 String methodName = compiler.namer.constructorBodyName(superElement); | |
| 116 List superInputs = <HInstruction>[]; | |
| 117 superInputs.add(new HThis()); | |
| 118 Link link = superInvocation.arguments.head; | |
| 119 for (; !link.isEmpty(); link = link.tail) { | |
| 120 visit(link.head); | |
| 121 superInputs.add(pop()); | |
| 122 } | |
| 123 add(new HInvokeDynamic(methodName, superInputs)); | |
| 124 } | |
| 125 body.accept(this); | |
| 126 return closeFunction(); | |
| 127 } | |
| 128 | |
| 129 void openFunction(NodeList parameters) { | |
| 55 stack = new List<HInstruction>(); | 130 stack = new List<HInstruction>(); |
| 56 definitions = new Map<Element, HInstruction>(); | 131 definitions = new Map<Element, HInstruction>(); |
| 57 | 132 |
| 58 graph = new HGraph(); | 133 graph = new HGraph(); |
| 59 HBasicBlock block = graph.addNewBlock(); | 134 HBasicBlock block = graph.addNewBlock(); |
| 60 | 135 |
| 61 open(graph.entry); | 136 open(graph.entry); |
| 62 visitParameterValues(parameters); | 137 visitParameterValues(parameters); |
| 63 close(new HGoto()).addSuccessor(block); | 138 close(new HGoto()).addSuccessor(block); |
| 64 | 139 |
| 65 open(block); | 140 open(block); |
| 66 body.accept(this); | 141 } |
| 67 | 142 |
| 143 HGraph closeFunction() { | |
| 68 // TODO(kasperl): Make this goto an implicit return. | 144 // TODO(kasperl): Make this goto an implicit return. |
| 69 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); | 145 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); |
| 70 graph.finalize(); | 146 graph.finalize(); |
| 71 return graph; | 147 return graph; |
| 72 } | 148 } |
| 73 | 149 |
| 74 HBasicBlock addNewBlock() { | 150 HBasicBlock addNewBlock() { |
| 75 HBasicBlock block = graph.addNewBlock(); | 151 HBasicBlock block = graph.addNewBlock(); |
| 76 if (isConditionExpression) block.isCondition = true; | 152 if (isConditionExpression) block.isCondition = true; |
| 77 return block; | 153 return block; |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 HStatic target = new HStatic(element); | 659 HStatic target = new HStatic(element); |
| 584 add(target); | 660 add(target); |
| 585 List inputs = <HInstruction>[target]; | 661 List inputs = <HInstruction>[target]; |
| 586 inputs.addAll(arguments); | 662 inputs.addAll(arguments); |
| 587 push(new HInvokeStatic(inputs)); | 663 push(new HInvokeStatic(inputs)); |
| 588 } | 664 } |
| 589 } | 665 } |
| 590 } | 666 } |
| 591 | 667 |
| 592 visitNewExpression(NewExpression node) { | 668 visitNewExpression(NewExpression node) { |
| 593 compiler.unimplemented("SsaBuilder: new expression"); | 669 visitSend(node.send); |
|
ngeoffray
2011/12/08 16:01:40
=> syntax?
floitsch
2011/12/08 16:36:00
Done.
| |
| 594 } | 670 } |
| 595 | 671 |
| 596 HInstruction updateDefinition(Node node, HInstruction value) { | 672 HInstruction updateDefinition(Node node, HInstruction value) { |
| 597 VariableElement element = elements[node]; | 673 VariableElement element = elements[node]; |
| 598 value = guard(element.type, value); | 674 value = guard(element.type, value); |
| 599 definitions[element] = value; | 675 definitions[element] = value; |
| 600 return value; | 676 return value; |
| 601 } | 677 } |
| 602 | 678 |
| 603 visitSendSet(SendSet node) { | 679 visitSendSet(SendSet node) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 761 visit(link.head); | 837 visit(link.head); |
| 762 inputs.add(pop()); | 838 inputs.add(pop()); |
| 763 } | 839 } |
| 764 push(new HLiteralList(inputs)); | 840 push(new HLiteralList(inputs)); |
| 765 } | 841 } |
| 766 | 842 |
| 767 visitConditional(Conditional node) { | 843 visitConditional(Conditional node) { |
| 768 compiler.unimplemented("SsaBuilder: conditional"); | 844 compiler.unimplemented("SsaBuilder: conditional"); |
| 769 } | 845 } |
| 770 } | 846 } |
| OLD | NEW |