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

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

Issue 188433002: Instruction selection before removing HTypeKnown (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 /** 7 /**
8 * Replaces some instructions with specialized versions to make codegen easier.
9 * Caches codegen information on nodes.
10 */
11 class SsaInstructionSelection extends HBaseVisitor {
12 final Compiler compiler;
13
14 SsaInstructionSelection(this.compiler);
15
16 void visitGraph(HGraph graph) {
17 visitDominatorTree(graph);
18 }
19
20 visitBasicBlock(HBasicBlock block) {
21 HInstruction instruction = block.first;
22 while (instruction != null) {
23 HInstruction next = instruction.next;
24 HInstruction replacement = instruction.accept(this);
25 if (replacement != instruction) {
26 block.rewrite(instruction, replacement);
27
28 // If the replacement instruction does not know its source element, use
29 // the source element of the instruction.
30 if (replacement.sourceElement == null) {
31 replacement.sourceElement = instruction.sourceElement;
32 }
33 if (replacement.sourcePosition == null) {
34 replacement.sourcePosition = instruction.sourcePosition;
35 }
36 if (!replacement.isInBasicBlock()) {
37 // The constant folding can return an instruction that is already
38 // part of the graph (like an input), so we only add the replacement
39 // if necessary.
40 block.addAfter(instruction, replacement);
41 // Visit the replacement as the next instruction in case it can also
42 // be constant folded away.
43 next = replacement;
44 }
45 block.remove(instruction);
46 }
47 instruction = next;
48 }
49 }
50
51 HInstruction visitInstruction(HInstruction node) {
52 return node;
53 }
54
55 HInstruction visitIs(HIs node) {
56 if (node.kind == HIs.RAW_CHECK) {
57 HInstruction interceptor = node.interceptor;
58 if (interceptor != null) {
59 JavaScriptBackend backend = compiler.backend;
60 return new HIsViaInterceptor(node.typeExpression, interceptor,
61 backend.boolType);
62 }
63 }
64 return node;
65 }
66
67 HInstruction visitIdentity(HIdentity node) {
68 node.singleComparisonOp = simpleOp(node.left, node.right);
69 return node;
70 }
71
72 String simpleOp(HInstruction left, HInstruction right) {
73 // Returns the single identity comparison (== or ===) or null if a more
74 // complex expression is required.
75 TypeMask leftType = left.instructionType;
76 TypeMask rightType = right.instructionType;
77 if (leftType.isNullable && rightType.isNullable) {
78 if (left.isConstantNull() ||
79 right.isConstantNull() ||
80 (left.isPrimitive(compiler) &&
81 leftType == rightType)) {
82 return '==';
83 }
84 return null;
85 }
86 return '===';
87 }
88 }
89
90 /**
8 * Remove [HTypeKnown] instructions from the graph, to make codegen 91 * Remove [HTypeKnown] instructions from the graph, to make codegen
9 * analysis easier. 92 * analysis easier.
10 */ 93 */
11 class SsaTypeKnownRemover extends HBaseVisitor { 94 class SsaTypeKnownRemover extends HBaseVisitor {
12 95
13 void visitGraph(HGraph graph) { 96 void visitGraph(HGraph graph) {
14 visitDominatorTree(graph); 97 visitDominatorTree(graph);
15 } 98 }
16 99
17 void visitBasicBlock(HBasicBlock block) { 100 void visitBasicBlock(HBasicBlock block) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 // A bounds check method must not have its first input generated at use site, 200 // A bounds check method must not have its first input generated at use site,
118 // because it's using it twice. 201 // because it's using it twice.
119 void visitBoundsCheck(HBoundsCheck instruction) { 202 void visitBoundsCheck(HBoundsCheck instruction) {
120 analyzeInputs(instruction, 1); 203 analyzeInputs(instruction, 1);
121 } 204 }
122 205
123 // An identity operation must only have its inputs generated at use site if 206 // An identity operation must only have its inputs generated at use site if
124 // does not require an expression with multiple uses (because of null / 207 // does not require an expression with multiple uses (because of null /
125 // undefined). 208 // undefined).
126 void visitIdentity(HIdentity instruction) { 209 void visitIdentity(HIdentity instruction) {
127 HInstruction left = instruction.left; 210 if (instruction.singleComparisonOp != null) {
128 HInstruction right = instruction.right;
129 if (singleIdentityComparison(left, right, compiler) != null) {
130 super.visitIdentity(instruction); 211 super.visitIdentity(instruction);
131 } 212 }
132 // Do nothing. 213 // Do nothing.
133 } 214 }
134 215
135 void visitTypeConversion(HTypeConversion instruction) { 216 void visitTypeConversion(HTypeConversion instruction) {
136 if (!instruction.isArgumentTypeCheck 217 if (!instruction.isArgumentTypeCheck
137 && !instruction.isReceiverTypeCheck) { 218 && !instruction.isReceiverTypeCheck) {
138 assert(instruction.isCheckedModeCheck || instruction.isCastTypeCheck); 219 assert(instruction.isCheckedModeCheck || instruction.isCastTypeCheck);
139 // Checked mode checks and cast checks compile to code that 220 // Checked mode checks and cast checks compile to code that
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 } 484 }
404 485
405 // If [thenInput] is defined in the first predecessor, then it is only used 486 // If [thenInput] is defined in the first predecessor, then it is only used
406 // by [phi] and can be generated at use site. 487 // by [phi] and can be generated at use site.
407 if (identical(thenInput.block, end.predecessors[0])) { 488 if (identical(thenInput.block, end.predecessors[0])) {
408 assert(thenInput.usedBy.length == 1); 489 assert(thenInput.usedBy.length == 1);
409 markAsGenerateAtUseSite(thenInput); 490 markAsGenerateAtUseSite(thenInput);
410 } 491 }
411 } 492 }
412 } 493 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698