19 trace_type_propagation,
21 "Trace flow graph type propagation");
25 if (FLAG_trace_strong_mode_types) {
33 if (FLAG_trace_strong_mode_types) {
35 if ((
type !=
nullptr) && !
type->IsDynamicType()) {
41void FlowGraphTypePropagator::Propagate(
FlowGraph* flow_graph) {
43 "FlowGraphTypePropagator");
48FlowGraphTypePropagator::FlowGraphTypePropagator(
FlowGraph* flow_graph)
50 flow_graph_(flow_graph),
52 visited_blocks_(new(flow_graph->zone())
54 flow_graph->reverse_postorder().
length())),
55 types_(flow_graph->current_ssa_temp_index()),
56 in_worklist_(nullptr),
58 collected_asserts_(nullptr) {
63 asserts_ =
new ZoneGrowableArray<AssertAssignableInstr*>(
66 asserts_->Add(
nullptr);
69 collected_asserts_ =
new ZoneGrowableArray<intptr_t>(10);
72void FlowGraphTypePropagator::Propagate() {
81 in_worklist_ =
new (flow_graph_->
zone())
83 for (intptr_t i = 0; i < worklist_.length(); i++) {
84 ASSERT(worklist_[i]->IsPhi());
90 while (!worklist_.is_empty()) {
91 Definition* def = RemoveLastFromWorklist();
94 THR_Print(
"recomputing type of v%" Pd ": %s\n", def->ssa_temp_index(),
95 def->Type()->ToCString());
97 if (def->RecomputeType()) {
100 THR_Print(
" ... new type %s\n", def->Type()->ToCString());
102 for (Value::Iterator it(def->input_use_list()); !it.Done();
104 Instruction* instr = it.Current()->instruction();
106 Definition* use_defn = instr->AsDefinition();
107 if (use_defn !=
nullptr) {
108 AddToWorklist(use_defn);
115void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) {
116 if (visited_blocks_->
Contains(block->postorder_number())) {
119 visited_blocks_->
Add(block->postorder_number());
121 const intptr_t rollback_point = rollback_.
length();
128 StrengthenAsserts(block);
133 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
134 Instruction* instr = it.Current();
136 for (intptr_t i = 0; i < instr->InputCount(); i++) {
137 VisitValue(instr->InputAt(i));
139 if (instr->IsDefinition()) {
140 instr->AsDefinition()->RecomputeType();
145 GotoInstr* goto_instr = block->last_instruction()->AsGoto();
146 if (goto_instr !=
nullptr) {
147 JoinEntryInstr*
join = goto_instr->successor();
148 intptr_t pred_index =
join->IndexOfPredecessor(block);
150 for (PhiIterator it(join); !it.Done(); it.Advance()) {
151 VisitValue(it.Current()->InputAt(pred_index));
155 for (intptr_t i = 0; i < block->dominated_blocks().
length(); ++i) {
156 PropagateRecursive(block->dominated_blocks()[i]);
159 RollbackTo(rollback_point);
162void FlowGraphTypePropagator::RollbackTo(intptr_t rollback_point) {
163 for (intptr_t i = rollback_.
length() - 1; i >= rollback_point; i--) {
164 types_[rollback_[i].index()] = rollback_[i].type();
166 rollback_.TruncateTo(rollback_point);
169CompileType* FlowGraphTypePropagator::TypeOf(Definition* def) {
170 const intptr_t index = def->ssa_temp_index();
172 CompileType*
type = types_[index];
173 if (
type ==
nullptr) {
174 type = types_[index] = def->Type();
180void FlowGraphTypePropagator::SetTypeOf(Definition* def, CompileType*
type) {
181 const intptr_t index = def->ssa_temp_index();
182 rollback_.Add(RollbackEntry(index, types_[index]));
183 types_[index] =
type;
186void FlowGraphTypePropagator::SetCid(Definition* def, intptr_t
cid) {
187 CompileType* current = TypeOf(def);
188 if (current->IsNone() || (current->ToCid() !=
cid)) {
193void FlowGraphTypePropagator::GrowTypes(intptr_t up_to) {
195 for (intptr_t i = types_.length(); i <= up_to; ++i) {
200void FlowGraphTypePropagator::EnsureMoreAccurateRedefinition(
202 Definition* original,
203 CompileType new_type) {
204 RedefinitionInstr* redef =
206 if (redef !=
nullptr) {
207 GrowTypes(redef->ssa_temp_index() + 1);
211void FlowGraphTypePropagator::VisitValue(
Value* value) {
212 CompileType*
type = TypeOf(
value->definition());
217 if (
type->IsNone() &&
value->instruction()->IsPhi()) {
225 THR_Print(
"reaching type to %s for v%" Pd " is %s\n",
226 value->instruction()->ToCString(),
227 value->definition()->ssa_temp_index(),
228 value->Type()->ToCString());
234 worklist_.Add(it.Current());
239 SetCid(
check->value()->definition(), kSmiCid);
245 SetCid(
check->index()->definition(), kSmiCid);
257 for (intptr_t i = 0, n = cids.
length(); i < n; i++) {
273 check->value()->definition()->OriginalDefinition()->AsLoadClassId();
274 if (load_cid !=
nullptr &&
check->cids().IsSingleCid()) {
282 if (
type->is_nullable()) {
288 if (
check->ssa_temp_index() == -1) {
290 GrowTypes(
check->ssa_temp_index() + 1);
301void FlowGraphTypePropagator::CheckNonNullSelector(
310 const Class& null_class =
311 Class::Handle(thread->isolate_group()->object_store()->null_class());
319 CompileType*
type = TypeOf(receiver);
320 if (
type->is_nullable()) {
323 EnsureMoreAccurateRedefinition(call, receiver,
type->CopyNonNullable());
360 const bool is_nullable =
370 auto defn =
check->value()->definition();
372 if (
check->ssa_temp_index() == -1) {
374 GrowTypes(
check->ssa_temp_index() + 1);
388 if (comparison ==
nullptr)
return;
389 bool negated = comparison->kind() == Token::kNE_STRICT;
396 bool is_simple_instance_of =
397 (call !=
nullptr) && call->MatchesCoreName(Symbols::_simpleInstanceOf());
402 EnsureMoreAccurateRedefinition(true_successor,
405 }
else if ((is_simple_instance_of || (instance_of !=
nullptr)) &&
415 if (is_simple_instance_of) {
416 ASSERT(call->ArgumentAt(1)->IsConstant());
417 const Object& type_obj = call->ArgumentAt(1)->AsConstant()->value();
418 if (!type_obj.IsType()) {
421 type = &Type::Cast(type_obj);
422 left = call->ArgumentAt(0);
427 if (!
type->IsTopTypeForInstanceOf()) {
428 const bool is_nullable = (
type->IsNullable() ||
type->IsTypeParameter() ||
429 (
type->IsNeverType() &&
type->IsLegacy()))
432 EnsureMoreAccurateRedefinition(
433 true_successor,
left,
442 EnsureMoreAccurateRedefinition(
451 EnsureMoreAccurateRedefinition(
456 Object::sentinel().ptr()) {
460 EnsureMoreAccurateRedefinition(
466 Object::sentinel().ptr()) {
470 EnsureMoreAccurateRedefinition(
477void FlowGraphTypePropagator::AddToWorklist(
Definition* defn) {
483 if (!in_worklist_->
Contains(index)) {
485 in_worklist_->
Add(index);
489Definition* FlowGraphTypePropagator::RemoveLastFromWorklist() {
490 Definition* defn = worklist_.RemoveLast();
491 ASSERT(defn->ssa_temp_index() != -1);
492 in_worklist_->
Remove(defn->ssa_temp_index());
500void FlowGraphTypePropagator::StrengthenAsserts(BlockEntryInstr* block) {
501 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
502 Instruction* instr = it.Current();
504 if (instr->IsCheckSmi() || instr->IsCheckClass()) {
505 StrengthenAssertWith(instr);
509 AssertAssignableInstr* assert = instr->AsAssertAssignable();
510 if (assert !=
nullptr) {
511 Definition* defn = assert->value()->definition()->OriginalDefinition();
512 if ((*asserts_)[defn->ssa_temp_index()] ==
nullptr) {
513 (*asserts_)[defn->ssa_temp_index()] = assert;
514 collected_asserts_->
Add(defn->ssa_temp_index());
519 for (intptr_t i = 0; i < collected_asserts_->
length(); i++) {
520 (*asserts_)[(*collected_asserts_)[i]] =
nullptr;
526void FlowGraphTypePropagator::StrengthenAssertWith(Instruction*
check) {
529 AssertAssignableInstr* kStrengthenedAssertMarker =
530 reinterpret_cast<AssertAssignableInstr*
>(-1);
532 Definition* defn =
check->InputAt(0)->definition()->OriginalDefinition();
534 AssertAssignableInstr* assert = (*asserts_)[defn->ssa_temp_index()];
535 if ((assert ==
nullptr) || (assert == kStrengthenedAssertMarker)) {
538 ASSERT(assert->env() !=
nullptr);
540 Instruction* check_clone =
nullptr;
541 if (
check->IsCheckSmi()) {
542 check_clone =
new CheckSmiInstr(assert->value()->Copy(zone()),
543 assert->deopt_id(),
check->source());
547 new CheckClassInstr(assert->value()->Copy(zone()), assert->deopt_id(),
548 check->AsCheckClass()->cids(),
check->source());
550 ASSERT(check_clone !=
nullptr);
551 check_clone->InsertBefore(assert);
552 assert->env()->DeepCopyTo(zone(), check_clone);
554 (*asserts_)[defn->ssa_temp_index()] = kStrengthenedAssertMarker;
567 can_be_null_ = can_be_null_ || other->can_be_null_;
568 can_be_sentinel_ = can_be_sentinel_ || other->can_be_sentinel_;
571 if ((cid_ ==
kNullCid) || (cid_ == kSentinelCid)) {
573 type_ = other->type_;
578 if ((other->cid_ ==
kNullCid) || (other->cid_ == kSentinelCid)) {
583 if (cid_ != other->cid_) {
589 type_ = other_abstract_type;
598 !abstract_type->IsFunctionType() && !abstract_type->IsRecordType()) {
611 type_ = &Object::dynamic_type();
616 ASSERT(new_type !=
nullptr);
623 if (old_type ==
nullptr || old_type->
IsNone()) {
633 const intptr_t new_type_cid = new_type->
ToCid();
634 const intptr_t old_type_cid = old_type->
ToCid();
635 if (new_type_cid != old_type_cid) {
637 preferred_type = new_type;
639 preferred_type = old_type;
643 if (preferred_type ==
nullptr) {
649 preferred_type = old_type;
651 preferred_type = new_type;
654 preferred_type = old_type;
658 preferred_type = new_type;
667 if ((preferred_type->
is_nullable() && !can_be_null) ||
670 preferred_type->type_);
674 return preferred_type;
680 bool can_be_sentinel) {
710 ASSERT(rep != kNoRepresentation);
716 &Object::dynamic_type());
721 &Object::dynamic_type());
740#if defined(HAS_SMI_63_BITS)
787 if ((type_ !=
nullptr) && type_->
IsNullType()) {
797 (can_be_sentinel_ && (cid_ != kSentinelCid))) {
806 if (type_ ==
nullptr) {
823 &implementation_cid)) {
824 cid_ = implementation_cid;
833 if (can_be_sentinel_ && (cid_ != kSentinelCid)) {
841 return !can_be_null_ ||
IsNull();
849 if (type_ ==
nullptr) {
852 return &Object::dynamic_type();
858 type_ = &Object::dynamic_type();
924 class_ids->
Add(cid_);
933 if (can_be_sentinel_) {
934 class_ids->
Add(kSentinelCid);
947 if (
type.IsInstantiated()) {
949 }
else if (
type.IsTypeParameter()) {
951 const auto& param = TypeParameter::Cast(
type);
954 }
else if (
type.HasTypeClass()) {
964 if (
type.IsFutureOrType() ||
978 return cid_ == kSmiCid;
997 if (
type.IsTypeParameter()) {
998 type = TypeParameter::Cast(
type).bound();
1000 if (
type.IsTypeParameter()) {
1004 const intptr_t type_class_id =
type.type_class_id();
1006 type_class_id == kInstanceCid || type_class_id == kFutureOrCid) {
1037 if (can_be_sentinel_) {
1043 const char* type_name =
"?";
1045 f->AddString(
"T{}");
1051 }
else if (type_ !=
nullptr) {
1054 type_name =
"!null";
1057 f->Printf(
"T{%s%s%s}", type_name, can_be_null_ ?
"?" :
"",
1058 can_be_sentinel_ ?
"~" :
"");
1069 if (reaching_type_ ==
nullptr) {
1072 return reaching_type_;
1082 if (
type !=
nullptr &&
type->owner() !=
nullptr &&
1086 reaching_type_ =
type;
1101 for (intptr_t i = 0; i <
InputCount(); i++) {
1103 THR_Print(
" phi %" Pd " input %" Pd ": v%" Pd " has reaching type %s\n",
1119 if (constrained_type_ !=
nullptr) {
1125 const bool is_nullable =
1129 constrained_type_->can_be_sentinel();
1134 value()->
Type()->ToNullableCid(),
nullptr);
1136 if (constrained_type_->ToNullableCid() !=
kDynamicCid) {
1138 constrained_type_->ToNullableCid(),
nullptr);
1142 value()->
Type()->IsSubtypeOf(*constrained_type_->ToAbstractType())
1144 : *constrained_type_);
1148 if (!can_be_sentinel) {
1162 if (
type->is_nullable()) {
1203 if (graph_entry ==
nullptr) {
1204 if (
auto function_entry = block_->AsFunctionEntry()) {
1205 graph_entry = function_entry->graph_entry();
1206 }
else if (
auto osr_entry = block_->AsOsrEntry()) {
1207 graph_entry = osr_entry->graph_entry();
1208 }
else if (
auto catch_entry = block_->AsCatchBlockEntry()) {
1209 graph_entry = catch_entry->graph_entry();
1226 if (
function.IsIrregexpFunction()) {
1230 switch (env_index()) {
1245 if (param_index >= 0) {
1250 if (
type.IsObjectType() ||
type.IsNullType()) {
1265 cid = type_class.
id();
1267 if (FLAG_use_cha_deopt ||
1269 if (FLAG_trace_cha) {
1271 " **(CHA) Computing exact type of receiver, "
1272 "no subclasses: %s\n",
1275 if (FLAG_use_cha_deopt) {
1281 cid = type_class.
id();
1291 const bool is_unchecked_entry_param =
1297 ASSERT(param !=
nullptr);
1301 bool inferred_nullable =
true;
1302 if (!block_->IsCatchBlockEntry()) {
1305 if (inferred_type !=
nullptr) {
1309 return *inferred_type;
1321 if ((
function.name() != Symbols::EqualOperator().ptr()) &&
1323 (is_unchecked_entry_param &&
1328 block_->IsCatchBlockEntry() && param->
is_late(),
1335 if (inferred_type !=
nullptr) {
1337 return *inferred_type;
1341 if (block_->IsCatchBlockEntry()) {
1362 if ((
cid != kTypeArgumentsCid) &&
value().IsInstance()) {
1377 const AbstractType* abs_type = &AbstractType::dynamic_type();
1378 if (
dst_type()->BindsToConstant() &&
1379 dst_type()->BoundConstant().IsAbstractType()) {
1380 abs_type = &AbstractType::Cast(
dst_type()->BoundConstant());
1437 kContextCid, &Object::dynamic_type());
1442 kContextCid, &Object::dynamic_type());
1447 kContextCid, &Object::dynamic_type());
1456 if (inferred_type !=
nullptr) {
1459 return *inferred_type;
1479 case Token::kNEGATE:
1507 if (inferred_type !=
nullptr) {
1509 return *inferred_type;
1520 if (result_type.IsInstantiated()) {
1533 if (
target.has_pragma()) {
1544 return is_nullable ?
type :
type.CopyNonNullable();
1548 Value* type_args_value) {
1549 ASSERT(inferred_type !=
nullptr);
1552 if ((
cid == kGrowableObjectArrayCid ||
cid == kArrayCid ||
1553 cid == kImmutableArrayCid) &&
1563 type_args = type_args.FromInstanceTypeArguments(thread, cls);
1568 type.SetIsFinalized();
1572 return *inferred_type;
1585 if (inferred_type !=
nullptr) {
1588 return *inferred_type;
1594 if (function_.has_pragma()) {
1615 if (
local().needs_covariant_check_in_method()) {
1644 bool is_nullable =
true;
1650 is_nullable =
false;
1657 is_nullable =
false;
1659 abstract_type =
nullptr;
1670 return CompileType(is_nullable, can_be_sentinel,
cid, abstract_type);
1689 if (!func.IsNull()) {
1710 if (
slot().IsRecordField()) {
1711 const intptr_t index = compiler::target::Record::field_index_at_offset(
1712 slot().offset_in_bytes());
1713 if (
auto* alloc =
instance()->definition()->AsAllocateSmallRecord()) {
1714 if (index < alloc->num_fields()) {
1715 return *(alloc->InputAt(index)->Type());
1719 if (instance_type->IsRecordType()) {
1720 const auto& record_type = RecordType::Cast(*instance_type);
1721 if (index < record_type.NumFields()) {
1722 const auto& field_type =
1740 case kOneByteStringCid:
1741 case kTwoByteStringCid:
1784#define kInt8Cid kSmiCid
1785#define CASE(Arity, Mask, Name, Args, Result) k##Result##Cid,
1811 case kUnboxedDouble:
1831 if (array_type.IsTypeParameter()) {
1835 if (!array_type.IsType()) {
1836 return Object::dynamic_type().ptr();
1838 const intptr_t
cid = array_type.type_class_id();
1839 if (
cid == kGrowableObjectArrayCid ||
cid == kArrayCid ||
1840 cid == kImmutableArrayCid ||
1841 array_type.type_class() ==
1843 const auto& type_args =
1847 return Object::dynamic_type().ptr();
1857 if (!elem_type.IsDynamicType()) {
1858 return elem_type.ptr();
1867 if (!elem_type.IsDynamicType()) {
1874 if (
auto* load_field = array->
definition()->AsLoadField()) {
1875 if (load_field->slot().IsIdentical(Slot::GrowableObjectArray_data())) {
1876 array = load_field->instance();
1878 if (!elem_type.IsDynamicType()) {
1888 if (
auto* load_field = array->
definition()->AsLoadField()) {
1889 if (load_field->slot().IsDartField()) {
1890 elem_type = load_field->slot().field().type();
1910 case kImmutableArrayCid: {
1912 if (result_type_ !=
nullptr &&
1920 case kTypeArgumentsCid:
1935 if ((class_id_ == kArrayCid) || (class_id_ == kImmutableArrayCid)) {
static float prev(float f)
#define check(reporter, ref, unref, make, kill)
static bool left(const SkPoint &p0, const SkPoint &p1)
#define DEBUG_ASSERT(cond)
bool IsSubtypeOf(const AbstractType &other, Heap::Space space, FunctionTypeMapping *function_type_equivalence=nullptr) const
virtual classid_t type_class_id() const
bool IsDartFunctionType() const
bool IsTopTypeForSubtyping() const
bool IsDartRecordType() const
const char * ScrubbedNameCString() const
bool IsObjectType() const
bool IsTopTypeForInstanceOf() const
virtual bool IsInstantiated(Genericity genericity=kAny, intptr_t num_free_fun_type_params=kAllFree) const
StringPtr ScrubbedName() const
virtual ClassPtr type_class() const
bool IsDynamicType() const
bool IsSentinelType() const
bool IsStrictlyNonNullable() const
virtual CompileType ComputeType() const
const Function & known_function() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
const Class & cls() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
classid_t class_id() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
static constexpr intptr_t kElementTypeTypeArgPos
virtual CompileType ComputeType() const
virtual bool RecomputeType()
virtual CompileType ComputeType() const
void TruncateTo(intptr_t length)
virtual CompileType ComputeType() const
bool Contains(intptr_t i) const
static const Bool & False()
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
Representation from_representation() const
virtual CompileType ComputeType() const
virtual bool RecomputeType()
virtual bool ValueFitsSmi() const
virtual CompileType ComputeType() const
Representation from_representation() const
TargetEntryInstr * false_successor() const
TargetEntryInstr * true_successor() const
ComparisonInstr * comparison() const
static bool HasSubclasses(const Class &cls)
void AddToGuardedClassesForSubclassCount(const Class &cls, intptr_t subclass_count)
static bool ConcreteSubclasses(const Class &cls, GrowableArray< intptr_t > *class_ids)
static bool ClassCanBeFuture(const Class &cls)
static bool HasSingleConcreteImplementation(const Class &interface, intptr_t *implementation_cid)
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual bool RecomputeType()
virtual bool RecomputeType()
virtual CompileType ComputeType() const
intptr_t MonomorphicReceiverCid() const
CidRange * At(int index) const
bool IsMonomorphic() const
ClassPtr At(intptr_t cid) const
const char * ScrubbedNameCString() const
StringPtr ScrubbedName() const
intptr_t NumTypeArguments() const
bool is_future_subtype() const
ClassPtr SuperClass(ClassTable *class_table=nullptr) const
virtual CompileType ComputeType() const
static CompileType * ComputeRefinedType(CompileType *old_type, CompileType *new_type)
void Union(CompileType *other)
bool IsAssignableTo(const AbstractType &other)
static constexpr bool kCanBeSentinel
CompileType CopyNonNullable()
static CompileType FromCid(intptr_t cid)
static constexpr bool kCannotBeSentinel
bool can_be_sentinel() const
bool IsInstanceOf(const AbstractType &other)
static CompileType DynamicOrSentinel()
static constexpr bool kCannotBeNull
static constexpr bool kCanBeNull
bool IsSubtypeOf(const AbstractType &other)
static CompileType Dynamic()
bool Specialize(GrowableArray< intptr_t > *class_ids)
static CompileType String()
static CompileType Null()
static CompileType NullableDouble()
static CompileType Object()
static CompileType FromRepresentation(Representation rep)
static CompileType Int32()
CompileType CopyNonSentinel()
static CompileType FromAbstractType(const AbstractType &type, bool can_be_null, bool can_be_sentinel)
static CompileType NullableInt()
const char * ToCString() const
void PrintTo(BaseTextBuffer *f) const
static CompileType Bool()
bool HasDecidableNullability()
static CompileType None()
const AbstractType * ToAbstractType()
static CompileType FromUnboxedRepresentation(Representation rep)
static CompileType Double()
const Class & ComparableClass()
static CompilerState & Current()
virtual CompileType ComputeType() const
const Object & value() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
Value * type_arguments() const
PRINT_OPERANDS_TO_SUPPORT PRINT_TO_SUPPORT bool UpdateType(CompileType new_type)
intptr_t ssa_temp_index() const
virtual CompileType ComputeType() const
const Function & interface_target() const
virtual PRINT_OPERANDS_TO_SUPPORT CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
bool has_initializer() const
bool needs_load_guard() const
intptr_t guarded_cid() const
AbstractTypePtr type() const
virtual void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr *instr)
virtual void VisitAssertBoolean(AssertBooleanInstr *instr)
virtual void VisitCheckClassId(CheckClassIdInstr *instr)
virtual void VisitCheckNull(CheckNullInstr *instr)
virtual void VisitCheckSmi(CheckSmiInstr *instr)
static void Propagate(FlowGraph *flow_graph)
virtual void VisitAssertSubtype(AssertSubtypeInstr *instr)
virtual void VisitAssertAssignable(AssertAssignableInstr *instr)
virtual void VisitJoinEntry(JoinEntryInstr *instr)
virtual void VisitGuardFieldClass(GuardFieldClassInstr *instr)
virtual void VisitInstanceCall(InstanceCallInstr *instr)
virtual void VisitCheckArrayBound(CheckArrayBoundInstr *instr)
virtual void VisitBranch(BranchInstr *instr)
virtual void VisitCheckClass(CheckClassInstr *instr)
GraphEntryInstr * graph_entry() const
bool should_print() const
intptr_t current_ssa_temp_index() const
RedefinitionInstr * EnsureRedefinition(Instruction *prev, Definition *original, CompileType compile_type)
void AllocateSSAIndex(Definition *def)
static void RenameDominatedUses(Definition *def, Instruction *dom, Definition *other)
virtual bool RecomputeType()
virtual CompileType ComputeType() const
bool IsCompiledForOsr() const
FunctionEntryInstr * unchecked_entry() const
const ParsedFunction & parsed_function() const
const Field & field() const
intptr_t GetReceiverClassIdAt(intptr_t index) const
virtual CompileType ComputeType() const
CompileType * result_type() const
const ICData * ic_data() const
const Function & interface_target() const
Token::Kind token_kind() const
virtual CompileType ComputeType() const
const String & function_name() const
bool has_unique_selector() const
const AbstractType & type() const
virtual CompileType ComputeType() const
static bool NullIsAssignableTo(const AbstractType &other)
const char * ToCString() const
Value * ArgumentValueAt(intptr_t index) const
virtual CompileType ComputeType() const
bool all_classes_finalized() const
ObjectStore * object_store() const
static IsolateGroup * Current()
ClassTable * class_table() const
bool PrintPropertyStr(const char *name, const String &s, intptr_t offset=0, intptr_t count=-1)
void PrintPropertyBool(const char *name, bool b)
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
bool can_pack_into_smi() const
intptr_t class_id() const
const Slot & slot() const
virtual CompileType ComputeType() const
intptr_t class_id() const
virtual bool RecomputeType()
virtual CompileType ComputeType() const
const LocalVariable & local() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
const Field & field() const
CompileType * inferred_type() const
const AbstractType & static_type() const
bool was_type_checked_by_caller() const
CompileType * inferred_arg_type() const
bool is_explicit_covariant_parameter() const
virtual CompileType ComputeType() const
static intptr_t ResultCidFromPragma(const Object &function_or_field)
static bool HasNonNullableResultTypeFromPragma(const Object &function_or_field)
intptr_t GetClassId() const
virtual const char * ToCString() const
static Object & ZoneHandle()
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
intptr_t param_index() const
const Function & function() const
LocalScope * scope() const
LocalVariable * ParameterVariable(intptr_t i) const
LocalVariable * RawParameterVariable(intptr_t i) const
virtual bool RecomputeType()
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
bool IsSureToCallSingleRecognizedTarget() const
const CallTargets & targets() const
virtual bool RecomputeType()
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
static FunctionPtr ResolveDynamicAnyArgs(Zone *zone, const Class &receiver_class, const String &function_name, bool allow_add=true)
virtual CompileType ComputeType() const
CompileType * result_type() const
const Function & function() const
bool is_known_list_constructor() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual Value * InputAt(intptr_t i) const
intptr_t ArgumentCount() const
bool calls_initializer() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
static Thread * Current()
CompilerState & compiler_state()
IsolateGroup * isolate_group() const
static TypePtr BoolType()
static TypePtr New(const Class &clazz, const TypeArguments &arguments, Nullability nullability=Nullability::kLegacy, Heap::Space space=Heap::kOld)
static TypePtr NullableDouble()
static TypePtr ObjectType()
static TypePtr NullableIntType()
static TypePtr StringType()
static TypePtr MintType()
static TypePtr NullType()
virtual CompileType ComputeType() const
virtual CompileType ComputeType() const
bool BindsToConstant() const
void SetReachingType(CompileType *type)
const Object & BoundConstant() const
Definition * definition() const
void RefineReachingType(CompileType *type)
intptr_t InputCount() const
Value * InputAt(intptr_t i) const
char * MakeCopyOfString(const char *str)
#define THR_Print(format,...)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
static const uint8_t buffer[]
constexpr bool FLAG_support_il_printer
#define DEFINE_FLAG(type, name, default_value, comment)
Dart_NativeFunction function
#define CASE(Arity, Mask, Name, Args, Result)
#define SIMD_OP_LIST(M, BINARY_OP)
static CompileType ComputeListFactoryType(CompileType *inferred_type, Value *type_args_value)
DART_EXPORT bool IsNull(Dart_Handle object)
static const intptr_t simd_op_result_cids[]
static AbstractTypePtr GetElementTypeFromArray(Value *array)
static AbstractTypePtr ExtractElementTypeFromArrayType(const AbstractType &array_type)
static CompileType ComputeArrayElementType(Value *array)
static bool CanPotentiallyBeSmi(const AbstractType &type, bool recurse)
static Dart_TypedData_Type GetType(intptr_t class_id)
bool IsInternalOnlyClassId(intptr_t index)
const char *const function_name
static void TraceStrongModeType(const Instruction *instr, const AbstractType &type)
SINT Vec< 2 *N, T > join(const Vec< N, T > &lo, const Vec< N, T > &hi)
static bool RequiresAllocation(Representation rep)
static intptr_t BoxCid(Representation rep)
bool IsIllegalRange() const
static constexpr bool IsUnboxedInteger(Representation rep)
static constexpr bool IsUnboxed(Representation rep)
static Representation RepresentationOfArrayElement(classid_t cid)
#define TIMELINE_DURATION(thread, stream, name)