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

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

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