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

Side by Side Diff: lib/compiler/implementation/operations.dart

Issue 10119010: Start propagating non-primitive types in the backend, and fold instructions that know about the typ… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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 interface Operation { 5 interface Operation {
6 6 final SourceString name;
7 bool isUserDefinable();
7 } 8 }
8 9
9 interface UnaryOperation extends Operation { 10 interface UnaryOperation extends Operation {
10 /** Returns [:null:] if it was unable to fold the operation. */ 11 /** Returns [:null:] if it was unable to fold the operation. */
11 Constant fold(Constant constant); 12 Constant fold(Constant constant);
12 } 13 }
13 14
14 class BitNotOperation implements UnaryOperation { 15 class BitNotOperation implements UnaryOperation {
16 final SourceString name = const SourceString('~');
17 bool isUserDefinable() => true;
15 const BitNotOperation(); 18 const BitNotOperation();
16 Constant fold(Constant constant) { 19 Constant fold(Constant constant) {
17 if (constant.isInt()) { 20 if (constant.isInt()) {
18 IntConstant intConstant = constant; 21 IntConstant intConstant = constant;
19 return new IntConstant(~intConstant.value); 22 return new IntConstant(~intConstant.value);
20 } 23 }
21 return null; 24 return null;
22 } 25 }
23 } 26 }
24 27
25 class NegateOperation implements UnaryOperation { 28 class NegateOperation implements UnaryOperation {
29 final SourceString name = const SourceString('negate');
30 bool isUserDefinable() => true;
26 const NegateOperation(); 31 const NegateOperation();
27 Constant fold(Constant constant) { 32 Constant fold(Constant constant) {
28 if (constant.isInt()) { 33 if (constant.isInt()) {
29 IntConstant intConstant = constant; 34 IntConstant intConstant = constant;
30 return new IntConstant(-intConstant.value); 35 return new IntConstant(-intConstant.value);
31 } 36 }
32 if (constant.isDouble()) { 37 if (constant.isDouble()) {
33 DoubleConstant doubleConstant = constant; 38 DoubleConstant doubleConstant = constant;
34 return new DoubleConstant(-doubleConstant.value); 39 return new DoubleConstant(-doubleConstant.value);
35 } 40 }
36 return null; 41 return null;
37 } 42 }
38 } 43 }
39 44
40 class NotOperation implements UnaryOperation { 45 class NotOperation implements UnaryOperation {
46 final SourceString name = const SourceString('!');
47 bool isUserDefinable() => true;
41 const NotOperation(); 48 const NotOperation();
42 Constant fold(Constant constant) { 49 Constant fold(Constant constant) {
43 if (constant.isBool()) { 50 if (constant.isBool()) {
44 BoolConstant boolConstant = constant; 51 BoolConstant boolConstant = constant;
45 return boolConstant.negate(); 52 return boolConstant.negate();
46 } 53 }
47 return null; 54 return null;
48 } 55 }
49 } 56 }
50 57
51 interface BinaryOperation extends Operation { 58 interface BinaryOperation extends Operation {
52 /** Returns [:null:] if it was unable to fold the operation. */ 59 /** Returns [:null:] if it was unable to fold the operation. */
53 Constant fold(Constant left, Constant right); 60 Constant fold(Constant left, Constant right);
54 } 61 }
55 62
56 /** 63 /**
57 * Operations that only work if both arguments are integers. 64 * Operations that only work if both arguments are integers.
58 */ 65 */
59 class BinaryIntOperation implements BinaryOperation { 66 class BinaryIntOperation implements BinaryOperation {
67 bool isUserDefinable() => true;
60 const BinaryIntOperation(); 68 const BinaryIntOperation();
61 Constant fold(Constant left, Constant right) { 69 Constant fold(Constant left, Constant right) {
62 if (left.isInt() && right.isInt()) { 70 if (left.isInt() && right.isInt()) {
63 IntConstant leftInt = left; 71 IntConstant leftInt = left;
64 IntConstant rightInt = right; 72 IntConstant rightInt = right;
65 int resultValue = foldInts(leftInt.value, rightInt.value); 73 int resultValue = foldInts(leftInt.value, rightInt.value);
66 if (resultValue === null) return null; 74 if (resultValue === null) return null;
67 return new IntConstant(resultValue); 75 return new IntConstant(resultValue);
68 } 76 }
69 return null; 77 return null;
70 } 78 }
71 79
72 abstract int foldInts(int left, int right); 80 abstract int foldInts(int left, int right);
73 } 81 }
74 82
75 class BitOrOperation extends BinaryIntOperation { 83 class BitOrOperation extends BinaryIntOperation {
84 final SourceString name = const SourceString('|');
76 const BitOrOperation(); 85 const BitOrOperation();
77 int foldInts(int left, int right) => left | right; 86 int foldInts(int left, int right) => left | right;
78 } 87 }
79 88
80 class BitAndOperation extends BinaryIntOperation { 89 class BitAndOperation extends BinaryIntOperation {
90 final SourceString name = const SourceString('&');
81 const BitAndOperation(); 91 const BitAndOperation();
82 int foldInts(int left, int right) => left & right; 92 int foldInts(int left, int right) => left & right;
83 } 93 }
84 94
85 class BitXorOperation extends BinaryIntOperation { 95 class BitXorOperation extends BinaryIntOperation {
96 final SourceString name = const SourceString('^');
86 const BitXorOperation(); 97 const BitXorOperation();
87 int foldInts(int left, int right) => left ^ right; 98 int foldInts(int left, int right) => left ^ right;
88 } 99 }
89 100
90 class ShiftLeftOperation extends BinaryIntOperation { 101 class ShiftLeftOperation extends BinaryIntOperation {
102 final SourceString name = const SourceString('<<');
91 const ShiftLeftOperation(); 103 const ShiftLeftOperation();
92 int foldInts(int left, int right) { 104 int foldInts(int left, int right) {
93 // TODO(floitsch): find a better way to guard against excessive shifts to 105 // TODO(floitsch): find a better way to guard against excessive shifts to
94 // the left. 106 // the left.
95 if (right > 100 || right < 0) return null; 107 if (right > 100 || right < 0) return null;
96 return left << right; 108 return left << right;
97 } 109 }
98 } 110 }
99 111
100 class ShiftRightOperation extends BinaryIntOperation { 112 class ShiftRightOperation extends BinaryIntOperation {
113 final SourceString name = const SourceString('>>');
101 const ShiftRightOperation(); 114 const ShiftRightOperation();
102 int foldInts(int left, int right) { 115 int foldInts(int left, int right) {
103 if (right < 0) return null; 116 if (right < 0) return null;
104 return left >> right; 117 return left >> right;
105 } 118 }
106 } 119 }
107 120
108 class BinaryBoolOperation implements BinaryOperation { 121 class BinaryBoolOperation implements BinaryOperation {
122 bool isUserDefinable() => false;
109 const BinaryBoolOperation(); 123 const BinaryBoolOperation();
110 Constant fold(Constant left, Constant right) { 124 Constant fold(Constant left, Constant right) {
111 if (left.isBool() && right.isBool()) { 125 if (left.isBool() && right.isBool()) {
112 BoolConstant leftBool = left; 126 BoolConstant leftBool = left;
113 BoolConstant rightBool = right; 127 BoolConstant rightBool = right;
114 bool resultValue = foldBools(leftBool.value, rightBool.value); 128 bool resultValue = foldBools(leftBool.value, rightBool.value);
115 return new BoolConstant(resultValue); 129 return new BoolConstant(resultValue);
116 } 130 }
117 return null; 131 return null;
118 } 132 }
119 133
120 abstract bool foldBools(bool left, bool right); 134 abstract bool foldBools(bool left, bool right);
121 } 135 }
122 136
123 class BooleanAnd extends BinaryBoolOperation { 137 class BooleanAnd extends BinaryBoolOperation {
138 final SourceString name = const SourceString('&&');
124 const BooleanAnd(); 139 const BooleanAnd();
125 bool foldBools(bool left, bool right) => left && right; 140 bool foldBools(bool left, bool right) => left && right;
126 } 141 }
127 142
128 class BooleanOr extends BinaryBoolOperation { 143 class BooleanOr extends BinaryBoolOperation {
144 final SourceString name = const SourceString('||');
129 const BooleanOr(); 145 const BooleanOr();
130 bool foldBools(bool left, bool right) => left || right; 146 bool foldBools(bool left, bool right) => left || right;
131 } 147 }
132 148
133 class ArithmeticNumOperation implements BinaryOperation { 149 class ArithmeticNumOperation implements BinaryOperation {
150 bool isUserDefinable() => true;
134 const ArithmeticNumOperation(); 151 const ArithmeticNumOperation();
135 Constant fold(Constant left, Constant right) { 152 Constant fold(Constant left, Constant right) {
136 if (left.isNum() && right.isNum()) { 153 if (left.isNum() && right.isNum()) {
137 NumConstant leftNum = left; 154 NumConstant leftNum = left;
138 NumConstant rightNum = right; 155 NumConstant rightNum = right;
139 num foldedValue; 156 num foldedValue;
140 if (left.isInt() && right.isInt()) { 157 if (left.isInt() && right.isInt()) {
141 foldedValue = foldInts(leftNum.value, rightNum.value); 158 foldedValue = foldInts(leftNum.value, rightNum.value);
142 } else { 159 } else {
143 foldedValue = foldNums(leftNum.value, rightNum.value); 160 foldedValue = foldNums(leftNum.value, rightNum.value);
144 } 161 }
145 // A division by 0 means that we might not have a folded value. 162 // A division by 0 means that we might not have a folded value.
146 if (foldedValue === null) return null; 163 if (foldedValue === null) return null;
147 if (left.isInt() && right.isInt() && !isDivide()) { 164 if (left.isInt() && right.isInt() && !isDivide()) {
148 assert(foldedValue is int); 165 assert(foldedValue is int);
149 return new IntConstant(foldedValue); 166 return new IntConstant(foldedValue);
150 } else { 167 } else {
151 return new DoubleConstant(foldedValue); 168 return new DoubleConstant(foldedValue);
152 } 169 }
153 } 170 }
154 } 171 }
155 172
156 bool isDivide() => false; 173 bool isDivide() => false;
157 num foldInts(int left, int right) => foldNums(left, right); 174 num foldInts(int left, int right) => foldNums(left, right);
158 abstract num foldNums(num left, num right); 175 abstract num foldNums(num left, num right);
159 } 176 }
160 177
161 class SubtractOperation extends ArithmeticNumOperation { 178 class SubtractOperation extends ArithmeticNumOperation {
179 final SourceString name = const SourceString('-');
162 const SubtractOperation(); 180 const SubtractOperation();
163 num foldNums(num left, num right) => left - right; 181 num foldNums(num left, num right) => left - right;
164 } 182 }
165 183
166 class MultiplyOperation extends ArithmeticNumOperation { 184 class MultiplyOperation extends ArithmeticNumOperation {
185 final SourceString name = const SourceString('*');
167 const MultiplyOperation(); 186 const MultiplyOperation();
168 num foldNums(num left, num right) => left * right; 187 num foldNums(num left, num right) => left * right;
169 } 188 }
170 189
171 class ModuloOperation extends ArithmeticNumOperation { 190 class ModuloOperation extends ArithmeticNumOperation {
191 final SourceString name = const SourceString('%');
172 const ModuloOperation(); 192 const ModuloOperation();
173 int foldInts(int left, int right) { 193 int foldInts(int left, int right) {
174 if (right == 0) return null; 194 if (right == 0) return null;
175 return left % right; 195 return left % right;
176 } 196 }
177 num foldNums(num left, num right) => left % right; 197 num foldNums(num left, num right) => left % right;
178 } 198 }
179 199
180 class TruncatingDivideOperation extends ArithmeticNumOperation { 200 class TruncatingDivideOperation extends ArithmeticNumOperation {
201 final SourceString name = const SourceString('~/');
181 const TruncatingDivideOperation(); 202 const TruncatingDivideOperation();
182 int foldInts(int left, int right) { 203 int foldInts(int left, int right) {
183 if (right == 0) return null; 204 if (right == 0) return null;
184 return left ~/ right; 205 return left ~/ right;
185 } 206 }
186 num foldNums(num left, num right) => left ~/ right; 207 num foldNums(num left, num right) => left ~/ right;
187 } 208 }
188 209
189 class DivideOperation extends ArithmeticNumOperation { 210 class DivideOperation extends ArithmeticNumOperation {
211 final SourceString name = const SourceString('/');
190 const DivideOperation(); 212 const DivideOperation();
191 num foldNums(num left, num right) => left / right; 213 num foldNums(num left, num right) => left / right;
192 bool isDivide() => true; 214 bool isDivide() => true;
193 } 215 }
194 216
195 class AddOperation implements BinaryOperation { 217 class AddOperation implements BinaryOperation {
218 final SourceString name = const SourceString('+');
219 bool isUserDefinable() => true;
196 const AddOperation(); 220 const AddOperation();
197 Constant fold(Constant left, Constant right) { 221 Constant fold(Constant left, Constant right) {
198 if (left.isInt() && right.isInt()) { 222 if (left.isInt() && right.isInt()) {
199 IntConstant leftInt = left; 223 IntConstant leftInt = left;
200 IntConstant rightInt = right; 224 IntConstant rightInt = right;
201 return new IntConstant(leftInt.value + rightInt.value); 225 return new IntConstant(leftInt.value + rightInt.value);
202 } else if (left.isNum() && right.isNum()) { 226 } else if (left.isNum() && right.isNum()) {
203 NumConstant leftNum = left; 227 NumConstant leftNum = left;
204 NumConstant rightNum = right; 228 NumConstant rightNum = right;
205 return new DoubleConstant(leftNum.value + rightNum.value); 229 return new DoubleConstant(leftNum.value + rightNum.value);
(...skipping 10 matching lines...) Expand all
216 new ConsDartString(leftString.value, rightDartString); 240 new ConsDartString(leftString.value, rightDartString);
217 return new StringConstant(concatenated); 241 return new StringConstant(concatenated);
218 } 242 }
219 } else { 243 } else {
220 return null; 244 return null;
221 } 245 }
222 } 246 }
223 } 247 }
224 248
225 class RelationalNumOperation implements BinaryOperation { 249 class RelationalNumOperation implements BinaryOperation {
250 bool isUserDefinable() => true;
226 const RelationalNumOperation(); 251 const RelationalNumOperation();
227 Constant fold(Constant left, Constant right) { 252 Constant fold(Constant left, Constant right) {
228 if (left.isNum() && right.isNum()) { 253 if (left.isNum() && right.isNum()) {
229 NumConstant leftNum = left; 254 NumConstant leftNum = left;
230 NumConstant rightNum = right; 255 NumConstant rightNum = right;
231 bool foldedValue = foldNums(leftNum.value, rightNum.value); 256 bool foldedValue = foldNums(leftNum.value, rightNum.value);
232 assert(foldedValue != null); 257 assert(foldedValue != null);
233 return new BoolConstant(foldedValue); 258 return new BoolConstant(foldedValue);
234 } 259 }
235 } 260 }
236 261
237 abstract bool foldNums(num left, num right); 262 abstract bool foldNums(num left, num right);
238 } 263 }
239 264
240 class LessOperation extends RelationalNumOperation { 265 class LessOperation extends RelationalNumOperation {
266 final SourceString name = const SourceString('<');
241 const LessOperation(); 267 const LessOperation();
242 bool foldNums(num left, num right) => left < right; 268 bool foldNums(num left, num right) => left < right;
243 } 269 }
244 270
245 class LessEqualOperation extends RelationalNumOperation { 271 class LessEqualOperation extends RelationalNumOperation {
272 final SourceString name = const SourceString('<=');
246 const LessEqualOperation(); 273 const LessEqualOperation();
247 bool foldNums(num left, num right) => left <= right; 274 bool foldNums(num left, num right) => left <= right;
248 } 275 }
249 276
250 class GreaterOperation extends RelationalNumOperation { 277 class GreaterOperation extends RelationalNumOperation {
278 final SourceString name = const SourceString('>');
251 const GreaterOperation(); 279 const GreaterOperation();
252 bool foldNums(num left, num right) => left > right; 280 bool foldNums(num left, num right) => left > right;
253 } 281 }
254 282
255 class GreaterEqualOperation extends RelationalNumOperation { 283 class GreaterEqualOperation extends RelationalNumOperation {
284 final SourceString name = const SourceString('>=');
256 const GreaterEqualOperation(); 285 const GreaterEqualOperation();
257 bool foldNums(num left, num right) => left >= right; 286 bool foldNums(num left, num right) => left >= right;
258 } 287 }
259 288
260 class EqualsOperation implements BinaryOperation { 289 class EqualsOperation implements BinaryOperation {
290 final SourceString name = const SourceString('==');
291 bool isUserDefinable() => true;
261 const EqualsOperation(); 292 const EqualsOperation();
262 Constant fold(Constant left, Constant right) { 293 Constant fold(Constant left, Constant right) {
263 if (left.isNum() && right.isNum()) { 294 if (left.isNum() && right.isNum()) {
264 // Numbers need to be treated specially because: NaN != NaN, -0.0 == 0.0, 295 // Numbers need to be treated specially because: NaN != NaN, -0.0 == 0.0,
265 // and 1 == 1.0. 296 // and 1 == 1.0.
266 NumConstant leftNum = left; 297 NumConstant leftNum = left;
267 NumConstant rightNum = right; 298 NumConstant rightNum = right;
268 return new BoolConstant(leftNum.value == rightNum.value); 299 return new BoolConstant(leftNum.value == rightNum.value);
269 } 300 }
270 if (left.isConstructedObject()) { 301 if (left.isConstructedObject()) {
271 // Unless we know that the user-defined object does not implement the 302 // Unless we know that the user-defined object does not implement the
272 // equality operator we cannot fold here. 303 // equality operator we cannot fold here.
273 return null; 304 return null;
274 } 305 }
275 return new BoolConstant(left == right); 306 return new BoolConstant(left == right);
276 } 307 }
277 } 308 }
278 309
279 class IdentityOperation implements BinaryOperation { 310 class IdentityOperation implements BinaryOperation {
311 final SourceString name = const SourceString('===');
312 bool isUserDefinable() => false;
280 const IdentityOperation(); 313 const IdentityOperation();
281 Constant fold(Constant left, Constant right) { 314 Constant fold(Constant left, Constant right) {
282 return new BoolConstant(left == right); 315 return new BoolConstant(left == right);
283 } 316 }
284 } 317 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/elements/elements.dart ('k') | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698