| 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); |
| 18 break; |
| 19 case ElementKind.CONSTRUCTOR_BODY: |
| 20 graph = compileConstructorBody(builder, function, element, elements); |
| 21 break; |
| 22 case ElementKind.FUNCTION: |
| 23 graph = compileMethod(builder, function, element, elements); |
| 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, |
| 38 FunctionElement element, |
| 39 TreeElements elements) { |
| 40 // The body of the constructor will be generated in a separate function. |
| 41 ConstructorBodyElement bodyElement = new ConstructorBodyElement(element); |
| 42 compiler.worklist.add(new WorkElement.toCodegen(bodyElement, elements)); |
| 43 ClassElement classElement = element.enclosingElement; |
| 44 classElement.backendMembers = |
| 45 classElement.backendMembers.prepend(bodyElement); |
| 46 // TODO(floitsch): pass initializer-list to builder. |
| 47 return builder.buildFactory(classElement, bodyElement, function.parameters); |
| 48 } |
| 49 |
| 50 HGraph compileConstructorBody(SsaBuilder builder, |
| 51 FunctionExpression function, |
| 52 FunctionElement element, |
| 53 TreeElements elements) { |
| 54 // TODO(floitsch): find super call and pass it to the builder. |
| 55 return builder.buildConstructorBody(null, |
| 56 function.parameters, |
| 57 function.body); |
| 58 } |
| 59 |
| 60 HGraph compileMethod(SsaBuilder builder, |
| 61 FunctionExpression function, |
| 62 FunctionElement element, |
| 27 TreeElements elements) { | 63 TreeElements elements) { |
| 28 SsaBuilder builder = new SsaBuilder(compiler, elements); | 64 return builder.buildMethod(function.parameters, function.body); |
| 29 HGraph graph = builder.build(parameters, body); | |
| 30 return graph; | |
| 31 } | 65 } |
| 32 } | 66 } |
| 33 | 67 |
| 34 class SsaBuilder implements Visitor { | 68 class SsaBuilder implements Visitor { |
| 35 final Compiler compiler; | 69 final Compiler compiler; |
| 36 final TreeElements elements; | 70 final TreeElements elements; |
| 37 HGraph graph; | 71 HGraph graph; |
| 38 | 72 |
| 39 // We build the Ssa graph by simulating a stack machine. | 73 // We build the Ssa graph by simulating a stack machine. |
| 40 List<HInstruction> stack; | 74 List<HInstruction> stack; |
| 41 | 75 |
| 42 Map<Element, HInstruction> definitions; | 76 Map<Element, HInstruction> definitions; |
| 43 | 77 |
| 44 // The current block to add instructions to. Might be null, if we are | 78 // The current block to add instructions to. Might be null, if we are |
| 45 // visiting dead code. | 79 // visiting dead code. |
| 46 HBasicBlock current; | 80 HBasicBlock current; |
| 47 // Whether we are currently processing a condition expression (e.g., from | 81 // Whether we are currently processing a condition expression (e.g., from |
| 48 // an if, while, do-while, or for statement, or the conditional expression. | 82 // an if, while, do-while, or for statement, or the conditional expression. |
| 49 // (Currently, only if-statements are processed this way). | 83 // (Currently, only if-statements are processed this way). |
| 50 bool isConditionExpression = false; | 84 bool isConditionExpression = false; |
| 51 | 85 |
| 52 SsaBuilder(this.compiler, this.elements); | 86 SsaBuilder(this.compiler, this.elements); |
| 53 | 87 |
| 54 HGraph build(NodeList parameters, Node body) { | 88 HGraph buildMethod(NodeList parameters, Node body) { |
| 89 openFunction(parameters); |
| 90 body.accept(this); |
| 91 return closeFunction(); |
| 92 } |
| 93 |
| 94 HGraph buildFactory(ClassElement classElement, |
| 95 ConstructorBodyElement bodyElement, |
| 96 NodeList parameters) { |
| 97 openFunction(parameters); |
| 98 HForeignNew newObject = new HForeignNew(classElement, []); |
| 99 add(newObject); |
| 100 String methodName = compiler.namer.getName(bodyElement); |
| 101 List bodyCallInputs = <HInstruction>[]; |
| 102 bodyCallInputs.add(newObject); |
| 103 Link link = parameters.nodes; |
| 104 for (; !link.isEmpty(); link = link.tail) { |
| 105 Element parameterElement = elements[link.head]; |
| 106 HInstruction currentValue = definitions[parameterElement]; |
| 107 bodyCallInputs.add(currentValue); |
| 108 } |
| 109 add(new HInvokeDynamic(methodName, bodyCallInputs)); |
| 110 close(new HReturn(newObject)).addSuccessor(graph.exit); |
| 111 return closeFunction(); |
| 112 } |
| 113 |
| 114 HGraph buildConstructorBody(Send superInvocation, |
| 115 NodeList parameters, |
| 116 Node body) { |
| 117 openFunction(parameters); |
| 118 if (superInvocation !== null) { |
| 119 compiler.unimplemented('SsaBuilder.buildConstructorBody'); |
| 120 Element superElement = elements[superInvocation]; |
| 121 String methodName = compiler.namer.constructorBodyName(superElement); |
| 122 List superInputs = <HInstruction>[]; |
| 123 superInputs.add(new HThis()); |
| 124 Link link = superInvocation.arguments.head; |
| 125 for (; !link.isEmpty(); link = link.tail) { |
| 126 visit(link.head); |
| 127 superInputs.add(pop()); |
| 128 } |
| 129 add(new HInvokeDynamic(methodName, superInputs)); |
| 130 } |
| 131 body.accept(this); |
| 132 return closeFunction(); |
| 133 } |
| 134 |
| 135 void openFunction(NodeList parameters) { |
| 55 stack = new List<HInstruction>(); | 136 stack = new List<HInstruction>(); |
| 56 definitions = new Map<Element, HInstruction>(); | 137 definitions = new Map<Element, HInstruction>(); |
| 57 | 138 |
| 58 graph = new HGraph(); | 139 graph = new HGraph(); |
| 59 HBasicBlock block = graph.addNewBlock(); | 140 HBasicBlock block = graph.addNewBlock(); |
| 60 | 141 |
| 61 open(graph.entry); | 142 open(graph.entry); |
| 62 visitParameterValues(parameters); | 143 visitParameterValues(parameters); |
| 63 close(new HGoto()).addSuccessor(block); | 144 close(new HGoto()).addSuccessor(block); |
| 64 | 145 |
| 65 open(block); | 146 open(block); |
| 66 body.accept(this); | 147 } |
| 67 | 148 |
| 149 HGraph closeFunction() { |
| 68 // TODO(kasperl): Make this goto an implicit return. | 150 // TODO(kasperl): Make this goto an implicit return. |
| 69 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); | 151 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); |
| 70 graph.finalize(); | 152 graph.finalize(); |
| 71 return graph; | 153 return graph; |
| 72 } | 154 } |
| 73 | 155 |
| 74 HBasicBlock addNewBlock() { | 156 HBasicBlock addNewBlock() { |
| 75 HBasicBlock block = graph.addNewBlock(); | 157 HBasicBlock block = graph.addNewBlock(); |
| 76 if (isConditionExpression) block.isCondition = true; | 158 if (isConditionExpression) block.isCondition = true; |
| 77 return block; | 159 return block; |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 } else { | 664 } else { |
| 583 HStatic target = new HStatic(element); | 665 HStatic target = new HStatic(element); |
| 584 add(target); | 666 add(target); |
| 585 List inputs = <HInstruction>[target]; | 667 List inputs = <HInstruction>[target]; |
| 586 inputs.addAll(arguments); | 668 inputs.addAll(arguments); |
| 587 push(new HInvokeStatic(inputs)); | 669 push(new HInvokeStatic(inputs)); |
| 588 } | 670 } |
| 589 } | 671 } |
| 590 } | 672 } |
| 591 | 673 |
| 592 visitNewExpression(NewExpression node) { | 674 visitNewExpression(NewExpression node) => visitSend(node.send); |
| 593 compiler.unimplemented("SsaBuilder: new expression"); | |
| 594 } | |
| 595 | 675 |
| 596 HInstruction updateDefinition(Node node, HInstruction value) { | 676 HInstruction updateDefinition(Node node, HInstruction value) { |
| 597 VariableElement element = elements[node]; | 677 VariableElement element = elements[node]; |
| 598 value = guard(element.type, value); | 678 value = guard(element.type, value); |
| 599 definitions[element] = value; | 679 definitions[element] = value; |
| 600 return value; | 680 return value; |
| 601 } | 681 } |
| 602 | 682 |
| 603 visitSendSet(SendSet node) { | 683 visitSendSet(SendSet node) { |
| 604 Operator op = node.assignmentOperator; | 684 Operator op = node.assignmentOperator; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 thenBlock.addSuccessor(joinBlock); | 869 thenBlock.addSuccessor(joinBlock); |
| 790 elseBlock.addSuccessor(joinBlock); | 870 elseBlock.addSuccessor(joinBlock); |
| 791 open(joinBlock); | 871 open(joinBlock); |
| 792 | 872 |
| 793 definitions = joinDefinitions(joinBlock, thenDefinitions, definitions); | 873 definitions = joinDefinitions(joinBlock, thenDefinitions, definitions); |
| 794 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]); | 874 HPhi phi = new HPhi.manyInputs(null, [thenInstruction, elseInstruction]); |
| 795 joinBlock.addPhi(phi); | 875 joinBlock.addPhi(phi); |
| 796 stack.add(phi); | 876 stack.add(phi); |
| 797 } | 877 } |
| 798 } | 878 } |
| OLD | NEW |