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
12 namespace v8 {
13 namespace internal {
14 namespace maglev {
15
16 class ValueNode;
17
18 #define COUNT(V) +1
19 static constexpr int kAllocatableGeneralRegisterCount =
20 ALLOCATABLE_GENERAL_REGISTERS(COUNT);
21 #undef COUNT
22
23 struct 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
uintptr_tRegisterStateFlags31 explicit constexpr operator uintptr_t() const {
32 return (is_initialized ? 1 << kIsInitializedShift : 0) |
33 (is_merge ? 1 << kIsMergeShift : 0);
34 }
RegisterStateFlagsRegisterStateFlags35 constexpr explicit RegisterStateFlags(uintptr_t state)
36 : is_initialized((state & (1 << kIsInitializedShift)) != 0),
37 is_merge((state & (1 << kIsMergeShift)) != 0) {}
RegisterStateFlagsRegisterStateFlags38 constexpr RegisterStateFlags(bool is_initialized, bool is_merge)
39 : is_initialized(is_initialized), is_merge(is_merge) {}
40 };
41 constexpr 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
47 typedef base::PointerWithPayload<void, RegisterStateFlags, 2> RegisterState;
48
49 struct RegisterMerge {
operandsRegisterMerge50 compiler::AllocatedOperand* operands() {
51 return reinterpret_cast<compiler::AllocatedOperand*>(this + 1);
52 }
operandRegisterMerge53 compiler::AllocatedOperand& operand(size_t i) { return operands()[i]; }
54
55 ValueNode* node;
56 };
57
LoadMergeState(RegisterState state,RegisterMerge ** merge)58 inline 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
LoadMergeState(RegisterState state,ValueNode ** node,RegisterMerge ** merge)68 inline 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