5#ifndef RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_H_
6#define RUNTIME_VM_COMPILER_BACKEND_LOCATIONS_H_
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
24class FlowGraphDeserializer;
25class FlowGraphSerializer;
31#define FOR_EACH_INTEGER_REPRESENTATION_KIND(M) \
32 M(UnboxedInt8, int8, false, int8_t) \
33 M(UnboxedUint8, uint8, true, uint8_t) \
34 M(UnboxedInt16, int16, false, int16_t) \
35 M(UnboxedUint16, uint16, true, uint16_t) \
36 M(UnboxedInt32, int32, false, int32_t) \
37 M(UnboxedUint32, uint32, true, uint32_t) \
38 M(UnboxedInt64, int64, false, int64_t)
42#define FOR_EACH_UNBOXED_REPRESENTATION_KIND(M) \
43 M(UnboxedDouble, double, _, double_t) \
44 M(UnboxedFloat, float, _, float_t) \
45 FOR_EACH_INTEGER_REPRESENTATION_KIND(M) \
46 M(UnboxedFloat32x4, float32x4, _, simd128_value_t) \
47 M(UnboxedInt32x4, int32x4, _, simd128_value_t) \
48 M(UnboxedFloat64x2, float64x2, _, simd128_value_t)
53#define FOR_EACH_SIMPLE_REPRESENTATION_KIND(M) \
54 M(Tagged, tagged, _, compiler::target::word) \
55 M(Untagged, untagged, _, compiler::target::word) \
56 FOR_EACH_UNBOXED_REPRESENTATION_KIND(M)
61#define FOR_EACH_REPRESENTATION_KIND(M) \
62 M(NoRepresentation, none, _, _) \
63 FOR_EACH_SIMPLE_REPRESENTATION_KIND(M) \
64 M(PairOfTagged, tagged_pair, _, _)
67#define DECLARE_REPRESENTATION(name, __, ___, ____) k##name,
69#undef DECLARE_REPRESENTATION
87#define REP_IN_SET_CLAUSE(name, __, ___, ____) \
109#undef REP_IN_SET_CLAUSE
114#define REP_SIZEOF_CLAUSE(name, __, ___, type) \
118#undef REP_SIZEOF_CLAUSE
128#define REP_IS_UNSIGNED_CLAUSE(name, __, unsigned, ___) \
132#undef REP_IS_UNSIGNED_CLAUSE
205 kPayloadBitsPos = kKindBitsPos + kKindBitsSize,
209 static constexpr uword kInvalidLocation = 0;
210 static constexpr uword kLocationTagMask = 0x3;
285 value_ = other.value_;
289 bool IsInvalid()
const {
return value_ == kInvalidLocation; }
311 return reinterpret_cast<ConstantInstr*
>(value_ & ~kLocationTagMask);
406 return static_cast<Register>(payload());
438 return static_cast<intptr_t
>(payload());
513 const char*
Name()
const;
533 void set_stack_index(intptr_t index) {
535 value_ = PayloadField::update(
541 value_ = PayloadField::update(StackSlotBaseField::update(
reg, payload()),
550 class KindField :
public BitField<uword, Kind, kKindBitsPos, kKindBitsSize> {
553 :
public BitField<uword, uword, kPayloadBitsPos, kPayloadBitsSize> {};
556 typedef BitField<uword, Policy, 0, 3> PolicyField;
559#if defined(ARCH_IS_64_BIT)
560 static constexpr intptr_t kBitsForBaseReg = 6;
562 static constexpr intptr_t kBitsForBaseReg = 5;
564 static constexpr intptr_t kBitsForStackIndex =
565 kPayloadBitsSize - kBitsForBaseReg;
566 class StackSlotBaseField
567 :
public BitField<uword, Register, 0, kBitsForBaseReg> {};
568 class StackIndexField
569 :
public BitField<uword, intptr_t, kBitsForBaseReg, kBitsForStackIndex> {
573 static constexpr intptr_t kStackIndexBias =
static_cast<intptr_t
>(1)
574 << (kBitsForStackIndex - 1);
602 intptr_t* cpu_reg_slots,
603 intptr_t* fpu_reg_slots);
611 for (intptr_t
i = 0;
i < kPairLength;
i++) {
612 ASSERT(locations_[
i].IsInvalid());
616 intptr_t
length()
const {
return kPairLength; }
621 return locations_[
i];
633 return &locations_[
i];
637 static constexpr intptr_t kPairLength = 2;
658 uintptr_t
data()
const {
return data_; }
661 static uintptr_t ToMask(
T value) {
663 return static_cast<uintptr_t
>(1) <<
static_cast<uintptr_t
>(
value);
672 : cpu_registers_(), untagged_cpu_registers_(), fpu_registers_() {
677 explicit RegisterSet(uintptr_t cpu_register_mask, uintptr_t fpu_register_mask)
688 if (include_fpu_registers) {
701#if defined(TARGET_ARCH_ARM)
702 if (reg ==
PC)
continue;
703#elif defined(TARGET_ARCH_ARM64)
704 if (reg ==
R31)
continue;
705#elif defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
706 if (reg ==
ZR || reg ==
TP || reg ==
GP)
continue;
718#if !defined(TARGET_ARCH_IA32)
735 uintptr_t fpu_register_mask) {
756 cpu_registers_.
Add(loc.
reg());
757 if (rep != kTagged) {
789 untagged_cpu_registers_.
Add(loc.
reg());
793 return !untagged_cpu_registers_.
IsEmpty() || !fpu_registers_.
IsEmpty();
797 return !untagged_cpu_registers_.
Contains(reg);
801 return cpu_registers_.
Contains(reg);
805 return fpu_registers_.
Contains(fpu_reg);
816 static bool Contains(uintptr_t register_set, intptr_t reg) {
817 return (register_set & (
static_cast<uintptr_t
>(1) << reg)) != 0;
824 cpu_registers_.
Clear();
825 fpu_registers_.
Clear();
826 untagged_cpu_registers_.
Clear();
868 ASSERT(index < num_inputs_);
869 return input_locations_[index];
874 ASSERT(index < num_inputs_);
875 return &input_locations_[index];
884 ASSERT(index < num_temps_);
885 return temp_locations_[index];
890 ASSERT(index < num_temps_);
891 return &temp_locations_[index];
896 ASSERT(index < num_temps_);
898 temp_locations_[index] = loc;
905 return output_location_;
910 return &output_location_;
946 void DiscoverWritableInputs();
947 void CheckWritableInputs();
955 if (stack_bitmap_ ==
nullptr) {
958 return *stack_bitmap_;
961 const intptr_t num_inputs_;
963 const intptr_t num_temps_;
967 BitmapBuilder* stack_bitmap_;
970 RegisterSet live_registers_;
973 intptr_t writable_inputs_;
static void encode(uint8_t output[16], const uint32_t input[4])
static constexpr T decode(S value)
static constexpr S encode(T value)
void Set(intptr_t bit_offset, bool value)
Location * in_slot(intptr_t index)
Location temp(intptr_t index) const
void SetStackBit(intptr_t index)
bool callee_safe_call() const
void Write(FlowGraphSerializer *s) const
Location out(intptr_t index) const
Location * temp_slot(intptr_t index)
LocationSummary(Zone *zone, intptr_t input_count, intptr_t temp_count, LocationSummary::ContainsCall contains_call)
const BitmapBuilder & stack_bitmap()
static LocationSummary * Make(Zone *zone, intptr_t input_count, Location out, ContainsCall contains_call)
intptr_t input_count() const
bool native_leaf_call() const
void set_temp(intptr_t index, Location loc)
intptr_t output_count() const
intptr_t temp_count() const
RegisterSet * live_registers()
void set_out(intptr_t index, Location loc)
bool always_calls() const
bool call_on_shared_slow_path() const
Location * out_slot(intptr_t index)
Location in(intptr_t index) const
void set_in(intptr_t index, Location loc)
void PrintTo(BaseTextBuffer *f) const
static Location StackSlot(intptr_t stack_index, Register base)
static Location MachineRegisterLocation(Kind kind, intptr_t reg)
Location ToCallerSpRelative() const
static Location NoLocation()
static Location QuadStackSlot(intptr_t stack_index, Register base)
static Location SameAsFirstInput()
const char * Name() const
bool IsFpuRegister() const
ConstantInstr * constant_instruction() const
static Location Pair(Location first, Location second)
void Write(FlowGraphSerializer *s) const
static Location RequiresStack()
intptr_t ToStackSlotOffset() const
Location ToEntrySpRelative() const
bool IsDoubleStackSlot() const
static Location FpuRegisterLocation(FpuRegister reg)
const char * ToCString() const
static Location DoubleStackSlot(intptr_t stack_index, Register base)
static uword EncodeStackIndex(intptr_t stack_index)
intptr_t stack_index() const
Location & operator=(const Location &other)
static bool IsMachineRegisterKind(Kind kind)
intptr_t pair_index() const
Location Component(intptr_t i) const
static Location WritableRegister()
bool IsRegisterBeneficial()
static Location UnallocatedLocation(Policy policy)
bool IsQuadStackSlot() const
Register base_reg() const
static Location Read(FlowGraphDeserializer *d)
Location(const Location &other)
static Location RegisterLocation(Register reg)
static Location PrefersRegister()
PairLocation * AsPairLocation() const
bool Equals(Location other) const
static Location RequiresRegister()
bool IsPairLocation() const
void PrintTo(BaseTextBuffer *f) const
bool IsUnallocated() const
bool IsMachineRegister() const
static Location RequiresFpuRegister()
FpuRegister fpu_reg() const
const Object & constant() const
Location ToSpRelative(intptr_t fp_to_sp_delta) const
bool HasStackIndex() const
intptr_t register_code() const
static Location Constant(const ConstantInstr *obj, int pair_index=0)
void SetAt(intptr_t i, Location loc)
Location * SlotAt(intptr_t i)
Location At(intptr_t i) const
void Write(FlowGraphSerializer *s) const
static bool Contains(uintptr_t register_set, intptr_t reg)
intptr_t FpuRegisterCount() const
bool ContainsFpuRegister(FpuRegister fpu_reg) const
uintptr_t fpu_registers() const
void AddAllGeneralRegisters()
void MarkUntagged(Location loc)
uintptr_t cpu_registers() const
RegisterSet(uintptr_t cpu_register_mask, uintptr_t fpu_register_mask)
void AddRegister(Register reg, Representation rep=kTagged)
void AddAllArgumentRegisters()
bool HasUntaggedValues() const
static intptr_t RegisterCount(intptr_t registers)
bool Contains(Location loc)
void AddTaggedRegisters(uintptr_t cpu_register_mask, uintptr_t fpu_register_mask)
void Add(Location loc, Representation rep=kTagged)
intptr_t CpuRegisterCount() const
void AddAllNonReservedRegisters(bool include_fpu_registers)
bool ContainsRegister(Register reg) const
bool IsTagged(Register reg) const
void Remove(Location loc)
bool Contains(T value) const
static constexpr bool TestBit(T mask, size_t position)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
#define REP_SIZEOF_CLAUSE(name, __, ___, type)
#define FOR_EACH_REPRESENTATION_KIND(M)
#define FOR_EACH_INTEGER_REPRESENTATION_KIND(M)
#define REP_IS_UNSIGNED_CLAUSE(name, __, unsigned, ___)
#define FOR_EACH_UNBOXED_REPRESENTATION_KIND(M)
#define FOR_EACH_SIMPLE_REPRESENTATION_KIND(M)
#define REP_IN_SET_CLAUSE(name, __, ___, ____)
#define DECLARE_REPRESENTATION(name, __, ___, ____)
static constexpr intptr_t kWordSize
Location LocationAnyOrConstant(Value *value)
Location LocationRegisterOrConstant(Value *value)
constexpr intptr_t kBitsPerWord
static constexpr Representation kUnboxedUword
const RegList kReservedCpuRegisters
static constexpr intptr_t kMaxLocationCount
Location LocationExceptionLocation()
constexpr intptr_t kBitsPerByte
intptr_t LocationCount(Representation rep)
Location LocationFixedRegisterOrConstant(Value *value, Register reg)
const int kNumberOfFpuRegisters
Location LocationWritableRegisterOrSmiConstant(Value *value, intptr_t min_value, intptr_t max_value)
Location LocationArgumentsDescriptorLocation()
Location LocationRemapForSlowPath(Location loc, Definition *def, intptr_t *cpu_reg_slots, intptr_t *fpu_reg_slots)
static constexpr bool IsArgumentRegister(Register reg)
static constexpr bool IsFpuArgumentRegister(FpuRegister reg)
static constexpr Representation kUnboxedAddress
compiler::Address LocationToStackSlotAddress(Location loc)
Location LocationStackTraceLocation()
constexpr intptr_t kWordSize
Location LocationWritableRegisterOrConstant(Value *value)
static constexpr Representation kUnboxedIntPtr
static constexpr Representation kUnboxedWord
Location LocationFixedRegisterOrSmiConstant(Value *value, Register reg)
Location LocationRegisterOrSmiConstant(Value *value, intptr_t min_value, intptr_t max_value)
static DecodeResult decode(std::string path)
static constexpr size_t ValueSize(Representation rep)
static constexpr bool IsUnboxedInteger(Representation rep)
static bool IsRepresentable(Representation rep, int64_t value)
static int64_t MaxValue(Representation rep)
static compiler::OperandSize OperandSize(Representation rep)
static int64_t MinValue(Representation rep)
static constexpr bool IsUnboxed(Representation rep)
static const char * ToCString(Representation rep)
static bool IsUnsignedInteger(Representation rep)
static Representation RepresentationOfArrayElement(classid_t cid)