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

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

Issue 11879047: Add a new class InvokeDynamicSpecializer and subclasses that know what input types are beneficial f… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
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.
4
5 part of ssa;
6
7 /**
8 * [InvokeDynamicSpecializer] and its subclasses are helpers to
9 * optimize intercepted dynamic calls. It knows what input types
10 * would be beneficial for performance, and how to change a invoke
11 * dynamic to a builtin instruction (e.g. HIndex, HBitNot).
12 */
13 class InvokeDynamicSpecializer {
14 const InvokeDynamicSpecializer();
15
16 HType computeDesiredTypeForInput(HInvokeDynamicMethod instruction,
17 HInstruction input,
18 HTypeMap types,
19 Compiler compiler) {
20 return HType.UNKNOWN;
21 }
22
23 HType computeTypeFromInputTypes(HInvokeDynamicMethod instruction,
24 HTypeMap types,
25 Compiler compiler) {
26 return HType.UNKNOWN;
27 }
28
29 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction,
30 HTypeMap types) {
31 return null;
32 }
33
34 static InvokeDynamicSpecializer lookupSpecializer(Selector selector) {
35 if (selector.kind == SelectorKind.INDEX) {
36 return selector.name == const SourceString('[]')
37 ? const IndexSpecializer()
38 : const IndexAssignSpecializer();
39 } else if (selector.kind == SelectorKind.OPERATOR) {
40 if (selector.name == const SourceString('unary-')) {
41 return const UnaryNegateSpecializer();
42 } else if (selector.name == const SourceString('~')) {
43 return const BitNotSpecializer();
44 }
45 }
46 return const InvokeDynamicSpecializer();
47 }
48 }
49
50 class IndexAssignSpecializer extends InvokeDynamicSpecializer {
51 const IndexAssignSpecializer();
52
53 HType computeDesiredTypeForInput(HInvokeDynamicMethod instruction,
54 HInstruction input,
55 HTypeMap types,
56 Compiler compiler) {
57 HInstruction index = instruction.inputs[2];
58 if (input == instruction.inputs[1] &&
59 (index.isTypeUnknown(types) || index.isNumber(types))) {
60 return HType.MUTABLE_ARRAY;
61 }
62 // The index should be an int when the receiver is a string or array.
63 // However it turns out that inserting an integer check in the optimized
64 // version is cheaper than having another bailout case. This is true,
65 // because the integer check will simply throw if it fails.
66 return HType.UNKNOWN;
67 }
68
69 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction,
70 HTypeMap types) {
71 if (instruction.inputs[1].isMutableArray(types)) {
72 return new HIndexAssign(instruction.inputs[1],
73 instruction.inputs[2],
74 instruction.inputs[3]);
75 }
76 return null;
77 }
78 }
79
80 class IndexSpecializer extends InvokeDynamicSpecializer {
81 const IndexSpecializer();
82
83 HType computeDesiredTypeForInput(HInvokeDynamicMethod instruction,
84 HInstruction input,
85 HTypeMap types,
86 Compiler compiler) {
87 HInstruction index = instruction.inputs[2];
88 if (input == instruction.inputs[1] &&
89 (index.isTypeUnknown(types) || index.isNumber(types))) {
90 return HType.INDEXABLE_PRIMITIVE;
91 }
92 // The index should be an int when the receiver is a string or array.
93 // However it turns out that inserting an integer check in the optimized
94 // version is cheaper than having another bailout case. This is true,
95 // because the integer check will simply throw if it fails.
96 return HType.UNKNOWN;
97 }
98
99 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction,
100 HTypeMap types) {
101 if (instruction.inputs[1].isIndexablePrimitive(types)) {
102 return new HIndex(instruction.inputs[1], instruction.inputs[2]);
103 }
104 return null;
105 }
106 }
107
108 class BitNotSpecializer extends InvokeDynamicSpecializer {
109 const BitNotSpecializer();
110
111 HType computeDesiredTypeForInput(HInvokeDynamicMethod instruction,
112 HInstruction input,
113 HTypeMap types,
114 Compiler compiler) {
115 if (input == instruction.inputs[1]) {
116 HType propagatedType = types[instruction];
117 if (propagatedType.isUnknown() || propagatedType.isNumber()) {
118 return HType.INTEGER;
119 }
120 }
121 return HType.UNKNOWN;
122 }
123
124 HType computeTypeFromInputTypes(HInvokeDynamicMethod instruction,
125 HTypeMap types,
126 Compiler compiler) {
127 // All bitwise operations on primitive types either produce an
128 // integer or throw an error.
129 if (instruction.inputs[1].isPrimitive(types)) return HType.INTEGER;
130 return HType.UNKNOWN;
131 }
132
133 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction,
134 HTypeMap types) {
135 HInstruction input = instruction.inputs[1];
136 if (input.isNumber(types)) return new HBitNot(input);
137 return null;
138 }
139 }
140
141 class UnaryNegateSpecializer extends InvokeDynamicSpecializer {
142 const UnaryNegateSpecializer();
143
144 HType computeDesiredTypeForInput(HInvokeDynamicMethod instruction,
145 HInstruction input,
146 HTypeMap types,
147 Compiler compiler) {
148 if (input == instruction.inputs[1]) {
149 HType propagatedType = types[instruction];
150 // If the outgoing type should be a number (integer, double or both) we
151 // want the outgoing type to be the input too.
152 // If we don't know the outgoing type we try to make it a number.
153 if (propagatedType.isNumber()) return propagatedType;
154 if (propagatedType.isUnknown()) return HType.NUMBER;
155 }
156 return HType.UNKNOWN;
157 }
158
159 HType computeTypeFromInputTypes(HInvokeDynamicMethod instruction,
160 HTypeMap types,
161 Compiler compiler) {
162 HType operandType = types[instruction.inputs[1]];
163 if (operandType.isNumber()) return operandType;
164 return HType.UNKNOWN;
165 }
166
167 HInstruction tryConvertToBuiltin(HInvokeDynamicMethod instruction,
168 HTypeMap types) {
169 HInstruction input = instruction.inputs[1];
170 if (input.isNumber(types)) return new HNegate(input);
171 return null;
172 }
173 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/builder.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698