Flutter Engine
The Flutter Engine
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 }
bool IsUnknown() const
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:585
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:41
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ 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:62

◆ 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:36

◆ 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) {
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.

330 {
332 }

◆ 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) {
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) &&
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.

◆ 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)
constexpr word kSmiMin
Definition: runtime_api.h:306

◆ 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 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: