Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | List of all members
dart::Range Class Reference

#include <range_analysis.h>

Inheritance diagram for dart::Range:
dart::ZoneAllocated

Public Member Functions

 Range ()
 
 Range (RangeBoundary min, RangeBoundary max)
 
 Range (const Range &other)
 
Rangeoperator= (const Range &other)
 
void PrintTo (BaseTextBuffer *f) const
 
bool Equals (const Range *other)
 
const RangeBoundarymin () const
 
const RangeBoundarymax () const
 
void set_min (const RangeBoundary &value)
 
void set_max (const RangeBoundary &value)
 
bool IsPositive () const
 
bool IsNegative () const
 
bool OnlyLessThanOrEqualTo (int64_t val) const
 
bool OnlyGreaterThanOrEqualTo (int64_t val) const
 
bool IsWithin (int64_t min_int, int64_t max_int) const
 
bool IsWithin (const Range *other) const
 
bool Overlaps (int64_t min_int, int64_t max_int) const
 
bool IsUnsatisfiable () const
 
bool IsSingleton () const
 
int64_t Singleton () const
 
Range Intersect (const Range *other) const
 
bool Fits (RangeBoundary::RangeSize size) const
 
void Clamp (RangeBoundary::RangeSize size)
 
void ClampToConstant (RangeBoundary::RangeSize size)
 
void Write (FlowGraphSerializer *s) const
 
 Range (FlowGraphDeserializer *d)
 
- Public Member Functions inherited from dart::ZoneAllocated
 ZoneAllocated ()
 
void * operator new (size_t size)
 
void * operator new (size_t size, Zone *zone)
 
void operator delete (void *pointer)
 

Static Public Member Functions

static bool IsUnknown (const Range *other)
 
static Range Full (RangeBoundary::RangeSize size)
 
static Range Full (Representation rep)
 
static const char * ToCString (const Range *range)
 
static RangeBoundary ConstantMinSmi (const Range *range)
 
static RangeBoundary ConstantMaxSmi (const Range *range)
 
static RangeBoundary ConstantMin (const Range *range)
 
static RangeBoundary ConstantMax (const Range *range)
 
static RangeBoundary ConstantMin (const Range *range, RangeBoundary::RangeSize size)
 
static RangeBoundary ConstantMax (const Range *range, RangeBoundary::RangeSize size)
 
static bool Fits (Range *range, Representation rep)
 
static void Add (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max, Definition *left_defn)
 
static void Sub (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max, Definition *left_defn)
 
