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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart

Issue 12211112: Start work on a non-complete type inferrer. Currently only analyzes return types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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 part of ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 new SsaDeadPhiEliminator(), 51 new SsaDeadPhiEliminator(),
52 new SsaConstantFolder(constantSystem, backend, work, types), 52 new SsaConstantFolder(constantSystem, backend, work, types),
53 new SsaTypePropagator(compiler, types), 53 new SsaTypePropagator(compiler, types),
54 new SsaReceiverSpecialization(compiler), 54 new SsaReceiverSpecialization(compiler),
55 new SsaGlobalValueNumberer(compiler, types), 55 new SsaGlobalValueNumberer(compiler, types),
56 new SsaCodeMotion(), 56 new SsaCodeMotion(),
57 new SsaValueRangeAnalyzer(constantSystem, types, work), 57 new SsaValueRangeAnalyzer(constantSystem, types, work),
58 // Previous optimizations may have generated new 58 // Previous optimizations may have generated new
59 // opportunities for constant folding. 59 // opportunities for constant folding.
60 new SsaConstantFolder(constantSystem, backend, work, types), 60 new SsaConstantFolder(constantSystem, backend, work, types),
61 new SsaSimplifyInterceptors(constantSystem), 61 new SsaSimplifyInterceptors(constantSystem, types),
62 new SsaDeadCodeEliminator(types)]; 62 new SsaDeadCodeEliminator(types)];
63 runPhases(graph, phases); 63 runPhases(graph, phases);
64 if (!speculative) { 64 if (!speculative) {
65 runPhase(graph, new SsaConstructionFieldTypes(backend, work, types)); 65 runPhase(graph, new SsaConstructionFieldTypes(backend, work, types));
66 } 66 }
67 }); 67 });
68 } 68 }
69 69
70 bool trySpeculativeOptimizations(CodegenWorkItem work, HGraph graph) { 70 bool trySpeculativeOptimizations(CodegenWorkItem work, HGraph graph) {
71 if (work.element.isField()) { 71 if (work.element.isField()) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 visitBasicBlock(HBasicBlock block) { 143 visitBasicBlock(HBasicBlock block) {
144 HInstruction instruction = block.first; 144 HInstruction instruction = block.first;
145 while (instruction != null) { 145 while (instruction != null) {
146 HInstruction next = instruction.next; 146 HInstruction next = instruction.next;
147 HInstruction replacement = instruction.accept(this); 147 HInstruction replacement = instruction.accept(this);
148 if (replacement != instruction) { 148 if (replacement != instruction) {
149 block.rewrite(instruction, replacement); 149 block.rewrite(instruction, replacement);
150 150
151 // If we can replace [instruction] with [replacement], then 151 // If we can replace [instruction] with [replacement], then
152 // [replacement]'s type can be narrowed. 152 // [replacement]'s type can be narrowed.
153 types[replacement] = 153 types[replacement] = types[replacement].intersection(
154 types[replacement].intersection(types[instruction], compiler); 154 types[instruction], compiler);
155 replacement.guaranteedType = replacement.guaranteedType.intersection(
156 instruction.guaranteedType, compiler);
155 157
156 // If the replacement instruction does not know its 158 // If the replacement instruction does not know its
157 // source element, use the source element of the 159 // source element, use the source element of the
158 // instruction. 160 // instruction.
159 if (replacement.sourceElement == null) { 161 if (replacement.sourceElement == null) {
160 replacement.sourceElement = instruction.sourceElement; 162 replacement.sourceElement = instruction.sourceElement;
161 } 163 }
162 if (replacement.sourcePosition == null) { 164 if (replacement.sourcePosition == null) {
163 replacement.sourcePosition = instruction.sourcePosition; 165 replacement.sourcePosition = instruction.sourcePosition;
164 } 166 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 return result; 253 return result;
252 } else if (actualReceiver.isConstantMap()) { 254 } else if (actualReceiver.isConstantMap()) {
253 HConstant constantInput = actualReceiver; 255 HConstant constantInput = actualReceiver;
254 MapConstant constant = constantInput.constant; 256 MapConstant constant = constantInput.constant;
255 return graph.addConstantInt(constant.length, constantSystem); 257 return graph.addConstantInt(constant.length, constantSystem);
256 } 258 }
257 return node; 259 return node;
258 } 260 }
259 261
260 HInstruction handleInterceptorCall(HInvokeDynamic node) { 262 HInstruction handleInterceptorCall(HInvokeDynamic node) {
261 // We only optimize for intercepted method calls in this method.
262 Selector selector = node.selector;
263
264 // Try constant folding the instruction. 263 // Try constant folding the instruction.
265 Operation operation = node.specializer.operation(constantSystem); 264 Operation operation = node.specializer.operation(constantSystem);
266 if (operation != null) { 265 if (operation != null) {
267 HInstruction instruction = node.inputs.length == 2 266 HInstruction instruction = node.inputs.length == 2
268 ? foldUnary(operation, node.inputs[1]) 267 ? foldUnary(operation, node.inputs[1])
269 : foldBinary(operation, node.inputs[1], node.inputs[2]); 268 : foldBinary(operation, node.inputs[1], node.inputs[2]);
270 if (instruction != null) return instruction; 269 if (instruction != null) return instruction;
271 } 270 }
272 271
273 // Try converting the instruction to a builtin instruction. 272 // Try converting the instruction to a builtin instruction.
274 HInstruction instruction = 273 HInstruction instruction =
275 node.specializer.tryConvertToBuiltin(node, types); 274 node.specializer.tryConvertToBuiltin(node, types);
276 if (instruction != null) return instruction; 275 if (instruction != null) return instruction;
277 276
278 // Check if this call does not need to be intercepted. 277 Selector selector = node.selector;
279 HInstruction input = node.inputs[1];
280 HType type = types[input];
281 var interceptor = node.inputs[0]; 278 var interceptor = node.inputs[0];
282 279
283 if (interceptor.isConstant() && selector.isCall()) { 280 // If the intercepted call is through a constant interceptor, we
281 // know which element to call.
282 if (node is !HOneShotInterceptor
283 && interceptor.isConstant()
284 && selector.isCall()) {
284 DartType type = types[interceptor].computeType(compiler); 285 DartType type = types[interceptor].computeType(compiler);
285 ClassElement cls = type.element; 286 ClassElement cls = type.element;
286 node.element = cls.lookupSelector(selector); 287 node.element = cls.lookupSelector(selector);
287 } 288 }
288 289
290 HInstruction input = node.inputs[1];
291 HType type = types[input];
292 // Check if this call does not need to be intercepted.
289 if (interceptor is !HThis && !type.canBePrimitive()) { 293 if (interceptor is !HThis && !type.canBePrimitive()) {
290 // If the type can be null, and the intercepted method can be in 294 // If the type can be null, and the intercepted method can be in
291 // the object class, keep the interceptor. 295 // the object class, keep the interceptor.
292 if (type.canBeNull()) { 296 if (type.canBeNull()) {
293 Set<ClassElement> interceptedClasses; 297 Set<ClassElement> interceptedClasses;
294 if (interceptor is HInterceptor) { 298 if (interceptor is HInterceptor) {
295 interceptedClasses = interceptor.interceptedClasses; 299 interceptedClasses = interceptor.interceptedClasses;
296 } else if (node is HOneShotInterceptor) { 300 } else if (node is HOneShotInterceptor) {
297 var oneShotInterceptor = node; 301 var oneShotInterceptor = node;
298 interceptedClasses = oneShotInterceptor.interceptedClasses; 302 interceptedClasses = oneShotInterceptor.interceptedClasses;
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1495 1499
1496 /** 1500 /**
1497 * This phase replaces all interceptors that are used only once with 1501 * This phase replaces all interceptors that are used only once with
1498 * one-shot interceptors. It saves code size and makes the receiver of 1502 * one-shot interceptors. It saves code size and makes the receiver of
1499 * an intercepted call a candidate for being generated at use site. 1503 * an intercepted call a candidate for being generated at use site.
1500 */ 1504 */
1501 class SsaSimplifyInterceptors extends HBaseVisitor 1505 class SsaSimplifyInterceptors extends HBaseVisitor
1502 implements OptimizationPhase { 1506 implements OptimizationPhase {
1503 final String name = "SsaSimplifyInterceptors"; 1507 final String name = "SsaSimplifyInterceptors";
1504 final ConstantSystem constantSystem; 1508 final ConstantSystem constantSystem;
1509 final HTypeMap types;
1505 HGraph graph; 1510 HGraph graph;
1506 1511
1507 SsaSimplifyInterceptors(this.constantSystem); 1512 SsaSimplifyInterceptors(this.constantSystem, this.types);
1508 1513
1509 void visitGraph(HGraph graph) { 1514 void visitGraph(HGraph graph) {
1510 this.graph = graph; 1515 this.graph = graph;
1511 visitDominatorTree(graph); 1516 visitDominatorTree(graph);
1512 } 1517 }
1513 1518
1514 void visitInterceptor(HInterceptor node) { 1519 void visitInterceptor(HInterceptor node) {
1515 if (node.usedBy.length != 1) return; 1520 if (node.usedBy.length != 1) return;
1516 // [HBailoutTarget] instructions might have the interceptor as 1521 // [HBailoutTarget] instructions might have the interceptor as
1517 // input. In such situation we let the dead code analyzer find out 1522 // input. In such situation we let the dead code analyzer find out
1518 // the interceptor is not needed. 1523 // the interceptor is not needed.
1519 if (node.usedBy[0] is !HInvokeDynamic) return; 1524 if (node.usedBy[0] is !HInvokeDynamic) return;
1520 1525
1521 HInvokeDynamic user = node.usedBy[0]; 1526 HInvokeDynamic user = node.usedBy[0];
1522 1527
1523 // If [node] was loop hoisted, we keep the interceptor. 1528 // If [node] was loop hoisted, we keep the interceptor.
1524 if (!user.hasSameLoopHeaderAs(node)) return; 1529 if (!user.hasSameLoopHeaderAs(node)) return;
1525 1530
1526 // Replace the user with a [HOneShotInterceptor]. 1531 // Replace the user with a [HOneShotInterceptor].
1527 HConstant nullConstant = graph.addConstantNull(constantSystem); 1532 HConstant nullConstant = graph.addConstantNull(constantSystem);
1528 List<HInstruction> inputs = new List<HInstruction>.from(user.inputs); 1533 List<HInstruction> inputs = new List<HInstruction>.from(user.inputs);
1529 inputs[0] = nullConstant; 1534 inputs[0] = nullConstant;
1530 HOneShotInterceptor interceptor = new HOneShotInterceptor( 1535 HOneShotInterceptor interceptor = new HOneShotInterceptor(
1531 user.selector, inputs, node.interceptedClasses); 1536 user.selector, inputs, node.interceptedClasses);
1532 interceptor.sourcePosition = user.sourcePosition; 1537 interceptor.sourcePosition = user.sourcePosition;
1533 interceptor.sourceElement = user.sourceElement; 1538 interceptor.sourceElement = user.sourceElement;
1539 interceptor.guaranteedType = user.guaranteedType;
1540 types[interceptor] = types[user];
1534 1541
1535 HBasicBlock block = user.block; 1542 HBasicBlock block = user.block;
1536 block.addAfter(user, interceptor); 1543 block.addAfter(user, interceptor);
1537 block.rewrite(user, interceptor); 1544 block.rewrite(user, interceptor);
1538 block.remove(user); 1545 block.remove(user);
1539 1546
1540 // The interceptor will be removed in the dead code elimination 1547 // The interceptor will be removed in the dead code elimination
1541 // phase. Note that removing it here would not work because of how 1548 // phase. Note that removing it here would not work because of how
1542 // the [visitBasicBlock] is implemented. 1549 // the [visitBasicBlock] is implemented.
1543 } 1550 }
1544 } 1551 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698