Mercurial > hg > truffle
comparison graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java @ 15131:9c1e53adc159
Remove unsigned flag from IntegerStamp.
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Tue, 15 Apr 2014 19:08:29 +0200 |
parents | ea712c41c5a2 |
children | 844cfee4041a |
comparison
equal
deleted
inserted
replaced
15130:ec22234bde0d | 15131:9c1e53adc159 |
---|---|
51 | 51 |
52 public static Stamp negate(Stamp stamp) { | 52 public static Stamp negate(Stamp stamp) { |
53 if (stamp instanceof IntegerStamp) { | 53 if (stamp instanceof IntegerStamp) { |
54 IntegerStamp integerStamp = (IntegerStamp) stamp; | 54 IntegerStamp integerStamp = (IntegerStamp) stamp; |
55 int bits = integerStamp.getBits(); | 55 int bits = integerStamp.getBits(); |
56 if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits, false)) { | 56 if (integerStamp.lowerBound() != IntegerStamp.defaultMinValue(bits)) { |
57 // TODO(ls) check if the mask calculation is correct... | 57 // TODO(ls) check if the mask calculation is correct... |
58 return StampFactory.forInteger(bits, false, -integerStamp.upperBound(), -integerStamp.lowerBound()); | 58 return StampFactory.forInteger(bits, -integerStamp.upperBound(), -integerStamp.lowerBound()); |
59 } | 59 } |
60 } else if (stamp instanceof FloatStamp) { | 60 } else if (stamp instanceof FloatStamp) { |
61 FloatStamp floatStamp = (FloatStamp) stamp; | 61 FloatStamp floatStamp = (FloatStamp) stamp; |
62 return new FloatStamp(floatStamp.getBits(), -floatStamp.upperBound(), -floatStamp.lowerBound(), floatStamp.isNonNaN()); | 62 return new FloatStamp(floatStamp.getBits(), -floatStamp.upperBound(), -floatStamp.lowerBound(), floatStamp.isNonNaN()); |
63 } | 63 } |
68 public static Stamp not(Stamp stamp) { | 68 public static Stamp not(Stamp stamp) { |
69 if (stamp instanceof IntegerStamp) { | 69 if (stamp instanceof IntegerStamp) { |
70 IntegerStamp integerStamp = (IntegerStamp) stamp; | 70 IntegerStamp integerStamp = (IntegerStamp) stamp; |
71 int bits = integerStamp.getBits(); | 71 int bits = integerStamp.getBits(); |
72 long defaultMask = IntegerStamp.defaultMask(bits); | 72 long defaultMask = IntegerStamp.defaultMask(bits); |
73 return new IntegerStamp(bits, integerStamp.isUnsigned(), ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & | 73 return new IntegerStamp(bits, ~integerStamp.upperBound(), ~integerStamp.lowerBound(), (~integerStamp.upMask()) & defaultMask, (~integerStamp.downMask()) & defaultMask); |
74 defaultMask); | |
75 } | 74 } |
76 return stamp.unrestricted(); | 75 return stamp.unrestricted(); |
77 } | 76 } |
78 | 77 |
79 public static Stamp meet(Collection<? extends StampProvider> values) { | 78 public static Stamp meet(Collection<? extends StampProvider> values) { |
110 } | 109 } |
111 return joinIllegal(stamp1, stamp2); | 110 return joinIllegal(stamp1, stamp2); |
112 } | 111 } |
113 | 112 |
114 public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) { | 113 public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) { |
115 assert stamp1.getBits() == stamp2.getBits() && stamp1.isUnsigned() == stamp2.isUnsigned(); | 114 assert stamp1.getBits() == stamp2.getBits(); |
116 if (stamp2.isStrictlyPositive()) { | 115 if (stamp2.isStrictlyPositive()) { |
117 long lowerBound = stamp1.lowerBound() / stamp2.lowerBound(); | 116 long lowerBound = stamp1.lowerBound() / stamp2.lowerBound(); |
118 long upperBound = stamp1.upperBound() / stamp2.lowerBound(); | 117 long upperBound = stamp1.upperBound() / stamp2.lowerBound(); |
119 return StampFactory.forInteger(stamp1.getBits(), stamp1.isUnsigned(), lowerBound, upperBound); | 118 return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound); |
120 } | 119 } |
121 return stamp1.unrestricted(); | 120 return stamp1.unrestricted(); |
122 } | 121 } |
123 | 122 |
124 private static boolean addOverflowsPositively(long x, long y, int bits, boolean unsigned) { | 123 private static boolean addOverflowsPositively(long x, long y, int bits) { |
125 long result = x + y; | 124 long result = x + y; |
126 if (bits == 64) { | 125 if (bits == 64) { |
127 if (unsigned) { | 126 return (~x & ~y & result) < 0; |
128 return ((x | y) & ~result) < 0; | 127 } else { |
129 } else { | 128 return result > IntegerStamp.defaultMaxValue(bits); |
130 return (~x & ~y & result) < 0; | 129 } |
131 } | 130 } |
132 } else { | 131 |
133 return result > IntegerStamp.defaultMaxValue(bits, unsigned); | 132 private static boolean addOverflowsNegatively(long x, long y, int bits) { |
134 } | |
135 } | |
136 | |
137 private static boolean addOverflowsNegatively(long x, long y, int bits, boolean unsigned) { | |
138 if (unsigned) { | |
139 return false; | |
140 } | |
141 | |
142 long result = x + y; | 133 long result = x + y; |
143 if (bits == 64) { | 134 if (bits == 64) { |
144 return (x & y & ~result) < 0; | 135 return (x & y & ~result) < 0; |
145 } else { | 136 } else { |
146 return result < IntegerStamp.defaultMinValue(bits, unsigned); | 137 return result < IntegerStamp.defaultMinValue(bits); |
147 } | 138 } |
148 } | 139 } |
149 | 140 |
150 public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) { | 141 public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) { |
151 int bits = stamp1.getBits(); | 142 int bits = stamp1.getBits(); |
152 boolean unsigned = stamp1.isUnsigned(); | 143 assert bits == stamp2.getBits(); |
153 assert bits == stamp2.getBits() && unsigned == stamp2.isUnsigned(); | |
154 | 144 |
155 if (stamp1.isUnrestricted()) { | 145 if (stamp1.isUnrestricted()) { |
156 return stamp1; | 146 return stamp1; |
157 } else if (stamp2.isUnrestricted()) { | 147 } else if (stamp2.isUnrestricted()) { |
158 return stamp2; | 148 return stamp2; |
166 newDownMask &= defaultMask; | 156 newDownMask &= defaultMask; |
167 newUpMask &= defaultMask; | 157 newUpMask &= defaultMask; |
168 | 158 |
169 long lowerBound; | 159 long lowerBound; |
170 long upperBound; | 160 long upperBound; |
171 boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), bits, unsigned); | 161 boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), bits); |
172 boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), bits, unsigned); | 162 boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), bits); |
173 boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), bits, unsigned); | 163 boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), bits); |
174 boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), bits, unsigned); | 164 boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), bits); |
175 if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) { | 165 if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsPositively && upperOverflowsPositively)) { |
176 lowerBound = IntegerStamp.defaultMinValue(bits, unsigned); | 166 lowerBound = IntegerStamp.defaultMinValue(bits); |
177 upperBound = IntegerStamp.defaultMaxValue(bits, unsigned); | 167 upperBound = IntegerStamp.defaultMaxValue(bits); |
178 } else { | 168 } else { |
179 lowerBound = (stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask; | 169 lowerBound = SignExtendNode.signExtend((stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask, bits); |
180 upperBound = (stamp1.upperBound() + stamp2.upperBound()) & defaultMask; | 170 upperBound = SignExtendNode.signExtend((stamp1.upperBound() + stamp2.upperBound()) & defaultMask, bits); |
181 if (!unsigned) { | 171 } |
182 lowerBound = SignExtendNode.signExtend(lowerBound, bits); | 172 IntegerStamp limit = StampFactory.forInteger(bits, lowerBound, upperBound); |
183 upperBound = SignExtendNode.signExtend(upperBound, bits); | |
184 } | |
185 } | |
186 IntegerStamp limit = StampFactory.forInteger(bits, unsigned, lowerBound, upperBound); | |
187 newUpMask &= limit.upMask(); | 173 newUpMask &= limit.upMask(); |
188 upperBound &= newUpMask; | 174 upperBound = SignExtendNode.signExtend(upperBound & newUpMask, bits); |
189 if (!unsigned) { | |
190 upperBound = SignExtendNode.signExtend(upperBound, bits); | |
191 } | |
192 newDownMask |= limit.downMask(); | 175 newDownMask |= limit.downMask(); |
193 lowerBound |= newDownMask; | 176 lowerBound |= newDownMask; |
194 return new IntegerStamp(bits, unsigned, lowerBound, upperBound, newDownMask, newUpMask); | 177 return new IntegerStamp(bits, lowerBound, upperBound, newDownMask, newUpMask); |
195 } | 178 } |
196 | 179 |
197 public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) { | 180 public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) { |
198 if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) { | 181 if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) { |
199 return stamp1.unrestricted(); | 182 return stamp1.unrestricted(); |
210 } else if (((downMask >>> (bits - 1)) & 1) == 1) { | 193 } else if (((downMask >>> (bits - 1)) & 1) == 1) { |
211 lowerBound = downMask; | 194 lowerBound = downMask; |
212 upperBound = upMask; | 195 upperBound = upMask; |
213 } else { | 196 } else { |
214 lowerBound = downMask | (-1L << (bits - 1)); | 197 lowerBound = downMask | (-1L << (bits - 1)); |
215 upperBound = IntegerStamp.defaultMaxValue(bits, false) & upMask; | 198 upperBound = IntegerStamp.defaultMaxValue(bits) & upMask; |
216 } | 199 } |
217 lowerBound = IntegerConvertNode.convert(lowerBound, bits, false); | 200 lowerBound = IntegerConvertNode.convert(lowerBound, bits, false); |
218 upperBound = IntegerConvertNode.convert(upperBound, bits, false); | 201 upperBound = IntegerConvertNode.convert(upperBound, bits, false); |
219 return new IntegerStamp(bits, false, lowerBound, upperBound, downMask, upMask); | 202 return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask); |
220 } | 203 } |
221 | 204 |
222 public static Stamp and(Stamp stamp1, Stamp stamp2) { | 205 public static Stamp and(Stamp stamp1, Stamp stamp2) { |
223 if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { | 206 if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { |
224 return and((IntegerStamp) stamp1, (IntegerStamp) stamp2); | 207 return and((IntegerStamp) stamp1, (IntegerStamp) stamp2); |
280 upperBound = upMask; | 263 upperBound = upMask; |
281 } else { | 264 } else { |
282 lowerBound = value.lowerBound() >>> shiftCount; | 265 lowerBound = value.lowerBound() >>> shiftCount; |
283 upperBound = value.upperBound() >>> shiftCount; | 266 upperBound = value.upperBound() >>> shiftCount; |
284 } | 267 } |
285 return new IntegerStamp(bits, value.isUnsigned(), lowerBound, upperBound, downMask, upMask); | 268 return new IntegerStamp(bits, lowerBound, upperBound, downMask, upMask); |
286 } | 269 } |
287 } | 270 } |
288 long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound()); | 271 long mask = IntegerStamp.upMaskFor(bits, value.lowerBound(), value.upperBound()); |
289 return stampForMask(bits, 0, mask); | 272 return stampForMask(bits, 0, mask); |
290 } | 273 } |
327 | 310 |
328 long defaultMask = IntegerStamp.defaultMask(resultBits); | 311 long defaultMask = IntegerStamp.defaultMask(resultBits); |
329 long downMask = SignExtendNode.signExtend(inputStamp.downMask(), inputBits) & defaultMask; | 312 long downMask = SignExtendNode.signExtend(inputStamp.downMask(), inputBits) & defaultMask; |
330 long upMask = SignExtendNode.signExtend(inputStamp.upMask(), inputBits) & defaultMask; | 313 long upMask = SignExtendNode.signExtend(inputStamp.upMask(), inputBits) & defaultMask; |
331 | 314 |
332 long lowerBound; | 315 return new IntegerStamp(resultBits, inputStamp.lowerBound(), inputStamp.upperBound(), downMask, upMask); |
333 long upperBound; | |
334 if (inputStamp.isUnsigned()) { | |
335 lowerBound = SignExtendNode.signExtend(inputStamp.lowerBound(), inputBits) & defaultMask; | |
336 upperBound = SignExtendNode.signExtend(inputStamp.upperBound(), inputBits) & defaultMask; | |
337 } else { | |
338 lowerBound = inputStamp.lowerBound(); | |
339 upperBound = inputStamp.upperBound(); | |
340 } | |
341 | |
342 return new IntegerStamp(resultBits, inputStamp.isUnsigned(), lowerBound, upperBound, downMask, upMask); | |
343 } else { | 316 } else { |
344 return input.illegal(); | 317 return input.illegal(); |
345 } | 318 } |
346 } | 319 } |
347 | 320 |
361 } | 334 } |
362 | 335 |
363 long lowerBound = ZeroExtendNode.zeroExtend(inputStamp.lowerBound(), inputBits); | 336 long lowerBound = ZeroExtendNode.zeroExtend(inputStamp.lowerBound(), inputBits); |
364 long upperBound = ZeroExtendNode.zeroExtend(inputStamp.upperBound(), inputBits); | 337 long upperBound = ZeroExtendNode.zeroExtend(inputStamp.upperBound(), inputBits); |
365 | 338 |
366 return new IntegerStamp(resultBits, inputStamp.isUnsigned(), lowerBound, upperBound, downMask, upMask); | 339 return new IntegerStamp(resultBits, lowerBound, upperBound, downMask, upMask); |
367 } else { | 340 } else { |
368 return input.illegal(); | 341 return input.illegal(); |
369 } | 342 } |
370 } | 343 } |
371 | 344 |
372 public static Stamp narrowingConversion(Stamp input, int resultBits) { | 345 public static Stamp narrowingConversion(Stamp input, int resultBits) { |
373 if (input instanceof IntegerStamp) { | 346 if (input instanceof IntegerStamp) { |
374 IntegerStamp inputStamp = (IntegerStamp) input; | 347 IntegerStamp inputStamp = (IntegerStamp) input; |
375 boolean unsigned = inputStamp.isUnsigned(); | |
376 int inputBits = inputStamp.getBits(); | 348 int inputBits = inputStamp.getBits(); |
377 assert resultBits <= inputBits; | 349 assert resultBits <= inputBits; |
378 if (resultBits == inputBits) { | 350 if (resultBits == inputBits) { |
379 return inputStamp; | 351 return inputStamp; |
380 } | 352 } |
381 | 353 |
382 final long upperBound; | 354 final long upperBound; |
383 if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits, unsigned)) { | 355 if (inputStamp.lowerBound() < IntegerStamp.defaultMinValue(resultBits)) { |
384 upperBound = IntegerStamp.defaultMaxValue(resultBits, unsigned); | 356 upperBound = IntegerStamp.defaultMaxValue(resultBits); |
385 } else { | 357 } else { |
386 upperBound = saturate(inputStamp.upperBound(), resultBits, unsigned); | 358 upperBound = saturate(inputStamp.upperBound(), resultBits); |
387 } | 359 } |
388 final long lowerBound; | 360 final long lowerBound; |
389 if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits, unsigned)) { | 361 if (inputStamp.upperBound() > IntegerStamp.defaultMaxValue(resultBits)) { |
390 lowerBound = IntegerStamp.defaultMinValue(resultBits, unsigned); | 362 lowerBound = IntegerStamp.defaultMinValue(resultBits); |
391 } else { | 363 } else { |
392 lowerBound = saturate(inputStamp.lowerBound(), resultBits, unsigned); | 364 lowerBound = saturate(inputStamp.lowerBound(), resultBits); |
393 } | 365 } |
394 | 366 |
395 long defaultMask = IntegerStamp.defaultMask(resultBits); | 367 long defaultMask = IntegerStamp.defaultMask(resultBits); |
396 long newDownMask = inputStamp.downMask() & defaultMask; | 368 long newDownMask = inputStamp.downMask() & defaultMask; |
397 long newUpMask = inputStamp.upMask() & defaultMask; | 369 long newUpMask = inputStamp.upMask() & defaultMask; |
398 long newLowerBound = (lowerBound | newDownMask) & newUpMask; | 370 long newLowerBound = SignExtendNode.signExtend((lowerBound | newDownMask) & newUpMask, resultBits); |
399 long newUpperBound = (upperBound | newDownMask) & newUpMask; | 371 long newUpperBound = SignExtendNode.signExtend((upperBound | newDownMask) & newUpMask, resultBits); |
400 if (!unsigned) { | 372 return new IntegerStamp(resultBits, newLowerBound, newUpperBound, newDownMask, newUpMask); |
401 newLowerBound = SignExtendNode.signExtend(newLowerBound, resultBits); | |
402 newUpperBound = SignExtendNode.signExtend(newUpperBound, resultBits); | |
403 } | |
404 return new IntegerStamp(resultBits, unsigned, newLowerBound, newUpperBound, newDownMask, newUpMask); | |
405 } else { | 373 } else { |
406 return input.illegal(); | 374 return input.illegal(); |
407 } | 375 } |
408 } | 376 } |
409 | 377 |
424 | 392 |
425 long defaultMask = IntegerStamp.defaultMask(toKind.getBitCount()); | 393 long defaultMask = IntegerStamp.defaultMask(toKind.getBitCount()); |
426 long intMask = IntegerStamp.defaultMask(32); | 394 long intMask = IntegerStamp.defaultMask(32); |
427 long newUpMask = signExtend(fromStamp.upMask() & defaultMask, toKind) & intMask; | 395 long newUpMask = signExtend(fromStamp.upMask() & defaultMask, toKind) & intMask; |
428 long newDownMask = signExtend(fromStamp.downMask() & defaultMask, toKind) & intMask; | 396 long newDownMask = signExtend(fromStamp.downMask() & defaultMask, toKind) & intMask; |
429 return new IntegerStamp(toKind.getStackKind().getBitCount(), false, (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask); | 397 return new IntegerStamp(toKind.getStackKind().getBitCount(), (int) ((lowerBound | newDownMask) & newUpMask), (int) ((upperBound | newDownMask) & newUpMask), newDownMask, newUpMask); |
430 } | 398 } |
431 | 399 |
432 private static long signExtend(long value, Kind valueKind) { | 400 private static long signExtend(long value, Kind valueKind) { |
433 if (valueKind != Kind.Char && valueKind != Kind.Long && (value >>> (valueKind.getBitCount() - 1) & 1) == 1) { | 401 if (valueKind != Kind.Char && valueKind != Kind.Long && (value >>> (valueKind.getBitCount() - 1) & 1) == 1) { |
434 return value | (-1L << valueKind.getBitCount()); | 402 return value | (-1L << valueKind.getBitCount()); |
435 } else { | 403 } else { |
436 return value; | 404 return value; |
437 } | 405 } |
438 } | 406 } |
439 | 407 |
440 private static long saturate(long v, int bits, boolean unsigned) { | 408 private static long saturate(long v, int bits) { |
441 if (bits < 64) { | 409 if (bits < 64) { |
442 long max = IntegerStamp.defaultMaxValue(bits, unsigned); | 410 long max = IntegerStamp.defaultMaxValue(bits); |
443 if (v > max) { | 411 if (v > max) { |
444 return max; | 412 return max; |
445 } | 413 } |
446 long min = IntegerStamp.defaultMinValue(bits, unsigned); | 414 long min = IntegerStamp.defaultMinValue(bits); |
447 if (v < min) { | 415 if (v < min) { |
448 return min; | 416 return min; |
449 } | 417 } |
450 } | 418 } |
451 return v; | 419 return v; |
463 return v; | 431 return v; |
464 } | 432 } |
465 | 433 |
466 /** | 434 /** |
467 * Compute the stamp resulting from the unsigned comparison being true. | 435 * Compute the stamp resulting from the unsigned comparison being true. |
468 * | 436 * |
469 * @return null if it's can't be true or it nothing useful can be encoded. | 437 * @return null if it's can't be true or it nothing useful can be encoded. |
470 */ | 438 */ |
471 public static Stamp unsignedCompare(Stamp stamp, Stamp stamp2) { | 439 public static Stamp unsignedCompare(Stamp stamp, Stamp stamp2) { |
472 IntegerStamp x = (IntegerStamp) stamp; | 440 IntegerStamp x = (IntegerStamp) stamp; |
473 IntegerStamp y = (IntegerStamp) stamp2; | 441 IntegerStamp y = (IntegerStamp) stamp2; |
486 // Test will fail. Return illegalStamp instead? | 454 // Test will fail. Return illegalStamp instead? |
487 return null; | 455 return null; |
488 } | 456 } |
489 // If the test succeeds then this proves that n is at greater than c so the bounds | 457 // If the test succeeds then this proves that n is at greater than c so the bounds |
490 // are [c+1..-n.upperBound)]. | 458 // are [c+1..-n.upperBound)]. |
491 return StampFactory.forInteger(x.getBits(), false, x.lowerBound() + 1, y.upperBound()); | 459 return StampFactory.forInteger(x.getBits(), x.lowerBound() + 1, y.upperBound()); |
492 } | 460 } |
493 return null; | 461 return null; |
494 } | 462 } |
495 // n <| c, where c is a strictly positive constant | 463 // n <| c, where c is a strictly positive constant |
496 if (y.lowerBound() == y.upperBound() && y.isStrictlyPositive()) { | 464 if (y.lowerBound() == y.upperBound() && y.isStrictlyPositive()) { |
497 // The test proves that n is positive and less than c, [0..c-1] | 465 // The test proves that n is positive and less than c, [0..c-1] |
498 return StampFactory.forInteger(y.getBits(), false, 0, y.lowerBound() - 1); | 466 return StampFactory.forInteger(y.getBits(), 0, y.lowerBound() - 1); |
499 } | 467 } |
500 return null; | 468 return null; |
501 } | 469 } |
502 } | 470 } |