static void Mul (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static void TruncDiv (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static void Mod (const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static void Shr (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static void Ushr (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static void Shl (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static void And (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static void BitwiseOp (const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
 
static bool OnlyPositiveOrZero (const Range &a, const Range &b)
 
static bool OnlyNegativeOrZero (const Range &a, const Range &b)
 
static int64_t ConstantAbsMax (const Range *range)
 
static int64_t ConstantAbsMin (const Range *range)
 
static void BinaryOp (const Token::Kind op, const Range *left_range, const Range *right_range, Definition *left_defn, Range *result)
 

Detailed Description

Definition at line 277 of file range_analysis.h.

Constructor & Destructor Documentation

◆ Range() [1/4]

dart::Range::Range ( )
inline

Definition at line 279 of file range_analysis.h.

279: min_(), max_() {}

◆ Range() [2/4]

dart::Range::Range ( RangeBoundary  min,
RangeBoundary  max 
)
inline

Definition at line 281 of file range_analysis.h.

281 : min_(min), max_(max) {
282 ASSERT(min_.IsUnknown() == max_.IsUnknown());
283 }
const RangeBoundary & min() const
const RangeBoundary & max() const
#define ASSERT(E)

◆ Range() [3/4]

dart::Range::Range ( const Range other)
inline

Definition at line 285 of file range_analysis.h.

286 : ZoneAllocated(), min_(other.min_), max_(other.max_) {}

◆ Range() [4/4]

dart::Range::Range ( FlowGraphDeserializer d)
explicit

Definition at line 2211 of file il_serializer.cc.

2212 : min_(RangeBoundary(d)), max_(RangeBoundary(d)) {}
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19

Member Function Documentation

◆ Add()

void dart::Range::Add ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max,
Definition left_defn 
)
static

Definition at line 2365 of file range_analysis.cc.

2369 {
2370 ASSERT(left_range != nullptr);
2371 ASSERT(right_range != nullptr);
2372 ASSERT(result_min != nullptr);
2373 ASSERT(result_max != nullptr);
2374
2375 RangeBoundary left_min = Definition::IsArrayLength(left_defn)
2377 : left_range->min();
2378
2379 RangeBoundary left_max = Definition::IsArrayLength(left_defn)
2381 : left_range->max();
2382
2383 bool overflow = false;
2384 if (!RangeBoundary::SymbolicAdd(left_min, right_range->min(), result_min)) {
2385 const auto left_min_bound = left_range->min().LowerBound();
2386 const auto right_min_bound = right_range->min().LowerBound();
2387 if (RangeBoundary::WillAddOverflow(left_min_bound, right_min_bound)) {
2388 overflow = true;
2389 } else {
2390 *result_min = RangeBoundary::Add(left_min_bound, right_min_bound);
2391 }
2392 }
2393 if (!RangeBoundary::SymbolicAdd(left_max, right_range->max(), result_max)) {
2394 const auto left_max_bound = left_range->max().UpperBound();
2395 const auto right_max_bound = right_range->max().UpperBound();
2396 if (RangeBoundary::WillAddOverflow(left_max_bound, right_max_bound)) {
2397 overflow = true;
2398 } else {
2399 *result_max = RangeBoundary::Add(left_max_bound, right_max_bound);
2400 }
2401 }
2402 if (overflow) {
2403 *result_min =
2405 *result_max =
2407 }
2408}
static bool IsArrayLength(Definition *def)
Definition il.cc:583
static RangeBoundary FromDefinition(Definition *defn, int64_t offs=0)
static bool SymbolicAdd(const RangeBoundary &a, const RangeBoundary &b, RangeBoundary *result)
static bool WillAddOverflow(const RangeBoundary &a, const RangeBoundary &b)
static RangeBoundary MinConstant(RangeSize size)
static RangeBoundary Add(const RangeBoundary &a, const RangeBoundary &b)
RangeBoundary LowerBound() const
static RangeBoundary MaxConstant(RangeSize size)

◆ And()

void dart::Range::And ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2318 of file range_analysis.cc.

2321 {
2322 ASSERT(left_range != nullptr);
2323 ASSERT(right_range != nullptr);
2324 ASSERT(result_min != nullptr);
2325 ASSERT(result_max != nullptr);
2326
2327 if (Range::ConstantMin(right_range).ConstantValue() >= 0) {
2328 *result_min = RangeBoundary::FromConstant(0);
2329 *result_max = Range::ConstantMax(right_range);
2330 return;
2331 }
2332
2333 if (Range::ConstantMin(left_range).ConstantValue() >= 0) {
2334 *result_min = RangeBoundary::FromConstant(0);
2335 *result_max = Range::ConstantMax(left_range);
2336 return;
2337 }
2338
2339 BitwiseOp(left_range, right_range, result_min, result_max);
2340}
static RangeBoundary FromConstant(int64_t val)
static void BitwiseOp(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static RangeBoundary ConstantMin(const Range *range)
static RangeBoundary ConstantMax(const Range *range)

◆ BinaryOp()

void dart::Range::BinaryOp ( const Token::Kind  op,
const Range left_range,
const Range right_range,
Definition left_defn,
Range result 
)
static

Definition at line 2573 of file range_analysis.cc.

2577 {
2578 ASSERT(left_range != nullptr);
2579 ASSERT(right_range != nullptr);
2580
2581 RangeBoundary min;
2582 RangeBoundary max;
2584
2585 switch (op) {
2586 case Token::kADD:
2587 Range::Add(left_range, right_range, &min, &max, left_defn);
2588 break;
2589
2590 case Token::kSUB:
2591 Range::Sub(left_range, right_range, &min, &max, left_defn);
2592 break;
2593
2594 case Token::kMUL:
2595 Range::Mul(left_range, right_range, &min, &max);
2596 break;
2597
2598 case Token::kTRUNCDIV:
2599 Range::TruncDiv(left_range, right_range, &min, &max);
2600 break;
2601
2602 case Token::kMOD:
2603 Range::Mod(right_range, &min, &max);
2604 break;
2605
2606 case Token::kSHL:
2607 Range::Shl(left_range, right_range, &min, &max);
2608 break;
2609
2610 case Token::kSHR:
2611 Range::Shr(left_range, right_range, &min, &max);
2612 break;
2613
2614 case Token::kUSHR:
2615 Range::Ushr(left_range, right_range, &min, &max);
2616 break;
2617
2618 case Token::kBIT_AND:
2619 Range::And(left_range, right_range, &min, &max);
2620 break;
2621
2622 case Token::kBIT_XOR:
2623 case Token::kBIT_OR:
2624 Range::BitwiseOp(left_range, right_range, &min, &max);
2625 break;
2626
2627 default:
2628 *result =
2631 return;
2632 }
2633
2634 ASSERT(!min.IsUnknown() && !max.IsUnknown());
2635
2636 // Sanity: avoid [l, u] with constants l > u.
2637 ASSERT(!min.IsConstant() || !max.IsConstant() ||
2639
2640 *result = Range(min, max);
2641}
bool IsConstant() const
int64_t ConstantValue() const
static void Shr(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static void Mul(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static void TruncDiv(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static void Ushr(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static void Add(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max, Definition *left_defn)
static void And(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static void Sub(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max, Definition *left_defn)
static void Shl(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static void Mod(const Range *right_range, RangeBoundary *min, RangeBoundary *max)
GAsyncResult * result

◆ BitwiseOp()

void dart::Range::BitwiseOp ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2348 of file range_analysis.cc.

2351 {
2352 const int bitsize = Utils::Maximum(BitSize(left_range), BitSize(right_range));
2353
2354 if (left_range->IsPositive() && right_range->IsPositive()) {
2355 *result_min = RangeBoundary::FromConstant(0);
2356 } else {
2357 *result_min =
2358 RangeBoundary::FromConstant(-(static_cast<uint64_t>(1) << bitsize));
2359 }
2360
2361 *result_max =
2362 RangeBoundary::FromConstant((static_cast<uint64_t>(1) << bitsize) - 1);
2363}
static constexpr T Maximum(T x, T y)
Definition utils.h:26
static int BitSize(const Range *range)

◆ Clamp()

void dart::Range::Clamp ( RangeBoundary::RangeSize  size)

Definition at line 2176 of file range_analysis.cc.

2176 {
2177 min_ = min_.Clamp(size);
2178 max_ = max_.Clamp(size);
2179}
RangeBoundary Clamp(RangeSize size) const

◆ ClampToConstant()

void dart::Range::ClampToConstant ( RangeBoundary::RangeSize  size)

Definition at line 2181 of file range_analysis.cc.

2181 {
2182 min_ = min_.LowerBound().Clamp(size);
2183 max_ = max_.UpperBound().Clamp(size);
2184}
RangeBoundary UpperBound() const

◆ ConstantAbsMax()

int64_t dart::Range::ConstantAbsMax ( const Range range)
static

Definition at line 2550 of file range_analysis.cc.

2550 {
2551 if (range == nullptr) {
2552 return RangeBoundary::kMax;
2553 }
2554 const int64_t abs_min =
2555 Utils::AbsWithSaturation(Range::ConstantMin(range).ConstantValue());
2556 const int64_t abs_max =
2557 Utils::AbsWithSaturation(Range::ConstantMax(range).ConstantValue());
2558 return Utils::Maximum(abs_min, abs_max);
2559}
static constexpr int64_t kMax
static T AbsWithSaturation(T x)
Definition utils.h:47

◆ ConstantAbsMin()

int64_t dart::Range::ConstantAbsMin ( const Range range)
static

Definition at line 2562 of file range_analysis.cc.

2562 {
2563 if (range == nullptr) {
2564 return 0;
2565 }
2566 const int64_t abs_min =
2567 Utils::AbsWithSaturation(Range::ConstantMin(range).ConstantValue());
2568 const int64_t abs_max =
2569 Utils::AbsWithSaturation(Range::ConstantMax(range).ConstantValue());
2570 return Utils::Minimum(abs_min, abs_max);
2571}
static T Minimum(T x, T y)
Definition utils.h:21

◆ ConstantMax() [1/2]

static RangeBoundary dart::Range::ConstantMax ( const Range range)
inlinestatic

Definition at line 338 of file range_analysis.h.

338 {
340 }

◆ ConstantMax() [2/2]

static RangeBoundary dart::Range::ConstantMax ( const Range range,
RangeBoundary::RangeSize  size 
)
inlinestatic

Definition at line 350 of file range_analysis.h.

351 {
352 if (range == nullptr) {
353 return RangeBoundary::MaxConstant(size);
354 }
355 return range->max().UpperBound().Clamp(size);
356 }

◆ ConstantMaxSmi()

static RangeBoundary dart::Range::ConstantMaxSmi ( const Range range)
inlinestatic

Definition at line 330 of file range_analysis.h.

◆ ConstantMin() [1/2]

static RangeBoundary dart::Range::ConstantMin ( const Range range)
inlinestatic

Definition at line 334 of file range_analysis.h.

334 {
336 }

◆ ConstantMin() [2/2]

static RangeBoundary dart::Range::ConstantMin ( const Range range,
RangeBoundary::RangeSize  size 
)
inlinestatic

Definition at line 342 of file range_analysis.h.

343 {
344 if (range == nullptr) {
345 return RangeBoundary::MinConstant(size);
346 }
347 return range->min().LowerBound().Clamp(size);
348 }

◆ ConstantMinSmi()

static RangeBoundary dart::Range::ConstantMinSmi ( const Range range)
inlinestatic

Definition at line 326 of file range_analysis.h.

326 {
328 }

◆ Equals()

bool dart::Range::Equals ( const Range other)
inline

Definition at line 311 of file range_analysis.h.

311 {
312 ASSERT(min_.IsUnknown() == max_.IsUnknown());
313 if (other == nullptr) {
314 return min_.IsUnknown();
315 }
316 return min_.Equals(other->min_) && max_.Equals(other->max_);
317 }
bool Equals(const RangeBoundary &other) const

◆ Fits() [1/2]

static bool dart::Range::Fits ( Range range,
Representation  rep 
)
inlinestatic

Definition at line 403 of file range_analysis.h.

403 {
404 if (range == nullptr) return false;
405 if (!RepresentationUtils::IsUnboxedInteger(rep)) return false;
406 const Range& other = Range::Full(rep);
407 return range->IsWithin(&other);
408 }
static Range Full(RangeBoundary::RangeSize size)
static constexpr bool IsUnboxedInteger(Representation rep)
Definition locations.h:92

◆ Fits() [2/2]

bool dart::Range::Fits ( RangeBoundary::RangeSize  size) const
inline

Definition at line 396 of file range_analysis.h.

396 {
397 return !min().LowerBound().Overflowed(size) &&
398 !max().UpperBound().Overflowed(size);
399 }
bool Overflowed(RangeBoundary::RangeSize size) const

◆ Full() [1/2]

static Range dart::Range::Full ( RangeBoundary::RangeSize  size)
inlinestatic

Definition at line 301 of file range_analysis.h.

301 {
304 }

◆ Full() [2/2]

Range dart::Range::Full ( Representation  rep)
static

Definition at line 2120 of file range_analysis.cc.

2120 {
2124}
static int64_t MaxValue(Representation rep)
Definition locations.cc:62
static int64_t MinValue(Representation rep)
Definition locations.cc:49

◆ Intersect()

Range dart::Range::Intersect ( const Range other) const
inline

Definition at line 391 of file range_analysis.h.

391 {
392 return Range(RangeBoundary::IntersectionMin(min(), other->min()),
393 RangeBoundary::IntersectionMax(max(), other->max()));
394 }
static RangeBoundary IntersectionMin(RangeBoundary a, RangeBoundary b)
static RangeBoundary IntersectionMax(RangeBoundary a, RangeBoundary b)

◆ IsNegative()

bool dart::Range::IsNegative ( ) const

Definition at line 2130 of file range_analysis.cc.

2130 {
2131 return OnlyLessThanOrEqualTo(-1);
2132}
bool OnlyLessThanOrEqualTo(int64_t val) const

◆ IsPositive()

bool dart::Range::IsPositive ( ) const

Definition at line 2126 of file range_analysis.cc.

2126 {
2127 return OnlyGreaterThanOrEqualTo(0);
2128}
bool OnlyGreaterThanOrEqualTo(int64_t val) const

◆ IsSingleton()

bool dart::Range::IsSingleton ( ) const
inline

Definition at line 381 of file range_analysis.h.

381 {
382 return min_.IsConstant() && max_.IsConstant() &&
383 min_.ConstantValue() == max_.ConstantValue();
384 }

◆ IsUnknown()

static bool dart::Range::IsUnknown ( const Range other)
inlinestatic

Definition at line 294 of file range_analysis.h.

294 {
295 if (other == nullptr) {
296 return true;
297 }
298 return other->min().IsUnknown();
299 }

◆ IsUnsatisfiable()

bool dart::Range::IsUnsatisfiable ( ) const

Definition at line 2166 of file range_analysis.cc.

2166 {
2167 // Constant case: For example [0, -1].
2168 if (Range::ConstantMin(this).ConstantValue() >
2169 Range::ConstantMax(this).ConstantValue()) {
2170 return true;
2171 }
2172 // Symbol case: For example [v+1, v].
2173 return DependOnSameSymbol(min(), max()) && min().offset() > max().offset();
2174}
int64_t offset() const
static bool DependOnSameSymbol(const RangeBoundary &a, const RangeBoundary &b)

◆ IsWithin() [1/2]

bool dart::Range::IsWithin ( const Range other) const

Definition at line 2149 of file range_analysis.cc.

2149 {
2150 auto const lower_bound = other->min().LowerBound();
2151 auto const upper_bound = other->max().UpperBound();
2152 return IsWithin(other->min().ConstantValue(), other->max().ConstantValue());
2153}
bool IsWithin(int64_t min_int, int64_t max_int) const

◆ IsWithin() [2/2]

bool dart::Range::IsWithin ( int64_t  min_int,
int64_t  max_int 
) const

Definition at line 2145 of file range_analysis.cc.

2145 {
2146 return OnlyGreaterThanOrEqualTo(min_int) && OnlyLessThanOrEqualTo(max_int);
2147}

◆ max()

const RangeBoundary & dart::Range::max ( ) const
inline

Definition at line 320 of file range_analysis.h.

320{ return max_; }

◆ min()

const RangeBoundary & dart::Range::min ( ) const
inline

Definition at line 319 of file range_analysis.h.

319{ return min_; }

◆ Mod()

void dart::Range::Mod ( const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2519 of file range_analysis.cc.

2521 {
2522 ASSERT(right_range != nullptr);
2523 ASSERT(result_min != nullptr);
2524 ASSERT(result_max != nullptr);
2525 // Each modulo result is positive and bounded by one less than
2526 // the maximum of the right-hand-side (it is unlikely that the
2527 // left-hand-side further refines this in typical programs).
2528 // Note that x % MinInt can be MaxInt and x % 0 always throws.
2529 const int64_t kModMin = 0;
2530 int64_t mod_max = kMaxInt64;
2531 if (Range::ConstantMin(right_range).ConstantValue() != kMinInt64) {
2532 const int64_t right_max = ConstantAbsMax(right_range);
2533 mod_max = Utils::Maximum(right_max - 1, kModMin);
2534 }
2535 *result_min = RangeBoundary::FromConstant(kModMin);
2536 *result_max = RangeBoundary::FromConstant(mod_max);
2537}
static int64_t ConstantAbsMax(const Range *range)
constexpr int64_t kMaxInt64
Definition globals.h:486
constexpr int64_t kMinInt64
Definition globals.h:485

◆ Mul()

void dart::Range::Mul ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2455 of file range_analysis.cc.

2458 {
2459 ASSERT(left_range != nullptr);
2460 ASSERT(right_range != nullptr);
2461 ASSERT(result_min != nullptr);
2462 ASSERT(result_max != nullptr);
2463
2464 const int64_t left_max = ConstantAbsMax(left_range);
2465 const int64_t right_max = ConstantAbsMax(right_range);
2466 if ((left_max <= -compiler::target::kSmiMin) &&
2467 (right_max <= -compiler::target::kSmiMin) &&
2468 ((left_max == 0) || (right_max <= kMaxInt64 / left_max))) {
2469 // Product of left and right max values stays in 64 bit range.
2470 const int64_t mul_max = left_max * right_max;
2471 if (OnlyPositiveOrZero(*left_range, *right_range) ||
2472 OnlyNegativeOrZero(*left_range, *right_range)) {
2473 // If both ranges are of the same sign then the range of the result
2474 // is positive and is between multiplications of absolute minimums
2475 // and absolute maximums.
2476 const int64_t mul_min =
2477 ConstantAbsMin(left_range) * ConstantAbsMin(right_range);
2478 *result_min = RangeBoundary::FromConstant(mul_min);
2479 *result_max = RangeBoundary::FromConstant(mul_max);
2480 } else {
2481 // If ranges have mixed signs then use conservative approximation:
2482 // absolute value of the result is less or equal to multiplication
2483 // of absolute maximums.
2484 *result_min = RangeBoundary::FromConstant(-mul_max);
2485 *result_max = RangeBoundary::FromConstant(mul_max);
2486 }
2487 return;
2488 }
2489
2492}
static bool OnlyNegativeOrZero(const Range &a, const Range &b)
static bool OnlyPositiveOrZero(const Range &a, const Range &b)
static int64_t ConstantAbsMin(const Range *range)

◆ OnlyGreaterThanOrEqualTo()

bool dart::Range::OnlyGreaterThanOrEqualTo ( int64_t  val) const

Definition at line 2139 of file range_analysis.cc.

2139 {
2140 const RangeBoundary lower_bound = min().LowerBound();
2141 return lower_bound.ConstantValue() >= val;
2142}

◆ OnlyLessThanOrEqualTo()

bool dart::Range::OnlyLessThanOrEqualTo ( int64_t  val) const

Definition at line 2134 of file range_analysis.cc.

2134 {
2135 const RangeBoundary upper_bound = max().UpperBound();
2136 return upper_bound.ConstantValue() <= val;
2137}

◆ OnlyNegativeOrZero()

bool dart::Range::OnlyNegativeOrZero ( const Range a,
const Range b 
)
static

Definition at line 2545 of file range_analysis.cc.

2545 {
2546 return a.OnlyLessThanOrEqualTo(0) && b.OnlyLessThanOrEqualTo(0);
2547}
static bool b
struct MyStruct a[10]

◆ OnlyPositiveOrZero()

bool dart::Range::OnlyPositiveOrZero ( const Range a,
const Range b 
)
static

Definition at line 2540 of file range_analysis.cc.

2540 {
2541 return a.OnlyGreaterThanOrEqualTo(0) && b.OnlyGreaterThanOrEqualTo(0);
2542}

◆ operator=()

Range & dart::Range::operator= ( const Range other)
inline

Definition at line 288 of file range_analysis.h.

288 {
289 min_ = other.min_;
290 max_ = other.max_;
291 return *this;
292 }

◆ Overlaps()

bool dart::Range::Overlaps ( int64_t  min_int,
int64_t  max_int 
) const

Definition at line 2155 of file range_analysis.cc.

2155 {
2156 RangeBoundary lower = min().LowerBound();
2157 RangeBoundary upper = max().UpperBound();
2158 const int64_t this_min = lower.ConstantValue();
2159 const int64_t this_max = upper.ConstantValue();
2160 if ((this_min <= min_int) && (min_int <= this_max)) return true;
2161 if ((this_min <= max_int) && (max_int <= this_max)) return true;
2162 if ((min_int < this_min) && (max_int > this_max)) return true;
2163 return false;
2164}

◆ PrintTo()

void dart::Range::PrintTo ( BaseTextBuffer f) const

◆ set_max()

void dart::Range::set_max ( const RangeBoundary value)
inline

Definition at line 324 of file range_analysis.h.

324{ max_ = value; }
uint8_t value

◆ set_min()

void dart::Range::set_min ( const RangeBoundary value)
inline

Definition at line 322 of file range_analysis.h.

322{ min_ = value; }

◆ Shl()

void dart::Range::Shl ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2186 of file range_analysis.cc.

2189 {
2190 ASSERT(left != nullptr);
2191 ASSERT(right != nullptr);
2192 ASSERT(result_min != nullptr);
2193 ASSERT(result_max != nullptr);
2194 RangeBoundary left_max = Range::ConstantMax(left);
2195 RangeBoundary left_min = Range::ConstantMin(left);
2196 // A negative shift count always deoptimizes (and throws), so the minimum
2197 // shift count is zero.
2198 int64_t right_max = Utils::Maximum(Range::ConstantMax(right).ConstantValue(),
2199 static_cast<int64_t>(0));
2200 int64_t right_min = Utils::Maximum(Range::ConstantMin(right).ConstantValue(),
2201 static_cast<int64_t>(0));
2202 bool overflow = false;
2203 {
2204 const auto shift_amount =
2205 left_min.ConstantValue() > 0 ? right_min : right_max;
2206 if (RangeBoundary::WillShlOverflow(left_min, shift_amount)) {
2207 overflow = true;
2208 } else {
2209 *result_min = RangeBoundary::Shl(left_min, shift_amount);
2210 }
2211 }
2212 {
2213 const auto shift_amount =
2214 left_max.ConstantValue() > 0 ? right_max : right_min;
2215 if (RangeBoundary::WillShlOverflow(left_max, shift_amount)) {
2216 overflow = true;
2217 } else {
2218 *result_max = RangeBoundary::Shl(left_max, shift_amount);
2219 }
2220 }
2221 if (overflow) {
2222 *result_min =
2224 *result_max =
2226 }
2227}
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
static RangeBoundary Shl(const RangeBoundary &value_boundary, int64_t shift_count)
static bool WillShlOverflow(const RangeBoundary &a, int64_t shift_count)

◆ Shr()

void dart::Range::Shr ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2229 of file range_analysis.cc.

2232 {
2233 RangeBoundary left_max = Range::ConstantMax(left);
2234 RangeBoundary left_min = Range::ConstantMin(left);
2235 // A negative shift count always deoptimizes (and throws), so the minimum
2236 // shift count is zero.
2237 int64_t right_max = Utils::Maximum(Range::ConstantMax(right).ConstantValue(),
2238 static_cast<int64_t>(0));
2239 int64_t right_min = Utils::Maximum(Range::ConstantMin(right).ConstantValue(),
2240 static_cast<int64_t>(0));
2241
2242 *result_min = RangeBoundary::Shr(
2243 left_min, left_min.ConstantValue() > 0 ? right_max : right_min);
2244
2245 *result_max = RangeBoundary::Shr(
2246 left_max, left_max.ConstantValue() > 0 ? right_min : right_max);
2247}
static RangeBoundary Shr(const RangeBoundary &value_boundary, int64_t shift_count)

◆ Singleton()

int64_t dart::Range::Singleton ( ) const
inline

Definition at line 386 of file range_analysis.h.

386 {
388 return min_.ConstantValue();
389 }
bool IsSingleton() const

◆ Sub()

void dart::Range::Sub ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max,
Definition left_defn 
)
static

Definition at line 2410 of file range_analysis.cc.

2414 {
2415 ASSERT(left_range != nullptr);
2416 ASSERT(right_range != nullptr);
2417 ASSERT(result_min != nullptr);
2418 ASSERT(result_max != nullptr);
2419
2420 RangeBoundary left_min = Definition::IsArrayLength(left_defn)
2422 : left_range->min();
2423
2424 RangeBoundary left_max = Definition::IsArrayLength(left_defn)
2426 : left_range->max();
2427
2428 bool overflow = false;
2429 if (!RangeBoundary::SymbolicSub(left_min, right_range->max(), result_min)) {
2430 const auto left_min_bound = left_range->min().LowerBound();
2431 const auto right_max_bound = right_range->max().UpperBound();
2432 if (RangeBoundary::WillSubOverflow(left_min_bound, right_max_bound)) {
2433 overflow = true;
2434 } else {
2435 *result_min = RangeBoundary::Sub(left_min_bound, right_max_bound);
2436 }
2437 }
2438 if (!RangeBoundary::SymbolicSub(left_max, right_range->min(), result_max)) {
2439 const auto left_max_bound = left_range->max().UpperBound();
2440 const auto right_min_bound = right_range->min().LowerBound();
2441 if (RangeBoundary::WillSubOverflow(left_max_bound, right_min_bound)) {
2442 overflow = true;
2443 } else {
2444 *result_max = RangeBoundary::Sub(left_max_bound, right_min_bound);
2445 }
2446 }
2447 if (overflow) {
2448 *result_min =
2450 *result_max =
2452 }
2453}
static bool WillSubOverflow(const RangeBoundary &a, const RangeBoundary &b)
static bool SymbolicSub(const RangeBoundary &a, const RangeBoundary &b, RangeBoundary *result)
static RangeBoundary Sub(const RangeBoundary &a, const RangeBoundary &b)

◆ ToCString()

static const char * dart::Range::ToCString ( const Range range)
static

◆ TruncDiv()

void dart::Range::TruncDiv ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2494 of file range_analysis.cc.

2497 {
2498 ASSERT(left_range != nullptr);
2499 ASSERT(right_range != nullptr);
2500 ASSERT(result_min != nullptr);
2501 ASSERT(result_max != nullptr);
2502
2503 if (left_range->OnlyGreaterThanOrEqualTo(0) &&
2504 right_range->OnlyGreaterThanOrEqualTo(1)) {
2505 const int64_t left_max = ConstantAbsMax(left_range);
2506 const int64_t left_min = ConstantAbsMin(left_range);
2507 const int64_t right_max = ConstantAbsMax(right_range);
2508 const int64_t right_min = ConstantAbsMin(right_range);
2509
2510 *result_max = RangeBoundary::FromConstant(left_max / right_min);
2511 *result_min = RangeBoundary::FromConstant(left_min / right_max);
2512 return;
2513 }
2514
2517}

◆ Ushr()

void dart::Range::Ushr ( const Range left_range,
const Range right_range,
RangeBoundary min,
RangeBoundary max 
)
static

Definition at line 2284 of file range_analysis.cc.

2287 {
2288 const int64_t left_max = Range::ConstantMax(left).ConstantValue();
2289 const int64_t left_min = Range::ConstantMin(left).ConstantValue();
2290 // A negative shift count always deoptimizes (and throws), so the minimum
2291 // shift count is zero.
2292 const int64_t right_max = Utils::Maximum(
2293 Range::ConstantMax(right).ConstantValue(), static_cast<int64_t>(0));
2294 const int64_t right_min = Utils::Maximum(
2295 Range::ConstantMin(right).ConstantValue(), static_cast<int64_t>(0));
2296
2297 uint64_t unsigned_left_min, unsigned_left_max;
2298 ConvertRangeToUnsigned(left_min, left_max, &unsigned_left_min,
2299 &unsigned_left_max);
2300
2301 const uint64_t unsigned_result_min =
2302 (right_max >= kBitsPerInt64)
2303 ? 0
2304 : unsigned_left_min >> static_cast<uint64_t>(right_max);
2305 const uint64_t unsigned_result_max =
2306 (right_min >= kBitsPerInt64)
2307 ? 0
2308 : unsigned_left_max >> static_cast<uint64_t>(right_min);
2309
2310 int64_t signed_result_min, signed_result_max;
2311 ConvertRangeToSigned(unsigned_result_min, unsigned_result_max,
2312 &signed_result_min, &signed_result_max);
2313
2314 *result_min = RangeBoundary(signed_result_min);
2315 *result_max = RangeBoundary(signed_result_max);
2316}
static void ConvertRangeToSigned(uint64_t a, uint64_t b, int64_t *sa, int64_t *sb)
static void ConvertRangeToUnsigned(int64_t a, int64_t b, uint64_t *ua, uint64_t *ub)
constexpr intptr_t kBitsPerInt64
Definition globals.h:467

◆ Write()

void dart::Range::Write ( FlowGraphSerializer s) const

Definition at line 2206 of file il_serializer.cc.

2206 {
2207 min_.Write(s);
2208 max_.Write(s);
2209}
void Write(FlowGraphSerializer *s) const
struct MyStruct s

The documentation for this class was generated from the following files: