• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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