Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jit_RangeAnalysis_h
8 #define jit_RangeAnalysis_h
10 #include "mozilla/FloatingPoint.h"
11 #include "mozilla/MathAlgorithms.h"
13 #include "jit/IonAnalysis.h"
14 #include "jit/MIR.h"
16 // windows.h defines those, which messes with the definitions below.
17 #undef min
18 #undef max
20 namespace js {
21 namespace jit {
23 class MBasicBlock;
24 class MIRGraph;
26 // An upper bound computed on the number of backedges a loop will take.
27 // This count only includes backedges taken while running Ion code: for OSR
28 // loops, this will exclude iterations that executed in the interpreter or in
29 // baseline compiled code.
30 struct LoopIterationBound : public TempObject
31 {
32 // Loop for which this bound applies.
33 MBasicBlock *header;
35 // Test from which this bound was derived. Code in the loop body which this
36 // test dominates (will include the backedge) will execute at most 'bound'
37 // times. Other code in the loop will execute at most '1 + Max(bound, 0)'
38 // times.
39 MTest *test;
41 // Symbolic bound computed for the number of backedge executions.
42 LinearSum sum;
44 LoopIterationBound(MBasicBlock *header, MTest *test, LinearSum sum)
45 : header(header), test(test), sum(sum)
46 {
47 }
48 };
50 // A symbolic upper or lower bound computed for a term.
51 struct SymbolicBound : public TempObject
52 {
53 private:
54 SymbolicBound(LoopIterationBound *loop, LinearSum sum)
55 : loop(loop), sum(sum)
56 {
57 }
59 public:
60 // Any loop iteration bound from which this was derived.
61 //
62 // If non-nullptr, then 'sum' is only valid within the loop body, at
63 // points dominated by the loop bound's test (see LoopIterationBound).
64 //
65 // If nullptr, then 'sum' is always valid.
66 LoopIterationBound *loop;
68 static SymbolicBound *New(TempAllocator &alloc, LoopIterationBound *loop, LinearSum sum) {
69 return new(alloc) SymbolicBound(loop, sum);
70 }
72 // Computed symbolic bound, see above.
73 LinearSum sum;
75 void print(Sprinter &sp) const;
76 void dump() const;
77 };
79 class RangeAnalysis
80 {
81 protected:
82 bool blockDominates(MBasicBlock *b, MBasicBlock *b2);
83 void replaceDominatedUsesWith(MDefinition *orig, MDefinition *dom,
84 MBasicBlock *block);
86 protected:
87 MIRGenerator *mir;
88 MIRGraph &graph_;
90 TempAllocator &alloc() const;
92 public:
93 MOZ_CONSTEXPR RangeAnalysis(MIRGenerator *mir, MIRGraph &graph) :
94 mir(mir), graph_(graph) {}
95 bool addBetaNodes();
96 bool analyze();
97 bool addRangeAssertions();
98 bool removeBetaNodes();
99 bool prepareForUCE(bool *shouldRemoveDeadCode);
100 bool truncate();
102 private:
103 bool analyzeLoop(MBasicBlock *header);
104 LoopIterationBound *analyzeLoopIterationCount(MBasicBlock *header,
105 MTest *test, BranchDirection direction);
106 void analyzeLoopPhi(MBasicBlock *header, LoopIterationBound *loopBound, MPhi *phi);
107 bool tryHoistBoundsCheck(MBasicBlock *header, MBoundsCheck *ins);
108 bool markBlocksInLoopBody(MBasicBlock *header, MBasicBlock *current);
109 };
111 class Range : public TempObject {
112 public:
113 // Int32 are signed. INT32_MAX is pow(2,31)-1 and INT32_MIN is -pow(2,31),
114 // so the greatest exponent we need is 31.
115 static const uint16_t MaxInt32Exponent = 31;
117 // UInt32 are unsigned. UINT32_MAX is pow(2,32)-1, so it's the greatest
118 // value that has an exponent of 31.
119 static const uint16_t MaxUInt32Exponent = 31;
121 // Maximal exponenent under which we have no precission loss on double
122 // operations. Double has 52 bits of mantissa, so 2^52+1 cannot be
123 // represented without loss.
124 static const uint16_t MaxTruncatableExponent = mozilla::FloatingPoint<double>::ExponentShift;
126 // Maximum exponent for finite values.
127 static const uint16_t MaxFiniteExponent = mozilla::FloatingPoint<double>::ExponentBias;
129 // An special exponent value representing all non-NaN values. This
130 // includes finite values and the infinities.
131 static const uint16_t IncludesInfinity = MaxFiniteExponent + 1;
133 // An special exponent value representing all possible double-precision
134 // values. This includes finite values, the infinities, and NaNs.
135 static const uint16_t IncludesInfinityAndNaN = UINT16_MAX;
137 // This range class uses int32_t ranges, but has several interfaces which
138 // use int64_t, which either holds an int32_t value, or one of the following
139 // special values which mean a value which is beyond the int32 range,
140 // potentially including infinity or NaN. These special values are
141 // guaranteed to compare greater, and less than, respectively, any int32_t
142 // value.
143 static const int64_t NoInt32UpperBound = int64_t(JSVAL_INT_MAX) + 1;
144 static const int64_t NoInt32LowerBound = int64_t(JSVAL_INT_MIN) - 1;
146 private:
147 // Absolute ranges.
148 //
149 // We represent ranges where the endpoints can be in the set:
150 // {-infty} U [INT_MIN, INT_MAX] U {infty}. A bound of +/-
151 // infty means that the value may have overflowed in that
152 // direction. When computing the range of an integer
153 // instruction, the ranges of the operands can be clamped to
154 // [INT_MIN, INT_MAX], since if they had overflowed they would
155 // no longer be integers. This is important for optimizations
156 // and somewhat subtle.
157 //
158 // N.B.: All of the operations that compute new ranges based
159 // on existing ranges will ignore the hasInt32*Bound_ flags of the
160 // input ranges; that is, they implicitly clamp the ranges of
161 // the inputs to [INT_MIN, INT_MAX]. Therefore, while our range might
162 // be unbounded (and could overflow), when using this information to
163 // propagate through other ranges, we disregard this fact; if that code
164 // executes, then the overflow did not occur, so we may safely assume
165 // that the range is [INT_MIN, INT_MAX] instead.
166 //
167 // To facilitate this trick, we maintain the invariants that:
168 // 1) hasInt32LowerBound_ == false implies lower_ == JSVAL_INT_MIN
169 // 2) hasInt32UpperBound_ == false implies upper_ == JSVAL_INT_MAX
170 //
171 // As a second and less precise range analysis, we represent the maximal
172 // exponent taken by a value. The exponent is calculated by taking the
173 // absolute value and looking at the position of the highest bit. All
174 // exponent computation have to be over-estimations of the actual result. On
175 // the Int32 this over approximation is rectified.
177 int32_t lower_;
178 bool hasInt32LowerBound_;
180 int32_t upper_;
181 bool hasInt32UpperBound_;
183 bool canHaveFractionalPart_;
184 uint16_t max_exponent_;
186 // Any symbolic lower or upper bound computed for this term.
187 const SymbolicBound *symbolicLower_;
188 const SymbolicBound *symbolicUpper_;
190 // This function simply makes several JS_ASSERTs to verify the internal
191 // consistency of this range.
192 void assertInvariants() const {
193 // Basic sanity :).
194 JS_ASSERT(lower_ <= upper_);
196 // When hasInt32LowerBound_ or hasInt32UpperBound_ are false, we set
197 // lower_ and upper_ to these specific values as it simplifies the
198 // implementation in some places.
199 JS_ASSERT_IF(!hasInt32LowerBound_, lower_ == JSVAL_INT_MIN);
200 JS_ASSERT_IF(!hasInt32UpperBound_, upper_ == JSVAL_INT_MAX);
202 // max_exponent_ must be one of three possible things.
203 JS_ASSERT(max_exponent_ <= MaxFiniteExponent ||
204 max_exponent_ == IncludesInfinity ||
205 max_exponent_ == IncludesInfinityAndNaN);
207 // Forbid the max_exponent_ field from implying better bounds for
208 // lower_/upper_ fields. We have to add 1 to the max_exponent_ when
209 // canHaveFractionalPart_ is true in order to accomodate fractional
210 // offsets. For example, 2147483647.9 is greater than INT32_MAX, so a
211 // range containing that value will have hasInt32UpperBound_ set to
212 // false, however that value also has exponent 30, which is strictly
213 // less than MaxInt32Exponent. For another example, 1.9 has an exponent
214 // of 0 but requires upper_ to be at least 2, which has exponent 1.
215 JS_ASSERT_IF(!hasInt32LowerBound_ || !hasInt32UpperBound_,
216 max_exponent_ + canHaveFractionalPart_ >= MaxInt32Exponent);
217 JS_ASSERT(max_exponent_ + canHaveFractionalPart_ >=
218 mozilla::FloorLog2(mozilla::Abs(upper_)));
219 JS_ASSERT(max_exponent_ + canHaveFractionalPart_ >=
220 mozilla::FloorLog2(mozilla::Abs(lower_)));
222 // The following are essentially static assertions, but FloorLog2 isn't
223 // trivially suitable for constexpr :(.
224 JS_ASSERT(mozilla::FloorLog2(JSVAL_INT_MIN) == MaxInt32Exponent);
225 JS_ASSERT(mozilla::FloorLog2(JSVAL_INT_MAX) == 30);
226 JS_ASSERT(mozilla::FloorLog2(UINT32_MAX) == MaxUInt32Exponent);
227 JS_ASSERT(mozilla::FloorLog2(0) == 0);
228 }
230 // Set the lower_ and hasInt32LowerBound_ values.
231 void setLowerInit(int64_t x) {
232 if (x > JSVAL_INT_MAX) {
233 lower_ = JSVAL_INT_MAX;
234 hasInt32LowerBound_ = true;
235 } else if (x < JSVAL_INT_MIN) {
236 lower_ = JSVAL_INT_MIN;
237 hasInt32LowerBound_ = false;
238 } else {
239 lower_ = int32_t(x);
240 hasInt32LowerBound_ = true;
241 }
242 }
243 // Set the upper_ and hasInt32UpperBound_ values.
244 void setUpperInit(int64_t x) {
245 if (x > JSVAL_INT_MAX) {
246 upper_ = JSVAL_INT_MAX;
247 hasInt32UpperBound_ = false;
248 } else if (x < JSVAL_INT_MIN) {
249 upper_ = JSVAL_INT_MIN;
250 hasInt32UpperBound_ = true;
251 } else {
252 upper_ = int32_t(x);
253 hasInt32UpperBound_ = true;
254 }
255 }
257 // Compute the least exponent value that would be compatible with the
258 // values of lower() and upper().
259 //
260 // Note:
261 // exponent of JSVAL_INT_MIN == 31
262 // exponent of JSVAL_INT_MAX == 30
263 uint16_t exponentImpliedByInt32Bounds() const {
264 // The number of bits needed to encode |max| is the power of 2 plus one.
265 uint32_t max = Max(mozilla::Abs(lower()), mozilla::Abs(upper()));
266 uint16_t result = mozilla::FloorLog2(max);
267 JS_ASSERT(result == (max == 0 ? 0 : mozilla::ExponentComponent(double(max))));
268 return result;
269 }
271 // When converting a range which contains fractional values to a range
272 // containing only integers, the old max_exponent_ value may imply a better
273 // lower and/or upper bound than was previously available, because they no
274 // longer need to be conservative about fractional offsets and the ends of
275 // the range.
276 //
277 // Given an exponent value and pointers to the lower and upper bound values,
278 // this function refines the lower and upper bound values to the tighest
279 // bound for integer values implied by the exponent.
280 static void refineInt32BoundsByExponent(uint16_t e, int32_t *l, int32_t *h) {
281 if (e < MaxInt32Exponent) {
282 // pow(2, max_exponent_+1)-1 to compute a maximum absolute value.
283 int32_t limit = (uint32_t(1) << (e + 1)) - 1;
284 *h = Min(*h, limit);
285 *l = Max(*l, -limit);
286 }
287 }
289 // If the value of any of the fields implies a stronger possible value for
290 // any other field, update that field to the stronger value. The range must
291 // be completely valid before and it is guaranteed to be kept valid.
292 void optimize() {
293 assertInvariants();
295 if (hasInt32Bounds()) {
296 // Examine lower() and upper(), and if they imply a better exponent
297 // bound than max_exponent_, set that value as the new
298 // max_exponent_.
299 uint16_t newExponent = exponentImpliedByInt32Bounds();
300 if (newExponent < max_exponent_) {
301 max_exponent_ = newExponent;
302 assertInvariants();
303 }
305 // If we have a completely precise range, the value is an integer,
306 // since we can only represent integers.
307 if (canHaveFractionalPart_ && lower_ == upper_) {
308 canHaveFractionalPart_ = false;
309 assertInvariants();
310 }
311 }
312 }
314 // Set the range fields to the given raw values.
315 void rawInitialize(int32_t l, bool lb, int32_t h, bool hb, bool f, uint16_t e) {
316 lower_ = l;
317 hasInt32LowerBound_ = lb;
318 upper_ = h;
319 hasInt32UpperBound_ = hb;
320 canHaveFractionalPart_ = f;
321 max_exponent_ = e;
322 optimize();
323 }
325 // Construct a range from the given raw values.
326 Range(int32_t l, bool lb, int32_t h, bool hb, bool f, uint16_t e)
327 : symbolicLower_(nullptr),
328 symbolicUpper_(nullptr)
329 {
330 rawInitialize(l, lb, h, hb, f, e);
331 }
333 public:
334 Range()
335 : symbolicLower_(nullptr),
336 symbolicUpper_(nullptr)
337 {
338 setUnknown();
339 }
341 Range(int64_t l, int64_t h, bool f = false, uint16_t e = MaxInt32Exponent)
342 : symbolicLower_(nullptr),
343 symbolicUpper_(nullptr)
344 {
345 set(l, h, f, e);
346 }
348 Range(const Range &other)
349 : lower_(other.lower_),
350 hasInt32LowerBound_(other.hasInt32LowerBound_),
351 upper_(other.upper_),
352 hasInt32UpperBound_(other.hasInt32UpperBound_),
353 canHaveFractionalPart_(other.canHaveFractionalPart_),
354 max_exponent_(other.max_exponent_),
355 symbolicLower_(nullptr),
356 symbolicUpper_(nullptr)
357 {
358 assertInvariants();
359 }
361 // Construct a range from the given MDefinition. This differs from the
362 // MDefinition's range() method in that it describes the range of values
363 // *after* any bailout checks.
364 Range(const MDefinition *def);
366 static Range *NewInt32Range(TempAllocator &alloc, int32_t l, int32_t h) {
367 return new(alloc) Range(l, h, false, MaxInt32Exponent);
368 }
370 static Range *NewUInt32Range(TempAllocator &alloc, uint32_t l, uint32_t h) {
371 // For now, just pass them to the constructor as int64_t values.
372 // They'll become unbounded if they're not in the int32_t range.
373 return new(alloc) Range(l, h, false, MaxUInt32Exponent);
374 }
376 static Range *NewDoubleRange(TempAllocator &alloc, double l, double h) {
377 if (mozilla::IsNaN(l) && mozilla::IsNaN(h))
378 return nullptr;
380 Range *r = new(alloc) Range();
381 r->setDouble(l, h);
382 return r;
383 }
385 void print(Sprinter &sp) const;
386 void dump(FILE *fp) const;
387 void dump() const;
388 bool update(const Range *other);
390 // Unlike the other operations, unionWith is an in-place
391 // modification. This is to avoid a bunch of useless extra
392 // copying when chaining together unions when handling Phi
393 // nodes.
394 void unionWith(const Range *other);
395 static Range *intersect(TempAllocator &alloc, const Range *lhs, const Range *rhs,
396 bool *emptyRange);
397 static Range *add(TempAllocator &alloc, const Range *lhs, const Range *rhs);
398 static Range *sub(TempAllocator &alloc, const Range *lhs, const Range *rhs);
399 static Range *mul(TempAllocator &alloc, const Range *lhs, const Range *rhs);
400 static Range *and_(TempAllocator &alloc, const Range *lhs, const Range *rhs);
401 static Range *or_(TempAllocator &alloc, const Range *lhs, const Range *rhs);
402 static Range *xor_(TempAllocator &alloc, const Range *lhs, const Range *rhs);
403 static Range *not_(TempAllocator &alloc, const Range *op);
404 static Range *lsh(TempAllocator &alloc, const Range *lhs, int32_t c);
405 static Range *rsh(TempAllocator &alloc, const Range *lhs, int32_t c);
406 static Range *ursh(TempAllocator &alloc, const Range *lhs, int32_t c);
407 static Range *lsh(TempAllocator &alloc, const Range *lhs, const Range *rhs);
408 static Range *rsh(TempAllocator &alloc, const Range *lhs, const Range *rhs);
409 static Range *ursh(TempAllocator &alloc, const Range *lhs, const Range *rhs);
410 static Range *abs(TempAllocator &alloc, const Range *op);
411 static Range *min(TempAllocator &alloc, const Range *lhs, const Range *rhs);
412 static Range *max(TempAllocator &alloc, const Range *lhs, const Range *rhs);
414 static bool negativeZeroMul(const Range *lhs, const Range *rhs);
416 bool isUnknownInt32() const {
417 return isInt32() && lower() == INT32_MIN && upper() == INT32_MAX;
418 }
420 bool isUnknown() const {
421 return !hasInt32LowerBound_ &&
422 !hasInt32UpperBound_ &&
423 canHaveFractionalPart_ &&
424 max_exponent_ == IncludesInfinityAndNaN;
425 }
427 bool hasInt32LowerBound() const {
428 return hasInt32LowerBound_;
429 }
430 bool hasInt32UpperBound() const {
431 return hasInt32UpperBound_;
432 }
434 // Test whether the value is known to be within [INT32_MIN,INT32_MAX].
435 // Note that this does not necessarily mean the value is an integer.
436 bool hasInt32Bounds() const {
437 return hasInt32LowerBound() && hasInt32UpperBound();
438 }
440 // Test whether the value is known to be representable as an int32.
441 bool isInt32() const {
442 return hasInt32Bounds() && !canHaveFractionalPart();
443 }
445 // Test whether the given value is known to be either 0 or 1.
446 bool isBoolean() const {
447 return lower() >= 0 && upper() <= 1 && !canHaveFractionalPart();
448 }
450 bool canHaveRoundingErrors() const {
451 return canHaveFractionalPart() || max_exponent_ >= MaxTruncatableExponent;
452 }
454 // Test whether the range contains zero.
455 bool canBeZero() const {
456 return lower_ <= 0 && upper_ >= 0;
457 }
459 // Test whether the range contains NaN values.
460 bool canBeNaN() const {
461 return max_exponent_ == IncludesInfinityAndNaN;
462 }
464 // Test whether the range contains infinities or NaN values.
465 bool canBeInfiniteOrNaN() const {
466 return max_exponent_ >= IncludesInfinity;
467 }
469 bool canHaveFractionalPart() const {
470 return canHaveFractionalPart_;
471 }
473 uint16_t exponent() const {
474 JS_ASSERT(!canBeInfiniteOrNaN());
475 return max_exponent_;
476 }
478 uint16_t numBits() const {
479 return exponent() + 1; // 2^0 -> 1
480 }
482 // Return the lower bound. Asserts that the value has an int32 bound.
483 int32_t lower() const {
484 JS_ASSERT(hasInt32LowerBound());
485 return lower_;
486 }
488 // Return the upper bound. Asserts that the value has an int32 bound.
489 int32_t upper() const {
490 JS_ASSERT(hasInt32UpperBound());
491 return upper_;
492 }
494 // Test whether all values in this range can are finite and negative.
495 bool isFiniteNegative() const {
496 return upper_ < 0 && !canBeInfiniteOrNaN();
497 }
499 // Test whether all values in this range can are finite and non-negative.
500 bool isFiniteNonNegative() const {
501 return lower_ >= 0 && !canBeInfiniteOrNaN();
502 }
504 // Test whether a value in this range can possibly be a finite
505 // negative value.
506 bool canBeFiniteNegative() const {
507 return lower_ < 0;
508 }
510 // Test whether a value in this range can possibly be a finite
511 // non-negative value.
512 bool canBeFiniteNonNegative() const {
513 return upper_ >= 0;
514 }
516 // Set this range to have a lower bound not less than x.
517 void refineLower(int32_t x) {
518 assertInvariants();
519 hasInt32LowerBound_ = true;
520 lower_ = Max(lower_, x);
521 optimize();
522 }
524 // Set this range to have an upper bound not greater than x.
525 void refineUpper(int32_t x) {
526 assertInvariants();
527 hasInt32UpperBound_ = true;
528 upper_ = Min(upper_, x);
529 optimize();
530 }
532 void setInt32(int32_t l, int32_t h) {
533 hasInt32LowerBound_ = true;
534 hasInt32UpperBound_ = true;
535 lower_ = l;
536 upper_ = h;
537 canHaveFractionalPart_ = false;
538 max_exponent_ = exponentImpliedByInt32Bounds();
539 assertInvariants();
540 }
542 void setDouble(double l, double h);
544 void setUnknown() {
545 set(NoInt32LowerBound, NoInt32UpperBound, true, IncludesInfinityAndNaN);
546 JS_ASSERT(isUnknown());
547 }
549 void set(int64_t l, int64_t h, bool f, uint16_t e) {
550 max_exponent_ = e;
551 canHaveFractionalPart_ = f;
552 setLowerInit(l);
553 setUpperInit(h);
554 optimize();
555 }
557 // Make the lower end of this range at least INT32_MIN, and make
558 // the upper end of this range at most INT32_MAX.
559 void clampToInt32();
561 // If this range exceeds int32_t range, at either or both ends, change
562 // it to int32_t range. Otherwise do nothing.
563 void wrapAroundToInt32();
565 // If this range exceeds [0, 32) range, at either or both ends, change
566 // it to the [0, 32) range. Otherwise do nothing.
567 void wrapAroundToShiftCount();
569 // If this range exceeds [0, 1] range, at either or both ends, change
570 // it to the [0, 1] range. Otherwise do nothing.
571 void wrapAroundToBoolean();
573 const SymbolicBound *symbolicLower() const {
574 return symbolicLower_;
575 }
576 const SymbolicBound *symbolicUpper() const {
577 return symbolicUpper_;
578 }
580 void setSymbolicLower(SymbolicBound *bound) {
581 symbolicLower_ = bound;
582 }
583 void setSymbolicUpper(SymbolicBound *bound) {
584 symbolicUpper_ = bound;
585 }
586 };
588 } // namespace jit
589 } // namespace js
591 #endif /* jit_RangeAnalysis_h */