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

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

Issue 10386161: Start compiler refactoring to support more than a single backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after
2043 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2047 beginExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2044 checkObject(input, '==='); 2048 checkObject(input, '===');
2045 buffer.add(" && "); 2049 buffer.add(" && ");
2046 checkType(input, element); 2050 checkType(input, element);
2047 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE); 2051 endExpression(JSPrecedence.LOGICAL_AND_PRECEDENCE);
2048 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2052 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2049 } 2053 }
2050 2054
2051 void checkType(HInstruction input, Element element) { 2055 void checkType(HInstruction input, Element element) {
2052 bool requiresNativeIsCheck = 2056 bool requiresNativeIsCheck =
2053 compiler.emitter.nativeEmitter.requiresNativeIsCheck(element); 2057 backend.emitter.nativeEmitter.requiresNativeIsCheck(element);
2054 if (!requiresNativeIsCheck) buffer.add('!!'); 2058 if (!requiresNativeIsCheck) buffer.add('!!');
2055 use(input, JSPrecedence.MEMBER_PRECEDENCE); 2059 use(input, JSPrecedence.MEMBER_PRECEDENCE);
2056 buffer.add('.'); 2060 buffer.add('.');
2057 buffer.add(compiler.namer.operatorIs(element)); 2061 buffer.add(compiler.namer.operatorIs(element));
2058 if (requiresNativeIsCheck) buffer.add('()'); 2062 if (requiresNativeIsCheck) buffer.add('()');
2059 } 2063 }
2060 2064
2061 void handleStringSupertypeCheck(HInstruction input, Element element) { 2065 void handleStringSupertypeCheck(HInstruction input, Element element) {
2062 // Make sure List and String don't share supertypes, otherwise we 2066 // Make sure List and String don't share supertypes, otherwise we
2063 // would need to check for List too. 2067 // would need to check for List too.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE); 2166 endExpression(JSPrecedence.LOGICAL_OR_PRECEDENCE);
2163 } 2167 }
2164 } 2168 }
2165 2169
2166 void visitTypeConversion(HTypeConversion node) { 2170 void visitTypeConversion(HTypeConversion node) {
2167 if (node.checked) { 2171 if (node.checked) {
2168 Element element = node.type.computeType(compiler).element; 2172 Element element = node.type.computeType(compiler).element;
2169 compiler.registerIsCheck(element); 2173 compiler.registerIsCheck(element);
2170 SourceString helper; 2174 SourceString helper;
2171 String additionalArgument; 2175 String additionalArgument;
2172 bool nativeCheck = 2176 bool nativeCheck = nativeEmitter.requiresNativeIsCheck(element);
2173 compiler.emitter.nativeEmitter.requiresNativeIsCheck(element);
2174 beginExpression(JSPrecedence.CALL_PRECEDENCE); 2177 beginExpression(JSPrecedence.CALL_PRECEDENCE);
2175 2178
2176 if (element == compiler.stringClass) { 2179 if (element == compiler.stringClass) {
2177 helper = const SourceString('stringTypeCheck'); 2180 helper = const SourceString('stringTypeCheck');
2178 } else if (element == compiler.doubleClass) { 2181 } else if (element == compiler.doubleClass) {
2179 helper = const SourceString('doubleTypeCheck'); 2182 helper = const SourceString('doubleTypeCheck');
2180 } else if (element == compiler.numClass) { 2183 } else if (element == compiler.numClass) {
2181 helper = const SourceString('numTypeCheck'); 2184 helper = const SourceString('numTypeCheck');
2182 } else if (element == compiler.boolClass) { 2185 } else if (element == compiler.boolClass) {
2183 helper = const SourceString('boolTypeCheck'); 2186 helper = const SourceString('boolTypeCheck');
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2215 if (additionalArgument !== null) buffer.add(", '$additionalArgument'"); 2218 if (additionalArgument !== null) buffer.add(", '$additionalArgument'");
2216 buffer.add(')'); 2219 buffer.add(')');
2217 endExpression(JSPrecedence.CALL_PRECEDENCE); 2220 endExpression(JSPrecedence.CALL_PRECEDENCE);
2218 } else { 2221 } else {
2219 use(node.checkedInput, expectedPrecedence); 2222 use(node.checkedInput, expectedPrecedence);
2220 } 2223 }
2221 } 2224 }
2222 } 2225 }
2223 2226
2224 class SsaOptimizedCodeGenerator extends SsaCodeGenerator { 2227 class SsaOptimizedCodeGenerator extends SsaCodeGenerator {
2225 SsaOptimizedCodeGenerator(compiler, work, parameters, parameterNames) 2228 SsaOptimizedCodeGenerator(backend, work, parameters, parameterNames)
2226 : super(compiler, work, parameters, parameterNames); 2229 : super(backend, work, parameters, parameterNames);
2227 2230
2228 void beginGraph(HGraph graph) {} 2231 void beginGraph(HGraph graph) {}
2229 void endGraph(HGraph graph) {} 2232 void endGraph(HGraph graph) {}
2230 2233
2231 void bailout(HTypeGuard guard, String reason) { 2234 void bailout(HTypeGuard guard, String reason) {
2232 HInstruction input = guard.guarded; 2235 HInstruction input = guard.guarded;
2233 Namer namer = compiler.namer; 2236 Namer namer = compiler.namer;
2234 Element element = work.element; 2237 Element element = work.element;
2235 buffer.add('return '); 2238 buffer.add('return ');
2236 if (element.isInstanceMember()) { 2239 if (element.isInstanceMember()) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 } 2387 }
2385 } 2388 }
2386 2389
2387 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { 2390 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator {
2388 2391
2389 final StringBuffer setup; 2392 final StringBuffer setup;
2390 final List<String> labels; 2393 final List<String> labels;
2391 int labelId = 0; 2394 int labelId = 0;
2392 int maxBailoutParameters = 0; 2395 int maxBailoutParameters = 0;
2393 2396
2394 SsaUnoptimizedCodeGenerator(compiler, work, parameters, parameterNames) 2397 SsaUnoptimizedCodeGenerator(backend, work, parameters, parameterNames)
2395 : super(compiler, work, parameters, parameterNames), 2398 : super(backend, work, parameters, parameterNames),
2396 setup = new StringBuffer(), 2399 setup = new StringBuffer(),
2397 labels = <String>[]; 2400 labels = <String>[];
2398 2401
2399 String pushLabel() { 2402 String pushLabel() {
2400 String label = 'L${labelId++}'; 2403 String label = 'L${labelId++}';
2401 labels.addLast(label); 2404 labels.addLast(label);
2402 return label; 2405 return label;
2403 } 2406 }
2404 2407
2405 String popLabel() { 2408 String popLabel() {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 startBailoutSwitch(); 2620 startBailoutSwitch();
2618 } 2621 }
2619 } 2622 }
2620 2623
2621 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { 2624 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
2622 if (labeledBlockInfo.body.start.hasGuards()) { 2625 if (labeledBlockInfo.body.start.hasGuards()) {
2623 endBailoutSwitch(); 2626 endBailoutSwitch();
2624 } 2627 }
2625 } 2628 }
2626 } 2629 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/closure.dart ('k') | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698