Flutter Engine
The Flutter Engine
range_analysis.h
Go to the documentation of this file.
1// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_BACKEND_RANGE_ANALYSIS_H_
6#define RUNTIME_VM_COMPILER_BACKEND_RANGE_ANALYSIS_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
14
15namespace dart {
16
17class RangeBoundary : public ValueObject {
18 public:
19#define FOR_EACH_RANGE_BOUNDARY_KIND(V) \
20 V(Unknown) \
21 V(Symbol) \
22 V(Constant)
23
24#define KIND_DEFN(name) k##name,
26#undef KIND_DEFN
27
28 enum RangeSize {
34 };
35
36 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) {}
37
39 : ValueObject(),
40 kind_(other.kind_),
41 value_(other.value_),
42 offset_(other.offset_) {}
43
44 explicit RangeBoundary(int64_t val)
45 : kind_(kConstant), value_(val), offset_(0) {}
46
48 kind_ = other.kind_;
49 value_ = other.value_;
50 offset_ = other.offset_;
51 return *this;
52 }
53
54 static constexpr int64_t kMin = kMinInt64;
55 static constexpr int64_t kMax = kMaxInt64;
56
57 // Construct a RangeBoundary for a constant value.
58 static RangeBoundary FromConstant(int64_t val) { return RangeBoundary(val); }
59
60 // Construct a RangeBoundary from a definition and offset.
61 static RangeBoundary FromDefinition(Definition* defn, int64_t offs = 0);
62
66 // Avoid creating symbolic range boundaries which can wrap around.
67 return false;
68 }
69 return true;
70 }
71
72 // Construct a RangeBoundary for the constant MinSmi value.
75 }
76
77 // Construct a RangeBoundary for the constant MaxSmi value.
80 }
81
82 // Construct a RangeBoundary for the constant kMin value.
84 switch (size) {
88 return FromConstant(kMinInt8);
90 return FromConstant(kMinInt16);
92 return FromConstant(kMinInt32);
94 return FromConstant(kMinInt64);
95 }
97 return FromConstant(kMinInt64);
98 }
99
101 switch (size) {
105 return FromConstant(kMaxInt8);
107 return FromConstant(kMaxInt16);
109 return FromConstant(kMaxInt32);
111 return FromConstant(kMaxInt64);
112 }
113 UNREACHABLE();
114 return FromConstant(kMaxInt64);
115 }
116
117 // Given two boundaries a and b, select one of them as c so that
118 //
119 // inf {[a, ...) ^ [b, ...)} >= inf {c}
120 //
122
123 // Given two boundaries a and b, select one of them as c so that
124 //
125 // sup {(..., a] ^ (..., b]} <= sup {c}
126 //
128
129 // Given two boundaries a and b compute boundary c such that
130 //
131 // inf {[a, ...) U [b, ...)} >= inf {c}
132 //
133 // Try to select c such that it is as close to inf {[a, ...) U [b, ...)}
134 // as possible.
138
139 // Given two boundaries a and b compute boundary c such that
140 //
141 // sup {(..., a] U (..., b]} <= sup {c}
142 //
143 // Try to select c such that it is as close to sup {(..., a] U (..., b]}
144 // as possible.
148
149 // Returns true when this is a constant that is outside of Smi range.
150 bool OverflowedSmi() const {
152 }
153
156 return !Equals(Clamp(size));
157 }
158
159 // Clamp constant boundary to MinConstant/MaxConstant of the given size.
161 if (IsConstant()) {
164
165 if (ConstantValue() <= range_min.ConstantValue()) {
166 return range_min;
167 }
168 if (ConstantValue() >= range_max.ConstantValue()) {
169 return range_max;
170 }
171 }
172
173 // If this range is a symbolic range, we do not clamp it.
174 // This could lead to some imprecision later on.
175 return *this;
176 }
177
179 return IsConstant() && (ConstantValue() <=
181 }
182
184 return IsConstant() && (ConstantValue() >=
186 }
187
188 intptr_t kind() const { return kind_; }
189
190 // Kind tests.
191 bool IsUnknown() const { return kind_ == kUnknown; }
192 bool IsConstant() const { return kind_ == kConstant; }
193 bool IsSymbol() const { return kind_ == kSymbol; }
194
195 // Returns the value of a kConstant RangeBoundary.
196 int64_t ConstantValue() const;
197
198 // Returns the Definition associated with a kSymbol RangeBoundary.
200 ASSERT(IsSymbol());
201 return reinterpret_cast<Definition*>(value_);
202 }
203
204 // Offset from symbol.
205 int64_t offset() const { return offset_; }
206
207 // Computes the LowerBound of this. Three cases:
208 // IsConstant() -> value().
209 // IsSymbol() -> lower bound computed from definition + offset.
211
212 // Computes the UpperBound of this. Three cases:
213 // IsConstant() -> value().
214 // IsSymbol() -> upper bound computed from definition + offset.
216
218 const char* ToCString() const;
219
220 static bool WillAddOverflow(const RangeBoundary& a, const RangeBoundary& b);
221
222 static RangeBoundary Add(const RangeBoundary& a, const RangeBoundary& b);
223
224 static bool WillSubOverflow(const RangeBoundary& a, const RangeBoundary& b);
225
226 static RangeBoundary Sub(const RangeBoundary& a, const RangeBoundary& b);
227
228 static bool WillShlOverflow(const RangeBoundary& a, int64_t shift_count);
229
230 static RangeBoundary Shl(const RangeBoundary& value_boundary,
231 int64_t shift_count);
232
233 static RangeBoundary Shr(const RangeBoundary& value_boundary,
234 int64_t shift_count);
235
236 // Attempts to calculate a + b when:
237 // a is a symbol and b is a constant OR
238 // a is a constant and b is a symbol
239 // returns true if it succeeds, output is in result.
240 static bool SymbolicAdd(const RangeBoundary& a,
241 const RangeBoundary& b,
243
244 // Attempts to calculate a - b when:
245 // a is a symbol and b is a constant
246 // returns true if it succeeds, output is in result.
247 static bool SymbolicSub(const RangeBoundary& a,
248 const RangeBoundary& b,
250
251 bool Equals(const RangeBoundary& other) const;
252
253 int64_t UpperBound(RangeSize size) const {
255 }
256
257 int64_t LowerBound(RangeSize size) const {
259 }
260
261 int64_t SmiUpperBound() const { return UpperBound(kRangeBoundarySmi); }
262
263 int64_t SmiLowerBound() const { return LowerBound(kRangeBoundarySmi); }
264
265 void Write(FlowGraphSerializer* s) const;
267
268 private:
269 RangeBoundary(Kind kind, int64_t value, int64_t offset)
270 : kind_(kind), value_(value), offset_(offset) {}
271
272 Kind kind_;
273 int64_t value_;
274 int64_t offset_;
275};
276
277class Range : public ZoneAllocated {
278 public:
279 Range() : min_(), max_() {}
280
282 ASSERT(min_.IsUnknown() == max_.IsUnknown());
283 }
284
285 Range(const Range& other)
286 : ZoneAllocated(), min_(other.min_), max_(other.max_) {}
287
288 Range& operator=(const Range& other) {
289 min_ = other.min_;
290 max_ = other.max_;
291 return *this;
292 }
293
294 static bool IsUnknown(const Range* other) {
295 if (other == nullptr) {
296 return true;
297 }
298 return other->min().IsUnknown();
299 }
300
304 }
305
306 static Range Full(Representation rep);
307
309 static const char* ToCString(const Range* range);
310
311 bool Equals(const Range* other) {
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 }
318
319 const RangeBoundary& min() const { return min_; }
320 const RangeBoundary& max() const { return max_; }
321
322 void set_min(const RangeBoundary& value) { min_ = value; }
323
324 void set_max(const RangeBoundary& value) { max_ = value; }
325
326 static RangeBoundary ConstantMinSmi(const Range* range) {
328 }
329
330 static RangeBoundary ConstantMaxSmi(const Range* range) {
332 }
333
334 static RangeBoundary ConstantMin(const Range* range) {
336 }
337
338 static RangeBoundary ConstantMax(const Range* range) {
340 }
341
342 static RangeBoundary ConstantMin(const Range* range,
344 if (range == nullptr) {
346 }
347 return range->min().LowerBound().Clamp(size);
348 }
349
350 static RangeBoundary ConstantMax(const Range* range,
352 if (range == nullptr) {
354 }
355 return range->max().UpperBound().Clamp(size);
356 }
357
358 // [0, +inf]
359 bool IsPositive() const;
360
361 // [-inf, -1]
362 bool IsNegative() const;
363
364 // [-inf, val].
365 bool OnlyLessThanOrEqualTo(int64_t val) const;
366
367 // [val, +inf].
368 bool OnlyGreaterThanOrEqualTo(int64_t val) const;
369
370 // Inclusive.
371 bool IsWithin(int64_t min_int, int64_t max_int) const;
372
373 // Inclusive.
374 bool IsWithin(const Range* other) const;
375
376 // Inclusive.
377 bool Overlaps(int64_t min_int, int64_t max_int) const;
378
379 bool IsUnsatisfiable() const;
380
381 bool IsSingleton() const {
382 return min_.IsConstant() && max_.IsConstant() &&
383 min_.ConstantValue() == max_.ConstantValue();
384 }
385
386 int64_t Singleton() const {
388 return min_.ConstantValue();
389 }
390
391 Range Intersect(const Range* other) const {
392 return Range(RangeBoundary::IntersectionMin(min(), other->min()),
394 }
395
397 return !min().LowerBound().Overflowed(size) &&
399 }
400
401 // Returns true if this range fits without truncation into
402 // the given representation.
403 static bool Fits(Range* range, Representation rep) {
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 }
409
410 // Clamp this to be within size.
412
413 // Clamp this to be within size and eliminate symbols.
415
416 static void Add(const Range* left_range,
417 const Range* right_range,
420 Definition* left_defn);
421
422 static void Sub(const Range* left_range,
423 const Range* right_range,
426 Definition* left_defn);
427
428 static void Mul(const Range* left_range,
429 const Range* right_range,
432
433 static void TruncDiv(const Range* left_range,
434 const Range* right_range,
437
438 static void Mod(const Range* right_range,
441
442 static void Shr(const Range* left_range,
443 const Range* right_range,
446
447 static void Ushr(const Range* left_range,
448 const Range* right_range,
451
452 static void Shl(const Range* left_range,
453 const Range* right_range,
456
457 static void And(const Range* left_range,
458 const Range* right_range,
461
462 static void BitwiseOp(const Range* left_range,
463 const Range* right_range,
466
467 // Both the a and b ranges are >= 0.
468 static bool OnlyPositiveOrZero(const Range& a, const Range& b);
469
470 // Both the a and b ranges are <= 0.
471 static bool OnlyNegativeOrZero(const Range& a, const Range& b);
472
473 // Return the maximum absolute value included in range.
474 static int64_t ConstantAbsMax(const Range* range);
475
476 // Return the minimum absolute value included in range.
477 static int64_t ConstantAbsMin(const Range* range);
478
479 static void BinaryOp(const Token::Kind op,
480 const Range* left_range,
481 const Range* right_range,
482 Definition* left_defn,
483 Range* result);
484
485 void Write(FlowGraphSerializer* s) const;
486 explicit Range(FlowGraphDeserializer* d);
487
488 private:
489 RangeBoundary min_;
490 RangeBoundary max_;
491};
492
493class RangeUtils : public AllStatic {
494 public:
496 return !Range::IsUnknown(range) && range->Fits(size);
497 }
498
499 static bool IsWithin(const Range* range, int64_t min, int64_t max) {
500 return !Range::IsUnknown(range) && range->IsWithin(min, max);
501 }
502
503 static bool IsWithin(const Range* range, const Range* other) {
504 return !Range::IsUnknown(range) && range->IsWithin(other);
505 }
506
507 static bool IsPositive(Range* range) {
508 return !Range::IsUnknown(range) && range->IsPositive();
509 }
510 static bool IsNegative(Range* range) {
511 return !Range::IsUnknown(range) && range->IsNegative();
512 }
513
514 static bool Overlaps(Range* range, intptr_t min, intptr_t max) {
515 return Range::IsUnknown(range) || range->Overlaps(min, max);
516 }
517
518 static bool CanBeZero(Range* range) { return Overlaps(range, 0, 0); }
519
520 static bool OnlyLessThanOrEqualTo(Range* range, intptr_t value) {
521 return !Range::IsUnknown(range) && range->OnlyLessThanOrEqualTo(value);
522 }
523
524 static bool IsSingleton(Range* range) {
525 return !Range::IsUnknown(range) && range->IsSingleton();
526 }
527};
528
529// Range analysis for integer values.
531 public:
532 explicit RangeAnalysis(FlowGraph* flow_graph)
533 : flow_graph_(flow_graph),
534 smi_range_(Range::Full(RangeBoundary::kRangeBoundarySmi)),
535 int64_range_(Range::Full(RangeBoundary::kRangeBoundaryInt64)) {}
536
537 // Infer ranges for all values and remove overflow checks from binary smi
538 // operations when proven redundant.
539 void Analyze();
540
541 // Helper that should be used to access ranges of inputs during range
542 // inference.
543 // Returns meaningful results for uses of non-smi/non-int definitions that
544 // have smi/int as a reaching type.
545 const Range* GetSmiRange(Value* value) const;
546 const Range* GetIntRange(Value* value) const;
547
548 static bool IsIntegerDefinition(Definition* defn) {
549 return defn->Type()->IsInt();
550 }
551
553
554 private:
555 enum JoinOperator { NONE, WIDEN, NARROW };
556 static char OpPrefix(JoinOperator op);
557
558 // Collect all integer values (smi or int), all 64-bit binary
559 // and shift operations, and all check bounds.
560 void CollectValues();
561
562 // Iterate over smi values and constrain them at branch successors.
563 // Additionally constraint values after CheckSmi instructions.
564 void InsertConstraints();
565
566 // Iterate over uses of the given definition and discover branches that
567 // constrain it. Insert appropriate Constraint instructions at true
568 // and false successor and rename all dominated uses to refer to a
569 // Constraint instead of this definition.
570 void InsertConstraintsFor(Definition* defn);
571
572 // Create a constraint for defn, insert it after given instruction and
573 // rename all uses that are dominated by it.
574 ConstraintInstr* InsertConstraintFor(Value* use,
575 Definition* defn,
576 Range* constraint,
577 Instruction* after);
578
579 bool ConstrainValueAfterBranch(Value* use, Definition* defn);
580 void ConstrainValueAfterCheckBound(Value* use,
581 CheckBoundBaseInstr* check,
582 Definition* defn);
583
584 // Infer ranges for integer (smi or mint) definitions.
585 void InferRanges();
586
587 // Collect integer definition in the reverse postorder.
588 void CollectDefinitions(BitVector* set);
589
590 // Recompute ranges of all definitions until they stop changing.
591 // Apply the given JoinOperator when computing Phi ranges.
592 void Iterate(JoinOperator op, intptr_t max_iterations);
593 bool InferRange(JoinOperator op, Definition* defn, intptr_t iteration);
594
595 // Based on computed ranges find and eliminate redundant CheckArrayBound
596 // instructions.
597 void EliminateRedundantBoundsChecks();
598
599 // Find unsatisfiable constraints and mark corresponding blocks unreachable.
600 void MarkUnreachableBlocks();
601
602 // Convert mint operations that stay within int32 range into Int32 operations.
603 void NarrowMintToInt32();
604
605 // Remove artificial Constraint instructions and replace them with actual
606 // unconstrained definitions.
607 void RemoveConstraints();
608
609 Range* ConstraintSmiRange(Token::Kind op, Definition* boundary);
610
611 Zone* zone() const { return flow_graph_->zone(); }
612
613 FlowGraph* flow_graph_;
614
615 // Range object representing full Smi range.
616 Range smi_range_;
617
618 Range int64_range_;
619
620 // All values that are known to be smi or mint.
621 GrowableArray<Definition*> values_;
622
623 // All 64-bit binary and shift operations.
624 GrowableArray<BinaryInt64OpInstr*> binary_int64_ops_;
625 GrowableArray<ShiftIntegerOpInstr*> shift_int64_ops_;
626
627 // All CheckArrayBound/GenericCheckBound instructions.
628 GrowableArray<CheckBoundBaseInstr*> bounds_checks_;
629
630 // All Constraints inserted during InsertConstraints phase. They are treated
631 // as smi values.
632 GrowableArray<ConstraintInstr*> constraints_;
633
634 // List of integer (smi or mint) definitions including constraints sorted
635 // in the reverse postorder.
636 GrowableArray<Definition*> definitions_;
637
638 DISALLOW_COPY_AND_ASSIGN(RangeAnalysis);
639};
640
641// Replaces Mint IL instructions with Uint32 IL instructions
642// when possible. Uses output of RangeAnalysis.
644 public:
645 explicit IntegerInstructionSelector(FlowGraph* flow_graph);
646
647 void Select();
648
649 private:
650 bool IsPotentialUint32Definition(Definition* def);
651 void FindPotentialUint32Definitions();
652 bool IsUint32NarrowingDefinition(Definition* def);
653 void FindUint32NarrowingDefinitions();
654 bool AllUsesAreUint32Narrowing(Value* list_head);
655 bool CanBecomeUint32(Definition* def);
656 void Propagate();
657 Definition* ConstructReplacementFor(Definition* def);
658 void ReplaceInstructions();
659
660 Zone* zone() const { return zone_; }
661
662 GrowableArray<Definition*> potential_uint32_defs_;
663 BitVector* selected_uint32_defs_;
664
665 FlowGraph* flow_graph_;
666 Zone* zone_;
667};
668
669} // namespace dart
670
671#endif // RUNTIME_VM_COMPILER_BACKEND_RANGE_ANALYSIS_H_
#define check(reporter, ref, unref, make, kill)
Definition: RefCntTest.cpp:85
#define UNREACHABLE()
Definition: assert.h:248
CompileType * Type()
Definition: il.h:2521
Zone * zone() const
Definition: flow_graph.h:261
IntegerInstructionSelector(FlowGraph *flow_graph)
void AssignRangesRecursively(Definition *defn)
const Range * GetIntRange(Value *value) const
static bool IsIntegerDefinition(Definition *defn)
const Range * GetSmiRange(Value *value) const
RangeAnalysis(FlowGraph *flow_graph)
bool IsUnknown() const
RangeBoundary(int64_t val)
int64_t UpperBound(RangeSize size) const
bool Equals(const RangeBoundary &other) const
bool IsConstant() const
bool OverflowedSmi() const
static bool WillSubOverflow(const RangeBoundary &a, const RangeBoundary &b)
static RangeBoundary FromDefinition(Definition *defn, int64_t offs=0)
int64_t offset() const
void Write(FlowGraphSerializer *s) const
int64_t SmiLowerBound() const
int64_t SmiUpperBound() const
static RangeBoundary MaxSmi()
RangeBoundary Clamp(RangeSize size) const
static bool SymbolicAdd(const RangeBoundary &a, const RangeBoundary &b, RangeBoundary *result)
static bool IsValidOffsetForSymbolicRangeBoundary(int64_t offset)
int64_t LowerBound(RangeSize size) const
bool IsMaximumOrAbove(RangeSize size) const
static bool WillAddOverflow(const RangeBoundary &a, const RangeBoundary &b)
static RangeBoundary MinConstant(RangeSize size)
static RangeBoundary Add(const RangeBoundary &a, const RangeBoundary &b)
RangeBoundary UpperBound() const
static constexpr int64_t kMin
static RangeBoundary JoinMax(RangeBoundary a, RangeBoundary b, RangeBoundary::RangeSize size)
RangeBoundary LowerBound() const
static bool SymbolicSub(const RangeBoundary &a, const RangeBoundary &b, RangeBoundary *result)
static RangeBoundary IntersectionMin(RangeBoundary a, RangeBoundary b)
static RangeBoundary MinSmi()
static RangeBoundary Shr(const RangeBoundary &value_boundary, int64_t shift_count)
static RangeBoundary IntersectionMax(RangeBoundary a, RangeBoundary b)
int64_t ConstantValue() const
static RangeBoundary JoinMin(RangeBoundary a, RangeBoundary b, RangeBoundary::RangeSize size)
static constexpr int64_t kMax
static RangeBoundary Sub(const RangeBoundary &a, const RangeBoundary &b)
RangeBoundary & operator=(const RangeBoundary &other)
RangeBoundary(const RangeBoundary &other)
bool IsSymbol() const
static RangeBoundary Shl(const RangeBoundary &value_boundary, int64_t shift_count)
intptr_t kind() const
static RangeBoundary MaxConstant(RangeSize size)
static bool WillShlOverflow(const RangeBoundary &a, int64_t shift_count)
const char * ToCString() const
void PrintTo(BaseTextBuffer *f) const
bool Overflowed(RangeBoundary::RangeSize size) const
bool IsMinimumOrBelow(RangeSize size) const
static RangeBoundary FromConstant(int64_t val)
Definition * symbol() const
static bool IsSingleton(Range *range)
static bool IsNegative(Range *range)
static bool Overlaps(Range *range, intptr_t min, intptr_t max)
static bool OnlyLessThanOrEqualTo(Range *range, intptr_t value)
static bool Fits(Range *range, RangeBoundary::RangeSize size)
static bool IsWithin(const Range *range, int64_t min, int64_t max)
static bool IsPositive(Range *range)
static bool CanBeZero(Range *range)
static bool IsWithin(const Range *range, const Range *other)
static RangeBoundary ConstantMinSmi(const Range *range)
static int64_t ConstantAbsMax(const Range *range)
static bool OnlyNegativeOrZero(const Range &a, const Range &b)
static void BitwiseOp(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
bool IsPositive() const
static const char * ToCString(const Range *range)
void set_max(const RangeBoundary &value)
static RangeBoundary ConstantMin(const Range *range, RangeBoundary::RangeSize size)
static void Shr(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
static bool Fits(Range *range, Representation rep)
static RangeBoundary ConstantMaxSmi(const Range *range)
bool IsWithin(int64_t min_int, int64_t max_int) const
Range Intersect(const Range *other) const
void ClampToConstant(RangeBoundary::RangeSize size)
Range & operator=(const Range &other)
static void Mul(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
Range(RangeBoundary min, RangeBoundary max)
bool IsNegative() const
static bool OnlyPositiveOrZero(const Range &a, const Range &b)
static bool IsUnknown(const Range *other)
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)
const RangeBoundary & min() const
bool IsUnsatisfiable() const
bool Fits(RangeBoundary::RangeSize size) const
static void BinaryOp(const Token::Kind op, const Range *left_range, const Range *right_range, Definition *left_defn, Range *result)
const RangeBoundary & max() const
Range(const Range &other)
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 Range Full(RangeBoundary::RangeSize size)
static void Sub(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max, Definition *left_defn)
void Clamp(RangeBoundary::RangeSize size)
static RangeBoundary ConstantMax(const Range *range, RangeBoundary::RangeSize size)
void Write(FlowGraphSerializer *s) const
static void Shl(const Range *left_range, const Range *right_range, RangeBoundary *min, RangeBoundary *max)
bool Equals(const Range *other)
bool OnlyGreaterThanOrEqualTo(int64_t val) const
static RangeBoundary ConstantMin(const Range *range)
void set_min(const RangeBoundary &value)
static void Mod(const Range *right_range, RangeBoundary *min, RangeBoundary *max)
void PrintTo(BaseTextBuffer *f) const
bool OnlyLessThanOrEqualTo(int64_t val) const
static RangeBoundary ConstantMax(const Range *range)
bool Overlaps(int64_t min_int, int64_t max_int) const
static int64_t ConstantAbsMin(const Range *range)
int64_t Singleton() const
bool IsSingleton() const
Definition: il.h:75
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
static bool b
struct MyStruct s
struct MyStruct a[10]
uint8_t value
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
constexpr word kSmiMin
Definition: runtime_api.h:306
bool IsSmi(int64_t v)
Definition: runtime_api.cc:31
constexpr word kSmiMax
Definition: runtime_api.h:305
Definition: dart_vm.cc:33
constexpr int16_t kMaxInt16
Definition: globals.h:480
constexpr int64_t kMaxInt64
Definition: globals.h:486
constexpr int64_t kMinInt64
Definition: globals.h:485
constexpr int32_t kMinInt32
Definition: globals.h:482
Representation
Definition: locations.h:66
constexpr int8_t kMaxInt8
Definition: globals.h:477
constexpr int32_t kMaxInt32
Definition: globals.h:483
constexpr int16_t kMinInt16
Definition: globals.h:479
constexpr int8_t kMinInt8
Definition: globals.h:476
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
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
#define KIND_DEFN(name)
static constexpr bool IsUnboxedInteger(Representation rep)
Definition: locations.h:92