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

Side by Side Diff: lib/compiler/implementation/ssa/codegen.dart

Issue 10386086: RFC: Start refactoring to provide more than a single backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Next iteration Created 8 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 SsaCodeGeneratorTask extends CompilerTask { 5 class SsaCodeGeneratorTask extends CompilerTask {
6 SsaCodeGeneratorTask(Compiler compiler) : super(compiler); 6 final JavaScriptBackend backend;
7 SsaCodeGeneratorTask(JavaScriptBackend backend)
8 : this.backend = backend,
9 super(backend.compiler);
7 String get name() => 'SSA code generator'; 10 String get name() => 'SSA code generator';
11 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter;
8 12
9 13
10 String buildJavaScriptFunction(FunctionElement element, 14 String buildJavaScriptFunction(FunctionElement element,
11 String parameters, 15 String parameters,
12 String body) { 16 String body) {
13 String extraSpace = ""; 17 String extraSpace = "";
14 // Members are emitted inside a JavaScript object literal. To line up the 18 // Members are emitted inside a JavaScript object literal. To line up the
15 // indentation we want the closing curly brace to be indented by one space. 19 // indentation we want the closing curly brace to be indented by one space.
16 // Example: 20 // Example:
17 // defineClass("A", "B", ... , { 21 // defineClass("A", "B", ... , {
(...skipping 12 matching lines...) Expand all
30 } 34 }
31 return 'function($parameters) {\n$body$extraSpace}'; 35 return 'function($parameters) {\n$body$extraSpace}';
32 } 36 }
33 37
34 String generateMethod(WorkItem work, HGraph graph) { 38 String generateMethod(WorkItem work, HGraph graph) {
35 return measure(() { 39 return measure(() {
36 compiler.tracer.traceGraph("codegen", graph); 40 compiler.tracer.traceGraph("codegen", graph);
37 Map<Element, String> parameterNames = getParameterNames(work); 41 Map<Element, String> parameterNames = getParameterNames(work);
38 String parameters = Strings.join(parameterNames.getValues(), ', '); 42 String parameters = Strings.join(parameterNames.getValues(), ', ');
39 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( 43 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator(
40 compiler, work, parameters, parameterNames); 44 backend, work, parameters, parameterNames);
41 codegen.visitGraph(graph); 45 codegen.visitGraph(graph);
42 46
43 FunctionElement element = work.element; 47 FunctionElement element = work.element;
44 String code; 48 String code;
45 if (element.isInstanceMember() 49 if (element.isInstanceMember()
46 && element.enclosingElement.isClass() 50 && element.enclosingElement.isClass()
47 && element.enclosingElement.isNative() 51 && element.enclosingElement.isNative()
48 && native.isOverriddenMethod(element, 52 && native.isOverriddenMethod(
49 element.enclosingElement, 53 element, element.enclosingElement, nativeEmitter)) {
50 compiler.emitter.nativeEmitter)) {
51 // Record that this method is overridden. In case of optional 54 // Record that this method is overridden. In case of optional
52 // arguments, the emitter will generate stubs to handle them, 55 // arguments, the emitter will generate stubs to handle them,
53 // and needs to know if the method is overridden. 56 // and needs to know if the method is overridden.
54 compiler.emitter.nativeEmitter.overriddenMethods.add(element); 57 nativeEmitter.overriddenMethods.add(element);
55 StringBuffer buffer = new StringBuffer(); 58 StringBuffer buffer = new StringBuffer();
56 native.generateMethodWithPrototypeCheckForElement( 59 native.generateMethodWithPrototypeCheckForElement(
57 compiler, buffer, element, '${codegen.buffer}', parameters); 60 compiler, buffer, element, '${codegen.buffer}', parameters);
58 code = buffer.toString(); 61 code = buffer.toString();
59 } else { 62 } else {
60 code = codegen.buffer.toString(); 63 code = codegen.buffer.toString();
61 } 64 }
62 return buildJavaScriptFunction(element, parameters, code); 65 return buildJavaScriptFunction(element, parameters, code);
63 }); 66 });
64 } 67 }
65 68
66 String generateBailoutMethod(WorkItem work, HGraph graph) { 69 String generateBailoutMethod(WorkItem work, HGraph graph) {
67 return measure(() { 70 return measure(() {
68 compiler.tracer.traceGraph("codegen-bailout", graph); 71 compiler.tracer.traceGraph("codegen-bailout", graph);
69 new SsaBailoutPropagator(compiler).visitGraph(graph); 72 new SsaBailoutPropagator(compiler).visitGraph(graph);
70 73
71 Map<Element, String> parameterNames = getParameterNames(work); 74 Map<Element, String> parameterNames = getParameterNames(work);
72 String parameters = Strings.join(parameterNames.getValues(), ', '); 75 String parameters = Strings.join(parameterNames.getValues(), ', ');
73 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( 76 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator(
74 compiler, work, parameters, parameterNames); 77 backend, work, parameters, parameterNames);
75 codegen.visitGraph(graph); 78 codegen.visitGraph(graph);
76 79
77 StringBuffer newParameters = new StringBuffer(); 80 StringBuffer newParameters = new StringBuffer();
78 if (!parameterNames.isEmpty()) newParameters.add('$parameters, '); 81 if (!parameterNames.isEmpty()) newParameters.add('$parameters, ');
79 newParameters.add('state'); 82 newParameters.add('state');
80 83
81 for (int i = 0; i < codegen.maxBailoutParameters; i++) { 84 for (int i = 0; i < codegen.maxBailoutParameters; i++) {
82 newParameters.add(', env$i'); 85 newParameters.add(', env$i');
83 } 86 }
84 87
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 * expression, and that it only generates expressions of the form 133 * expression, and that it only generates expressions of the form
131 * variable = expression 134 * variable = expression
132 * which are also valid as parts of a "var" declaration. 135 * which are also valid as parts of a "var" declaration.
133 */ 136 */
134 static final int TYPE_STATEMENT = 0; 137 static final int TYPE_STATEMENT = 0;
135 static final int TYPE_EXPRESSION = 1; 138 static final int TYPE_EXPRESSION = 1;
136 static final int TYPE_DECLARATION = 2; 139 static final int TYPE_DECLARATION = 2;
137 140
138 static final String TEMPORARY_PREFIX = 't'; 141 static final String TEMPORARY_PREFIX = 't';
139 142
140 final Compiler compiler; 143 final JavaScriptBackend backend;
141 final WorkItem work; 144 final WorkItem work;
142 final StringBuffer buffer; 145 final StringBuffer buffer;
143 final String parameters; 146 final String parameters;
144 147
145 final Map<Element, String> parameterNames; 148 final Map<Element, String> parameterNames;
146 final Map<int, String> names; 149 final Map<int, String> names;
147 final Set<String> usedNames; 150 final Set<String> usedNames;
148 final Set<HInstruction> declaredInstructions; 151 final Set<HInstruction> declaredInstructions;
149 final Map<String, int> prefixes; 152 final Map<String, int> prefixes;
150 final Set<HInstruction> generateAtUseSite; 153 final Set<HInstruction> generateAtUseSite;
(...skipping 21 matching lines...) Expand all
172 HBasicBlock currentBlock; 175 HBasicBlock currentBlock;
173 176
174 // Records a block-information that is being handled specially. 177 // Records a block-information that is being handled specially.
175 // Used to break bad recursion. 178 // Used to break bad recursion.
176 HBlockInformation currentBlockInformation; 179 HBlockInformation currentBlockInformation;
177 // The subgraph is used to delimit traversal for some constructions, e.g., 180 // The subgraph is used to delimit traversal for some constructions, e.g.,
178 // if branches. 181 // if branches.
179 SubGraph subGraph; 182 SubGraph subGraph;
180 183
181 LibraryElement get currentLibrary() => work.element.getLibrary(); 184 LibraryElement get currentLibrary() => work.element.getLibrary();
185 Compiler get compiler() => backend.compiler;
182 186
183 bool isGenerateAtUseSite(HInstruction instruction) { 187 bool isGenerateAtUseSite(HInstruction instruction) {
184 return generateAtUseSite.contains(instruction); 188 return generateAtUseSite.contains(instruction);
185 } 189 }
186 190
187 SsaCodeGenerator(this.compiler, 191 SsaCodeGenerator(this.backend,
188 this.work, 192 this.work,
189 this.parameters, 193 this.parameters,
190 this.parameterNames) 194 this.parameterNames)
191 : names = new Map<int, String>(), 195 : names = new Map<int, String>(),
192 prefixes = new Map<String, int>(), 196 prefixes = new Map<String, int>(),
193 usedNames = new Set<String>(), 197 usedNames = new Set<String>(),
194 declaredInstructions = new Set<HInstruction>(), 198 declaredInstructions = new Set<HInstruction>(),
195 buffer = new StringBuffer(), 199 buffer = new StringBuffer(),
196 generateAtUseSite = new Set<HInstruction>(), 200 generateAtUseSite = new Set<HInstruction>(),
197 logicalOperations = new Map<HPhi, String>(), 201 logicalOperations = new Map<HPhi, String>(),
198 breakAction = new Map<Element, ElementAction>(), 202 breakAction = new Map<Element, ElementAction>(),
199 continueAction = new Map<Element, ElementAction>(), 203 continueAction = new Map<Element, ElementAction>(),
200 phiEquivalence = new Equivalence<HPhi>(), 204 phiEquivalence = new Equivalence<HPhi>(),
201 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] { 205 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] {
202 206
203 for (final name in parameterNames.getValues()) { 207 for (final name in parameterNames.getValues()) {
204 prefixes[name] = 0; 208 prefixes[name] = 0;
205 } 209 }
206 210
207 // Create a namespace for temporaries. 211 // Create a namespace for temporaries.
208 prefixes[TEMPORARY_PREFIX] = 0; 212 prefixes[TEMPORARY_PREFIX] = 0;
209 213
210 Interceptors interceptors = compiler.builder.interceptors; 214 Interceptors interceptors = backend.builder.interceptors;
211 equalsNullElement = interceptors.getEqualsNullInterceptor(); 215 equalsNullElement = interceptors.getEqualsNullInterceptor();
212 boolifiedEqualsNullElement = 216 boolifiedEqualsNullElement =
213 interceptors.getBoolifiedVersionOf(equalsNullElement); 217 interceptors.getBoolifiedVersionOf(equalsNullElement);
214 } 218 }
215 219
216 abstract visitTypeGuard(HTypeGuard node); 220 abstract visitTypeGuard(HTypeGuard node);
217 221
218 abstract beginGraph(HGraph graph); 222 abstract beginGraph(HGraph graph);
219 abstract endGraph(HGraph graph); 223 abstract endGraph(HGraph graph);
220 224
(...skipping 1815 matching lines...) Expand 10 before | Expand all | Expand 10 after
2036 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2040 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2037 checkObject(input, '==='); 2041 checkObject(input, '===');
2038 buffer.add(" && "); 2042 buffer.add(" && ");
2039 checkType(input, element); 2043 checkType(input, element);
2040 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2044 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2041 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2045 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2042 } 2046 }
2043 2047
2044 void checkType(HInstruction input, Element element) { 2048 void checkType(HInstruction input, Element element) {
2045 bool requiresNativeIsCheck = 2049 bool requiresNativeIsCheck =
2046 compiler.emitter.nativeEmitter.requiresNativeIsCheck(element); 2050 compiler.backend.emitter.nativeEmitter.requiresNativeIsCheck(element);
2047 if (!requiresNativeIsCheck) buffer.add('!!'); 2051 if (!requiresNativeIsCheck) buffer.add('!!');
2048 use(input, JSPrecedence.MEMBER_PRECEDENCE); 2052 use(input, JSPrecedence.MEMBER_PRECEDENCE);
2049 buffer.add('.'); 2053 buffer.add('.');
2050 buffer.add(compiler.namer.operatorIs(element)); 2054 buffer.add(compiler.namer.operatorIs(element));
2051 if (requiresNativeIsCheck) buffer.add('()'); 2055 if (requiresNativeIsCheck) buffer.add('()');
2052 } 2056 }
2053 2057
2054 void handleStringSupertypeCheck(HInstruction input, Element element) { 2058 void handleStringSupertypeCheck(HInstruction input, Element element) {
2055 // Make sure List and String don't share supertypes, otherwise we 2059 // Make sure List and String don't share supertypes, otherwise we
2056 // would need to check for List too. 2060 // would need to check for List too.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2155 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2159 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2156 } 2160 }
2157 } 2161 }
2158 2162
2159 void visitTypeConversion(HTypeConversion node) { 2163 void visitTypeConversion(HTypeConversion node) {
2160 if (node.checked) { 2164 if (node.checked) {
2161 Element element = node.type.computeType(compiler).element; 2165 Element element = node.type.computeType(compiler).element;
2162 compiler.registerIsCheck(element); 2166 compiler.registerIsCheck(element);
2163 SourceString helper; 2167 SourceString helper;
2164 String additionalArgument; 2168 String additionalArgument;
2165 bool nativeCheck = 2169 bool nativeCheck = nativeEmitter.requiresNativeIsCheck(element);
2166 compiler.emitter.nativeEmitter.requiresNativeIsCheck(element);
2167 beginExpression(JSPrecedence.CALL_PRECEDENCE); 2170 beginExpression(JSPrecedence.CALL_PRECEDENCE);
2168 2171
2169 if (element == compiler.stringClass) { 2172 if (element == compiler.stringClass) {
2170 helper = const SourceString('stringTypeCheck'); 2173 helper = const SourceString('stringTypeCheck');
2171 } else if (element == compiler.doubleClass) { 2174 } else if (element == compiler.doubleClass) {
2172 helper = const SourceString('doubleTypeCheck'); 2175 helper = const SourceString('doubleTypeCheck');
2173 } else if (element == compiler.numClass) { 2176 } else if (element == compiler.numClass) {
2174 helper = const SourceString('numTypeCheck'); 2177 helper = const SourceString('numTypeCheck');
2175 } else if (element == compiler.boolClass) { 2178 } else if (element == compiler.boolClass) {
2176 helper = const SourceString('boolTypeCheck'); 2179 helper = const SourceString('boolTypeCheck');
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2208 if (additionalArgument !== null) buffer.add(", '$additionalArgument'"); 2211 if (additionalArgument !== null) buffer.add(", '$additionalArgument'");
2209 buffer.add(')'); 2212 buffer.add(')');
2210 endExpression(JSPrecedence.CALL_PRECEDENCE); 2213 endExpression(JSPrecedence.CALL_PRECEDENCE);
2211 } else { 2214 } else {
2212 use(node.checkedInput, expectedPrecedence); 2215 use(node.checkedInput, expectedPrecedence);
2213 } 2216 }
2214 } 2217 }
2215 } 2218 }
2216 2219
2217 class SsaOptimizedCodeGenerator extends SsaCodeGenerator { 2220 class SsaOptimizedCodeGenerator extends SsaCodeGenerator {
2218 SsaOptimizedCodeGenerator(compiler, work, parameters, parameterNames) 2221 SsaOptimizedCodeGenerator(backend, work, parameters, parameterNames)
2219 : super(compiler, work, parameters, parameterNames); 2222 : super(backend, work, parameters, parameterNames);
2220 2223
2221 void beginGraph(HGraph graph) {} 2224 void beginGraph(HGraph graph) {}
2222 void endGraph(HGraph graph) {} 2225 void endGraph(HGraph graph) {}
2223 2226
2224 void bailout(HTypeGuard guard, String reason) { 2227 void bailout(HTypeGuard guard, String reason) {
2225 HInstruction input = guard.guarded; 2228 HInstruction input = guard.guarded;
2226 Namer namer = compiler.namer; 2229 Namer namer = compiler.namer;
2227 Element element = work.element; 2230 Element element = work.element;
2228 buffer.add('return '); 2231 buffer.add('return ');
2229 if (element.isInstanceMember()) { 2232 if (element.isInstanceMember()) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 } 2380 }
2378 } 2381 }
2379 2382
2380 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { 2383 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
2381 2384
2382 final StringBuffer setup; 2385 final StringBuffer setup;
2383 final List<String> labels; 2386 final List<String> labels;
2384 int labelId = 0; 2387 int labelId = 0;
2385 int maxBailoutParameters = 0; 2388 int maxBailoutParameters = 0;
2386 2389
2387 SsaUnoptimizedCodeGenerator(compiler, work, parameters, parameterNames) 2390 SsaUnoptimizedCodeGenerator(backend, work, parameters, parameterNames)
2388 : super(compiler, work, parameters, parameterNames), 2391 : super(backend, work, parameters, parameterNames),
2389 setup = new StringBuffer(), 2392 setup = new StringBuffer(),
2390 labels = <String>[]; 2393 labels = <String>[];
2391 2394
2392 String pushLabel() { 2395 String pushLabel() {
2393 String label = 'L${labelId++}'; 2396 String label = 'L${labelId++}';
2394 labels.addLast(label); 2397 labels.addLast(label);
2395 return label; 2398 return label;
2396 } 2399 }
2397 2400
2398 String popLabel() { 2401 String popLabel() {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2610 startBailoutSwitch(); 2613 startBailoutSwitch();
2611 } 2614 }
2612 } 2615 }
2613 2616
2614 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2617 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2615 if (labeledBlockInfo.body.start.hasGuards()) { 2618 if (labeledBlockInfo.body.start.hasGuards()) {
2616 endBailoutSwitch(); 2619 endBailoutSwitch();
2617 } 2620 }
2618 } 2621 }
2619 } 2622 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698