5#ifndef RUNTIME_VM_COMPILER_BACKEND_IL_H_
6#define RUNTIME_VM_COMPILER_BACKEND_IL_H_
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
46class BlockEntryWithInitialDefs;
49class CatchBlockEntryInstr;
50class CheckBoundBaseInstr;
55class FlowGraphCompiler;
56class FlowGraphVisitor;
57class ForwardInstructionIterator;
59class InstructionVisitor;
68class UnboxIntegerInstr;
83 bool Done()
const {
return current_ ==
nullptr; }
87 if (next_ !=
nullptr) next_ = next_->
next_use();
97 previous_use_(nullptr),
99 instruction_(nullptr),
101 reaching_type_(nullptr) {}
118 return (next_use_ ==
nullptr) && (previous_use_ ==
nullptr);
140 copy->reaching_type_ = reaching_type_;
151#if defined(INCLUDE_IL_PRINTER)
190 Value* previous_use_;
203 CidRange(intptr_t cid_start_arg, intptr_t cid_end_arg)
259 if (range.Contains(
cid)) {
271 cid_subtype_ranges_nullable_(),
272 cid_subtype_ranges_abstract_nullable_(),
273 cid_subtype_ranges_nonnullable_(),
274 cid_subtype_ranges_abstract_nonnullable_() {
285 bool include_abstract,
289 intptr_t* lower_limit,
290 intptr_t* upper_limit);
324 bool include_abstract,
337 bool include_abstract,
340 std::unique_ptr<CidRangeVector[]> cid_subtype_ranges_nullable_;
341 std::unique_ptr<CidRangeVector[]> cid_subtype_ranges_abstract_nullable_;
342 std::unique_ptr<CidRangeVector[]> cid_subtype_ranges_nonnullable_;
343 std::unique_ptr<CidRangeVector[]> cid_subtype_ranges_abstract_nonnullable_;
348template <
typename T,
intptr_t N>
365 const T&
At(intptr_t i)
const {
return (*
this)[i]; }
367 void SetAt(intptr_t i,
const T& val) { (*this)[i] = val; }
379 static T sentinel =
nullptr;
384 static T sentinel =
nullptr;
405#define FOR_EACH_INSTRUCTION(M) \
406 M(GraphEntry, kNoGC) \
407 M(JoinEntry, kNoGC) \
408 M(TargetEntry, kNoGC) \
409 M(FunctionEntry, kNoGC) \
410 M(NativeEntry, kNoGC) \
412 M(IndirectEntry, kNoGC) \
413 M(CatchBlockEntry, kNoGC) \
415 M(Redefinition, kNoGC) \
416 M(ReachabilityFence, kNoGC) \
417 M(Parameter, kNoGC) \
418 M(NativeParameter, kNoGC) \
419 M(LoadIndexedUnsafe, kNoGC) \
420 M(StoreIndexedUnsafe, kNoGC) \
421 M(MemoryCopy, kNoGC) \
423 M(ParallelMove, kNoGC) \
424 M(MoveArgument, kNoGC) \
425 M(DartReturn, kNoGC) \
426 M(NativeReturn, kNoGC) \
431 M(IndirectGoto, kNoGC) \
433 M(AssertAssignable, _) \
434 M(AssertSubtype, _) \
435 M(AssertBoolean, _) \
438 M(LeafRuntimeCall, kNoGC) \
440 M(PolymorphicInstanceCall, _) \
441 M(DispatchTableCall, _) \
443 M(CachableIdempotentCall, _) \
444 M(LoadLocal, kNoGC) \
445 M(DropTemps, kNoGC) \
447 M(StoreLocal, kNoGC) \
448 M(StrictCompare, kNoGC) \
449 M(EqualityCompare, kNoGC) \
450 M(RelationalOp, kNoGC) \
452 M(DebugStepCheck, _) \
453 M(RecordCoverage, kNoGC) \
454 M(LoadIndexed, kNoGC) \
455 M(LoadCodeUnits, _) \
456 M(StoreIndexed, kNoGC) \
458 M(LoadStaticField, _) \
459 M(StoreStaticField, kNoGC) \
460 M(BooleanNegate, kNoGC) \
461 M(BoolToInt, kNoGC) \
462 M(IntToBool, kNoGC) \
465 M(AllocateObject, _) \
466 M(AllocateClosure, _) \
467 M(AllocateRecord, _) \
468 M(AllocateSmallRecord, _) \
469 M(AllocateTypedData, _) \
471 M(LoadUntagged, kNoGC) \
472 M(CalculateElementAddress, kNoGC) \
473 M(LoadClassId, kNoGC) \
474 M(InstantiateType, _) \
475 M(InstantiateTypeArguments, _) \
476 M(AllocateContext, _) \
477 M(AllocateUninitializedContext, _) \
479 M(BinarySmiOp, kNoGC) \
480 M(BinaryInt32Op, kNoGC) \
481 M(HashDoubleOp, kNoGC) \
482 M(HashIntegerOp, kNoGC) \
483 M(UnarySmiOp, kNoGC) \
484 M(UnaryDoubleOp, kNoGC) \
485 M(CheckStackOverflow, _) \
486 M(SmiToDouble, kNoGC) \
487 M(Int32ToDouble, kNoGC) \
488 M(Int64ToDouble, kNoGC) \
489 M(DoubleToInteger, _) \
490 M(DoubleToSmi, kNoGC) \
491 M(DoubleToFloat, kNoGC) \
492 M(FloatToDouble, kNoGC) \
493 M(FloatCompare, kNoGC) \
494 M(CheckClass, kNoGC) \
495 M(CheckClassId, kNoGC) \
497 M(CheckNull, kNoGC) \
498 M(CheckCondition, kNoGC) \
500 M(UnboxedConstant, kNoGC) \
501 M(CheckEitherNonSmi, kNoGC) \
502 M(BinaryDoubleOp, kNoGC) \
503 M(DoubleTestOp, kNoGC) \
504 M(MathMinMax, kNoGC) \
508 M(UnboxInt64, kNoGC) \
509 M(CaseInsensitiveCompare, kNoGC) \
510 M(BinaryInt64Op, kNoGC) \
511 M(ShiftInt64Op, kNoGC) \
512 M(SpeculativeShiftInt64Op, kNoGC) \
513 M(UnaryInt64Op, kNoGC) \
514 M(CheckArrayBound, kNoGC) \
515 M(GenericCheckBound, kNoGC) \
516 M(CheckWritable, kNoGC) \
517 M(Constraint, kNoGC) \
518 M(StringToCharCode, kNoGC) \
519 M(OneByteStringFromCharCode, kNoGC) \
521 M(InvokeMathCFunction, kNoGC) \
522 M(TruncDivMod, kNoGC) \
524 M(GuardFieldClass, _) \
525 M(GuardFieldLength, _) \
526 M(GuardFieldType, _) \
527 M(IfThenElse, kNoGC) \
528 M(MaterializeObject, _) \
531 M(TestRange, kNoGC) \
532 M(ExtractNthOutput, kNoGC) \
534 M(UnboxLane, kNoGC) \
536 M(BinaryUint32Op, kNoGC) \
537 M(ShiftUint32Op, kNoGC) \
538 M(SpeculativeShiftUint32Op, kNoGC) \
539 M(UnaryUint32Op, kNoGC) \
541 M(UnboxUint32, kNoGC) \
543 M(UnboxInt32, kNoGC) \
544 M(BoxSmallInt, kNoGC) \
545 M(IntConverter, kNoGC) \
548 M(LoadThread, kNoGC) \
549 M(Deoptimize, kNoGC) \
553#define FOR_EACH_ABSTRACT_INSTRUCTION(M) \
555 M(ArrayAllocation, _) \
556 M(BinaryIntegerOp, _) \
559 M(CheckBoundBase, _) \
561 M(InstanceCallBase, _) \
563 M(ShiftIntegerOp, _) \
564 M(UnaryIntegerOp, _) \
567#define FORWARD_DECLARATION(type, attrs) class type##Instr;
570#undef FORWARD_DECLARATION
572#define DEFINE_INSTRUCTION_TYPE_CHECK(type) \
573 virtual type##Instr* As##type() { \
576 virtual const type##Instr* As##type() const { \
579 virtual const char* DebugName() const { \
584#define DECLARE_INSTRUCTION_NO_BACKEND(type) \
585 virtual Tag tag() const { \
588 virtual void Accept(InstructionVisitor* visitor); \
589 DEFINE_INSTRUCTION_TYPE_CHECK(type)
591#define DECLARE_INSTRUCTION_BACKEND() \
592 virtual LocationSummary* MakeLocationSummary(Zone* zone, bool optimizing) \
594 virtual void EmitNativeCode(FlowGraphCompiler* compiler);
597#define DECLARE_INSTRUCTION(type) \
598 DECLARE_INSTRUCTION_NO_BACKEND(type) \
599 DECLARE_INSTRUCTION_BACKEND()
602#define DECLARE_ABSTRACT_INSTRUCTION(type) \
605 virtual Tag tag() const = 0; \
606 DEFINE_INSTRUCTION_TYPE_CHECK(type)
608#define DECLARE_COMPARISON_METHODS \
609 virtual LocationSummary* MakeLocationSummary(Zone* zone, bool optimizing) \
611 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, \
612 BranchLabels labels);
614#define DECLARE_COMPARISON_INSTRUCTION(type) \
615 DECLARE_INSTRUCTION_NO_BACKEND(type) \
616 DECLARE_COMPARISON_METHODS
618template <
typename T,
bool is_enum>
623 using type = std::underlying_type_t<T>;
635#define WRITE_INSTRUCTION_FIELD(type, name) \
636 s->Write<serializable_type_t<type>>( \
637 static_cast<serializable_type_t<type>>(name));
638#define READ_INSTRUCTION_FIELD(type, name) \
639 , name(static_cast<std::remove_cv_t<type>>( \
640 d->Read<serializable_type_t<type>>()))
641#define DECLARE_INSTRUCTION_FIELD(type, name) type name;
649#define DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(Instr, BaseClass, FieldList) \
651 virtual void WriteTo(FlowGraphSerializer* s) { \
652 BaseClass::WriteTo(s); \
653 FieldList(WRITE_INSTRUCTION_FIELD) \
655 explicit Instr(FlowGraphDeserializer* d) \
656 : BaseClass(d) FieldList(READ_INSTRUCTION_FIELD) {} \
659 FieldList(DECLARE_INSTRUCTION_FIELD)
661#define DECLARE_CUSTOM_SERIALIZATION(Instr) \
663 virtual void WriteTo(FlowGraphSerializer* s); \
664 explicit Instr(FlowGraphDeserializer* d);
666#define DECLARE_EMPTY_SERIALIZATION(Instr, BaseClass) \
668 explicit Instr(FlowGraphDeserializer* d) : BaseClass(d) {}
670#define DECLARE_EXTRA_SERIALIZATION \
672 virtual void WriteExtra(FlowGraphSerializer* s); \
673 virtual void ReadExtra(FlowGraphDeserializer* d);
675#if defined(INCLUDE_IL_PRINTER)
676#define PRINT_TO_SUPPORT virtual void PrintTo(BaseTextBuffer* f) const;
677#define PRINT_OPERANDS_TO_SUPPORT \
678 virtual void PrintOperandsTo(BaseTextBuffer* f) const;
682#define DECLARE_ATTRIBUTE(Attribute) \
683 auto GetAttributes() const { \
684 return std::make_tuple(Attribute); \
686 static auto GetAttributeNames() { \
687 return std::make_tuple(#Attribute); \
691#define DECLARE_ATTRIBUTES_NAMED(names, values) \
692 auto GetAttributes() const { \
693 return std::make_tuple values; \
695 static auto GetAttributeNames() { \
696 return std::make_tuple names; \
699#define PRINT_TO_SUPPORT
700#define PRINT_OPERANDS_TO_SUPPORT
701#define DECLARE_ATTRIBUTE(Attribute)
702#define DECLARE_ATTRIBUTES_NAMED(names, values)
711 intptr_t cid_end_arg,
715 :
CidRange(cid_start_arg, cid_end_arg),
739 int argument_number);
779 intptr_t receiver_cid,
809 for (intptr_t i = 0, n =
cid_ranges_.length(); i < n; i++) {
812 if (j != kSmiCid && j != kMintCid) {
824 void CreateHelper(
Zone* zone,
const ICData& ic_data);
825 void MergeIntoRanges();
836 intptr_t receiver_cid,
837 intptr_t argument_cid);
843 for (intptr_t i = 0, n = feedback_.
length(); i < n; i++) {
844 if (feedback_[i].second !=
cid) {
855 for (intptr_t i = 0, n = feedback_.
length(); i < n; i++) {
856 if ((feedback_[i].first != cid_a) && (feedback_[i].first != cid_b)) {
859 if ((feedback_[i].second != cid_a) && (feedback_[i].second != cid_b)) {
876 if (feedback_.
length() != 1)
return false;
877 return (feedback_[0].first ==
cid) && (feedback_[0].second ==
cid);
881 for (intptr_t i = 0, n = feedback_.
length(); i < n; i++) {
882 if ((feedback_[i].first ==
cid) && (feedback_[i].second ==
cid)) {
898template <
typename Trait>
958#define DECLARE_TAG(type, attrs) k##type,
997 bool is_static_call);
1010 value->set_instruction(
this);
1011 value->set_use_index(i);
1074 return env() !=
nullptr &&
1091 ASSERT(!IsBranch() || (instr ==
nullptr));
1093 ASSERT(instr ==
nullptr || !instr->IsBlockEntry());
1155#define DECLARE_INSTRUCTION_TYPE_CHECK(Name, Type) \
1156 bool Is##Name() const { return (As##Name() != nullptr); } \
1157 Type* As##Name() { \
1158 auto const_this = static_cast<const Instruction*>(this); \
1159 return const_cast<Type*>(const_this->As##Name()); \
1161 virtual const Type* As##Name() const { return nullptr; }
1162#define INSTRUCTION_TYPE_CHECK(Name, Attrs) \
1163 DECLARE_INSTRUCTION_TYPE_CHECK(Name, Name##Instr)
1171#undef INSTRUCTION_TYPE_CHECK
1172#undef DECLARE_INSTRUCTION_TYPE_CHECK
1174 template <
typename T>
1176 return static_cast<T*
>(
this);
1179 template <
typename T>
1181 return static_cast<const T*
>(
this);
1187 ASSERT(locs_ !=
nullptr);
1194 bool is_optimizing)
const = 0;
1197 ASSERT(locs_ ==
nullptr);
1219 return (PassSpecificId::DecodePass(pass_specific_id_) == pass)
1220 ? PassSpecificId::DecodeId(pass_specific_id_)
1221 : PassSpecificId::kNoId;
1224 pass_specific_id_ = PassSpecificId::Encode(pass,
id);
1227 return (PassSpecificId::DecodePass(pass_specific_id_) == pass) &&
1228 (PassSpecificId::DecodeId(pass_specific_id_) !=
1229 PassSpecificId::kNoId);
1240 for (intptr_t i = 0; i <
InputCount(); i++) {
1309 inlining_id_ =
value;
1363#if defined(TARGET_ARCH_IA32)
1366 return FLAG_enable_slow_path_sharing && FLAG_precompiled_mode &&
1380 if ((rep == kUnboxedFloat) || (rep == kUnboxedDouble) ||
1381 (rep == kUnboxedFloat32x4) || (rep == kUnboxedInt32x4) ||
1382 (rep == kUnboxedFloat64x2)) {
1406 deopt_id_ = instr.deopt_id_;
1422 class PassSpecificId {
1425 return (
id << kPassBits) | pass;
1432 static intptr_t DecodeId(intptr_t
value) {
return (
value >> kPassBits); }
1434 static constexpr intptr_t kNoId = -1;
1437 static constexpr intptr_t kPassBits = 8;
1439 "Pass Id does not fit into the bit field");
1443 intptr_t pass_specific_id_ = PassSpecificId::kNoId;
1448 intptr_t inlining_id_;
1483template <
typename DefaultBase,
typename PureBase>
1488template <
typename DefaultBase,
typename PureBase>
1493template <intptr_t
N,
1494 typename ThrowsTrait,
1495 template <
typename Default,
typename Pure>
class CSETrait =
NoCSE>
1497 :
public CSETrait<Instruction, PureInstruction>::Base {
1499 using BaseClass =
typename CSETrait<Instruction, PureInstruction>::Base;
1511 virtual bool MayThrow()
const {
return ThrowsTrait::kCanThrow; }
1529 dest_ = other.dest_;
1616 return TokenPosition::kParallelMove;
1620 ASSERT(move_schedule_ !=
nullptr);
1621 return *move_schedule_;
1625 move_schedule_ = &schedule;
1668 return dominated_blocks_;
1672 ASSERT(!block->IsFunctionEntry() || this->IsGraphEntry());
1673 block->set_dominator(
this);
1674 dominated_blocks_.Add(block);
1692 if (parallel_move_ ==
nullptr) {
1695 return parallel_move_;
1739 return TokenPosition::kControlFlow;
1784 dominated_blocks_(1) {}
1799 intptr_t try_index_;
1800 intptr_t preorder_number_ = -1;
1801 intptr_t postorder_number_ = -1;
1803 intptr_t stack_depth_;
1806 intptr_t start_pos_ = -1;
1807 intptr_t end_pos_ = -1;
1833 : current_(block_entry) {
1839 current_ = current_->
next();
1842 bool Done()
const {
return current_ ==
nullptr; }
1852 return current_ == other.current_;
1856 return !(*
this == other);
1880 : block_entry_(block_entry), current_(block_entry->last_instruction()) {
1881 ASSERT(block_entry_->previous() ==
nullptr);
1886 current_ = current_->previous();
1889 bool Done()
const {
return current_ == block_entry_; }
1891 void RemoveCurrentFromGraph();
1908 intptr_t stack_depth)
1912 return &initial_definitions_;
1915 return &initial_definitions_;
1943 virtual intptr_t PredecessorCount()
const {
return 0; }
1948 virtual intptr_t SuccessorCount()
const;
1956 indirect_entries_.Add(entry);
1961 void RelinkToOsrEntry(
Zone* zone, intptr_t max_block_id);
1962 bool IsCompiledForOsr()
const;
1971 spill_slot_count_ =
count;
1984 fixed_slot_count_ =
count;
1990 unchecked_entry_ =
target;
1998 return catch_entries_;
2002 return indirect_entries_;
2006 return catch_entries().is_empty() && unchecked_entry() ==
nullptr;
2028 const intptr_t osr_id_;
2029 intptr_t entry_count_;
2030 intptr_t spill_slot_count_;
2031 intptr_t fixed_slot_count_;
2032 bool needs_frame_ =
true;
2042 intptr_t stack_depth = 0)
2050 virtual intptr_t PredecessorCount()
const {
return predecessors_.length(); }
2052 return predecessors_[index];
2060 PhiInstr* InsertPhi(intptr_t var_index, intptr_t var_count);
2061 void RemoveDeadPhis(
Definition* replacement);
2070#define FIELD_LIST(F) F(ZoneGrowableArray<PhiInstr*>*, phis_)
2080 friend class BlockEntryInstr;
2107 return (phis_ ==
nullptr) || (index_ >= phis_->length());
2113 void RemoveCurrentFromGraph();
2125 intptr_t stack_depth = 0)
2127 edge_weight_(0.0) {}
2131 double edge_weight()
const {
return edge_weight_; }
2136 return (predecessor_ ==
nullptr) ? 0 : 1;
2139 ASSERT((index == 0) && (predecessor_ !=
nullptr));
2140 return predecessor_;
2145#define FIELD_LIST(F) F(double, edge_weight_)
2156 ASSERT(predecessor_ ==
nullptr);
2157 predecessor_ = predecessor;
2185 graph_entry_(graph_entry) {}
2189 virtual intptr_t PredecessorCount()
const {
2190 return (graph_entry_ ==
nullptr) ? 0 : 1;
2193 ASSERT(index == 0 && graph_entry_ !=
nullptr);
2194 return graph_entry_;
2205 ASSERT(graph_entry_ ==
nullptr && predecessor->IsGraphEntry());
2206 graph_entry_ = predecessor->AsGraphEntry();
2226 marshaller_(marshaller) {}
2232#define FIELD_LIST(F) F(const compiler::ffi::CallbackMarshaller&, marshaller_)
2254 intptr_t stack_depth)
2256 graph_entry_(graph_entry) {}
2260 virtual intptr_t PredecessorCount()
const {
2261 return (graph_entry_ ==
nullptr) ? 0 : 1;
2264 ASSERT(index == 0 && graph_entry_ !=
nullptr);
2265 return graph_entry_;
2276 ASSERT(graph_entry_ ==
nullptr && predecessor->IsGraphEntry());
2277 graph_entry_ = predecessor->AsGraphEntry();
2288 intptr_t indirect_id,
2292 indirect_id_(indirect_id) {}
2296 intptr_t indirect_id()
const {
return indirect_id_; }
2300#define FIELD_LIST(F) F(const intptr_t, indirect_id_)
2314 const Array& handler_types,
2315 intptr_t catch_try_index,
2316 bool needs_stacktrace,
2326 graph_entry_(graph_entry),
2327 predecessor_(nullptr),
2328 catch_handler_types_(
Array::ZoneHandle(handler_types.ptr())),
2329 catch_try_index_(catch_try_index),
2330 exception_var_(exception_var),
2331 stacktrace_var_(stacktrace_var),
2332 raw_exception_var_(raw_exception_var),
2333 raw_stacktrace_var_(raw_stacktrace_var),
2334 needs_stacktrace_(needs_stacktrace),
2335 is_generated_(is_generated) {}
2339 virtual intptr_t PredecessorCount()
const {
2340 return (predecessor_ ==
nullptr) ? 0 : 1;
2343 ASSERT((index == 0) && (predecessor_ !=
nullptr));
2344 return predecessor_;
2354 return raw_stacktrace_var_;
2375 ASSERT(predecessor_ ==
nullptr);
2376 predecessor_ = predecessor;
2381 const Array& catch_handler_types_;
2382 const intptr_t catch_try_index_;
2387 const bool needs_stacktrace_;
2413#define FOR_EACH_ALIAS_IDENTITY_VALUE(V) \
2417 V(AllocationSinkingCandidate, 3)
2421#define VALUE_CASE(name, val) \
2436 return value_ == kAllocationSinkingCandidate;
2443 value_ = other.value_;
2453#define VALUE_DEFN(name, val) k##name = val,
2458#undef FOR_EACH_ALIAS_IDENTITY_VALUE
2462 COMPILE_ASSERT((kAllocationSinkingCandidate & kNotAliased) != 0);
2474 intptr_t deopt_id = DeoptId::kNone)
2488 ssa_temp_index_ = index;
2493 intptr_t
vreg(intptr_t index)
const {
2494 ASSERT((index >= 0) && (index < location_count()));
2495 if (ssa_temp_index_ == -1)
return -1;
2496 return ssa_temp_index_ * kMaxLocationCount + index;
2504 if (type_ ==
nullptr) {
2506 type->set_owner(
this);
2512 bool HasType()
const {
return (type_ !=
nullptr); }
2514 inline bool IsInt64Definition();
2517 return IsBinaryInt32Op() || IsBoxInt32() || IsUnboxInt32() ||
2526 return CompileType::FromRepresentation(representation());
2536 if (type_ ==
nullptr) {
2538 type->set_owner(
this);
2543 if (type_->IsNone() || !type_->IsEqualTo(&new_type)) {
2552 return (input_use_list_ !=
nullptr) || (env_use_list_ !=
nullptr);
2554 bool HasOnlyUse(
Value* use)
const;
2555 bool HasOnlyInputUse(
Value* use)
const;
2576 return representation() == kUntagged;
2582 return !MayHaveVisibleEffect() && !CanDeoptimize();
2588 return CanReplaceWithConstant();
2614 Object& constant_value();
2619 void set_range(
const Range&);
2626 static constexpr intptr_t kReplacementMarker = -2;
2629 if (ssa_temp_index_ == kReplacementMarker) {
2630 return reinterpret_cast<Definition*
>(temp_index_);
2636 ASSERT(ssa_temp_index_ >= 0);
2638 ssa_temp_index_ = kReplacementMarker;
2639 temp_index_ =
reinterpret_cast<intptr_t
>(other);
2654 virtual Value* RedefinedValue()
const;
2660 Definition* OriginalDefinitionIgnoreBoxingAndConstraints();
2681#if defined(INCLUDE_IL_PRINTER)
2682 const char* TypeAsCString()
const {
2683 return HasType() ? type_->ToCString() :
"";
2688 intptr_t temp_index_ = -1;
2689 intptr_t ssa_temp_index_ = -1;
2690 Value* input_use_list_ =
nullptr;
2691 Value* env_use_list_ =
nullptr;
2693 Object* constant_value_ =
nullptr;
2694 CompileType* type_ =
nullptr;
2701 RemoveFromUseList();
2702 set_definition(def);
2707 RemoveFromUseList();
2708 set_definition(def);
2724template <intptr_t
N,
2725 typename ThrowsTrait,
2726 template <
typename Impure,
typename Pure>
class CSETrait = NoCSE>
2729 using BaseClass =
typename CSETrait<Definition, PureDefinition>::Base;
2734 intptr_t deopt_id = DeoptId::kNone)
2740 virtual bool MayThrow()
const {
return ThrowsTrait::kCanThrow; }
2756 intptr_t deopt_id = DeoptId::kNone)
2758 for (intptr_t i = 0, n = inputs_.length(); i < n; ++i) {
2759 SetInputAt(i, inputs_[i]);
2764 intptr_t deopt_id = DeoptId::kNone)
2766 for (intptr_t i = 0, n = inputs_.length(); i < n; ++i) {
2767 SetInputAt(i, inputs_[i]);
2771 intptr_t deopt_id = DeoptId::kNone)
2772 :
Definition(deopt_id), inputs_(num_inputs) {
2773 inputs_.EnsureLength(num_inputs,
nullptr);
2785 void RawSetInputAt(intptr_t i,
Value* value) { inputs_[i] =
value; }
2793 representation_(kTagged),
2795 is_receiver_(kUnknownReceiver) {}
2802 virtual bool RecomputeType();
2814 return representation_;
2830 return (CompilerState::Current().is_aot() ||
2831 (representation_ != kUnboxedInt32))
2848 reaching_defs_ = reaching_defs;
2854 bool IsRedundant()
const;
2859 Definition* GetReplacementForRedundantPhi()
const;
2866 enum
ReceiverType { kUnknownReceiver = -1, kNotReceiver = 0, kReceiver = 1 };
2883 int8_t is_receiver_;
2904 static constexpr intptr_t kNotFunctionParameter = -1;
2908 intptr_t param_index,
2911 : env_index_(env_index),
2912 param_index_(param_index),
2913 representation_(representation),
2921 intptr_t env_index()
const {
return env_index_; }
2922 intptr_t
index()
const {
return env_index(); }
2954#define FIELD_LIST(F) \
2955 F(const intptr_t, env_index_) \
2956 F(const intptr_t, param_index_) \
2957 F(const Representation, representation_)
2983 : marshaller_(marshaller), def_index_(def_index) {}
2988 return marshaller_.RepInFfiCall(def_index_);
3003#define FIELD_LIST(F) \
3004 F(const compiler::ffi::CallbackMarshaller&, marshaller_) \
3005 F(const intptr_t, def_index_)
3033 SetInputAt(kIndexPos, index);
3034 SetInputAt(kValuePos,
value);
3037 enum { kIndexPos = 0, kValuePos = 1 };
3042 ASSERT(index == kIndexPos || index == kValuePos);
3050 return other.AsStoreIndexedUnsafe()->offset() ==
offset();
3060#define FIELD_LIST(F) F(const intptr_t, offset_)
3089 : offset_(
offset), representation_(representation) {
3090 UpdateType(result_type);
3091 SetInputAt(0, index);
3104 return other.AsLoadIndexedUnsafe()->offset() ==
offset();
3115#define FIELD_LIST(F) \
3116 F(const intptr_t, offset_) \
3117 F(const Representation, representation_)
3137 bool unboxed_inputs,
3138 bool can_overlap =
true)
3139 : src_cid_(src_cid),
3140 dest_cid_(dest_cid),
3141 element_size_(
Instance::ElementSizeFor(src_cid)),
3142 unboxed_inputs_(unboxed_inputs),
3143 can_overlap_(can_overlap) {
3144 ASSERT(IsArrayTypeSupported(src_cid));
3145 ASSERT(IsArrayTypeSupported(dest_cid));
3147 Instance::ElementSizeFor(dest_cid));
3148 SetInputAt(kSrcPos, src);
3149 SetInputAt(kDestPos, dest);
3150 SetInputAt(kSrcStartPos, src_start);
3151 SetInputAt(kDestStartPos, dest_start);
3152 SetInputAt(kLengthPos,
length);
3166 if (index == kSrcPos || index == kDestPos) {
3168 return kNoRepresentation;
3170 ASSERT(index <= kLengthPos);
3171 return unboxed_inputs() ? kUnboxedIntPtr : kTagged;
3178 if (
auto*
const copy = other.AsMemoryCopy()) {
3179 if (element_size_ !=
copy->element_size_)
return false;
3180 if (unboxed_inputs_ !=
copy->unboxed_inputs_)
return false;
3181 if (can_overlap_ !=
copy->can_overlap_)
return false;
3182 if (src_cid_ !=
copy->src_cid_)
return false;
3183 if (dest_cid_ !=
copy->dest_cid_)
return false;
3208#define FIELD_LIST(F) \
3209 F(const classid_t, src_cid_) \
3210 F(const classid_t, dest_cid_) \
3211 F(intptr_t, element_size_) \
3212 F(bool, unboxed_inputs_) \
3213 F(const bool, can_overlap_)
3238 intptr_t num_elements,
3273 if (array_cid == kPointerCid || array_cid == kStringCid)
return false;
3291 SetInputAt(0, arg_desc);
3296 const
Code& code()
const {
return code_; }
3301 return &other.AsTailCall()->code() == &code();
3311#define FIELD_LIST(F) F(const Code&, code_)
3334 : representation_(representation),
3335 is_register_move_(IsRegisterMove(location)),
3336 location_(location) {
3337 ASSERT(IsSupportedLocation(location));
3338 SetInputAt(0,
value);
3343 bool is_register_move()
const {
return is_register_move_; }
3348 ASSERT(!is_register_move());
3366 return TokenPosition::kMoveArgument;
3373 return representation();
3378#define FIELD_LIST(F) \
3379 F(const Representation, representation_) \
3380 F(const bool, is_register_move_)
3390 static bool IsSupportedLocation(
Location loc,
bool can_be_fpu_value =
true) {
3391#if defined(TARGET_ARCH_IS_32_BIT)
3394 return IsSupportedLocation(pair_loc->At(0),
false) &&
3395 IsSupportedLocation(pair_loc->At(1),
false);
3419 return move_arguments !=
nullptr ? (*move_arguments)[index]->value()
3424 return ArgumentValueAt(index)->definition();
3430 intptr_t deopt_id = DeoptId::kNone)
3442 return kNotSpeculative;
3460 token_pos_(
source.token_pos),
3461 representation_(representation) {
3462 SetInputAt(0,
value);
3477 auto const other_return = other.AsDartReturn();
3478 return token_pos() == other_return->
token_pos();
3487 return representation_;
3494#define FIELD_LIST(F) \
3495 F(const TokenPosition, token_pos_) \
3496 F(const Representation, representation_)
3520 SetInputAt(0,
value);
3521 inputs_[1] =
nullptr;
3528 SetInputAt(0, typed_data_base);
3538 return marshaller_.RepInFfiCall(compiler::ffi::kResultIndex);
3543 return kUnboxedWord;
3554 return marshaller_.NumReturnDefinitions();
3558 auto const other_return = other.AsNativeReturn();
3559 return token_pos() == other_return->
token_pos();
3564#define FIELD_LIST(F) F(const compiler::ffi::CallbackMarshaller&, marshaller_)
3588 SetInputAt(0, exception);
3598 return !CompilerState::Current().is_aot();
3603#define FIELD_LIST(F) F(const TokenPosition, token_pos_)
3619 intptr_t catch_try_index,
3624 token_pos_(
source.token_pos),
3625 catch_try_index_(catch_try_index) {
3626 SetInputAt(0, exception);
3627 SetInputAt(1, stacktrace);
3639 return !CompilerState::Current().is_aot();
3644#define FIELD_LIST(F) \
3645 F(const TokenPosition, token_pos_) \
3646 F(const intptr_t, catch_try_index_)
3671#define FIELD_LIST(F) F(const char*, message_)
3687 parallel_move_(nullptr),
3688 successor_(entry) {}
3697 virtual intptr_t SuccessorCount()
const;
3722 return HasParallelMove() && !parallel_move()->IsRedundant();
3726 if (parallel_move_ ==
nullptr) {
3729 return parallel_move_;
3733 return TokenPosition::kControlFlow;
3738#define FIELD_LIST(F) \
3739 F(double, edge_weight_) \
3742 F(ParallelMoveInstr*, parallel_move_)
3784 SetInputAt(0, target_index);
3795 ASSERT(successor->next()->IsGoto());
3796 ASSERT(successor->next()->AsGoto()->successor()->IsIndirectEntry());
3797 successors_.Add(successor);
3802 ASSERT(index < SuccessorCount());
3803 return successors_[index];
3868 auto const other_comparison = other.AsComparison();
3869 return kind() == other_comparison->kind() &&
3870 (operation_cid() == other_comparison->operation_cid());
3877 if (
right()->BindsToConstant(constant_operand)) {
3878 *other_operand =
left();
3880 }
else if (
left()->BindsToConstant(constant_operand)) {
3881 *other_operand =
right();
3890#define FIELD_LIST(F) \
3891 F(const TokenPosition, token_pos_) \
3892 F(Token::Kind, kind_) \
3894 F(intptr_t, operation_cid_)
3904 intptr_t deopt_id = DeoptId::kNone)
3906 token_pos_(
source.token_pos),
3927template <intptr_t
N,
3928 typename ThrowsTrait,
3929 template <
typename Impure,
typename Pure>
class CSETrait = NoCSE>
3931 :
public CSETrait<ComparisonInstr, PureComparison>::Base {
3933 using BaseClass =
typename CSETrait<ComparisonInstr, PureComparison>::Base;
3937 intptr_t deopt_id = DeoptId::kNone)
3943 virtual bool MayThrow()
const {
return ThrowsTrait::kCanThrow; }
3957 :
Instruction(deopt_id), comparison_(comparison) {
3959 for (intptr_t i = comparison->
InputCount() - 1; i >= 0; --i) {
3966 virtual intptr_t ArgumentCount()
const {
3967 return comparison()->ArgumentCount();
3970 comparison()->SetMoveArguments(move_arguments);
3973 return comparison()->GetMoveArguments();
3976 intptr_t
InputCount()
const {
return comparison()->InputCount(); }
3981 virtual intptr_t
inlining_id()
const {
return comparison_->inlining_id(); }
3983 return comparison_->set_inlining_id(
value);
3986 return comparison_->has_inlining_id();
3990 return comparison()->ComputeCanDeoptimize();
3994 return comparison()->CanBecomeDeoptimizationTarget();
3998 return comparison()->HasUnknownSideEffects();
4001 virtual bool CanCallDart()
const {
return comparison()->CanCallDart(); }
4007 return comparison()->DeoptimizationTarget();
4011 return comparison()->RequiredInputRepresentation(i);
4018 constant_target_ =
target;
4023 Instruction::CopyDeoptIdFrom(instr);
4024 comparison()->CopyDeoptIdFrom(instr);
4027 virtual bool MayThrow()
const {
return comparison()->MayThrow(); }
4035 virtual intptr_t SuccessorCount()
const;
4040#define FIELD_LIST(F) F(ComparisonInstr*, comparison_)
4048 comparison()->RawSetInputAt(i,
value);
4069#define FIELD_LIST(F) F(const ICData::DeoptReasonId, deopt_reason_)
4083 bool inserted_by_constant_propagation =
false)
4084 : constrained_type_(nullptr),
4085 inserted_by_constant_propagation_(inserted_by_constant_propagation) {
4086 SetInputAt(0,
value);
4091 Value* value()
const {
return inputs_[0]; }
4094 virtual bool RecomputeType();
4102 return inserted_by_constant_propagation_;
4108 virtual Value* RedefinedValue()
const;
4112#define FIELD_LIST(F) \
4113 F(CompileType*, constrained_type_) \
4114 F(bool, inserted_by_constant_propagation_)
4135 return kNoRepresentation;
4158 SetInputAt(0,
value);
4187#define FIELD_LIST(F) F(Range*, constraint_)
4217 switch (representation()) {
4220 case kUnboxedUint16:
4221 case kUnboxedUint32:
4224 return IsSmi() && compiler::target::SmiValue(
value()) == 0;
4225 case kUnboxedDouble:
4226 return compiler::target::IsDouble(
value()) &&
4227 bit_cast<uint64_t>(compiler::target::DoubleValue(
value())) == 0;
4237 virtual bool AttributesEqual(
const Instruction& other)
const;
4244 intptr_t pair_index = 0);
4249#define FIELD_LIST(F) \
4250 F(const Object&, value_) \
4251 F(const TokenPosition, token_pos_)
4279 (&
value(), representation()))
4295 kInstantiatorTAVPos = 0,
4296 kFunctionTAVPos = 1,
4303 Value* instantiator_type_arguments,
4304 Value* function_type_arguments,
4310 SetInputAt(kInstantiatorTAVPos, instantiator_type_arguments);
4311 SetInputAt(kFunctionTAVPos, function_type_arguments);
4312 SetInputAt(kSubTypePos, sub_type);
4313 SetInputAt(kSuperTypePos, super_type);
4314 SetInputAt(kDstNamePos, dst_name);
4320 return inputs_[kInstantiatorTAVPos];
4331 return !CompilerState::Current().is_aot();
4334 return InputCount();
4345#define FIELD_LIST(F) F(const TokenPosition, token_pos_)
4358#define FOR_EACH_ASSERT_ASSIGNABLE_KIND(V) \
4360 V(InsertedByFrontend) \
4364#define KIND_DEFN(name) k##name,
4368 static const char* KindToCString(
Kind kind);
4369 static bool ParseKind(
const char* str,
Kind* out);
4374 kInstantiatorTAVPos = 2,
4375 kFunctionTAVPos = 3,
4382 Value* instantiator_type_arguments,
4383 Value* function_type_arguments,
4388 token_pos_(
source.token_pos),
4389 dst_name_(dst_name),
4392 SetInputAt(kInstancePos,
value);
4393 SetInputAt(kDstTypePos, dst_type);
4394 SetInputAt(kInstantiatorTAVPos, instantiator_type_arguments);
4395 SetInputAt(kFunctionTAVPos, function_type_arguments);
4398 virtual intptr_t statistics_tag()
const;
4402 virtual bool RecomputeType();
4407 return inputs_[kInstantiatorTAVPos];
4416 return !CompilerState::Current().is_aot();
4419#if !defined(TARGET_ARCH_IA32)
4420 return InputCount();
4440 virtual Value* RedefinedValue()
const;
4446#define FIELD_LIST(F) \
4447 F(const TokenPosition, token_pos_) \
4448 F(const String&, dst_name_) \
4449 F(const Kind, kind_)
4466 SetInputAt(0,
value);
4477 return !CompilerState::Current().is_aot();
4480 return InputCount();
4487 virtual Value* RedefinedValue()
const;
4491#define FIELD_LIST(F) F(const TokenPosition, token_pos_)
4504 intptr_t count_with_type_args,
4505 intptr_t size_with_type_args,
4506 const Array& argument_names)
4507 : type_args_len(type_args_len),
4508 count_with_type_args(count_with_type_args),
4509 size_with_type_args(size_with_type_args),
4510 count_without_type_args(count_with_type_args -
4511 (type_args_len > 0 ? 1 : 0)),
4512 size_without_type_args(size_with_type_args -
4513 (type_args_len > 0 ? 1 : 0)),
4514 argument_names(argument_names) {}
4517 return ArgumentsDescriptor::New(type_args_len, count_without_type_args,
4518 size_without_type_args, argument_names);
4529template <
intptr_t kExtraInputs>
4533 intptr_t type_args_len,
4534 const Array& argument_names,
4538 type_args_len_(type_args_len),
4539 argument_names_(argument_names),
4540 token_pos_(
source.token_pos) {
4541 DEBUG_ASSERT(argument_names.IsNotTemporaryScopedHandle());
4542 ASSERT(InputCount() >= kExtraInputs);
4552 return !CompilerState::Current().is_aot();
4555 return kExtraInputs;
4561 return ArgumentCount() - FirstArgIndex();
4564 return ArgumentsSize() - FirstArgIndex();
4569 return move_arguments_ !=
nullptr ? move_arguments_->length()
4570 : InputCount() - kExtraInputs;
4575 ASSERT(move_arguments_ ==
nullptr);
4576 move_arguments_ = move_arguments;
4579 return move_arguments_;
4583 ASSERT(move_arguments_ ==
nullptr);
4585 SetMoveArguments(move_arguments);
4586 ASSERT(InputCount() == ArgumentCount() + kExtraInputs);
4587 const intptr_t extra_inputs_base = InputCount() - kExtraInputs;
4588 for (intptr_t i = 0, n = ArgumentCount(); i < n; ++i) {
4589 InputAt(i)->RemoveFromUseList();
4591 for (intptr_t i = 0; i < kExtraInputs; ++i) {
4592 SetInputAt(i, InputAt(extra_inputs_base + i));
4594 inputs_.TruncateTo(kExtraInputs);
4600 return ArgumentsDescriptor::New(
4601 type_args_len(), ArgumentCountWithoutTypeArgs(),
4602 ArgumentsSizeWithoutTypeArgs(), argument_names());
4609 const intptr_t type_args_len_;
4610 const Array& argument_names_;
4621 intptr_t type_args_len,
4622 const Array& argument_names,
4630 target_function_(target_function) {
4631 DEBUG_ASSERT(target_function.IsNotTemporaryScopedHandle());
4636 const
Function& target_function()
const {
return target_function_; }
4645#define FIELD_LIST(F) F(const Function&, target_function_)
4660 const String& function_name,
4663 intptr_t type_args_len,
4664 const Array& argument_names,
4668 const Function& tearoff_interface_target)
4672 std::move(arguments),
4676 token_kind_(token_kind),
4677 interface_target_(interface_target),
4678 tearoff_interface_target_(tearoff_interface_target),
4679 result_type_(nullptr),
4680 has_unique_selector_(
false),
4682 receiver_is_not_smi_(
false),
4683 is_call_on_this_(
false) {
4685 DEBUG_ASSERT(interface_target.IsNotTemporaryScopedHandle());
4686 DEBUG_ASSERT(tearoff_interface_target.IsNotTemporaryScopedHandle());
4687 ASSERT(InputCount() > 0);
4688 ASSERT(Token::IsBinaryOperator(token_kind) ||
4689 Token::IsEqualityOperator(token_kind) ||
4690 Token::IsRelationalOperator(token_kind) ||
4691 Token::IsUnaryOperator(token_kind) ||
4692 Token::IsIndexOperator(token_kind) ||
4693 Token::IsTypeTestOperator(token_kind) ||
4694 Token::IsTypeCastOperator(token_kind) || token_kind == Token::kGET ||
4695 token_kind == Token::kSET || token_kind == Token::kILLEGAL);
4700 return (ic_data() !=
nullptr) && !ic_data()->IsNull();
4710 return tearoff_interface_target_;
4733 if (result_type_ ==
nullptr) {
4736 return result_type_->ToCid();
4739 FunctionPtr ResolveForReceiverClass(
const Class& cls,
bool allow_add =
true);
4754 void UpdateReceiverSminess(
Zone* zone);
4756 bool CanReceiverBeSmiBasedOnInterfaceTarget(
Zone* zone)
const;
4759 if (type_args_len() > 0) {
4761 return kGuardInputs;
4765 if (interface_target_.IsNull())
return kGuardInputs;
4766 return interface_target_.is_unboxed_parameter_at(idx) ? kNotSpeculative
4770 virtual intptr_t ArgumentsSize()
const;
4772 virtual Representation RequiredInputRepresentation(intptr_t idx)
const;
4778#define FIELD_LIST(F) \
4779 F(const ICData*, ic_data_) \
4780 F(const String&, function_name_) \
4782 F(const Token::Kind, token_kind_) \
4783 F(const Function&, interface_target_) \
4784 F(const Function&, tearoff_interface_target_) \
4786 F(CompileType*, result_type_) \
4787 F(bool, has_unique_selector_) \
4788 F(Code::EntryKind, entry_kind_) \
4789 F(bool, receiver_is_not_smi_) \
4790 F(bool, is_call_on_this_)
4810 const String& function_name,
4813 intptr_t type_args_len,
4814 const Array& argument_names,
4815 intptr_t checked_argument_count,
4818 const Function& interface_target = Function::null_function(),
4819 const Function& tearoff_interface_target = Function::null_function())
4824 std::move(arguments),
4827 GetICData(ic_data_array, deopt_id,
false),
4830 tearoff_interface_target),
4831 checked_argument_count_(checked_argument_count),
4832 receivers_static_type_(nullptr) {}
4836 const String& function_name,
4839 intptr_t type_args_len,
4840 const Array& argument_names,
4841 intptr_t checked_argument_count,
4843 const Function& interface_target = Function::null_function(),
4844 const Function& tearoff_interface_target = Function::null_function())
4848 std::move(arguments),
4854 tearoff_interface_target),
4855 checked_argument_count_(checked_argument_count),
4856 receivers_static_type_(nullptr) {}
4860 intptr_t checked_argument_count()
const {
return checked_argument_count_; }
4863 return ic_data() ==
nullptr ? 0 : ic_data()->AggregateCount();
4867 ASSERT(receiver_type !=
nullptr);
4868 receivers_static_type_ = receiver_type;
4887#define FIELD_LIST(F) \
4888 F(const intptr_t, checked_argument_count_) \
4889 F(const AbstractType*, receivers_static_type_)
4910 ASSERT(!call->HasMoveArguments());
4912 for (intptr_t i = 0, n = call->ArgumentCount(); i < n; ++i) {
4913 args.Add(call->ArgumentValueAt(i)->CopyWithType(zone));
4916 call->source(), call->function_name(), call->token_kind(),
4917 std::move(
args), call->type_args_len(), call->argument_names(),
4918 call->ic_data(), call->deopt_id(), call->interface_target(),
4919 call->tearoff_interface_target(), targets, complete);
4921 new_call->set_entry_kind(call->entry_kind());
4922 new_call->set_has_unique_selector(call->has_unique_selector());
4923 if (call->is_call_on_this()) {
4924 new_call->mark_as_call_on_this();
4933 bool HasOnlyDispatcherOrImplicitAccessorTargets()
const;
4938 bool IsSureToCallSingleRecognizedTarget()
const;
4940 virtual intptr_t CallCount()
const;
4957 static TypePtr ComputeRuntimeType(
const CallTargets& targets);
4961#define FIELD_LIST(F) \
4962 F(const CallTargets&, targets_) \
4963 F(const bool, complete_) \
4964 F(intptr_t, total_call_count_)
4973 const String& function_name,
4976 intptr_t type_args_len,
4977 const Array& argument_names,
4981 const Function& tearoff_interface_target,
4987 std::move(arguments),
4993 tearoff_interface_target),
4995 complete_(complete) {
4997 total_call_count_ = CallCount();
5014 intptr_t type_args_len,
5015 const Array& argument_names)
5019 std::move(arguments),
5021 interface_target_(interface_target),
5022 selector_(selector) {
5023 ASSERT(selector !=
nullptr);
5024 DEBUG_ASSERT(interface_target_.IsNotTemporaryScopedHandle());
5025 ASSERT(InputCount() > 0);
5038 const
Function& interface_target()
const {
return interface_target_; }
5041 return String::Handle(interface_target().
name()).ToCString();
5057 if (type_args_len() > 0) {
5059 return kGuardInputs;
5063 return interface_target_.is_unboxed_parameter_at(idx) ? kNotSpeculative
5067 virtual intptr_t ArgumentsSize()
const;
5069 virtual Representation RequiredInputRepresentation(intptr_t idx)
const;
5075#define FIELD_LIST(F) \
5076 F(const Function&, interface_target_) \
5077 F(const compiler::TableSelector*, selector_)
5094 bool needs_number_check,
5110 bool AttributesEqual(
const Instruction& other)
const;
5114#define FIELD_LIST(F) \
5117 F(bool, needs_number_check_)
5131 intptr_t input_index,
5147 ASSERT(kind == Token::kEQ || kind == Token::kNE);
5148 SetInputAt(0,
left);
5149 SetInputAt(1,
right);
5186 return cid_results_;
5198 return GetDeoptId() != DeoptId::kNone;
5206 virtual bool AttributesEqual(
const Instruction& other)
const;
5210#define FIELD_LIST(F) F(const ZoneGrowableArray<intptr_t>&, cid_results_)
5244 return value_representation_;
5247 virtual bool AttributesEqual(
const Instruction& other)
const;
5251#define FIELD_LIST(F) \
5252 F(const uword, lower_) \
5253 F(const uword, upper_) \
5254 F(const Representation, value_representation_)
5273 bool null_aware =
false,
5274 SpeculativeMode speculative_mode = kGuardInputs)
5276 null_aware_(null_aware),
5277 speculative_mode_(speculative_mode) {
5278 ASSERT(Token::IsEqualityOperator(kind));
5279 SetInputAt(0,
left);
5280 SetInputAt(1,
right);
5281 set_operation_cid(
cid);
5296 ASSERT((idx == 0) || (idx == 1));
5297 if (is_null_aware())
return kTagged;
5298 if (operation_cid() == kDoubleCid)
return kUnboxedDouble;
5299 if (operation_cid() == kMintCid)
return kUnboxedInt64;
5300 if (operation_cid() == kIntegerCid)
return kUnboxedUword;
5305 return speculative_mode_;
5309 return ComparisonInstr::AttributesEqual(other) &&
5310 (null_aware_ == other.AsEqualityCompare()->null_aware_) &&
5311 (speculative_mode_ == other.AsEqualityCompare()->speculative_mode_);
5318#define FIELD_LIST(F) \
5319 F(bool, null_aware_) \
5320 F(const SpeculativeMode, speculative_mode_)
5339 SpeculativeMode speculative_mode = kGuardInputs)
5341 speculative_mode_(speculative_mode) {
5342 ASSERT(Token::IsRelationalOperator(kind));
5343 SetInputAt(0,
left);
5344 SetInputAt(1,
right);
5345 set_operation_cid(
cid);
5357 ASSERT((idx == 0) || (idx == 1));
5358 if (operation_cid() == kDoubleCid)
return kUnboxedDouble;
5359 if (operation_cid() == kMintCid)
return kUnboxedInt64;
5364 return speculative_mode_;
5368 return ComparisonInstr::AttributesEqual(other) &&
5369 (speculative_mode_ == other.AsRelationalOp()->speculative_mode_);
5374#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
5394 comparison_(comparison),
5395 if_true_(
Smi::Cast(if_true->BoundConstant()).
Value()),
5396 if_false_(
Smi::Cast(if_false->BoundConstant()).
Value()) {
5399 for (intptr_t i = comparison->
InputCount() - 1; i >= 0; --i) {
5410 intptr_t InputCount()
const {
return comparison()->InputCount(); }
5415 return comparison()->ComputeCanDeoptimize();
5419 return comparison()->CanBecomeDeoptimizationTarget();
5423 return comparison()->DeoptimizationTarget();
5427 return comparison()->RequiredInputRepresentation(i);
5438 virtual bool AllowsCSE()
const {
return comparison()->AllowsCSE(); }
5440 return comparison()->HasUnknownSideEffects();
5442 virtual bool CanCallDart()
const {
return comparison()->CanCallDart(); }
5445 auto const other_if_then_else = other.AsIfThenElse();
5446 return (comparison()->tag() == other_if_then_else->comparison()->tag()) &&
5448 (if_true_ == other_if_then_else->if_true_) &&
5449 (if_false_ == other_if_then_else->if_false_);
5452 virtual bool MayThrow()
const {
return comparison()->MayThrow(); }
5455 Definition::CopyDeoptIdFrom(instr);
5456 comparison()->CopyDeoptIdFrom(instr);
5461#define FIELD_LIST(F) \
5462 F(ComparisonInstr*, comparison_) \
5463 F(const intptr_t, if_true_) \
5464 F(const intptr_t, if_false_)
5473 virtual void RawSetInputAt(intptr_t i,
Value* value) {
5474 comparison()->RawSetInputAt(i,
value);
5484 intptr_t type_args_len,
5485 const Array& argument_names,
5493 std::move(arguments),
5495 ic_data_(GetICData(ic_data_array, deopt_id,
true)),
5498 rebind_rule_(rebind_rule),
5499 result_type_(nullptr),
5500 is_known_list_constructor_(
false),
5509 intptr_t type_args_len,
5510 const Array& argument_names,
5513 intptr_t call_count,
5518 std::move(arguments),
5521 call_count_(call_count),
5523 rebind_rule_(rebind_rule),
5524 result_type_(nullptr),
5525 is_known_list_constructor_(
false),
5538 intptr_t call_count) {
5539 ASSERT(!call->HasMoveArguments());
5541 for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
5542 args.Add(call->ArgumentValueAt(i)->CopyWithType());
5545 call->source(),
target, call->type_args_len(), call->argument_names(),
5546 std::move(
args), call->deopt_id(), call_count, ICData::kNoRebind);
5547 if (call->result_type() !=
nullptr) {
5548 new_call->result_type_ = call->result_type();
5557 return (ic_data() !=
nullptr) && !ic_data()->IsNull();
5577 return ic_data() ==
nullptr ? call_count_ : ic_data()->AggregateCount();
5582 return !CompilerState::Current().is_aot();
5597 bool InitResultType(
Zone* zone);
5606 if (result_type_ ==
nullptr) {
5609 return result_type_->ToCid();
5614 is_known_list_constructor_ =
value;
5624 if (type_args_len() > 0 ||
function().IsFactory()) {
5626 return kGuardInputs;
5630 return function_.is_unboxed_parameter_at(idx) ? kNotSpeculative
5634 virtual intptr_t ArgumentsSize()
const;
5636 virtual Representation RequiredInputRepresentation(intptr_t idx)
const;
5650#define FIELD_LIST(F) \
5651 F(const ICData*, ic_data_) \
5652 F(const intptr_t, call_count_) \
5653 F(const Function&, function_) \
5654 F(const ICData::RebindRule, rebind_rule_) \
5656 F(CompileType*, result_type_) \
5658 F(bool, is_known_list_constructor_) \
5659 F(Code::EntryKind, entry_kind_) \
5660 F(AliasIdentity, identity_)
5690 intptr_t type_args_len,
5691 const Array& argument_names,
5719 if (type_args_len() > 0) {
5721 return kGuardInputs;
5725 return function_.is_unboxed_parameter_at(idx) ? kNotSpeculative
5729 virtual intptr_t ArgumentsSize()
const;
5731 virtual Representation RequiredInputRepresentation(intptr_t idx)
const;
5740#define FIELD_LIST(F) \
5741 F(const Representation, representation_) \
5742 F(const Function&, function_) \
5743 F(AliasIdentity, identity_)
5760 token_pos_(
source.token_pos) {}
5781#define FIELD_LIST(F) \
5782 F(const LocalVariable&, local_) \
5784 F(const TokenPosition, token_pos_)
5798 : num_temps_(num_temps), has_input_(
value != nullptr) {
5800 SetInputAt(0,
value);
5806 virtual intptr_t InputCount()
const {
return has_input_ ? 1 : 0; }
5808 ASSERT(has_input_ && (i == 0));
5831#define FIELD_LIST(F) \
5832 F(const intptr_t, num_temps_) \
5833 F(const bool, has_input_)
5841 virtual void RawSetInputAt(intptr_t i,
Value* value) {
5872 virtual
bool ComputeCanDeoptimize()
const {
return false; }
5885#define FIELD_LIST(F) F(ConstantInstr*, null_)
5906 token_pos_(
source.token_pos) {
5907 SetInputAt(0,
value);
5933#define FIELD_LIST(F) \
5934 F(const LocalVariable&, local_) \
5937 F(const TokenPosition, token_pos_)
5957 Array::null_array(),
5962 token_pos_(
source.token_pos),
5963 link_lazily_(link_lazily) {
5967 ASSERT(ArgumentCount() ==
5973 const
String& native_name()
const {
return native_name_; }
5992#define FIELD_LIST(F) \
5993 F(const String&, native_name_) \
5994 F(const Function&, function_) \
5995 F(const TokenPosition, token_pos_)
6003 void set_native_c_function(NativeFunction value) {
6004 native_c_function_ =
value;
6013 bool is_bootstrap_native_ =
false;
6014 bool is_auto_scope_ =
true;
6015 bool link_lazily_ =
true;
6036 marshaller_(marshaller),
6039 ASSERT_EQUAL(InputCount(), InputCountForMarshaller(marshaller));
6042 for (intptr_t i = 0; i < InputCount(); i++) {
6043 ASSERT(!InputAt(i)->definition()->MayCreateUnsafeUntaggedPointer());
6051 intptr_t TargetAddressIndex()
const {
6052 return marshaller_.NumArgumentDefinitions();
6057 ASSERT(marshaller_.ReturnsCompound());
6058 return marshaller_.NumArgumentDefinitions() + 1;
6077 return !CompilerState::Current().is_aot();
6085 virtual Representation RequiredInputRepresentation(intptr_t idx)
const;
6094 return FLAG_precompiled_mode;
6105#define FIELD_LIST(F) \
6106 F(const compiler::ffi::CallMarshaller&, marshaller_) \
6150 return argument_representations_.length();
6162 if (idx < argument_representations_.length()) {
6163 return argument_representations_.At(idx);
6170 if (representation() != kUntagged)
return false;
6176 for (intptr_t i = 0; i < TargetAddressIndex(); i++) {
6177 if (InputAt(i)->definition()->MayCreateUnsafeUntaggedPointer()) {
6185 return return_representation_;
6189 return RepresentationUtils::IsUnboxed(representation())
6190 ? CompileType::FromUnboxedRepresentation(representation())
6191 : CompileType::Object();
6223 token_pos_(
source.token_pos),
6224 stub_kind_(stub_kind) {}
6233#define FIELD_LIST(F) \
6234 F(const TokenPosition, token_pos_) \
6235 F(const UntaggedPcDescriptors::Kind, stub_kind_)
6301 Kind kind = Kind::kOther,
6303 compiler::Assembler::kRelaxedNonAtomic)
6306 emit_store_barrier_(emit_store_barrier),
6307 memory_order_(memory_order),
6308 token_pos_(
source.token_pos),
6309 is_initialization_(kind ==
Kind::kInitializing),
6310 stores_inner_pointer_(stores_inner_pointer) {
6311 switch (stores_inner_pointer) {
6312 case InnerPointerAccess::kNotUntagged:
6315 case InnerPointerAccess::kMayBeInnerPointer:
6319 case InnerPointerAccess::kCannotBeInnerPointer:
6323 SetInputAt(kInstancePos,
instance);
6324 SetInputAt(kValuePos,
value);
6333 Kind kind = Kind::kOther,
6335 compiler::Assembler::kRelaxedNonAtomic)
6352 Kind kind = Kind::kOther)
6364 return slot().representation() != kTagged ? kNotSpeculative : kGuardInputs;
6369 (&slot(), is_initialization()))
6371 enum { kInstancePos = 0, kValuePos = 1 };
6381 if (slot().has_untagged_instance()) {
6385 if (slot().representation() != kTagged) {
6395 if (
value()->definition()->
Type()->IsBool()) {
6398 return value()->NeedsWriteBarrier() &&
6403 emit_store_barrier_ =
value;
6407 return stores_inner_pointer_;
6411 ASSERT(stores_inner_pointer_ != InnerPointerAccess::kNotUntagged);
6413 ASSERT(
value == InnerPointerAccess::kCannotBeInnerPointer);
6414 stores_inner_pointer_ =
value;
6431 virtual Representation RequiredInputRepresentation(intptr_t index)
const;
6437#define FIELD_LIST(F) \
6438 F(const Slot&, slot_) \
6439 F(StoreBarrierType, emit_store_barrier_) \
6440 F(compiler::Assembler::MemoryOrder, memory_order_) \
6441 F(const TokenPosition, token_pos_) \
6443 F(const bool, is_initialization_) \
6444 F(InnerPointerAccess, stores_inner_pointer_)
6459 return value()->Type()->CanBeSmi() ? compiler::Assembler::kValueCanBeSmi
6460 : compiler::Assembler::kValueIsNotSmi;
6470 SetInputAt(0,
value);
6486#define FIELD_LIST(F) F(const Field&, field_)
6508 virtual bool AttributesEqual(
const Instruction& other)
const;
6527 virtual bool AttributesEqual(
const Instruction& other)
const;
6552 virtual bool AttributesEqual(
const Instruction& other)
const;
6560template <
intptr_t N>
6566 bool calls_initializer =
false,
6567 intptr_t deopt_id = DeoptId::kNone,
6568 const Field* field =
nullptr)
6570 token_pos_(
source.token_pos),
6571 throw_exception_on_initialization_(
6572 field != nullptr && !field->has_initializer() && field->is_late()),
6573 calls_initializer_(calls_initializer) {
6574 ASSERT(!calls_initializer || field !=
nullptr);
6575 ASSERT(!calls_initializer || (deopt_id != DeoptId::kNone));
6583 return throw_exception_on_initialization_;
6588 return Base::SlowPathSharingSupported(is_optimizing);
6594 return calls_initializer() && !CompilerState::Current().is_aot();
6597 return Base::InputCount();
6601 return calls_initializer() && !throw_exception_on_initialization();
6612 virtual bool MayThrow()
const {
return calls_initializer(); }
6614#define FIELD_LIST(F) \
6615 F(const TokenPosition, token_pos_) \
6616 F(const bool, throw_exception_on_initialization_) \
6617 F(bool, calls_initializer_)
6630 bool calls_initializer =
false,
6631 intptr_t deopt_id = DeoptId::kNone)
6649 return field().is_final() &&
6650 (!field().is_late() || field().has_initializer());
6653 virtual bool AttributesEqual(
const Instruction& other)
const;
6657#define FIELD_LIST(F) F(const Field&, field_)
6675 token_pos_(
source.token_pos) {
6677 SetInputAt(kValuePos,
value);
6681 enum { kValuePos = 0 };
6685 const
Field& field()
const {
return field_; }
6701#define FIELD_LIST(F) \
6702 F(const Field&, field_) \
6703 F(const TokenPosition, token_pos_)
6713 return value()->Type()->CanBeSmi() ? compiler::Assembler::kValueCanBeSmi
6714 : compiler::Assembler::kValueIsNotSmi;
6730 intptr_t index_scale,
6737 enum { kArrayPos = 0, kIndexPos = 1 };
6743 virtual bool RecomputeType();
6747 if (idx == kArrayPos)
return kNoRepresentation;
6749 return index_unboxed_ ? kUnboxedIntPtr : kTagged;
6765 return GetDeoptId();
6776 return ReturnRepresentation(class_id());
6787#define FIELD_LIST(F) \
6788 F(const bool, index_unboxed_) \
6789 F(const intptr_t, index_scale_) \
6790 F(const intptr_t, class_id_) \
6791 F(const AlignmentType, alignment_) \
6792 F(const TokenPosition, token_pos_) \
6794 F(CompileType*, result_type_)
6816 intptr_t element_count,
6820 class_id_(class_id),
6821 token_pos_(
source.token_pos),
6822 element_count_(element_count),
6823 representation_(kTagged) {
6824 ASSERT(element_count == 1 || element_count == 2 || element_count == 4);
6827 SetInputAt(1, index);
6838 return kNoRepresentation;
6852 return compiler::target::Instance::ElementSizeFor(class_id_);
6859 return element_count() <=
6860 compiler::target::kSmiBits / (index_scale() *
kBitsPerByte);
6872 return !can_pack_into_smi() && (representation() == kTagged);
6875#define FIELD_LIST(F) \
6876 F(const intptr_t, class_id_) \
6877 F(const TokenPosition, token_pos_) \
6878 F(const intptr_t, element_count_) \
6879 F(Representation, representation_)
6894 SetInputAt(0, char_code);
6928 return other.AsStringToCharCode()->cid_ == cid_;
6931#define FIELD_LIST(F) F(const intptr_t, cid_)
6972 const Slot& decoder_scan_flags_field)
6973 : scan_flags_field_(decoder_scan_flags_field) {
6974 SetInputAt(0, decoder);
6975 SetInputAt(1, bytes);
6976 SetInputAt(2,
start);
6978 SetInputAt(4,
table);
6984 ASSERT(idx >= 0 || idx <= 4);
6986 if (idx == 2 || idx == 3)
return kUnboxedIntPtr;
6998 return kNotSpeculative;
7002 return scan_flags_field_.Equals(other.AsUtf8Scan()->scan_flags_field_);
7005 bool IsScanFlagsUnboxed()
const;
7009#define FIELD_LIST(F) F(const Slot&, scan_flags_field_)
7027 intptr_t index_scale,
7032 SpeculativeMode speculative_mode = kGuardInputs);
7035 enum { kArrayPos = 0, kIndexPos = 1, kValuePos = 2 };
7046 if (array()->definition() ==
value()->definition()) {
7052 if (
value()->definition()->
Type()->IsBool()) {
7055 return value()->NeedsWriteBarrier() &&
7060 emit_store_barrier_ =
value;
7064 return speculative_mode_;
7074 virtual Representation RequiredInputRepresentation(intptr_t idx)
const;
7083 return GetDeoptId();
7094#define FIELD_LIST(F) \
7095 F(StoreBarrierType, emit_store_barrier_) \
7096 F(const bool, index_unboxed_) \
7097 F(const intptr_t, index_scale_) \
7098 F(const intptr_t, class_id_) \
7099 F(const AlignmentType, alignment_) \
7100 F(const TokenPosition, token_pos_) \
7101 F(const SpeculativeMode, speculative_mode_)
7110 return compiler::Assembler::kValueCanBeSmi;
7119 intptr_t coverage_index,
7122 coverage_array_(coverage_array),
7123 coverage_index_(coverage_index),
7124 token_pos_(
source.token_pos) {}
7133#define FIELD_LIST(F) \
7134 F(const Array&, coverage_array_) \
7135 F(const intptr_t, coverage_index_) \
7136 F(const TokenPosition, token_pos_)
7176 Value* value()
const {
return inputs_[0]; }
7197 ASSERT(
value->definition()->representation() == kUnboxedInt32);
7198 SetInputAt(0,
value);
7207 return kUnboxedInt32;
7225 Value* instantiator_type_arguments,
7226 Value* function_type_arguments,
7230 token_pos_(
source.token_pos),
7233 SetInputAt(0,
value);
7234 SetInputAt(1, instantiator_type_arguments);
7235 SetInputAt(2, function_type_arguments);
7250 return !CompilerState::Current().is_aot();
7257#define FIELD_LIST(F) \
7258 F(const TokenPosition, token_pos_) \
7259 F(const AbstractType&, type_)
7276 intptr_t deopt_id = DeoptId::kNone)
7278 token_pos_(
source.token_pos),
7299 return !CompilerState::Current().is_aot();
7302 return InputCount();
7313 for (intptr_t i = 0; i < InputCount(); i++) {
7314 auto*
const input_slot = SlotForInput(i);
7315 if (input_slot !=
nullptr && input_slot->IsIdentical(slot)) {
7330#define FIELD_LIST(F) \
7331 F(const TokenPosition, token_pos_) \
7332 F(AliasIdentity, identity_)
7343template <
intptr_t N>
7373 enum { kTypeArgumentsPos = 0 };
7377 Value* type_arguments =
nullptr)
7380 has_type_arguments_(type_arguments != nullptr),
7381 type_arguments_slot_(nullptr),
7382 type_arguments_(type_arguments) {
7386 if (has_type_arguments_) {
7387 SetInputAt(kTypeArgumentsPos, type_arguments);
7388 type_arguments_slot_ =
7389 &Slot::GetTypeArgumentsSlotFor(Thread::Current(), cls);
7399 virtual intptr_t
InputCount()
const {
return has_type_arguments_ ? 1 : 0; }
7401 ASSERT(has_type_arguments_ && i == kTypeArgumentsPos);
7402 return type_arguments_;
7413 return WillAllocateNewOrRemembered(cls());
7421 return pos == kTypeArgumentsPos ? type_arguments_slot_ :
nullptr;
7426#define FIELD_LIST(F) \
7427 F(const Class&, cls_) \
7428 F(const bool, has_type_arguments_) \
7429 F(const Slot*, type_arguments_slot_)
7437 virtual void RawSetInputAt(intptr_t i,
Value* value) {
7438 ASSERT(has_type_arguments_ && (i == kTypeArgumentsPos));
7439 type_arguments_ =
value;
7454 kInstantiatorTypeArgsPos = 2,
7457 Value* closure_function,
7459 Value* instantiator_type_args,
7464 has_instantiator_type_args_(instantiator_type_args != nullptr),
7465 is_generic_(is_generic),
7466 is_tear_off_(is_tear_off) {
7467 SetInputAt(kFunctionPos, closure_function);
7468 SetInputAt(kContextPos, context);
7469 if (has_instantiator_type_args_) {
7470 SetInputAt(kInstantiatorTypeArgsPos, instantiator_type_args);
7478 return has_instantiator_type_args() ? 3 : 2;
7485 return has_instantiator_type_args_;
7492 if (
value->BindsToConstant()) {
7494 return Function::Cast(
value->BoundConstant());
7496 return Object::null_function();
7502 return &Slot::Closure_function();
7504 return &Slot::Closure_context();
7505 case kInstantiatorTypeArgsPos:
7506 return has_instantiator_type_args()
7507 ? &Slot::Closure_instantiator_type_arguments()
7510 return TemplateAllocation::SlotForInput(
pos);
7521 const auto other_ac = other.AsAllocateClosure();
7522 return (other_ac->has_instantiator_type_args() ==
7523 has_instantiator_type_args()) &&
7524 (other_ac->is_generic() == is_generic()) &&
7525 (other_ac->is_tear_off() == is_tear_off());
7532#define FIELD_LIST(F) \
7533 F(const bool, has_instantiator_type_args_) \
7534 F(const bool, is_generic_) \
7535 F(const bool, is_tear_off_)
7549 intptr_t num_context_variables,
7560 return compiler::target::WillAllocateNewOrRememberedContext(
7561 num_context_variables_);
7568#define FIELD_LIST(F) F(const intptr_t, num_context_variables_)
7597 compiler::target::Record::InstanceSize(num_fields()));
7600#define FIELD_LIST(F) F(const RecordShape, shape_)
7622 const intptr_t num_fields = shape.
num_fields();
7623 ASSERT(num_fields == 2 || num_fields == 3);
7624 ASSERT((num_fields > 2) == (value2 !=
nullptr));
7625 SetInputAt(0, value0);
7626 SetInputAt(1, value1);
7627 if (num_fields > 2) {
7628 SetInputAt(2, value2);
7641 return &Slot::GetRecordFieldSlot(
7642 Thread::Current(), compiler::target::Record::field_offset(
pos));
7649 compiler::target::Record::InstanceSize(num_fields()));
7652#define FIELD_LIST(F) F(const RecordShape, shape_)
7670 intptr_t length_or_shape,
7675 length_or_shape_(length_or_shape),
7677 registers_remapped_(
false),
7678 allocation_(allocation) {
7679 ASSERT(slots_.length() == InputCount());
7688 return slots_[i]->offset_in_bytes();
7692 ASSERT(0 <= i && i < InputCount());
7693 return locations_[i];
7704 ASSERT(0 <= idx && idx < InputCount());
7705 return kNoRepresentation;
7717 void RemapRegisters(intptr_t* cpu_reg_slots, intptr_t* fpu_reg_slots);
7724#define FIELD_LIST(F) \
7725 F(const Class&, cls_) \
7726 F(intptr_t, length_or_shape_) \
7727 F(const ZoneGrowableArray<const Slot*>&, slots_) \
7728 F(bool, registers_remapped_)
7741 bool visited_for_liveness_ =
false;
7755 return num_elements()->BindsToSmiConstant();
7758 return num_elements()->BoundSmiConstant();
7769template <
intptr_t N>
7793 Value* type_arguments,
7794 Value* num_elements,
7797 SetInputAt(kTypeArgumentsPos, type_arguments);
7798 SetInputAt(kLengthPos, num_elements);
7801 enum { kTypeArgumentsPos = 0, kLengthPos = 1 };
7813 if (!HasConstantNumElements())
return false;
7814 return compiler::target::WillAllocateNewOrRememberedArray(
7815 GetConstantNumElements());
7820 case kTypeArgumentsPos:
7821 return &Slot::Array_type_arguments();
7823 return &Slot::Array_length();
7825 return TemplateArrayAllocation::SlotForInput(
pos);
7839 Value* num_elements,
7842 SetInputAt(kLengthPos, num_elements);
7845 enum { kLengthPos = 0 };
7863 return &Slot::TypedDataBase_length();
7865 return TemplateArrayAllocation::SlotForInput(
pos);
7869#define FIELD_LIST(F) F(const classid_t, class_id_)
7894 SetInputAt(0,
object);
7903 return kNoRepresentation;
7918 return other.AsLoadUntagged()->offset_ == offset_;
7923#define FIELD_LIST(F) F(const intptr_t, offset_)
7948 intptr_t index_scale,
7950 : index_scale_(index_scale) {
7951 ASSERT(
base->definition()->representation() == kUntagged);
7952 ASSERT(Utils::IsPowerOfTwo(index_scale));
7953 ASSERT(1 <= index_scale && index_scale <= 16);
7954 SetInputAt(kBasePos,
base);
7955 SetInputAt(kIndexPos, index);
7956 SetInputAt(kOffsetPos,
offset);
7964 if (idx == kBasePos)
return kUntagged;
7965 ASSERT(idx == kIndexPos || idx == kOffsetPos);
7966 return kUnboxedIntPtr;
7977 return base()->definition()->MayCreateUnsafeUntaggedPointer();
7980 virtual bool AllowsCSE()
const {
return !MayCreateUnsafeUntaggedPointer(); }
7986 return other.AsCalculateElementAddress()->index_scale_ == index_scale_;
7991#define FIELD_LIST(F) F(const intptr_t, index_scale_)
8006 bool input_can_be_smi =
true)
8007 : representation_(representation), input_can_be_smi_(input_can_be_smi) {
8008 ASSERT(representation == kTagged || representation == kUnboxedUword);
8009 SetInputAt(0,
object);
8023 auto const other_load = other.AsLoadClassId();
8024 return other_load->representation_ == representation_ &&
8025 other_load->input_can_be_smi_ == input_can_be_smi_;
8033#define FIELD_LIST(F) \
8034 F(const Representation, representation_) \
8035 F(const bool, input_can_be_smi_)
8059 bool calls_initializer =
false,
8060 intptr_t deopt_id = DeoptId::kNone)
8064 slot.IsDartField() ? &slot.field() : nullptr),
8066 loads_inner_pointer_(loads_inner_pointer) {
8067 switch (loads_inner_pointer) {
8068 case InnerPointerAccess::kNotUntagged:
8071 case InnerPointerAccess::kMayBeInnerPointer:
8075 case InnerPointerAccess::kCannotBeInnerPointer:
8086 bool calls_initializer =
false,
8087 intptr_t deopt_id = DeoptId::kNone)
8099 return loads_inner_pointer_;
8103 ASSERT(loads_inner_pointer_ != InnerPointerAccess::kNotUntagged);
8105 ASSERT(
value == InnerPointerAccess::kCannotBeInnerPointer);
8106 loads_inner_pointer_ =
value;
8111 return slot_.has_untagged_instance() ? kUntagged : kTagged;
8125 bool MayCreateUntaggedAlias() const;
8127 virtual
bool MayCreateUnsafeUntaggedPointer() const;
8129 bool IsImmutableLoad()
const {
8133 if (slot().IsIdentical(Slot::PointerBase_data())) {
8134 return loads_inner_pointer() != InnerPointerAccess::kMayBeInnerPointer;
8136 return slot().is_immutable();
8158 static bool IsFixedLengthArrayCid(intptr_t cid);
8162 virtual bool AllowsCSE()
const {
return slot_.is_immutable(); }
8166 virtual bool AttributesEqual(
const Instruction& other)
const;
8170#define FIELD_LIST(F) \
8171 F(const Slot&, slot_) \
8172 F(InnerPointerAccess, loads_inner_pointer_)
8180 intptr_t OffsetInBytes()
const {
return slot().offset_in_bytes(); }
8184 void EmitNativeCodeForInitializerCall(FlowGraphCompiler*
compiler);
8193 Value* instantiator_type_arguments,
8194 Value* function_type_arguments,
8197 token_pos_(
source.token_pos),
8200 SetInputAt(0, instantiator_type_arguments);
8201 SetInputAt(1, function_type_arguments);
8206 Value* instantiator_type_arguments()
const {
return inputs_[0]; }
8213 return !CompilerState::Current().is_aot();
8216 return InputCount();
8223#define FIELD_LIST(F) \
8224 F(const TokenPosition, token_pos_) \
8225 F(const AbstractType&, type_)
8239 Value* instantiator_type_arguments,
8240 Value* function_type_arguments,
8241 Value* type_arguments,
8242 const Class& instantiator_class,
8246 token_pos_(
source.token_pos),
8247 instantiator_class_(instantiator_class),
8249 DEBUG_ASSERT(instantiator_class.IsNotTemporaryScopedHandle());
8251 SetInputAt(0, instantiator_type_arguments);
8252 SetInputAt(1, function_type_arguments);
8253 SetInputAt(2, type_arguments);
8258 Value* instantiator_type_arguments()
const {
return inputs_[0]; }
8267 return !CompilerState::Current().is_aot();
8270 return InputCount();
8278 bool* with_runtime_check =
nullptr)
const {
8279 if (instantiator_class().
IsNull() || !type_arguments()->BindsToConstant() ||
8280 !type_arguments()->BoundConstant().IsTypeArguments()) {
8283 const auto& type_args =
8284 TypeArguments::Cast(type_arguments()->BoundConstant());
8285 return type_args.CanShareInstantiatorTypeArguments(instantiator_class(),
8286 with_runtime_check);
8290 if (
function().
IsNull() || !type_arguments()->BindsToConstant() ||
8291 !type_arguments()->BoundConstant().IsTypeArguments()) {
8294 const auto& type_args =
8295 TypeArguments::Cast(type_arguments()->BoundConstant());
8296 return type_args.CanShareFunctionTypeArguments(
function(),
8297 with_runtime_check);
8301 bool with_runtime_check;
8302 if (CanShareInstantiatorTypeArguments(&with_runtime_check)) {
8303 ASSERT(with_runtime_check);
8304 return StubCode::InstantiateTypeArgumentsMayShareInstantiatorTA();
8305 }
else if (CanShareFunctionTypeArguments(&with_runtime_check)) {
8306 ASSERT(with_runtime_check);
8307 return StubCode::InstantiateTypeArgumentsMayShareFunctionTA();
8309 return StubCode::InstantiateTypeArguments();
8314#define FIELD_LIST(F) \
8315 F(const TokenPosition, token_pos_) \
8316 F(const Class&, instantiator_class_) \
8317 F(const Function&, function_)
8341 return context_slots_;
8353 return compiler::target::WillAllocateNewOrRememberedContext(
8354 context_slots().
length());
8359#define FIELD_LIST(F) F(const ZoneGrowableArray<const Slot*>&, context_slots_)
8375 Value* context_value,
8379 token_pos_(
source.token_pos),
8380 context_slots_(context_slots) {
8381 SetInputAt(0, context_value);
8388 return context_slots_;
8399 return !CompilerState::Current().is_aot();
8402 return InputCount();
8407#define FIELD_LIST(F) \
8408 F(const TokenPosition, token_pos_) \
8409 F(const ZoneGrowableArray<const Slot*>&, context_slots_)
8424 SetInputAt(0,
left);
8425 SetInputAt(1,
right);
8433 virtual
bool ComputeCanDeoptimize()
const {
return true; }
8458 if (!RepresentationUtils::IsUnboxedInteger(rep))
return rep;
8460 return RepresentationUtils::ValueSize(rep) < 4 ? kUnboxedIntPtr : rep;
8491 return from_representation();
8495 return other.AsBox()->from_representation() == from_representation();
8503 return kNotSpeculative;
8506#define FIELD_LIST(F) F(const Representation, from_representation_)
8515 : from_representation_(from_representation) {
8516 SetInputAt(0,
value);
8520 intptr_t ValueOffset()
const {
8521 return Boxing::ValueOffset(from_representation());
8532 virtual bool ValueFitsSmi()
const;
8537 virtual bool RecomputeType();
8556 compiler::target::kSmiBits);
8628 SpeculativeMode speculative_mode = kGuardInputs);
8633 if (SpeculativeModeOfInputs() == kNotSpeculative) {
8637 const intptr_t value_cid =
value()->Type()->ToCid();
8638 const intptr_t box_cid = BoxCid();
8640 if (value_cid == box_cid) {
8644 if (CanConvertSmi() && (value_cid == kSmiCid)) {
8652 return speculative_mode_;
8660 auto const other_unbox = other.AsUnbox();
8661 return (representation() == other_unbox->representation()) &&
8662 (speculative_mode_ == other_unbox->speculative_mode_);
8671#define FIELD_LIST(F) \
8672 F(const Representation, representation_) \
8673 F(SpeculativeMode, speculative_mode_)
8684 SpeculativeMode speculative_mode)
8686 representation_(representation),
8687 speculative_mode_(speculative_mode) {
8689 ASSERT_EQUAL(Boxing::NativeRepresentation(representation), representation);
8690 SetInputAt(0,
value);
8694 speculative_mode_ =
value;
8698 bool CanConvertSmi()
const;
8705 intptr_t BoxCid()
const {
return Boxing::BoxCid(representation_); }
8707 intptr_t ValueOffset()
const {
return Boxing::ValueOffset(representation_); }
8720 SpeculativeMode speculative_mode)
8722 is_truncating_(truncation_mode == kTruncate) {}
8728 virtual bool ComputeCanDeoptimize()
const;
8731 auto const other_unbox = other.AsUnboxInteger();
8732 return UnboxInstr::AttributesEqual(other) &&
8733 (other_unbox->is_truncating_ == is_truncating_);
8744#define FIELD_LIST(F) F(bool, is_truncating_)
8761 SpeculativeMode speculative_mode)
8766 speculative_mode) {}
8780 SpeculativeMode speculative_mode = kGuardInputs)
8802 SpeculativeMode speculative_mode = kGuardInputs)
8807 speculative_mode) {}
8821 SpeculativeMode speculative_mode)
8826 speculative_mode) {}
8836bool Definition::IsInt64Definition() {
8837 return (
Type()->ToCid() == kMintCid) || IsBinaryInt64Op() ||
8838 IsUnaryInt64Op() || IsShiftInt64Op() || IsSpeculativeShiftInt64Op() ||
8839 IsBoxInt64() || IsUnboxInt64();
8854 bool handle_surrogates,
8856 : handle_surrogates_(handle_surrogates), cid_(
cid) {
8858 ASSERT(index_scale() == 2);
8860 SetInputAt(1, lhs_index);
8861 SetInputAt(2, rhs_index);
8874 return compiler::target::Instance::ElementSizeFor(cid_);
8885 const auto* other_compare = other.AsCaseInsensitiveCompare();
8886 return (other_compare->handle_surrogates_ == handle_surrogates_) &&
8887 (other_compare->cid_ == cid_);
8890#define FIELD_LIST(F) \
8891 F(const bool, handle_surrogates_) \
8892 F(const intptr_t, cid_)
8910 intptr_t result_cid)
8913 result_cid_(result_cid) {
8914 ASSERT((result_cid == kSmiCid) || (result_cid == kDoubleCid));
8915 SetInputAt(0, left_value);
8916 SetInputAt(1, right_value);
8929 if (result_cid() == kSmiCid) {
8932 ASSERT(result_cid() == kDoubleCid);
8933 return kUnboxedDouble;
8937 if (result_cid() == kSmiCid) {
8940 ASSERT(result_cid() == kDoubleCid);
8941 return kUnboxedDouble;
8947 return GetDeoptId();
8952 virtual bool AttributesEqual(
const Instruction& other)
const;
8954#define FIELD_LIST(F) \
8955 F(const MethodRecognizer::Kind, op_kind_) \
8956 F(const intptr_t, result_cid_)
8974 SpeculativeMode speculative_mode = kGuardInputs,
8978 token_pos_(
source.token_pos),
8979 speculative_mode_(speculative_mode),
8980 representation_(representation) {
8981 ASSERT((representation == kUnboxedFloat) ||
8982 (representation == kUnboxedDouble));
8983 SetInputAt(0,
left);
8984 SetInputAt(1,
right);
8999 ASSERT((idx == 0) || (idx == 1));
9000 return representation_;
9004 return speculative_mode_;
9010 return GetDeoptId();
9022 auto const other_bin_op = other.AsBinaryDoubleOp();
9023 return (op_kind() == other_bin_op->op_kind()) &&
9024 (speculative_mode_ == other_bin_op->speculative_mode_) &&
9025 (representation_ == other_bin_op->representation_);
9028#define FIELD_LIST(F) \
9029 F(const Token::Kind, op_kind_) \
9030 F(const TokenPosition, token_pos_) \
9031 F(const SpeculativeMode, speculative_mode_) \
9032 F(const Representation, representation_)
9050 SetInputAt(0,
value);
9061 return kUnboxedDouble;
9073 return op_kind_ == other.AsDoubleTestOp()->op_kind() &&
9074 ComparisonInstr::AttributesEqual(other);
9079#define FIELD_LIST(F) F(const MethodRecognizer::Kind, op_kind_)
9094 SetInputAt(0,
value);
9106 return GetDeoptId();
9113 return kUnboxedDouble;
9118 virtual
bool ComputeCanDeoptimize()
const {
return false; }
9134 SetInputAt(0,
value);
9146 return GetDeoptId();
9158 virtual
bool ComputeCanDeoptimize()
const {
return false; }
9164#define FIELD_LIST(F) F(const bool, smi_)
9181 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT));
9182 SetInputAt(0,
value);
9189 SpeculativeMode speculative_mode,
9198 return other.AsUnaryIntegerOp()->op_kind() == op_kind();
9204 return GetDeoptId();
9213#define FIELD_LIST(F) F(const Token::Kind, op_kind_)
9231 return op_kind() == Token::kNEGATE;
9248 ASSERT(IsSupported(op_kind));
9257 return kUnboxedUint32;
9261 return op_kind == Token::kBIT_NOT;
9277 SpeculativeMode speculative_mode = kGuardInputs)
9279 speculative_mode_(speculative_mode) {
9280 ASSERT(op_kind == Token::kBIT_NOT || op_kind == Token::kNEGATE);
9289 return kUnboxedInt64;
9293 auto const unary_op_other = other.AsUnaryInt64Op();
9294 return UnaryIntegerOpInstr::AttributesEqual(other) &&
9295 (speculative_mode_ == unary_op_other->speculative_mode_);
9299 return speculative_mode_;
9304#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
9323 can_overflow_(
true),
9324 is_truncating_(
false) {
9325 SetInputAt(0,
left);
9326 SetInputAt(1,
right);
9335 SpeculativeMode speculative_mode = kGuardInputs);
9346 SpeculativeMode speculative_mode = kGuardInputs);
9354 ASSERT(!is_truncating_ || !overflow);
9355 can_overflow_ = overflow;
9360 is_truncating_ =
true;
9361 set_can_overflow(
false);
9366 bool RightIsNonZero()
const;
9370 bool RightIsPowerOfTwoConstant()
const;
9374 virtual bool AttributesEqual(
const Instruction& other)
const;
9386#define FIELD_LIST(F) \
9387 F(const Token::Kind, op_kind_) \
9388 F(bool, can_overflow_) \
9389 F(bool, is_truncating_)
9397 void InferRangeHelper(
const Range* left_range,
9398 const Range* right_range,
9414 Range* right_range =
nullptr)
9416 right_range_(right_range) {}
9418 virtual bool ComputeCanDeoptimize()
const;
9425 Range* right_range()
const {
return right_range_; }
9427#define FIELD_LIST(F) F(Range*, right_range_)
9445 SetInputAt(0,
left);
9446 SetInputAt(1,
right);
9450#if defined(TARGET_ARCH_IS_32_BIT)
9455 case Token::kBIT_AND:
9456 case Token::kBIT_OR:
9457 case Token::kBIT_XOR:
9463 if (
right->BindsToConstant() &&
right->BoundConstant().IsSmi()) {
9464 const intptr_t
value = Smi::Cast(
right->BoundConstant()).Value();
9477 virtual bool ComputeCanDeoptimize()
const;
9482 ASSERT((idx == 0) || (idx == 1));
9483 return kUnboxedInt32;
9502 ASSERT(IsSupported(op_kind));
9510 ASSERT((idx == 0) || (idx == 1));
9511 return kUnboxedUint32;
9515 return kNotSpeculative;
9523 case Token::kBIT_AND:
9524 case Token::kBIT_OR:
9525 case Token::kBIT_XOR:
9546 SpeculativeMode speculative_mode = kGuardInputs)
9548 speculative_mode_(speculative_mode) {
9558 return (op_kind() == Token::kMOD || op_kind() == Token::kTRUNCDIV) &&
9565 ASSERT((idx == 0) || (idx == 1));
9566 return kUnboxedInt64;
9570 return speculative_mode_;
9574 return BinaryIntegerOpInstr::AttributesEqual(other) &&
9575 (speculative_mode_ == other.AsBinaryInt64Op()->speculative_mode_);
9580#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
9599 Range* right_range =
nullptr)
9601 shift_range_(right_range) {
9602 ASSERT((op_kind == Token::kSHL) || (op_kind == Token::kSHR) ||
9603 (op_kind == Token::kUSHR));
9616#define FIELD_LIST(F) F(Range*, shift_range_)
9624 static constexpr intptr_t kShiftCountLimit = 63;
9628 bool IsShiftCountInRange(int64_t
max = kShiftCountLimit)
const;
9642 Range* right_range =
nullptr)
9646 return kNotSpeculative;
9649 virtual bool MayThrow()
const {
return !IsShiftCountInRange(); }
9654 ASSERT((idx == 0) || (idx == 1));
9655 return kUnboxedInt64;
9674 Range* right_range =
nullptr)
9679 return !IsShiftCountInRange();
9685 ASSERT((idx == 0) || (idx == 1));
9686 return (idx == 0) ? kUnboxedInt64 : kTagged;
9705 Range* right_range =
nullptr)
9709 return kNotSpeculative;
9713 return !IsShiftCountInRange(kUint32ShiftCountLimit);
9719 ASSERT((idx == 0) || (idx == 1));
9720 return (idx == 0) ? kUnboxedUint32 : kUnboxedInt64;
9728 static constexpr intptr_t kUint32ShiftCountLimit = 31;
9741 Range* right_range =
nullptr)
9749 ASSERT((idx == 0) || (idx == 1));
9750 return (idx == 0) ? kUnboxedUint32 : kTagged;
9759 static constexpr intptr_t kUint32ShiftCountLimit = 31;
9769 SpeculativeMode speculative_mode = kGuardInputs,
9773 speculative_mode_(speculative_mode),
9774 representation_(representation) {
9775 ASSERT((representation == kUnboxedFloat) ||
9776 (representation == kUnboxedDouble));
9777 SetInputAt(0,
value);
9785 virtual
bool ComputeCanDeoptimize()
const {
return false; }
9790 return GetDeoptId();
9797 return representation_;
9801 return speculative_mode_;
9806 return (op_kind_ == other_op->op_kind_) &&
9807 (speculative_mode_ == other_op->speculative_mode_) &&
9808 (representation_ == other_op->representation_);
9815#define FIELD_LIST(F) \
9816 F(const Token::Kind, op_kind_) \
9817 F(const SpeculativeMode, speculative_mode_) \
9818 F(const Representation, representation_)
9843 intptr_t stack_depth,
9844 intptr_t loop_depth,
9848 token_pos_(
source.token_pos),
9849 stack_depth_(stack_depth),
9850 loop_depth_(loop_depth),
9852 ASSERT(kind != kOsrOnly || loop_depth > 0);
9862 virtual
bool ComputeCanDeoptimize()
const {
return false; }
9864 return !CompilerState::Current().is_aot();
9876 return SlowPathSharingSupported(is_optimizing);
9881#define FIELD_LIST(F) \
9882 F(const TokenPosition, token_pos_) \
9883 F(const intptr_t, stack_depth_) \
9884 F(const intptr_t, loop_depth_) \
9885 F(const Kind, kind_)
9901 SetInputAt(0,
value);
9915#define FIELD_LIST(F) F(const TokenPosition, token_pos_)
9936 return kUnboxedInt32;
9955 SpeculativeMode speculative_mode = kGuardInputs)
9957 SetInputAt(0,
value);
9966 return kUnboxedInt64;
9974 return GetDeoptId();
9980 return speculative_mode_;
9984 return speculative_mode_ == other.AsInt64ToDouble()->speculative_mode_;
9987#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
10004 ASSERT((recognized_kind == MethodRecognizer::kDoubleToInteger) ||
10005 (recognized_kind == MethodRecognizer::kDoubleFloorToInt) ||
10006 (recognized_kind == MethodRecognizer::kDoubleCeilToInt));
10007 SetInputAt(0,
value);
10019 return kUnboxedDouble;
10024 return kNotSpeculative;
10028 return !CompilerState::Current().is_aot();
10036 return other.AsDoubleToInteger()->recognized_kind() == recognized_kind();
10039#define FIELD_LIST(F) F(const MethodRecognizer::Kind, recognized_kind_)
10056 SetInputAt(0,
value);
10068 return kUnboxedDouble;
10085 SpeculativeMode speculative_mode = kGuardInputs)
10087 SetInputAt(0,
value);
10094 virtual
bool ComputeCanDeoptimize()
const {
return false; }
10100 return kUnboxedDouble;
10104 return speculative_mode_;
10113#define FIELD_LIST(F) F(const SpeculativeMode, speculative_mode_)
10128 SetInputAt(0,
value);
10141 return kUnboxedFloat;
10160 : op_kind_(op_kind) {
10161 SetInputAt(0,
left);
10162 SetInputAt(1,
right);
10174 virtual
bool ComputeCanDeoptimize()
const {
return false; }
10179 return kUnboxedFloat;
10183 return other.AsFloatCompare()->op_kind() == op_kind();
10186#define FIELD_LIST(F) F(const Token::Kind, op_kind_)
10215 virtual
bool ComputeCanDeoptimize()
const {
return false; }
10220 ASSERT((0 <= idx) && (idx < InputCount()));
10221 return kUnboxedDouble;
10225 ASSERT((0 <= idx) && (idx < InputCount()));
10226 return kNotSpeculative;
10235 auto const other_invoke = other.AsInvokeMathCFunction();
10236 return other_invoke->recognized_kind() == recognized_kind();
10241 static constexpr intptr_t kSavedSpTempIndex = 0;
10242 static constexpr intptr_t kObjectTempIndex = 1;
10243 static constexpr intptr_t kDoubleTempIndex = 2;
10247#define FIELD_LIST(F) \
10248 F(const MethodRecognizer::Kind, recognized_kind_) \
10249 F(const TokenPosition, token_pos_)
10266 intptr_t definition_cid)
10268 definition_rep_(definition_rep),
10269 definition_cid_(definition_cid) {
10270 SetInputAt(0,
value);
10279 virtual
bool ComputeCanDeoptimize()
const {
return false; }
10287 if (representation() == kTagged) {
10288 return kPairOfTagged;
10291 return definition_rep_;
10295 auto const other_extract = other.AsExtractNthOutput();
10296 return (other_extract->representation() == representation()) &&
10297 (other_extract->index() == index());
10302#define FIELD_LIST(F) \
10303 F(const intptr_t, index_) \
10304 F(const Representation, definition_rep_) \
10305 F(const intptr_t, definition_cid_)
10326 virtual
bool ComputeCanDeoptimize()
const {
return false; }
10331 ASSERT((0 <= idx) && (idx < InputCount()));
10348 intptr_t definition_cid)
10350 definition_rep_(definition_rep),
10351 definition_cid_(definition_cid) {
10352 SetInputAt(0,
value);
10362 intptr_t
lane()
const {
return lane_; }
10372 auto const other_split = other.AsUnboxLane();
10373 return (other_split->representation() == representation()) &&
10374 (other_split->lane() == lane());
10381#define FIELD_LIST(F) \
10382 F(const intptr_t, lane_) \
10383 F(const Representation, definition_rep_) \
10384 F(const intptr_t, definition_cid_)
10398 : from_representation_(from_representation) {
10399 ASSERT(from_representation == kUnboxedDouble);
10400 ASSERT(
x->definition()->representation() == from_representation);
10401 ASSERT(
y->definition()->representation() == from_representation);
10410 : from_representation_(from_representation) {
10411 ASSERT((from_representation == kUnboxedInt32) ||
10412 (from_representation == kUnboxedFloat));
10413 ASSERT(
x->definition()->representation() == from_representation);
10414 ASSERT(
y->definition()->representation() == from_representation);
10416 ASSERT(
w->definition()->representation() == from_representation);
10424 switch (from_representation_) {
10425 case kUnboxedDouble:
10427 case kUnboxedFloat:
10429 case kUnboxedInt32:
10439 ASSERT((from_representation() == kUnboxedInt32) ||
10440 (from_representation() == kUnboxedFloat));
10444 ASSERT((from_representation() == kUnboxedInt32) ||
10445 (from_representation() == kUnboxedFloat));
10457 ASSERT(idx == 0 || idx == 1 || idx == 2 || idx == 3);
10458 return from_representation();
10462 return other.AsBoxLanes()->from_representation() == from_representation();
10470 return kNotSpeculative;
10475#define FIELD_LIST(F) F(const Representation, from_representation_)
10490 static intptr_t OutputIndexOf(
Token::Kind token);
10497 ASSERT((0 <= idx) && (idx < InputCount()));
10505 virtual
bool AttributesEqual(const
Instruction& other)
const {
return true; }
10512 Range* divisor_range()
const {
10521 return InputAt(1)->definition()->range();
10536 virtual
bool ComputeCanDeoptimize()
const {
return true; }
10546 bool IsNullCheck()
const {
return IsDeoptIfNull() || IsDeoptIfNotNull(); }
10548 bool IsDeoptIfNull()
const;
10549 bool IsDeoptIfNotNull()
const;
10551 bool IsBitTest()
const;
10552 static bool IsCompactCidRange(
const Cids& cids);
10553 intptr_t ComputeCidMask()
const;
10558 virtual bool AttributesEqual(
const Instruction& other)
const;
10562#define FIELD_LIST(F) \
10563 F(const Cids&, cids_) \
10564 F(bool, is_bit_test_) \
10565 F(const TokenPosition, token_pos_)
10575 intptr_t cid_start,
10580 bool use_near_jump);
10597 SetInputAt(0,
value);
10605 virtual
bool ComputeCanDeoptimize()
const {
return true; }
10611#define FIELD_LIST(F) F(const TokenPosition, token_pos_)
10634 const String& function_name,
10639 token_pos_(
source.token_pos),
10641 exception_type_(exception_type) {
10644 SetInputAt(0,
value);
10653 return SlowPathSharingSupported(is_optimizing);
10659 virtual bool RecomputeType();
10665 return !CompilerState::Current().is_aot();
10671 virtual bool AttributesEqual(
const Instruction& other)
const;
10673 static void AddMetadataForRuntimeCall(
CheckNullInstr* check_null,
10676 virtual Value* RedefinedValue()
const;
10680#define FIELD_LIST(F) \
10681 F(const TokenPosition, token_pos_) \
10682 F(const String&, function_name_) \
10683 F(const ExceptionType, exception_type_)
10698 SetInputAt(0,
value);
10706 virtual
bool ComputeCanDeoptimize()
const {
return true; }
10719#define FIELD_LIST(F) F(CidRangeValue, cids_)
10727 bool Contains(intptr_t cid)
const;
10738 SetInputAt(kLengthPos,
length);
10739 SetInputAt(kIndexPos, index);
10749 virtual Value* RedefinedValue()
const;
10753 bool IsRedundant(
bool use_loops =
false);
10756 enum { kLengthPos = 0, kIndexPos = 1 };
10777 virtual bool RecomputeType();
10784 static intptr_t LengthOffsetFor(intptr_t class_id);
10786 static bool IsFixedLengthArrayType(intptr_t class_id);
10790#define FIELD_LIST(F) F(bool, generalized_)
10811 return compiler::target::kWordSize == 8;
10822 virtual bool RecomputeType();
10827 return kNotSpeculative;
10831 return UseUnboxedRepresentation() ? kUnboxedInt64 : kTagged;
10835 ASSERT(idx == kIndexPos || idx == kLengthPos);
10836 return UseUnboxedRepresentation() ? kUnboxedInt64 : kTagged;
10843 return !CompilerState::Current().is_aot();
10849 return SlowPathSharingSupported(is_optimizing);
10861 kWriteUnmodifiableTypedData = 0,
10862 kDeeplyImmutableAttachNativeFinalizer = 1,
10868 Kind kind = Kind::kWriteUnmodifiableTypedData)
10870 SetInputAt(kReceiver, receiver);
10877 Value* value()
const {
return inputs_[kReceiver]; }
10881 virtual Value* RedefinedValue()
const;
10885 return !CompilerState::Current().is_aot();
10895#define FIELD_LIST(F) F(const Kind, kind_)
10912 :
Instruction(deopt_id), comparison_(comparison) {
10915 for (intptr_t i = comparison->
InputCount() - 1; i >= 0; --i) {
10924 virtual
bool ComputeCanDeoptimize()
const {
return true; }
10936 virtual intptr_t
InputCount()
const {
return comparison()->InputCount(); }
10942 Instruction::CopyDeoptIdFrom(instr);
10943 comparison()->CopyDeoptIdFrom(instr);
10948#define FIELD_LIST(F) F(ComparisonInstr*, comparison_)
10957 virtual void RawSetInputAt(intptr_t i,
Value* value) {
10958 comparison()->RawSetInputAt(i,
value);
10971 from_representation_(from),
10972 to_representation_(to),
10973 is_truncating_(to == kUnboxedUint32) {
10976 ASSERT_EQUAL(Boxing::NativeRepresentation(from), from);
10978 ASSERT(from == kUnboxedInt64 || from == kUnboxedUint32 ||
10979 from == kUnboxedInt32 || from == kUntagged);
10980 ASSERT(to == kUnboxedInt64 || to == kUnboxedUint32 || to == kUnboxedInt32 ||
10982 ASSERT(from != kUntagged || to == kUnboxedIntPtr || to == kUnboxedAddress);
10983 ASSERT(to != kUntagged || from == kUnboxedIntPtr ||
10984 from == kUnboxedAddress);
10986 ASSERT(!
value->definition()->MayCreateUnsafeUntaggedPointer());
10987 SetInputAt(0,
value);
11000 virtual bool ComputeCanDeoptimize()
const;
11010 ASSERT(other.IsIntConverter());
11011 auto const converter = other.AsIntConverter();
11012 return (converter->from() == from()) && (converter->to() == to()) &&
11013 (converter->is_truncating() == is_truncating());
11029 (from(), to(), is_truncating()))
11033#define FIELD_LIST(F) \
11034 F(const Representation, from_representation_) \
11035 F(const Representation, to_representation_) \
11036 F(bool, is_truncating_)
11054 from_representation_(from),
11055 to_representation_(to) {
11057 ASSERT((to == kUnboxedInt32 && from == kUnboxedFloat) ||
11058 (to == kUnboxedFloat && from == kUnboxedInt32) ||
11059 (to == kUnboxedInt64 && from == kUnboxedDouble) ||
11060 (to == kUnboxedDouble && from == kUnboxedInt64));
11061 SetInputAt(0,
value);
11079 ASSERT(other.IsBitCast());
11080 auto const converter = other.AsBitCast();
11081 return converter->from() == from() && converter->to() == to();
11088#define FIELD_LIST(F) \
11089 F(const Representation, from_representation_) \
11090 F(const Representation, to_representation_)
11120 ASSERT(other.IsLoadThread());
11156#define SIMD_BINARY_OP(M, T, Name) M(2, _, T##Name, (T, T), T)
11160#define SIMD_BINARY_FLOAT_OP_LIST(M, OP, T) \
11161 SIMD_BINARY_OP(OP, T, Add) \
11162 SIMD_BINARY_OP(OP, T, Sub) \
11163 SIMD_BINARY_OP(OP, T, Mul) \
11164 SIMD_BINARY_OP(OP, T, Div) \
11165 SIMD_BINARY_OP(M, T, Min) \
11166 SIMD_BINARY_OP(M, T, Max)
11170#define SIMD_BINARY_INTEGER_OP_LIST(M, OP, T) \
11171 SIMD_BINARY_OP(OP, T, Add) \
11172 SIMD_BINARY_OP(OP, T, Sub) \
11173 SIMD_BINARY_OP(OP, T, BitAnd) \
11174 SIMD_BINARY_OP(OP, T, BitOr) \
11175 SIMD_BINARY_OP(OP, T, BitXor)
11178#define SIMD_PER_COMPONENT_XYZW(M, Arity, Name, Inputs, Output) \
11179 M(Arity, _, Name##X, Inputs, Output) \
11180 M(Arity, _, Name##Y, Inputs, Output) \
11181 M(Arity, _, Name##Z, Inputs, Output) \
11182 M(Arity, _, Name##W, Inputs, Output)
11185#define SIMD_CONVERSION(M, FromType, ToType) \
11186 M(1, _, FromType##To##ToType, (FromType), ToType)
11195#define SIMD_OP_LIST(M, BINARY_OP) \
11196 SIMD_BINARY_FLOAT_OP_LIST(M, BINARY_OP, Float32x4) \
11197 SIMD_BINARY_FLOAT_OP_LIST(M, BINARY_OP, Float64x2) \
11198 SIMD_BINARY_INTEGER_OP_LIST(M, BINARY_OP, Int32x4) \
11199 SIMD_PER_COMPONENT_XYZW(M, 1, Float32x4Get, (Float32x4), Double) \
11200 SIMD_PER_COMPONENT_XYZW(M, 2, Float32x4With, (Double, Float32x4), Float32x4) \
11201 SIMD_PER_COMPONENT_XYZW(M, 1, Int32x4GetFlag, (Int32x4), Bool) \
11202 SIMD_PER_COMPONENT_XYZW(M, 2, Int32x4WithFlag, (Int32x4, Bool), Int32x4) \
11203 M(1, MASK, Float32x4Shuffle, (Float32x4), Float32x4) \
11204 M(1, MASK, Int32x4Shuffle, (Int32x4), Int32x4) \
11205 M(2, MASK, Float32x4ShuffleMix, (Float32x4, Float32x4), Float32x4) \
11206 M(2, MASK, Int32x4ShuffleMix, (Int32x4, Int32x4), Int32x4) \
11207 M(2, _, Float32x4Equal, (Float32x4, Float32x4), Int32x4) \
11208 M(2, _, Float32x4GreaterThan, (Float32x4, Float32x4), Int32x4) \
11209 M(2, _, Float32x4GreaterThanOrEqual, (Float32x4, Float32x4), Int32x4) \
11210 M(2, _, Float32x4LessThan, (Float32x4, Float32x4), Int32x4) \
11211 M(2, _, Float32x4LessThanOrEqual, (Float32x4, Float32x4), Int32x4) \
11212 M(2, _, Float32x4NotEqual, (Float32x4, Float32x4), Int32x4) \
11213 M(4, _, Int32x4FromInts, (Int32, Int32, Int32, Int32), Int32x4) \
11214 M(4, _, Int32x4FromBools, (Bool, Bool, Bool, Bool), Int32x4) \
11215 M(4, _, Float32x4FromDoubles, (Double, Double, Double, Double), Float32x4) \
11216 M(2, _, Float64x2FromDoubles, (Double, Double), Float64x2) \
11217 M(0, _, Float32x4Zero, (), Float32x4) \
11218 M(0, _, Float64x2Zero, (), Float64x2) \
11219 M(1, _, Float32x4Splat, (Double), Float32x4) \
11220 M(1, _, Float64x2Splat, (Double), Float64x2) \
11221 M(1, _, Int32x4GetSignMask, (Int32x4), Int8) \
11222 M(1, _, Float32x4GetSignMask, (Float32x4), Int8) \
11223 M(1, _, Float64x2GetSignMask, (Float64x2), Int8) \
11224 M(2, _, Float32x4Scale, (Double, Float32x4), Float32x4) \
11225 M(2, _, Float64x2Scale, (Float64x2, Double), Float64x2) \
11226 M(1, _, Float32x4Sqrt, (Float32x4), Float32x4) \
11227 M(1, _, Float64x2Sqrt, (Float64x2), Float64x2) \
11228 M(1, _, Float32x4Reciprocal, (Float32x4), Float32x4) \
11229 M(1, _, Float32x4ReciprocalSqrt, (Float32x4), Float32x4) \
11230 M(1, _, Float32x4Negate, (Float32x4), Float32x4) \
11231 M(1, _, Float64x2Negate, (Float64x2), Float64x2) \
11232 M(1, _, Float32x4Abs, (Float32x4), Float32x4) \
11233 M(1, _, Float64x2Abs, (Float64x2), Float64x2) \
11234 M(3, _, Float32x4Clamp, (Float32x4, Float32x4, Float32x4), Float32x4) \
11235 M(3, _, Float64x2Clamp, (Float64x2, Float64x2, Float64x2), Float64x2) \
11236 M(1, _, Float64x2GetX, (Float64x2), Double) \
11237 M(1, _, Float64x2GetY, (Float64x2), Double) \
11238 M(2, _, Float64x2WithX, (Float64x2, Double), Float64x2) \
11239 M(2, _, Float64x2WithY, (Float64x2, Double), Float64x2) \
11240 M(3, _, Int32x4Select, (Int32x4, Float32x4, Float32x4), Float32x4) \
11241 SIMD_CONVERSION(M, Float32x4, Int32x4) \
11242 SIMD_CONVERSION(M, Int32x4, Float32x4) \
11243 SIMD_CONVERSION(M, Float32x4, Float64x2) \
11244 SIMD_CONVERSION(M, Float64x2, Float32x4)
11249#define DECLARE_ENUM(Arity, Mask, Name, ...) k##Name,
11260 intptr_t mask = 0);
11271 intptr_t deopt_id) {
11279 intptr_t deopt_id) {
11286 intptr_t deopt_id) {
11298 virtual intptr_t InputCount()
const;
11300 ASSERT(0 <= i && i < InputCount());
11311 virtual Representation RequiredInputRepresentation(intptr_t idx)
const;
11321 return GetDeoptId();
11328 auto const other_op = other.AsSimdOp();
11329 return kind() == other_op->kind() &&
11330 (!HasMask() || mask() == other_op->mask());
11338#define FIELD_LIST(F) \
11339 F(const Kind, kind_) \
11350 : Definition(deopt_id), kind_(kind) {
11351 SetInputAt(0,
left);
11355 : Definition(deopt_id), kind_(kind) {
11356 SetInputAt(0,
left);
11357 SetInputAt(1,
right);
11360 bool HasMask()
const;
11361 void set_mask(intptr_t mask) { mask_ = mask; }
11377 kCloneSuspendState,
11381 kFfiAsyncCallbackSend,
11390 token_pos_(
source.token_pos) {
11391 SetInputAt(0, operand);
11403 return InputCount();
11409#define FIELD_LIST(F) \
11410 F(const StubId, stub_id_) \
11411 F(const TokenPosition, token_pos_)
11427 kAwaitWithTypeCheck,
11429 kSuspendSyncStarAtStart,
11430 kSuspendSyncStarAtYield,
11438 intptr_t resume_deopt_id)
11441 resume_deopt_id_(resume_deopt_id),
11442 token_pos_(
source.token_pos) {
11443 SetInputAt(0, operand);
11444 if (has_type_args()) {
11445 SetInputAt(1, type_args);
11447 ASSERT(type_args ==
nullptr);
11452 virtual intptr_t
InputCount()
const {
return has_type_args() ? 2 : 1; }
11456 ASSERT(has_type_args());
11469 return InputCount();
11477#define FIELD_LIST(F) \
11478 F(StubId, stub_id_) \
11479 F(const intptr_t, resume_deopt_id_) \
11480 F(const TokenPosition, token_pos_)
11491#undef DECLARE_INSTRUCTION
11499 : environment_(environment), index_(0) {}
11503 environment_(other.environment_),
11504 index_(other.index_) {}
11507 environment_ = other.environment_;
11508 index_ = other.index_;
11520 return (environment_ ==
nullptr) || (index_ >= environment_->Length());
11525 ASSERT(environment_->values_[index_] !=
nullptr);
11526 return environment_->values_[index_];
11532 environment_->values_[index_] =
value;
11537 return environment_->locations_[index_];
11542 environment_->locations_[index_] = loc;
11560 iterator_.Advance();
11564 bool Done()
const {
return iterator_.environment() ==
nullptr; }
11568 return iterator_.CurrentValue();
11573 iterator_.SetCurrentValue(
value);
11578 return iterator_.CurrentLocation();
11583 iterator_.SetCurrentLocation(loc);
11588 while (!Done() && iterator_.Done()) {
11593 ShallowIterator iterator_;
11597 static Environment* From(Zone* zone,
11598 const GrowableArray<Definition*>& definitions,
11599 intptr_t fixed_parameter_count,
11600 intptr_t lazy_deopt_pruning_count,
11601 const ParsedFunction& parsed_function);
11604 ASSERT(locations_ ==
nullptr);
11605 locations_ = locations;
11612 ASSERT(DeoptIdBits::decode(bitfield_) != DeoptId::kNone);
11613 return DeoptIdBits::decode(bitfield_);
11617 return LazyDeoptPruningBits::decode(bitfield_);
11621 return LazyDeoptToBeforeDeoptId::decode(bitfield_);
11625 bitfield_ = LazyDeoptToBeforeDeoptId::update(
true, bitfield_);
11628 bitfield_ = LazyDeoptPruningBits::update(0, bitfield_);
11637 if (LazyDeoptToBeforeDeoptId()) {
11638 ASSERT(LazyDeoptPruneCount() == 0);
11640 const intptr_t num_args_to_prune = LazyDeoptPruneCount();
11641 if (num_args_to_prune == 0)
return this;
11642 return DeepCopy(zone, Length() - num_args_to_prune);
11649 while (
result->outer() !=
nullptr)
11656 void PushValue(
Value* value);
11658 intptr_t
Length()
const {
return values_.length(); }
11661 ASSERT((index >= 0) && (index < values_.length()));
11662 return locations_[index];
11668 while (index >=
env->Length()) {
11670 index -=
env->Length();
11673 return env->ValueAt(index);
11679 intptr_t
count = 0;
11681 if (it.CurrentValue()->definition()->IsMoveArgument()) {
11693 void DeepCopyToOuter(
Zone* zone,
11695 intptr_t outer_deopt_id)
const;
11697 void DeepCopyAfterTo(
Zone* zone,
11718 class LazyDeoptPruningBits :
public BitField<uintptr_t, uintptr_t, 0, 8> {};
11719 class LazyDeoptToBeforeDeoptId
11720 :
public BitField<uintptr_t, bool, LazyDeoptPruningBits::kNextBit, 1> {};
11721 class Hoisted :
public BitField<uintptr_t,
11723 LazyDeoptToBeforeDeoptId::kNextBit,
11725 class DeoptIdBits :
public BitField<uintptr_t,
11728 kBitsPerWord - Hoisted::kNextBit,
11731 Environment(intptr_t
length,
11732 intptr_t fixed_parameter_count,
11733 intptr_t lazy_deopt_pruning_count,
11735 Environment* outer)
11737 fixed_parameter_count_(fixed_parameter_count),
11740 LazyDeoptPruningBits::
encode(lazy_deopt_pruning_count)),
11744 void SetDeoptId(intptr_t deopt_id) {
11745 bitfield_ = DeoptIdBits::update(deopt_id, bitfield_);
11747 void SetLazyDeoptPruneCount(intptr_t value) {
11748 bitfield_ = LazyDeoptPruningBits::update(value, bitfield_);
11750 void SetLazyDeoptToBeforeDeoptId(
bool value) {
11751 bitfield_ = LazyDeoptToBeforeDeoptId::update(value, bitfield_);
11754 GrowableArray<Value*> values_;
11756 const intptr_t fixed_parameter_count_;
11759 uintptr_t bitfield_;
11760 const Function& function_;
11761 Environment* outer_;
11773#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
11774 virtual void Visit##ShortName(ShortName##Instr* instr) {}
11778#undef DECLARE_VISIT_INSTRUCTION
11789 : current_iterator_(nullptr), block_order_(&block_order) {}
11793 return current_iterator_;
11798 virtual void VisitBlocks();
11802 block_order_ = &block_order;
11813#define DEFINE_UNIMPLEMENTED_INSTRUCTION(Name) \
11814 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \
11818 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { \
11822template <
intptr_t kExtraInputs>
11824 if (
auto static_call = this->AsStaticCall()) {
11825 return static_call->function().name();
11826 }
else if (
auto instance_call = this->AsInstanceCall()) {
11827 return instance_call->function_name().ptr();
11835 return (constant ==
nullptr) || constant->
value().
ptr() ==
value.ptr();
11837#undef DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS
11838#undef DECLARE_CUSTOM_SERIALIZATION
11839#undef DECLARE_EMPTY_SERIALIZATION
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
static float next(float f)
static float prev(float f)
static sk_sp< Effect > Create()
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
static void encode(uint8_t output[16], const uint32_t input[4])
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define DEBUG_ASSERT(cond)
#define ASSERT_EQUAL(expected, actual)
#define COMPILE_ASSERT(expr)
static AliasIdentity NotAliased()
static AliasIdentity Aliased()
bool IsNotAliased() const
AliasIdentity & operator=(const AliasIdentity &other)
bool IsAllocationSinkingCandidate() const
static AliasIdentity Unknown()
AliasIdentity(const AliasIdentity &other)
static AliasIdentity AllocationSinkingCandidate()
virtual const Slot * SlotForInput(intptr_t pos)
virtual bool WillAllocateNewOrRemembered() const
virtual bool AllowsCSE() const
virtual intptr_t InputCount() const
virtual bool AttributesEqual(const Instruction &other) const
bool has_instantiator_type_args() const
Value * closure_function() const
virtual bool HasUnknownSideEffects() const
const Function & known_function() const
AllocateClosureInstr(const InstructionSource &source, Value *closure_function, Value *context, Value *instantiator_type_args, bool is_generic, bool is_tear_off, intptr_t deopt_id)
virtual bool HasUnknownSideEffects() const
const ZoneGrowableArray< const Slot * > & context_slots() const
virtual bool ComputeCanDeoptimize() const
AllocateContextInstr(const InstructionSource &source, const ZoneGrowableArray< const Slot * > &context_slots, intptr_t deopt_id)
intptr_t num_context_variables() const
virtual bool WillAllocateNewOrRemembered() const
DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr)
Value * type_arguments() const
virtual bool MayHaveVisibleEffect() const
const Class & cls() const
virtual bool HasUnknownSideEffects() const
virtual Value * InputAt(intptr_t i) const
AllocateObjectInstr(const InstructionSource &source, const Class &cls, intptr_t deopt_id, Value *type_arguments=nullptr)
virtual const Slot * SlotForInput(intptr_t pos)
virtual bool WillAllocateNewOrRemembered() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(AllocateObjectInstr, AllocationInstr, FIELD_LIST) private
static bool WillAllocateNewOrRemembered(const Class &cls)
virtual intptr_t InputCount() const
virtual bool HasUnknownSideEffects() const
virtual bool WillAllocateNewOrRemembered() const
AllocateRecordInstr(const InstructionSource &source, RecordShape shape, intptr_t deopt_id)
RecordShape shape() const
intptr_t num_fields() const
virtual bool WillAllocateNewOrRemembered() const
intptr_t num_fields() const
AllocateSmallRecordInstr(const InstructionSource &source, RecordShape shape, Value *value0, Value *value1, Value *value2, intptr_t deopt_id)
virtual const Slot * SlotForInput(intptr_t pos)
virtual bool HasUnknownSideEffects() const
RecordShape shape() const
virtual intptr_t InputCount() const
virtual bool WillAllocateNewOrRemembered() const
AllocateTypedDataInstr(const InstructionSource &source, classid_t class_id, Value *num_elements, intptr_t deopt_id)
classid_t class_id() const
virtual Value * num_elements() const
virtual bool HasUnknownSideEffects() const
virtual const Slot * SlotForInput(intptr_t pos)
virtual bool WillAllocateNewOrRemembered() const
virtual bool HasUnknownSideEffects() const
intptr_t num_context_variables() const
virtual bool ObjectIsInitialized()
virtual bool MayThrow() const
intptr_t InputForSlot(const Slot &slot)
virtual bool WillAllocateNewOrRemembered() const =0
virtual AliasIdentity Identity() const
virtual bool ObjectIsInitialized()
virtual void SetIdentity(AliasIdentity identity)
virtual const Slot * SlotForInput(intptr_t pos)
AllocationInstr(const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
virtual TokenPosition token_pos() const
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
PRINT_OPERANDS_TO_SUPPORT DECLARE_ABSTRACT_INSTRUCTION(Allocation)
intptr_t GetConstantNumElements() const
ArrayAllocationInstr(const InstructionSource &source, intptr_t deopt_id)
bool HasConstantNumElements() const
virtual Value * num_elements() const =0
DECLARE_ABSTRACT_INSTRUCTION(ArrayAllocation)
virtual bool ComputeCanDeoptimize() const
const String & dst_name() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
Value * function_type_arguments() const
Value * instantiator_type_arguments() const
virtual bool AttributesEqual(const Instruction &other) const
virtual bool CanBecomeDeoptimizationTarget() const
virtual bool ComputeCanDeoptimizeAfterCall() const
@ FOR_EACH_ASSERT_ASSIGNABLE_KIND
AssertAssignableInstr(const InstructionSource &source, Value *value, Value *dst_type, Value *instantiator_type_arguments, Value *function_type_arguments, const String &dst_name, intptr_t deopt_id, Kind kind=kUnknown)
virtual TokenPosition token_pos() const
virtual TokenPosition token_pos() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
virtual bool AttributesEqual(const Instruction &other) const
AssertBooleanInstr(const InstructionSource &source, Value *value, intptr_t deopt_id)
virtual bool ComputeCanDeoptimize() const
virtual bool CanBecomeDeoptimizationTarget() const
AssertSubtypeInstr(const InstructionSource &source, Value *instantiator_type_arguments, Value *function_type_arguments, Value *sub_type, Value *super_type, Value *dst_name, intptr_t deopt_id)
virtual bool AttributesEqual(const Instruction &other) const
Value * function_type_arguments() const
DECLARE_INSTRUCTION(AssertSubtype)
virtual TokenPosition token_pos() const
Value * super_type() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool ComputeCanDeoptimize() const
Value * instantiator_type_arguments() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
Instruction * Current() const
BackwardInstructionIterator(BlockEntryInstr *block_entry)
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
BinaryDoubleOpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, const InstructionSource &source, SpeculativeMode speculative_mode=kGuardInputs, Representation representation=kUnboxedDouble)
Token::Kind op_kind() const
virtual TokenPosition token_pos() const
virtual Representation representation() const
virtual bool ComputeCanDeoptimize() const
virtual intptr_t DeoptimizationTarget() const
bool OperandsAre(intptr_t cid) const
bool OperandsAreSmiOrMint() const
bool IncludesOperands(intptr_t cid) const
bool OperandsAreSmiOrNull() const
bool ArgumentIs(intptr_t cid) const
static const BinaryFeedback * CreateMonomorphic(Zone *zone, intptr_t receiver_cid, intptr_t argument_cid)
bool OperandsAreSmiOrDouble() const
bool OperandsAreEither(intptr_t cid_a, intptr_t cid_b) const
BinaryFeedback(Zone *zone)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
BinaryInt32OpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id)
virtual Representation representation() const
static bool IsSupported(Token::Kind op_kind, Value *left, Value *right)
virtual bool ComputeCanDeoptimize() const
BinaryInt64OpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation representation() const
virtual bool MayThrow() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
void set_can_overflow(bool overflow)
bool can_overflow() const
Token::Kind op_kind() const
bool is_truncating() const
BinaryIntegerOpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id)
virtual intptr_t DeoptimizationTarget() const
BinarySmiOpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, Range *right_range=nullptr)
virtual bool ComputeCanDeoptimize() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual Representation representation() const
BinaryUint32OpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
static bool IsSupported(Token::Kind op_kind)
BitCastInstr(Representation from, Representation to, Value *value)
Representation to() const
virtual bool AttributesEqual(const Instruction &other) const
virtual bool ComputeCanDeoptimize() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
Representation from() const
DECLARE_INSTRUCTION(BitCast)
virtual Representation representation() const
ForwardInstructionIterator end() const
ForwardInstructionIterator begin() const
InstructionsIterable(BlockEntryInstr *block)
BlockEntryInstr * dominator() const
InstructionsIterable instructions()
void ClearDominatedBlocks()
intptr_t NestingDepth() const
void set_preorder_number(intptr_t number)
intptr_t try_index() const
intptr_t postorder_number() const
ParallelMoveInstr * GetParallelMove()
bool FindOsrEntryAndRelink(GraphEntryInstr *graph_entry, Instruction *parent, BitVector *block_marks)
void AddDominatedBlock(BlockEntryInstr *block)
virtual void ClearPredecessors()=0
ParallelMoveInstr * parallel_move() const
void set_block_id(intptr_t block_id)
virtual bool ComputeCanDeoptimize() const
bool HasNonRedundantParallelMove() const
intptr_t preorder_number() const
bool HasParallelMove() const
bool InsideTryBlock() const
intptr_t block_id() const
virtual bool HasUnknownSideEffects() const
virtual intptr_t PredecessorCount() const =0
void set_try_index(intptr_t index)
BlockEntryInstr * ImmediateDominator() const
LoopInfo * loop_info() const
virtual BlockEntryInstr * GetBlock()
void set_loop_info(LoopInfo *loop_info)
virtual void AddPredecessor(BlockEntryInstr *predecessor)=0
void set_end_pos(intptr_t pos)
void set_stack_depth(intptr_t s)
const GrowableArray< BlockEntryInstr * > & dominated_blocks()
void set_start_pos(intptr_t pos)
bool Dominates(BlockEntryInstr *other) const
virtual bool CanBecomeDeoptimizationTarget() const
BlockEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id, intptr_t stack_depth)
void ReplaceAsPredecessorWith(BlockEntryInstr *new_block)
void set_postorder_number(intptr_t number)
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const =0
bool IsLoopHeader() const
void ClearAllInstructions()
virtual TokenPosition token_pos() const
void set_last_instruction(Instruction *instr)
intptr_t stack_depth() const
bool DiscoverBlock(BlockEntryInstr *predecessor, GrowableArray< BlockEntryInstr * > *preorder, GrowableArray< intptr_t > *parent)
intptr_t start_pos() const
Instruction * last_instruction() const
const GrowableArray< Definition * > * initial_definitions() const
void PrintInitialDefinitionsTo(BaseTextBuffer *f) const
virtual BlockEntryWithInitialDefs * AsBlockEntryWithInitialDefs()
BlockEntryWithInitialDefs(intptr_t block_id, intptr_t try_index, intptr_t deopt_id, intptr_t stack_depth)
GrowableArray< Definition * > * initial_definitions()
virtual const BlockEntryWithInitialDefs * AsBlockEntryWithInitialDefs() const
virtual bool ComputeCanDeoptimize() const
virtual bool HasUnknownSideEffects() const
virtual Representation representation() const
BoolToIntInstr(Value *value)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool ComputeCanDeoptimize() const
virtual bool HasUnknownSideEffects() const
BooleanNegateInstr(Value *value)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual bool ComputeCanDeoptimize() const
virtual TokenPosition token_pos() const
virtual intptr_t DeoptimizationTarget() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(BoxInstr, TemplateDefinition, FIELD_LIST) protected
Representation from_representation() const
virtual bool AttributesEqual(const Instruction &other) const
BoxInt32Instr(Value *value)
BoxInt64Instr(Value *value)
BoxInteger32Instr(Representation representation, Value *value)
BoxIntegerInstr(Representation representation, Value *value)
virtual bool CanTriggerGC() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
intptr_t InputCount() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool AttributesEqual(const Instruction &other) const
virtual intptr_t DeoptimizationTarget() const
BoxLanesInstr(Representation from_representation, Value *x, Value *y)
virtual TokenPosition token_pos() const
virtual bool ComputeCanDeoptimize() const
BoxLanesInstr(Representation from_representation, Value *x, Value *y, Value *z, Value *w)
Representation from_representation() const
BoxSmallIntInstr(Representation rep, Value *value)
virtual bool ValueFitsSmi() const
BoxUint32Instr(Value *value)
virtual void CopyDeoptIdFrom(const Instruction &instr)
TargetEntryInstr ** false_successor_address()
TargetEntryInstr * false_successor() const
intptr_t InputCount() const
void set_constant_target(TargetEntryInstr *target)
virtual void SetMoveArguments(MoveArgumentsArray *move_arguments)
virtual bool MayThrow() const
virtual MoveArgumentsArray * GetMoveArguments() const
TargetEntryInstr ** true_successor_address()
virtual bool has_inlining_id() const
virtual void RawSetInputAt(intptr_t i, Value *value)
virtual bool ComputeCanDeoptimize() const
virtual intptr_t inlining_id() const
TargetEntryInstr * constant_target() const
virtual intptr_t DeoptimizationTarget() const
virtual void set_inlining_id(intptr_t value)
virtual bool HasUnknownSideEffects() const
TargetEntryInstr * true_successor() const
ComparisonInstr * comparison() const
virtual Representation RequiredInputRepresentation(intptr_t i) const
Value * InputAt(intptr_t i) const
BranchInstr(ComparisonInstr *comparison, intptr_t deopt_id)
virtual bool CanCallDart() const
virtual TokenPosition token_pos() const
virtual bool CanBecomeDeoptimizationTarget() const
virtual bool ComputeCanDeoptimize() const
virtual void SetIdentity(AliasIdentity identity)
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool HasUnknownSideEffects() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const
virtual AliasIdentity Identity() const
virtual bool CanBecomeDeoptimizationTarget() const
virtual Representation representation() const
virtual bool MayCreateUnsafeUntaggedPointer() const
virtual bool CanCallDart() const
CalculateElementAddressInstr(Value *base, Value *index, intptr_t index_scale, Value *offset)
virtual bool MayCreateUnsafeUntaggedPointer() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
intptr_t index_scale() const
virtual bool HasUnknownSideEffects() const
virtual bool AllowsCSE() const
virtual bool AttributesEqual(const Instruction &other) const
virtual bool ComputeCanDeoptimize() const
Call1ArgStubInstr(const InstructionSource &source, StubId stub_id, Value *operand, intptr_t deopt_id)
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
virtual TokenPosition token_pos() const
virtual bool ComputeCanDeoptimize() const
DECLARE_INSTRUCTION(Call1ArgStub)
virtual bool HasUnknownSideEffects() const
virtual bool CanCallDart() const
virtual bool ComputeCanDeoptimizeAfterCall() const
void Write(FlowGraphSerializer *s) const
bool ReceiverIs(intptr_t cid) const
bool ReceiverIsSmiOrMint() const
static const CallTargets * CreateMonomorphic(Zone *zone, intptr_t receiver_cid, const Function &target)
const Function & MostPopularTarget() const
TargetInfo * TargetAt(int i) const
bool HasSingleTarget() const
static const CallTargets * CreateAndExpand(Zone *zone, const ICData &ic_data)
intptr_t AggregateCallCount() const
const Function & FirstTarget() const
StaticTypeExactnessState MonomorphicExactness() const
bool HasSingleRecognizedTarget() const
virtual bool ComputeCanDeoptimize() const
Value * rhs_index() const
CaseInsensitiveCompareInstr(Value *str, Value *lhs_index, Value *rhs_index, Value *length, bool handle_surrogates, intptr_t cid)
intptr_t class_id() const
Value * lhs_index() const
virtual Representation representation() const
virtual bool AttributesEqual(const Instruction &other) const
intptr_t index_scale() const
const LocalVariable * exception_var() const
CatchBlockEntryInstr(bool is_generated, intptr_t block_id, intptr_t try_index, GraphEntryInstr *graph_entry, const Array &handler_types, intptr_t catch_try_index, bool needs_stacktrace, intptr_t deopt_id, const LocalVariable *exception_var, const LocalVariable *stacktrace_var, const LocalVariable *raw_exception_var, const LocalVariable *raw_stacktrace_var)
const LocalVariable * raw_stacktrace_var() const
virtual void ClearPredecessors()
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const
virtual void AddPredecessor(BlockEntryInstr *predecessor)
intptr_t catch_try_index() const
const Array & catch_handler_types() const
const LocalVariable * stacktrace_var() const
bool needs_stacktrace() const
bool is_generated() const
const LocalVariable * raw_exception_var() const
GraphEntryInstr * graph_entry() const
virtual bool ComputeCanDeoptimize() const
virtual bool AttributesEqual(const Instruction &other) const
CheckArrayBoundInstr(Value *length, Value *index, intptr_t deopt_id)
CheckBoundBaseInstr(Value *length, Value *index, intptr_t deopt_id)
DECLARE_ABSTRACT_INSTRUCTION(CheckBoundBase)
const CidRangeValue & cids() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(CheckClassIdInstr, TemplateInstruction, FIELD_LIST) private DISALLOW_COPY_AND_ASSIGN(CheckClassIdInstr)
virtual bool AllowsCSE() const
virtual bool HasUnknownSideEffects() const
virtual bool AttributesEqual(const Instruction &other) const
CheckClassIdInstr(Value *value, CidRangeValue cids, intptr_t deopt_id)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(CheckClassInstr, TemplateInstruction, FIELD_LIST) private void EmitBitTest(FlowGraphCompiler *compiler, intptr_t min, intptr_t max, intptr_t mask, compiler::Label *deopt)
void EmitNullCheck(FlowGraphCompiler *compiler, compiler::Label *deopt)
virtual TokenPosition token_pos() const
const Cids & cids() const
DISALLOW_COPY_AND_ASSIGN(CheckClassInstr)
virtual bool HasUnknownSideEffects() const
virtual bool AllowsCSE() const
virtual Value * InputAt(intptr_t i) const
CheckConditionInstr(ComparisonInstr *comparison, intptr_t deopt_id)
virtual void CopyDeoptIdFrom(const Instruction &instr)
virtual bool MayThrow() const
virtual bool AllowsCSE() const
virtual intptr_t InputCount() const
ComparisonInstr * comparison() const
DISALLOW_COPY_AND_ASSIGN(CheckConditionInstr)
virtual bool AttributesEqual(const Instruction &other) const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(CheckConditionInstr, Instruction, FIELD_LIST) DECLARE_EXTRA_SERIALIZATION private
virtual bool HasUnknownSideEffects() const
virtual bool AttributesEqual(const Instruction &other) const
CheckEitherNonSmiInstr(Value *left, Value *right, intptr_t deopt_id)
virtual bool UseSharedSlowPathStub(bool is_optimizing) const
virtual bool ComputeCanDeoptimizeAfterCall() const
CheckNullInstr(Value *value, const String &function_name, intptr_t deopt_id, const InstructionSource &source, ExceptionType exception_type=kNoSuchMethod)
virtual bool CanBecomeDeoptimizationTarget() const
const String & function_name() const
virtual TokenPosition token_pos() const
ExceptionType exception_type() const
virtual bool ComputeCanDeoptimize() const
virtual TokenPosition token_pos() const
CheckSmiInstr(Value *value, intptr_t deopt_id, const InstructionSource &source)
virtual bool AttributesEqual(const Instruction &other) const
virtual TokenPosition token_pos() const
virtual bool ComputeCanDeoptimizeAfterCall() const
CheckStackOverflowInstr(const InstructionSource &source, intptr_t stack_depth, intptr_t loop_depth, intptr_t deopt_id, Kind kind)
virtual bool UseSharedSlowPathStub(bool is_optimizing) const
virtual bool HasUnknownSideEffects() const
intptr_t stack_depth() const
virtual bool CanEliminate(const BlockEntryInstr *block) const
intptr_t loop_depth() const
virtual bool ComputeCanDeoptimizeAfterCall() const
CheckWritableInstr(Value *receiver, intptr_t deopt_id, const InstructionSource &source, Kind kind=Kind::kWriteUnmodifiableTypedData)
virtual bool ComputeCanDeoptimize() const
virtual bool AttributesEqual(const Instruction &other) const
static bool ContainsCid(const CidRangeVector &ranges, intptr_t cid)
void Sort(int compare(CidRange *const *a, CidRange *const *b))
bool HasClassId(intptr_t cid) const
static Cids * CreateMonomorphic(Zone *zone, intptr_t cid)
intptr_t MonomorphicReceiverCid() const
static Cids * CreateForArgument(Zone *zone, const BinaryFeedback &binary_feedback, int argument_number)
void SetLength(intptr_t len)
intptr_t ComputeLowestCid() const
CidRange * At(int index) const
intptr_t ComputeHighestCid() const
GrowableArray< CidRange * > cid_ranges_
void Add(CidRange *target)
bool Equals(const Cids &other) const
bool IsMonomorphic() const
CidRange & operator[](intptr_t index) const
intptr_t target_instance_size() const
intptr_t NumTypeArguments() const
virtual TokenPosition token_pos() const
const ZoneGrowableArray< const Slot * > & context_slots() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
virtual bool ComputeCanDeoptimizeAfterCall() const
Value * context_value() const
virtual bool ComputeCanDeoptimize() const
virtual bool HasUnknownSideEffects() const
CloneContextInstr(const InstructionSource &source, Value *context_value, const ZoneGrowableArray< const Slot * > &context_slots, intptr_t deopt_id)
virtual intptr_t CallCount() const
virtual bool HasUnknownSideEffects() const
ClosureCallInstr(const Function &target_function, InputsArray &&inputs, intptr_t type_args_len, const Array &argument_names, const InstructionSource &source, intptr_t deopt_id)
virtual void NegateComparison()
virtual bool CanBecomeDeoptimizationTarget() const
void set_operation_cid(intptr_t value)
bool IsComparisonWithConstant(Value **other_operand, ConstantInstr **constant_operand)
intptr_t operation_cid() const
virtual bool AttributesEqual(const Instruction &other) const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(ComparisonInstr, Definition, FIELD_LIST) protected
virtual intptr_t DeoptimizationTarget() const
virtual TokenPosition token_pos() const
static constexpr intptr_t kNumPasses
static CompilerState & Current()
const Object & value() const
void EmitMoveToLocation(FlowGraphCompiler *compiler, const Location &destination, Register tmp=kNoRegister, intptr_t pair_index=0)
ConstantInstr(const Object &value)
PRINT_OPERANDS_TO_SUPPORT DECLARE_ATTRIBUTE & value()
bool HasZeroRepresentation() const
virtual TokenPosition token_pos() const
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimize() const
void set_target(TargetEntryInstr *target)
TargetEntryInstr * target() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(ConstraintInstr, TemplateDefinition, FIELD_LIST) DECLARE_EXTRA_SERIALIZATION private DISALLOW_COPY_AND_ASSIGN(ConstraintInstr)
ConstraintInstr(Value *value, Range *constraint)
virtual bool HasUnknownSideEffects() const
virtual bool AttributesEqual(const Instruction &other) const
Range * constraint() const
virtual const Slot * SlotForInput(intptr_t pos)
virtual bool WillAllocateNewOrRemembered() const
virtual bool HasUnknownSideEffects() const
CreateArrayInstr(const InstructionSource &source, Value *type_arguments, Value *num_elements, intptr_t deopt_id)
Value * type_arguments() const
virtual Value * num_elements() const
virtual intptr_t InputCount() const
virtual Value * InputAt(intptr_t i) const
virtual bool AttributesEqual(const Instruction &other) const
DartReturnInstr(const InstructionSource &source, Value *value, intptr_t deopt_id, Representation representation=kTagged)
virtual intptr_t DeoptimizationTarget() const
virtual Representation representation() const
virtual Representation RequiredInputRepresentation(intptr_t index) const
virtual bool CanBecomeDeoptimizationTarget() const
virtual void RawSetInputAt(intptr_t i, Value *value)
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimize() const
DebugStepCheckInstr(const InstructionSource &source, UntaggedPcDescriptors::Kind stub_kind, intptr_t deopt_id)
Value * env_use_list() const
PRINT_OPERANDS_TO_SUPPORT PRINT_TO_SUPPORT bool UpdateType(CompileType new_type)
virtual AliasIdentity Identity() const
void SetReplacement(Definition *other)
Value * input_use_list() const
virtual CompileType ComputeType() const
Definition * Replacement()
virtual bool CanEliminate(const BlockEntryInstr *block) const
intptr_t location_count() const
void AddEnvUse(Value *value)
void set_temp_index(intptr_t index)
void set_type(CompileType *type)
virtual intptr_t CallCount() const
virtual bool MayCreateUnsafeUntaggedPointer() const
bool HasPairRepresentation() const
virtual Definition * AsDefinition()
Definition(intptr_t deopt_id=DeoptId::kNone)
intptr_t vreg(intptr_t index) const
Definition(const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
void AddInputUse(Value *value)
intptr_t temp_index() const
virtual bool RecomputeType()
void set_ssa_temp_index(intptr_t index)
void set_input_use_list(Value *head)
virtual const Definition * AsDefinition() const
virtual void SetIdentity(AliasIdentity identity)
virtual bool CanReplaceWithConstant() const
ValueListIterable input_uses() const
intptr_t ssa_temp_index() const
void set_env_use_list(Value *head)
static constexpr intptr_t kNone
virtual bool AttributesEqual(const Instruction &other) const
virtual bool ComputeCanDeoptimize() const
DeoptimizeInstr(ICData::DeoptReasonId deopt_reason, intptr_t deopt_id)
virtual bool HasUnknownSideEffects() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const
virtual bool CanBecomeDeoptimizationTarget() const
virtual intptr_t DeoptimizationTarget() const
const compiler::TableSelector * selector() const
const char * selector_name() const
DispatchTableCallInstr(const InstructionSource &source, const Function &interface_target, const compiler::TableSelector *selector, InputsArray &&arguments, intptr_t type_args_len, const Array &argument_names)
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool ComputeCanDeoptimize() const
MethodRecognizer::Kind op_kind() const
DoubleTestOpInstr(MethodRecognizer::Kind op_kind, Value *value, intptr_t deopt_id, const InstructionSource &source)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
virtual intptr_t DeoptimizationTarget() const
virtual bool AttributesEqual(const Instruction &other) const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
DoubleToFloatInstr(Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
virtual intptr_t DeoptimizationTarget() const
virtual bool AttributesEqual(const Instruction &other) const
MethodRecognizer::Kind recognized_kind() const
virtual bool HasUnknownSideEffects() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const
virtual bool ComputeCanDeoptimize() const
DoubleToIntegerInstr(Value *value, MethodRecognizer::Kind recognized_kind, intptr_t deopt_id)
virtual intptr_t DeoptimizationTarget() const
DoubleToSmiInstr(Value *value, intptr_t deopt_id)
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool ComputeCanDeoptimize() const
DISALLOW_COPY_AND_ASSIGN(DropTempsInstr)
virtual bool HasUnknownSideEffects() const
intptr_t num_temps() const
DropTempsInstr(intptr_t num_temps, Value *value)
virtual TokenPosition token_pos() const
virtual Value * InputAt(intptr_t i) const
virtual bool ComputeCanDeoptimize() const
virtual bool MayThrow() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(DropTempsInstr, Definition, FIELD_LIST) private
T & operator[](intptr_t i)
const T & operator[](intptr_t i) const
void SetAt(intptr_t i, const T &val)
T & operator[](intptr_t i)
const T & At(intptr_t i) const
const T & operator[](intptr_t i) const
void SetCurrentValue(Value *value)
Value * CurrentValue() const
Location CurrentLocation() const
DeepIterator(Environment *environment)
void SetCurrentLocation(Location loc)
ShallowIterator(Environment *environment)
Environment * environment() const
void SetCurrentLocation(Location loc)
ShallowIterator(const ShallowIterator &other)
ShallowIterator & operator=(const ShallowIterator &other)
Value * CurrentValue() const
Location CurrentLocation() const
void SetCurrentValue(Value *value)
intptr_t CountArgsPushed()
Location LocationAt(intptr_t index) const
intptr_t fixed_parameter_count() const
intptr_t LazyDeoptPruneCount() const
void PrintTo(BaseTextBuffer *f) const
void set_locations(Location *locations)
void MarkAsLazyDeoptToBeforeDeoptId()
const Function & function() const
const char * ToCString() const
intptr_t GetDeoptId() const
bool LazyDeoptToBeforeDeoptId() const
Environment * Outermost()
Value * ValueAt(intptr_t ix) const
Environment * DeepCopy(Zone *zone) const
Environment * outer() const
Environment * GetLazyDeoptEnv(Zone *zone)
Value * ValueAtUseIndex(intptr_t index) const
virtual bool AttributesEqual(const Instruction &other) const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual bool ComputeCanDeoptimize() const
EqualityCompareInstr(const InstructionSource &source, Token::Kind kind, Value *left, Value *right, intptr_t cid, intptr_t deopt_id, bool null_aware=false, SpeculativeMode speculative_mode=kGuardInputs)
bool is_null_aware() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
void set_null_aware(bool value)
intptr_t CompoundReturnTypedDataIndex() const
DISALLOW_COPY_AND_ASSIGN(FfiCallInstr)
FfiCallInstr(intptr_t deopt_id, const compiler::ffi::CallMarshaller &marshaller, bool is_leaf, InputsArray &&inputs)
virtual bool MayThrow() const
virtual bool HasUnknownSideEffects() const
static intptr_t InputCountForMarshaller(const compiler::ffi::CallMarshaller &marshaller)
static bool CanExecuteGeneratedCodeInSafepoint()
virtual bool MayCreateUnsafeUntaggedPointer() const
virtual bool CanCallDart() const
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimizeAfterCall() const
Token::Kind op_kind() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
FloatCompareInstr(Token::Kind op_kind, Value *left, Value *right)
virtual bool AttributesEqual(const Instruction &other) const
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual intptr_t DeoptimizationTarget() const
FloatToDoubleInstr(Value *value, intptr_t deopt_id)
virtual bool ComputeCanDeoptimize() const
void set_block_order(const GrowableArray< BlockEntryInstr * > &block_order)
FlowGraphVisitor(const GrowableArray< BlockEntryInstr * > &block_order)
ForwardInstructionIterator * current_iterator() const
virtual ~FlowGraphVisitor()
ForwardInstructionIterator * current_iterator_
ForwardInstructionIterator(const ForwardInstructionIterator &other)=default
ForwardInstructionIterator & operator++()
ForwardInstructionIterator()
Instruction * operator*() const
ForwardInstructionIterator(BlockEntryInstr *block_entry)
bool operator!=(const ForwardInstructionIterator &other) const
Instruction * Current() const
bool operator==(const ForwardInstructionIterator &other) const
void RemoveCurrentFromGraph()
ForwardInstructionIterator & operator=(const ForwardInstructionIterator &other)=default
GraphEntryInstr * graph_entry() const
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const
virtual void ClearPredecessors()
virtual void AddPredecessor(BlockEntryInstr *predecessor)
FunctionEntryInstr(GraphEntryInstr *graph_entry, intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
GenericCheckBoundInstr(Value *length, Value *index, intptr_t deopt_id)
virtual intptr_t DeoptimizationTarget() const
virtual bool MayThrow() const
virtual bool AttributesEqual(const Instruction &other) const
static bool UseUnboxedRepresentation()
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool UseSharedSlowPathStub(bool is_optimizing) const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool ComputeCanDeoptimize() const
virtual Representation representation() const
ParallelMoveInstr * parallel_move() const
bool HasNonRedundantParallelMove() const
bool HasParallelMove() const
JoinEntryInstr * successor() const
void adjust_edge_weight(double scale_factor)
double edge_weight() const
void set_edge_weight(double weight)
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimize() const
virtual intptr_t DeoptimizationTarget() const
DISALLOW_COPY_AND_ASSIGN(GotoInstr)
void set_successor(JoinEntryInstr *successor)
void set_block(BlockEntryInstr *block)
virtual bool CanBecomeDeoptimizationTarget() const
GotoInstr(JoinEntryInstr *entry, intptr_t deopt_id)
virtual TokenPosition token_pos() const
ParallelMoveInstr * GetParallelMove()
intptr_t fixed_slot_count() const
intptr_t entry_count() const
void AddCatchEntry(CatchBlockEntryInstr *entry)
FunctionEntryInstr * normal_entry() const
intptr_t spill_slot_count() const
FunctionEntryInstr * unchecked_entry() const
void AddIndirectEntry(IndirectEntryInstr *entry)
void set_unchecked_entry(FunctionEntryInstr *target)
const ParsedFunction & parsed_function() const
bool HasSingleEntryPoint() const
void set_normal_entry(FunctionEntryInstr *entry)
const GrowableArray< IndirectEntryInstr * > & indirect_entries() const
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const
void set_fixed_slot_count(intptr_t count)
virtual void ClearPredecessors()
virtual void AddPredecessor(BlockEntryInstr *predecessor)
void set_osr_entry(OsrEntryInstr *entry)
OsrEntryInstr * osr_entry() const
void set_spill_slot_count(intptr_t count)
void set_entry_count(intptr_t count)
const GrowableArray< CatchBlockEntryInstr * > & catch_entries() const
GuardFieldClassInstr(Value *value, const Field &field, intptr_t deopt_id)
virtual bool ComputeCanDeoptimize() const
virtual bool CanBecomeDeoptimizationTarget() const
const Field & field() const
GuardFieldInstr(Value *value, const Field &field, intptr_t deopt_id)
GuardFieldLengthInstr(Value *value, const Field &field, intptr_t deopt_id)
GuardFieldTypeInstr(Value *value, const Field &field, intptr_t deopt_id)
virtual Representation representation() const
virtual CompileType ComputeType() const
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
HashDoubleOpInstr(Value *value, intptr_t deopt_id)
virtual intptr_t DeoptimizationTarget() const
static HashDoubleOpInstr * Create(Value *value, intptr_t deopt_id)
HashIntegerOpInstr(Value *value, bool smi, intptr_t deopt_id)
virtual Representation representation() const
virtual CompileType ComputeType() const
static HashIntegerOpInstr * Create(Value *value, bool smi, intptr_t deopt_id)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool AttributesEqual(const Instruction &other) const
virtual intptr_t DeoptimizationTarget() const
bool InstanceOfHasClassRange(const AbstractType &type, intptr_t *lower_limit, intptr_t *upper_limit)
bool CanUseGenericSubtypeRangeCheckFor(const AbstractType &type)
const CidRangeVector & SubtypeRangesForClass(const Class &klass, bool include_abstract, bool exclude_null)
static constexpr intptr_t kNoCompatibleTAVOffset
HierarchyInfo(Thread *thread)
bool CanUseRecordSubtypeRangeCheckFor(const AbstractType &type)
bool CanUseSubtypeRangeCheckFor(const AbstractType &type)
virtual bool AllowsCSE() const
virtual bool HasUnknownSideEffects() const
Value * InputAt(intptr_t i) const
virtual void CopyDeoptIdFrom(const Instruction &instr)
virtual bool CanCallDart() const
ComparisonInstr * comparison() const
DISALLOW_COPY_AND_ASSIGN(IfThenElseInstr)
intptr_t if_false() const
virtual bool MayThrow() const
virtual bool ComputeCanDeoptimize() const
virtual bool AttributesEqual(const Instruction &other) const
virtual bool CanBecomeDeoptimizationTarget() const
IfThenElseInstr(ComparisonInstr *comparison, Value *if_true, Value *if_false, intptr_t deopt_id)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(IfThenElseInstr, Definition, FIELD_LIST) DECLARE_EXTRA_SERIALIZATION private
virtual intptr_t DeoptimizationTarget() const
virtual Representation RequiredInputRepresentation(intptr_t i) const
IndirectEntryInstr(intptr_t block_id, intptr_t indirect_id, intptr_t try_index, intptr_t deopt_id)
virtual bool ComputeCanDeoptimize() const
virtual intptr_t SuccessorCount() const
void AddSuccessor(TargetEntryInstr *successor)
virtual bool CanBecomeDeoptimizationTarget() const
virtual TargetEntryInstr * SuccessorAt(intptr_t index) const
virtual bool HasUnknownSideEffects() const
IndirectGotoInstr(intptr_t target_count, Value *target_index)
void set_ic_data(const ICData *value)
CompileType * result_type() const
virtual intptr_t DeoptimizationTarget() const
DECLARE_ABSTRACT_INSTRUCTION(InstanceCallBase)
void set_result_type(CompileType *result_type)
virtual bool CanBecomeDeoptimizationTarget() const
Code::EntryKind entry_kind() const
void set_has_unique_selector(bool b)
const ICData * ic_data() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(InstanceCallBaseInstr, TemplateDartCall, FIELD_LIST) protected void set_ic_data(ICData *value)
void set_receiver_is_not_smi(bool value)
const Function & tearoff_interface_target() const
InstanceCallBaseInstr(const InstructionSource &source, const String &function_name, Token::Kind token_kind, InputsArray &&arguments, intptr_t type_args_len, const Array &argument_names, const ICData *ic_data, intptr_t deopt_id, const Function &interface_target, const Function &tearoff_interface_target)
const Function & interface_target() const
bool is_call_on_this() const
void SetResultType(Zone *zone, CompileType new_type)
Token::Kind token_kind() const
void mark_as_call_on_this()
bool receiver_is_not_smi() const
virtual bool HasUnknownSideEffects() const
intptr_t result_cid() const
void set_entry_kind(Code::EntryKind value)
const String & function_name() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const
bool has_unique_selector() const
InstanceCallInstr(const InstructionSource &source, const String &function_name, Token::Kind token_kind, InputsArray &&arguments, intptr_t type_args_len, const Array &argument_names, intptr_t checked_argument_count, const ZoneGrowableArray< const ICData * > &ic_data_array, intptr_t deopt_id, const Function &interface_target=Function::null_function(), const Function &tearoff_interface_target=Function::null_function())
virtual intptr_t CallCount() const
DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr)
void SetTargets(const CallTargets *targets)
void set_receivers_static_type(const AbstractType *receiver_type)
InstanceCallInstr(const InstructionSource &source, const String &function_name, Token::Kind token_kind, InputsArray &&arguments, intptr_t type_args_len, const Array &argument_names, intptr_t checked_argument_count, intptr_t deopt_id, const Function &interface_target=Function::null_function(), const Function &tearoff_interface_target=Function::null_function())
void SetBinaryFeedback(const class BinaryFeedback *binary)
InstanceOfInstr(const InstructionSource &source, Value *value, Value *instantiator_type_arguments, Value *function_type_arguments, const AbstractType &type, intptr_t deopt_id)
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimizeAfterCall() const
const AbstractType & type() const
virtual bool HasUnknownSideEffects() const
virtual TokenPosition token_pos() const
Value * function_type_arguments() const
Value * instantiator_type_arguments() const
Value * type_arguments() const
Value * function_type_arguments() const
InstantiateTypeArgumentsInstr(const InstructionSource &source, Value *instantiator_type_arguments, Value *function_type_arguments, Value *type_arguments, const Class &instantiator_class, const Function &function, intptr_t deopt_id)
virtual bool ComputeCanDeoptimizeAfterCall() const
bool CanShareFunctionTypeArguments(bool *with_runtime_check=nullptr) const
virtual TokenPosition token_pos() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
virtual bool HasUnknownSideEffects() const
const Class & instantiator_class() const
const Function & function() const
const Code & GetStub() const
virtual bool ComputeCanDeoptimize() const
bool CanShareInstantiatorTypeArguments(bool *with_runtime_check=nullptr) const
virtual bool HasUnknownSideEffects() const
Value * function_type_arguments() const
const AbstractType & type() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool ComputeCanDeoptimize() const
virtual TokenPosition token_pos() const
InstantiateTypeInstr(const InstructionSource &source, const AbstractType &type, Value *instantiator_type_arguments, Value *function_type_arguments, intptr_t deopt_id)
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
InstructionIndexedPropertyIterable(const Instruction *instr)
virtual ~InstructionVisitor()
bool WasEliminated() const
void InsertBefore(Instruction *next)
virtual bool AttributesEqual(const Instruction &other) const
virtual void Accept(InstructionVisitor *visitor)=0
Instruction * next() const
virtual intptr_t InputCount() const =0
intptr_t GetDeoptId() const
virtual bool UseSharedSlowPathStub(bool is_optimizing) const
virtual void RawSetInputAt(intptr_t i, Value *value)=0
void set_previous(Instruction *instr)
void SetEnvironment(Environment *deopt_env)
void InheritDeoptTargetAfter(FlowGraph *flow_graph, Definition *call, Definition *result)
void LinkTo(Instruction *next)
Instruction(const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
virtual bool MayThrow() const =0
void InheritDeoptTarget(Zone *zone, Instruction *other)
virtual bool HasUnknownSideEffects() const =0
virtual Value * InputAt(intptr_t i) const =0
void Goto(JoinEntryInstr *entry)
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual BlockEntryInstr * SuccessorAt(intptr_t index) const
virtual BlockEntryInstr * GetBlock()
void ReadExtraWithoutInputs(FlowGraphDeserializer *d)
virtual void CopyDeoptIdFrom(const Instruction &instr)
virtual bool ComputeCanDeoptimize() const =0
virtual bool CanBecomeDeoptimizationTarget() const
Environment * env() const
virtual LocationSummary * MakeLocationSummary(Zone *zone, bool is_optimizing) const =0
virtual void EmitNativeCode(FlowGraphCompiler *compiler)
bool HasUnmatchedInputRepresentations() const
const char * ToCString() const
virtual uword Hash() const
virtual void SetMoveArguments(MoveArgumentsArray *move_arguments)
Instruction * AppendInstruction(Instruction *tail)
void InitializeLocationSummary(Zone *zone, bool optimizing)
void CheckField(const Field &field) const
virtual TokenPosition token_pos() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual void ReplaceInputsWithMoveArguments(MoveArgumentsArray *move_arguments)
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
bool HasPassSpecificId(CompilerPass::Id pass) const
virtual bool MayHaveVisibleEffect() const
virtual intptr_t ArgumentCount() const
void set_next(Instruction *instr)
InstructionIndexedPropertyIterable< SuccessorsTrait > SuccessorsIterable
virtual intptr_t statistics_tag() const
void WriteExtraWithoutInputs(FlowGraphSerializer *s)
static const intptr_t kInstructionAttrs[kNumInstructions]
bool IsDominatedBy(Instruction *dom)
bool Equals(const Instruction &other) const
virtual intptr_t DeoptimizationTarget() const
static const ICData * GetICData(const ZoneGrowableArray< const ICData * > &ic_data_array, intptr_t deopt_id, bool is_static_call)
Definition * ArgumentAt(intptr_t index) const
void Unsupported(FlowGraphCompiler *compiler)
Instruction(intptr_t deopt_id=DeoptId::kNone)
bool NeedsEnvironment() const
virtual Representation representation() const
SuccessorsIterable successors() const
bool CanDeoptimize() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
intptr_t GetPassSpecificId(CompilerPass::Id pass) const
virtual bool AllowsCSE() const
void RepairArgumentUsesInEnvironment() const
void ReplaceInEnvironment(Definition *current, Definition *replacement)
InstructionIndexedPropertyIterable< InputsTrait > InputsIterable
Location::Kind RegisterKindForResult() const
virtual Tag tag() const =0
void SetInputAt(intptr_t i, Value *value)
InstructionSource source() const
Value * ArgumentValueAt(intptr_t index) const
virtual bool has_inlining_id() const
intptr_t deopt_id() const
void InsertAfter(Instruction *prev)
virtual bool CanCallDart() const
virtual intptr_t SuccessorCount() const
Instruction * RemoveFromGraph(bool return_previous=true)
bool HasMoveArguments() const
void SetPassSpecificId(CompilerPass::Id pass, intptr_t id)
SpeculativeMode SpeculativeModeOfInputs() const
virtual MoveArgumentsArray * GetMoveArguments() const
virtual void set_inlining_id(intptr_t value)
static bool SlowPathSharingSupported(bool is_optimizing)
virtual bool CanTriggerGC() const
virtual const char * DebugName() const =0
Instruction * previous() const
static LocationSummary * MakeCallSummary(Zone *zone, const Instruction *instr, LocationSummary *locs=nullptr)
virtual intptr_t inlining_id() const
Int32ToDoubleInstr(Value *value)
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation representation() const
virtual bool ComputeCanDeoptimize() const
virtual bool AttributesEqual(const Instruction &other) const
virtual intptr_t DeoptimizationTarget() const
virtual bool ComputeCanDeoptimize() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
Int64ToDoubleInstr(Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
virtual Representation representation() const
IntConverterInstr(Representation from, Representation to, Value *value, intptr_t deopt_id)
virtual Representation representation() const
DECLARE_INSTRUCTION(IntConverter)
virtual bool MayCreateUnsafeUntaggedPointer() const
bool is_truncating() const
DECLARE_ATTRIBUTES_NAMED(("from", "to", "is_truncating"),(from(), to(), is_truncating())) PRINT_OPERANDS_TO_SUPPORT DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(IntConverterInstr
virtual intptr_t DeoptimizationTarget() const
virtual bool AttributesEqual(const Instruction &other) const
Representation to() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
Representation from() const
IntToBoolInstr(Value *value)
virtual bool ComputeCanDeoptimize() const
virtual bool HasUnknownSideEffects() const
virtual Representation representation() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool AllowsCSE() const
virtual bool AttributesEqual(const Instruction &other) const
virtual intptr_t DeoptimizationTarget() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const
MethodRecognizer::Kind recognized_kind() const
virtual bool MayThrow() const
virtual TokenPosition token_pos() const
virtual bool HasUnknownSideEffects() const
ZoneGrowableArray< PhiInstr * > * phis() const
JoinEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id, intptr_t stack_depth=0)
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const
virtual bool HasUnknownSideEffects() const
GrowableArray< BlockEntryInstr * > predecessors_
virtual void ClearPredecessors()
DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr)
virtual CompileType ComputeType() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
virtual bool MayThrow() const
intptr_t TargetAddressIndex() const
virtual bool MayCreateUnsafeUntaggedPointer() const
virtual bool HasUnknownSideEffects() const
virtual bool CanCallDart() const
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimize() const
LoadClassIdInstr(Value *object, Representation representation=kTagged, bool input_can_be_smi=true)
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation representation() const
virtual Representation representation() const
virtual bool ComputeCanDeoptimize() const
intptr_t index_scale() const
bool can_pack_into_smi() const
virtual bool CanTriggerGC() const
intptr_t element_count() const
virtual bool HasUnknownSideEffects() const
LoadCodeUnitsInstr(Value *str, Value *index, intptr_t element_count, intptr_t class_id, const InstructionSource &source)
intptr_t class_id() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
TokenPosition token_pos() const
void set_representation(Representation repr)
bool IsImmutableLengthLoad() const
virtual bool AllowsCSE() const
void set_loads_inner_pointer(InnerPointerAccess value)
const Slot & slot() const
InnerPointerAccess loads_inner_pointer() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
LoadFieldInstr(Value *instance, const Slot &slot, const InstructionSource &source, bool calls_initializer=false, intptr_t deopt_id=DeoptId::kNone)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(LoadFieldInstr, TemplateLoadField, FIELD_LIST) private DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr)
virtual bool CanTriggerGC() const
LoadFieldInstr(Value *instance, const Slot &slot, InnerPointerAccess loads_inner_pointer, const InstructionSource &source, bool calls_initializer=false, intptr_t deopt_id=DeoptId::kNone)
intptr_t class_id() const
TokenPosition token_pos() const
virtual intptr_t DeoptimizationTarget() const
virtual bool ComputeCanDeoptimize() const
virtual bool HasUnknownSideEffects() const
intptr_t index_scale() const
Representation representation() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool HasUnknownSideEffects() const
LoadIndexedUnsafeInstr(Value *index, intptr_t offset, CompileType result_type, Representation representation=kTagged)
Register base_reg() const
virtual Representation representation() const
virtual bool ComputeCanDeoptimize() const
virtual bool AttributesEqual(const Instruction &other) const
LoadLocalInstr(const LocalVariable &local, const InstructionSource &source)
virtual TokenPosition token_pos() const
const LocalVariable & local() const
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimize() const
LoadStaticFieldInstr(const Field &field, const InstructionSource &source, bool calls_initializer=false, intptr_t deopt_id=DeoptId::kNone)
virtual bool AllowsCSE() const
const Field & field() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool MayCreateUnsafeUntaggedPointer() const
DECLARE_INSTRUCTION(LoadThread)
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation representation() const
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimize() const
LoadUntaggedInstr(Value *object, intptr_t offset)
virtual bool HasUnknownSideEffects() const
virtual bool MayCreateUnsafeUntaggedPointer() const
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation representation() const
static Location NoLocation()
bool IsFpuRegister() const
bool IsDoubleStackSlot() const
intptr_t stack_index() const
Register base_reg() const
PairLocation * AsPairLocation() const
bool Equals(Location other) const
bool IsPairLocation() const
bool IsMachineRegister() const
MakePairInstr(Value *x, Value *y)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
virtual bool AttributesEqual(const Instruction &other) const
MakeTempInstr(Zone *zone)
virtual TokenPosition token_pos() const
virtual bool MayThrow() const
virtual bool HasUnknownSideEffects() const
intptr_t FieldOffsetAt(intptr_t i) const
void set_locations(Location *locations)
virtual bool MayThrow() const
AllocationInstr * allocation() const
void mark_visited_for_liveness()
bool was_visited_for_liveness() const
virtual bool ComputeCanDeoptimize() const
const Class & cls() const
intptr_t length_or_shape() const
DISALLOW_COPY_AND_ASSIGN(MaterializeObjectInstr)
MaterializeObjectInstr(AllocationInstr *allocation, const Class &cls, intptr_t length_or_shape, const ZoneGrowableArray< const Slot * > &slots, InputsArray &&values)
virtual bool HasUnknownSideEffects() const
const Location & LocationAt(intptr_t i)
virtual bool CanReplaceWithConstant() const
virtual intptr_t DeoptimizationTarget() const
MathMinMaxInstr(MethodRecognizer::Kind op_kind, Value *left_value, Value *right_value, intptr_t deopt_id, intptr_t result_cid)
intptr_t result_cid() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
virtual bool ComputeCanDeoptimize() const
MethodRecognizer::Kind op_kind() const
bool unboxed_inputs() const
classid_t src_cid() const
PRINT_OPERANDS_TO_SUPPORT DECLARE_ATTRIBUTE(element_size())
classid_t dest_cid() const
virtual bool HasUnknownSideEffects() const
intptr_t element_size() const
Value * src_start() const
virtual bool AttributesEqual(const Instruction &other) const
static bool IsArrayTypeSupported(classid_t array_cid)
DISALLOW_COPY_AND_ASSIGN(MemoryCopyInstr)
void EmitLoopCopy(FlowGraphCompiler *compiler, Register dest_reg, Register src_reg, Register length_reg, compiler::Label *done, compiler::Label *copy_forwards=nullptr)
void PrepareLengthRegForLoop(FlowGraphCompiler *compiler, Register length_reg, compiler::Label *done)
virtual bool ComputeCanDeoptimize() const
Value * dest_start() const
MemoryCopyInstr(Value *src, classid_t src_cid, Value *dest, classid_t dest_cid, Value *src_start, Value *dest_start, Value *length, bool unboxed_inputs, bool can_overlap=true)
virtual Representation RequiredInputRepresentation(intptr_t index) const
static bool IsRegisterMove(Location loc)
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(MoveArgumentInstr, TemplateDefinition, FIELD_LIST) DECLARE_EXTRA_SERIALIZATION private
virtual bool HasUnknownSideEffects() const
Location * location_slot()
virtual Representation representation() const
Location location() const
virtual TokenPosition token_pos() const
virtual bool ComputeCanDeoptimize() const
intptr_t sp_relative_index() const
MoveArgumentInstr(Value *value, Representation representation, Location location)
DISALLOW_COPY_AND_ASSIGN(MoveArgumentInstr)
void ClearPending(Location dest)
bool Blocks(Location loc) const
bool IsEliminated() const
MoveOperands & operator=(const MoveOperands &other)
void Write(FlowGraphSerializer *s) const
void set_dest(const Location &value)
MoveOperands(const MoveOperands &other)
MoveOperands(Location dest, Location src)
void set_src(const Location &value)
void set_is_bootstrap_native(bool value)
virtual bool ComputeCanDeoptimize() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(NativeCallInstr, TemplateDartCall, FIELD_LIST) private
bool is_auto_scope() const
virtual TokenPosition token_pos() const
DISALLOW_COPY_AND_ASSIGN(NativeCallInstr)
NativeCallInstr(const String &name, const Function &function, bool link_lazily, const InstructionSource &source, InputsArray &&args)
void set_is_auto_scope(bool value)
virtual bool HasUnknownSideEffects() const
bool is_bootstrap_native() const
virtual bool CanCallDart() const
const Function & function() const
NativeFunction native_c_function() const
NativeEntryInstr(const compiler::ffi::CallbackMarshaller &marshaller, GraphEntryInstr *graph_entry, intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
virtual bool MayCreateUnsafeUntaggedPointer() const
NativeParameterInstr(const compiler::ffi::CallbackMarshaller &marshaller, intptr_t def_index)
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimize() const
NativeReturnInstr(Value *typed_data_base, Value *offset, const compiler::ffi::CallbackMarshaller &marshaller)
virtual PRINT_OPERANDS_TO_SUPPORT Representation RequiredInputRepresentation(intptr_t idx) const
virtual Value * InputAt(intptr_t i) const
virtual bool CanBecomeDeoptimizationTarget() const
virtual void RawSetInputAt(intptr_t i, Value *value)
virtual bool AttributesEqual(const Instruction &other) const
NativeReturnInstr(Value *value, const compiler::ffi::CallbackMarshaller &marshaller)
virtual intptr_t InputCount() const
virtual bool ComputeCanDeoptimize() const
Value * char_code() const
virtual bool AttributesEqual(const Instruction &other) const
OneByteStringFromCharCodeInstr(Value *char_code)
OsrEntryInstr(GraphEntryInstr *graph_entry, intptr_t block_id, intptr_t try_index, intptr_t deopt_id, intptr_t stack_depth)
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const
virtual void ClearPredecessors()
GraphEntryInstr * graph_entry() const
virtual void AddPredecessor(BlockEntryInstr *predecessor)
Location At(intptr_t i) const
virtual bool HasUnknownSideEffects() const
intptr_t NumMoves() const
virtual bool ComputeCanDeoptimize() const
const MoveSchedule & move_schedule() const
const GrowableArray< MoveOperands * > & moves() const
virtual TokenPosition token_pos() const
MoveOperands * AddMove(Location dest, Location src)
MoveOperands * MoveOperandsAt(intptr_t index) const
void set_move_schedule(const MoveSchedule &schedule)
void set_block(BlockEntryInstr *block)
virtual bool HasUnknownSideEffects() const
virtual Representation RequiredInputRepresentation(intptr_t index) const
intptr_t param_index() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(ParameterInstr, TemplateDefinition, FIELD_LIST) DECLARE_EXTRA_SERIALIZATION private Location location_
virtual bool ComputeCanDeoptimize() const
const Location & location() const
virtual uword Hash() const
ParameterInstr(BlockEntryInstr *block, intptr_t env_index, intptr_t param_index, const Location &loc, Representation representation)
virtual BlockEntryInstr * GetBlock()
virtual Representation representation() const
DISALLOW_COPY_AND_ASSIGN(ParameterInstr)
JoinEntryInstr * block() const
virtual void set_representation(Representation r)
virtual uword Hash() const
virtual bool HasUnknownSideEffects() const
void set_is_receiver(ReceiverType is_receiver)
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
PhiInstr(JoinEntryInstr *block, intptr_t num_inputs)
virtual Representation RequiredInputRepresentation(intptr_t i) const
BitVector * reaching_defs() const
void set_reaching_defs(BitVector *reaching_defs)
virtual bool MayCreateUnsafeUntaggedPointer() const
virtual bool ComputeCanDeoptimize() const
virtual Representation representation() const
virtual bool MayThrow() const
ReceiverType is_receiver() const
virtual BlockEntryInstr * GetBlock()
PhiInstr * Current() const
PhiIterator(JoinEntryInstr *join)
void set_total_call_count(intptr_t count)
DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr)
intptr_t NumberOfChecks() const
const CallTargets & targets() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(PolymorphicInstanceCallInstr, InstanceCallBaseInstr, FIELD_LIST) private
static PolymorphicInstanceCallInstr * FromCall(Zone *zone, InstanceCallBaseInstr *call, const CallTargets &targets, bool complete)
intptr_t total_call_count()
virtual bool HasUnknownSideEffects() const
virtual bool AllowsCSE() const
PureComparison(const InstructionSource &source, Token::Kind kind, intptr_t deopt_id)
virtual bool HasUnknownSideEffects() const
virtual bool AllowsCSE() const
PureDefinition(const InstructionSource &source, intptr_t deopt_id)
PureDefinition(intptr_t deopt_id)
PureInstruction(intptr_t deopt_id)
virtual bool AllowsCSE() const
PureInstruction(const InstructionSource &source, intptr_t deopt_id)
virtual bool HasUnknownSideEffects() const
intptr_t catch_try_index() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool ComputeCanDeoptimize() const
Value * stacktrace() const
Value * exception() const
virtual bool HasUnknownSideEffects() const
ReThrowInstr(const InstructionSource &source, intptr_t catch_try_index, intptr_t deopt_id, Value *exception, Value *stacktrace)
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimize() const
ReachabilityFenceInstr(Value *value)
virtual bool CanEliminate(const BlockEntryInstr *block) const
RecordCoverageInstr(const Array &coverage_array, intptr_t coverage_index, const InstructionSource &source)
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimize() const
intptr_t num_fields() const
bool inserted_by_constant_propagation() const
RedefinitionInstr(Value *value, bool inserted_by_constant_propagation=false)
virtual bool ComputeCanDeoptimize() const
void set_constrained_type(CompileType *type)
virtual bool HasUnknownSideEffects() const
CompileType * constrained_type() const
virtual bool ComputeCanDeoptimize() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
RelationalOpInstr(const InstructionSource &source, Token::Kind kind, Value *left, Value *right, intptr_t cid, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual bool ComputeCanDeoptimize() const
virtual bool HasUnknownSideEffects() const
virtual bool MayThrow() const
ReturnBaseInstr(const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
virtual bool ComputeCanDeoptimize() const
ShiftInt64OpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, Range *right_range=nullptr)
virtual Representation representation() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool MayThrow() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
void set_shift_range(Range *shift_range)
ShiftIntegerOpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, Range *right_range=nullptr)
Range * shift_range() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual bool ComputeCanDeoptimize() const
virtual Representation representation() const
virtual bool MayThrow() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
ShiftUint32OpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, Range *right_range=nullptr)
static SimdOpInstr * Create(Kind kind, Value *left, Value *right, intptr_t deopt_id)
virtual Value * InputAt(intptr_t i) const
virtual intptr_t DeoptimizationTarget() const
virtual bool AllowsCSE() const
virtual bool MayThrow() const
virtual void RawSetInputAt(intptr_t i, Value *value)
virtual bool ComputeCanDeoptimize() const
static SimdOpInstr * Create(MethodRecognizer::Kind kind, Value *left, Value *right, intptr_t deopt_id)
static SimdOpInstr * Create(MethodRecognizer::Kind kind, Value *left, intptr_t deopt_id)
virtual bool HasUnknownSideEffects() const
virtual bool AttributesEqual(const Instruction &other) const
Representation representation() const
bool may_contain_inner_pointer() const
virtual TokenPosition token_pos() const
virtual bool AttributesEqual(const Instruction &other) const
virtual bool ComputeCanDeoptimize() const
SmiToDoubleInstr(Value *value, const InstructionSource &source)
SpeculativeShiftInt64OpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, Range *right_range=nullptr)
virtual Representation representation() const
virtual bool ComputeCanDeoptimize() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
SpeculativeShiftUint32OpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, Range *right_range=nullptr)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
DECLARE_EMPTY_SERIALIZATION(SpeculativeShiftUint32OpInstr, ShiftIntegerOpInstr) private DISALLOW_COPY_AND_ASSIGN(SpeculativeShiftUint32OpInstr)
virtual bool ComputeCanDeoptimize() const
const ICData * ic_data() const
StaticCallInstr(const InstructionSource &source, const Function &function, intptr_t type_args_len, const Array &argument_names, InputsArray &&arguments, const ZoneGrowableArray< const ICData * > &ic_data_array, intptr_t deopt_id, ICData::RebindRule rebind_rule)
CompileType * result_type() const
static StaticCallInstr * FromCall(Zone *zone, const C *call, const Function &target, intptr_t call_count)
virtual bool ComputeCanDeoptimizeAfterCall() const
DISALLOW_COPY_AND_ASSIGN(StaticCallInstr)
void SetResultType(Zone *zone, CompileType new_type)
void set_ic_data(const ICData *value)
virtual bool HasUnknownSideEffects() const
intptr_t result_cid() const
void set_is_known_list_constructor(bool value)
virtual bool CanCallDart() const
Code::EntryKind entry_kind() const
virtual intptr_t CallCount() const
virtual bool CanBecomeDeoptimizationTarget() const
void set_entry_kind(Code::EntryKind value)
bool is_known_list_constructor() const
virtual bool ComputeCanDeoptimize() const
virtual void SetIdentity(AliasIdentity identity)
virtual intptr_t DeoptimizationTarget() const
virtual AliasIdentity Identity() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t idx) const
bool IsRecognizedFactory() const
StaticCallInstr(const InstructionSource &source, const Function &function, intptr_t type_args_len, const Array &argument_names, InputsArray &&arguments, intptr_t deopt_id, intptr_t call_count, ICData::RebindRule rebind_rule)
StopInstr(const char *message)
virtual bool ComputeCanDeoptimize() const
DECLARE_INSTRUCTION(Stop)
virtual bool HasUnknownSideEffects() const
const char * message() const
InnerPointerAccess stores_inner_pointer() const
void set_emit_store_barrier(StoreBarrierType value)
void set_stores_inner_pointer(InnerPointerAccess value)
StoreFieldInstr(const Slot &slot, Value *instance, Value *value, StoreBarrierType emit_store_barrier, const InstructionSource &source, Kind kind=Kind::kOther, compiler::Assembler::MemoryOrder memory_order=compiler::Assembler::kRelaxedNonAtomic)
bool ShouldEmitStoreBarrier() const
DISALLOW_COPY_AND_ASSIGN(StoreFieldInstr)
virtual TokenPosition token_pos() const
virtual intptr_t DeoptimizationTarget() const
bool is_initialization() const
virtual bool MayHaveVisibleEffect() const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(StoreFieldInstr, TemplateInstruction, FIELD_LIST) private intptr_t OffsetInBytes() const
virtual bool HasUnknownSideEffects() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
StoreFieldInstr(const Field &field, Value *instance, Value *value, StoreBarrierType emit_store_barrier, const InstructionSource &source, const ParsedFunction *parsed_function, Kind kind=Kind::kOther)
virtual bool CanTriggerGC() const
StoreFieldInstr(const Slot &slot, Value *instance, Value *value, StoreBarrierType emit_store_barrier, InnerPointerAccess stores_inner_pointer, const InstructionSource &source, Kind kind=Kind::kOther, compiler::Assembler::MemoryOrder memory_order=compiler::Assembler::kRelaxedNonAtomic)
compiler::Assembler::CanBeSmi CanValueBeSmi() const
virtual bool ComputeCanDeoptimize() const
const Slot & slot() const
bool ShouldEmitStoreBarrier() const
virtual bool HasUnknownSideEffects() const
intptr_t class_id() const
virtual intptr_t DeoptimizationTarget() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
intptr_t index_scale() const
virtual bool ComputeCanDeoptimize() const
void set_emit_store_barrier(StoreBarrierType value)
virtual bool MayHaveVisibleEffect() const
virtual bool AttributesEqual(const Instruction &other) const
virtual bool HasUnknownSideEffects() const
virtual bool MayHaveVisibleEffect() const
StoreIndexedUnsafeInstr(Value *index, Value *value, intptr_t offset)
Register base_reg() const
virtual bool ComputeCanDeoptimize() const
virtual TokenPosition token_pos() const
StoreLocalInstr(const LocalVariable &local, Value *value, const InstructionSource &source)
virtual bool HasUnknownSideEffects() const
const LocalVariable & local() const
virtual bool ComputeCanDeoptimize() const
StoreStaticFieldInstr(const Field &field, Value *value, const InstructionSource &source)
virtual bool HasUnknownSideEffects() const
virtual TokenPosition token_pos() const
virtual bool MayHaveVisibleEffect() const
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimize() const
PRINT_OPERANDS_TO_SUPPORT
bool needs_number_check() const
DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr)
void set_needs_number_check(bool value)
StringToCharCodeInstr(Value *str, intptr_t cid)
virtual bool AttributesEqual(const Instruction &other) const
virtual bool ComputeCanDeoptimize() const
virtual intptr_t InputCount() const
virtual TokenPosition token_pos() const
SuspendInstr(const InstructionSource &source, StubId stub_id, Value *operand, Value *type_args, intptr_t deopt_id, intptr_t resume_deopt_id)
virtual bool HasUnknownSideEffects() const
bool has_type_args() const
intptr_t resume_deopt_id() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
Value * type_args() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool CanCallDart() const
DECLARE_INSTRUCTION(Suspend)
virtual bool ComputeCanDeoptimize() const
virtual bool AttributesEqual(const Instruction &other) const
TailCallInstr(const Code &code, Value *arg_desc)
virtual bool ComputeCanDeoptimize() const
virtual bool HasUnknownSideEffects() const
void adjust_edge_weight(double scale_factor)
DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr)
virtual DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(TargetEntryInstr, BlockEntryInstr, FIELD_LIST) private void ClearPredecessors()
virtual BlockEntryInstr * PredecessorAt(intptr_t index) const
virtual intptr_t PredecessorCount() const
TargetEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id, intptr_t stack_depth=0)
void set_edge_weight(double weight)
virtual void AddPredecessor(BlockEntryInstr *predecessor)
virtual intptr_t InputCount() const
virtual Value * InputAt(intptr_t i) const
virtual bool MayHaveVisibleEffect() const
virtual void RawSetInputAt(intptr_t i, Value *value)
EmbeddedArray< Value *, N > inputs_
TemplateAllocation(const InstructionSource &source, intptr_t deopt_id)
virtual void RawSetInputAt(intptr_t i, Value *value)
virtual intptr_t InputCount() const
virtual Value * InputAt(intptr_t i) const
TemplateArrayAllocation(const InstructionSource &source, intptr_t deopt_id)
EmbeddedArray< Value *, N > inputs_
virtual intptr_t InputCount() const
virtual Value * InputAt(intptr_t i) const
virtual void RawSetInputAt(intptr_t i, Value *value)
EmbeddedArray< Value *, N > inputs_
TemplateComparison(const InstructionSource &source, Token::Kind kind, intptr_t deopt_id=DeoptId::kNone)
virtual bool MayThrow() const
typename CSETrait< ComparisonInstr, PureComparison >::Base BaseClass
virtual MoveArgumentsArray * GetMoveArguments() const
virtual bool MayThrow() const
intptr_t type_args_len() const
const Array & argument_names() const
intptr_t ArgumentCount() const
intptr_t FirstArgIndex() const
virtual bool CanCallDart() const
virtual bool ComputeCanDeoptimizeAfterCall() const
TemplateDartCall(intptr_t deopt_id, intptr_t type_args_len, const Array &argument_names, InputsArray &&inputs, const InstructionSource &source)
virtual void SetMoveArguments(MoveArgumentsArray *move_arguments)
intptr_t ArgumentCountWithoutTypeArgs() const
virtual intptr_t ArgumentsSize() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
intptr_t ArgumentsSizeWithoutTypeArgs() const
ArrayPtr GetArgumentsDescriptor() const
virtual bool ComputeCanDeoptimize() const
virtual void ReplaceInputsWithMoveArguments(MoveArgumentsArray *move_arguments)
virtual TokenPosition token_pos() const
TemplateDefinition(intptr_t deopt_id=DeoptId::kNone)
EmbeddedArray< Value *, N > inputs_
typename CSETrait< Definition, PureDefinition >::Base BaseClass
virtual intptr_t InputCount() const
virtual bool MayThrow() const
virtual Value * InputAt(intptr_t i) const
TemplateDefinition(const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
virtual void RawSetInputAt(intptr_t i, Value *value)
TemplateInstruction(intptr_t deopt_id=DeoptId::kNone)
TemplateInstruction(const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
virtual void RawSetInputAt(intptr_t i, Value *value)
EmbeddedArray< Value *, N > inputs_
typename CSETrait< Instruction, PureInstruction >::Base BaseClass
virtual intptr_t InputCount() const
virtual Value * InputAt(intptr_t i) const
virtual bool MayThrow() const
virtual bool ComputeCanDeoptimize() const
virtual bool CanTriggerGC() const
virtual bool CanCallDart() const
virtual intptr_t NumberOfInputsConsumedBeforeCall() const
void set_calls_initializer(bool value)
bool calls_initializer() const
bool throw_exception_on_initialization() const
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool UseSharedSlowPathStub(bool is_optimizing) const
TemplateLoadField(const InstructionSource &source, bool calls_initializer=false, intptr_t deopt_id=DeoptId::kNone, const Field *field=nullptr)
virtual TokenPosition token_pos() const
virtual intptr_t DeoptimizationTarget() const
virtual bool MayThrow() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual bool ComputeCanDeoptimize() const
DECLARE_COMPARISON_INSTRUCTION(TestCids)
const ZoneGrowableArray< intptr_t > & cid_results() const
virtual bool ComputeCanDeoptimize() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
DECLARE_COMPARISON_INSTRUCTION(TestRange)
TestSmiInstr(const InstructionSource &source, Token::Kind kind, Value *left, Value *right)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
DECLARE_COMPARISON_INSTRUCTION(TestSmi)
virtual bool ComputeCanDeoptimize() const
void set_hierarchy_info(HierarchyInfo *value)
static Thread * Current()
ThrowInstr(const InstructionSource &source, intptr_t deopt_id, Value *exception)
virtual bool ComputeCanDeoptimize() const
virtual bool ComputeCanDeoptimizeAfterCall() const
virtual bool HasUnknownSideEffects() const
Value * exception() const
virtual bool ComputeCanDeoptimize() const
virtual Representation representation() const
virtual intptr_t DeoptimizationTarget() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual bool AttributesEqual(const Instruction &other) const
virtual Representation representation() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual intptr_t DeoptimizationTarget() const
UnaryDoubleOpInstr(Token::Kind op_kind, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs, Representation representation=kUnboxedDouble)
Token::Kind op_kind() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
virtual bool ComputeCanDeoptimize() const
virtual Representation representation() const
virtual bool AttributesEqual(const Instruction &other) const
UnaryInt64OpInstr(Token::Kind op_kind, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual intptr_t DeoptimizationTarget() const
UnaryIntegerOpInstr(Token::Kind op_kind, Value *value, intptr_t deopt_id)
virtual bool AttributesEqual(const Instruction &other) const
Token::Kind op_kind() const
virtual bool ComputeCanDeoptimize() const
UnarySmiOpInstr(Token::Kind op_kind, Value *value, intptr_t deopt_id)
virtual bool ComputeCanDeoptimize() const
UnaryUint32OpInstr(Token::Kind op_kind, Value *value, intptr_t deopt_id)
virtual Representation RequiredInputRepresentation(intptr_t idx) const
virtual Representation representation() const
static bool IsSupported(Token::Kind op_kind)
virtual TokenPosition token_pos() const
virtual Representation representation() const
void set_speculative_mode(SpeculativeMode value)
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(UnboxInstr, TemplateDefinition, FIELD_LIST) protected
virtual intptr_t DeoptimizationTarget() const
virtual bool ComputeCanDeoptimize() const
UnboxInt32Instr(TruncationMode truncation_mode, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
UnboxInt64Instr(Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode)
UnboxInteger32Instr(Representation representation, TruncationMode truncation_mode, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode)
virtual bool AttributesEqual(const Instruction &other) const
UnboxIntegerInstr(Representation representation, TruncationMode truncation_mode, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode)
bool is_truncating() const
virtual bool AttributesEqual(const Instruction &other) const
UnboxLaneInstr(Value *value, intptr_t n, Representation definition_rep, intptr_t definition_cid)
virtual bool ComputeCanDeoptimize() const
virtual Representation representation() const
virtual Representation RequiredInputRepresentation(intptr_t idx) const
UnboxUint32Instr(Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
uword constant_address() const
virtual Representation representation() const
virtual bool AttributesEqual(const Instruction &other) const
virtual bool HasUnknownSideEffects() const
virtual bool ComputeCanDeoptimize() const
virtual intptr_t DeoptimizationTarget() const
Utf8ScanInstr(Value *decoder, Value *bytes, Value *start, Value *end, Value *table, const Slot &decoder_scan_flags_field)
virtual Representation representation() const
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
static constexpr T NBitMask(size_t n)
ValueListIterable(Value *value)
void BindToEnvironment(Definition *definition)
void set_use_index(intptr_t index)
bool BindsToConstantNull() const
bool BindsToConstant() const
void set_previous_use(Value *previous)
intptr_t use_index() const
bool CanBe(const Object &value)
static void AddToList(Value *value, Value **list)
void SetReachingType(CompileType *type)
bool Equals(const Value &other) const
intptr_t BoundSmiConstant() const
bool BindsToSmiConstant() const
Instruction * instruction() const
void set_next_use(Value *next)
Value * previous_use() const
const Object & BoundConstant() const
void set_definition(Definition *definition)
Value * CopyWithType(Zone *zone)
CompileType * reaching_type() const
Definition * definition() const
void BindTo(Definition *definition)
Value(Definition *definition)
const char * ToCString() const
void RefineReachingType(CompileType *type)
void set_instruction(Instruction *instruction)
VariadicDefinition(InputsArray &&inputs, intptr_t deopt_id=DeoptId::kNone)
VariadicDefinition(const intptr_t num_inputs, intptr_t deopt_id=DeoptId::kNone)
intptr_t InputCount() const
Value * InputAt(intptr_t i) const
VariadicDefinition(InputsArray &&inputs, const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
intptr_t NumArgumentDefinitions() const
bool ReturnsCompound() const
@ kNormal
Default priority level.
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
void PrintTo(FlValue *v, std::ostream *os)
Dart_NativeFunction function
static float max(float r, float g, float b)
static float min(float r, float g, float b)
#define VALUE_DEFN(name, val)
#define DECLARE_INSTRUCTION_BACKEND()
#define DECLARE_COMPARISON_INSTRUCTION(type)
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs)
#define DECLARE_EMPTY_SERIALIZATION(Instr, BaseClass)
#define DECLARE_INSTRUCTION_TYPE_CHECK(Name, Type)
#define DECLARE_TAG(type, attrs)
#define FOR_EACH_INSTRUCTION(M)
#define DECLARE_ATTRIBUTE(Attribute)
#define DECLARE_ABSTRACT_INSTRUCTION(type)
#define DECLARE_ATTRIBUTES_NAMED(names, values)
#define DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS(Instr, BaseClass, FieldList)
#define VALUE_CASE(name, val)
#define PRINT_OPERANDS_TO_SUPPORT
#define INSTRUCTION_TYPE_CHECK(Name, Attrs)
#define DECLARE_INSTRUCTION_NO_BACKEND(type)
#define FOR_EACH_ALIAS_IDENTITY_VALUE(V)
#define DECLARE_INSTRUCTION(type)
#define DECLARE_ENUM(Arity, Mask, Name,...)
#define FORWARD_DECLARATION(type, attrs)
#define DECLARE_CUSTOM_SERIALIZATION(Instr)
#define SIMD_OP_LIST(M, BINARY_OP)
#define DECLARE_EXTRA_SERIALIZATION
#define FOR_EACH_ABSTRACT_INSTRUCTION(M)
bool IsTypedDataBaseClassId(intptr_t index)
constexpr intptr_t kBitsPerWord
DART_EXPORT bool IsNull(Dart_Handle object)
constexpr intptr_t kBitsPerByte
GrowableArray< Value * > InputsArray
unibrow::Mapping< unibrow::Ecma262Canonicalize > Canonicalize
intptr_t LocationCount(Representation rep)
MallocGrowableArray< CidRangeValue > CidRangeVector
bool IsClampedTypedDataBaseClassId(intptr_t index)
bool IsAllocatableInNewSpace(intptr_t size)
ZoneGrowableArray< MoveArgumentInstr * > MoveArgumentsArray
typename unwrap_enum< std::remove_cv_t< T >, std::is_enum< T >::value >::type serializable_type_t
const char *const function_name
void(* NativeFunction)(NativeArguments *arguments)
static constexpr intptr_t kInvalidTryIndex
bool IsStringClassId(intptr_t index)
const intptr_t count_with_type_args
const intptr_t count_without_type_args
const intptr_t type_args_len
ArgumentsInfo(intptr_t type_args_len, intptr_t count_with_type_args, intptr_t size_with_type_args, const Array &argument_names)
const intptr_t size_with_type_args
const intptr_t size_without_type_args
const Array & argument_names
ArrayPtr ToArgumentsDescriptor() const
static constexpr Representation NativeRepresentation(Representation rep)
compiler::Label * fall_through
compiler::Label * false_label
compiler::Label * true_label
CidRangeValue(intptr_t cid_start_arg, intptr_t cid_end_arg)
bool Contains(intptr_t cid) const
bool Equals(const CidRangeValue &other) const
CidRangeValue(const CidRange &other)
bool IsIllegalRange() const
CidRange(intptr_t cid_start_arg, intptr_t cid_end_arg)
bool IsIllegalRange() const
DISALLOW_COPY_AND_ASSIGN(CidRange)
bool Contains(intptr_t cid) const
bool operator==(const Iterator &other)
bool operator!=(const Iterator &other)
const Instruction * instr
static BlockEntryInstr * At(const Instruction *instr, intptr_t index)
static intptr_t Length(const Instruction *instr)
static constexpr bool kCanThrow
StaticTypeExactnessState exactness
DISALLOW_COPY_AND_ASSIGN(TargetInfo)
TargetInfo(intptr_t cid_start_arg, intptr_t cid_end_arg, const Function *target_arg, intptr_t count_arg, StaticTypeExactnessState exactness)
static constexpr bool kCanThrow
bool operator==(const Iterator &other)
Value * operator*() const
bool operator!=(const Iterator &other)
std::underlying_type_t< T > type