1// Copyright 2022 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef V8_MAGLEV_MAGLEV_REGALLOC_DATA_H_ 6#define V8_MAGLEV_MAGLEV_REGALLOC_DATA_H_ 7 8#include "src/base/pointer-with-payload.h" 9#include "src/codegen/register.h" 10#include "src/compiler/backend/instruction.h" 11 12namespace v8 { 13namespace internal { 14namespace maglev { 15 16class ValueNode; 17 18#define COUNT(V) +1 19static constexpr int kAllocatableGeneralRegisterCount = 20 ALLOCATABLE_GENERAL_REGISTERS(COUNT); 21#undef COUNT 22 23struct RegisterStateFlags { 24 // TODO(v8:7700): Use the good old Flags mechanism. 25 static constexpr int kIsMergeShift = 0; 26 static constexpr int kIsInitializedShift = 1; 27 28 const bool is_initialized = false; 29 const bool is_merge = false; 30 31 explicit constexpr operator uintptr_t() const { 32 return (is_initialized ? 1 << kIsInitializedShift : 0) | 33 (is_merge ? 1 << kIsMergeShift : 0); 34 } 35 constexpr explicit RegisterStateFlags(uintptr_t state) 36 : is_initialized((state & (1 << kIsInitializedShift)) != 0), 37 is_merge((state & (1 << kIsMergeShift)) != 0) {} 38 constexpr RegisterStateFlags(bool is_initialized, bool is_merge) 39 : is_initialized(is_initialized), is_merge(is_merge) {} 40}; 41constexpr bool operator==(const RegisterStateFlags& left, 42 const RegisterStateFlags& right) { 43 return left.is_initialized == right.is_initialized && 44 left.is_merge == right.is_merge; 45} 46 47typedef base::PointerWithPayload<void, RegisterStateFlags, 2> RegisterState; 48 49struct RegisterMerge { 50 compiler::AllocatedOperand* operands() { 51 return reinterpret_cast<compiler::AllocatedOperand*>(this + 1); 52 } 53 compiler::AllocatedOperand& operand(size_t i) { return operands()[i]; } 54 55 ValueNode* node; 56}; 57 58inline bool LoadMergeState(RegisterState state, RegisterMerge** merge) { 59 DCHECK(state.GetPayload().is_initialized); 60 if (state.GetPayload().is_merge) { 61 *merge = static_cast<RegisterMerge*>(state.GetPointer()); 62 return true; 63 } 64 *merge = nullptr; 65 return false; 66} 67 68inline bool LoadMergeState(RegisterState state, ValueNode** node, 69 RegisterMerge** merge) { 70 DCHECK(state.GetPayload().is_initialized); 71 if (LoadMergeState(state, merge)) { 72 *node = (*merge)->node; 73 return true; 74 } 75 *node = static_cast<ValueNode*>(state.GetPointer()); 76 return false; 77} 78 79} // namespace maglev 80} // namespace internal 81} // namespace v8 82 83#endif // V8_MAGLEV_MAGLEV_REGALLOC_DATA_H_ 84