1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef RCC_CODEGEN_MACHINEJUMPTABLEINFO_H
#define RCC_CODEGEN_MACHINEJUMPTABLEINFO_H
#include "rcc/CodeGen/MachineIRTypes.h"
#include "rcc/CodeGen/MachineMemOperand.h"
#include "rcc/Support/Error.h"
#include <cstddef>
#include <cstdint>
#include <optional>
#include <span>
#include <utility>
#include <variant>
#include <vector>
namespace rcc {
class MachineBasicBlock;
class MachineFunction;
enum class JumpTableEntryEncoding : std::uint8_t {
AbsoluteAddress,
RelativeToTableBase,
RelativeToEntry,
CompressedOffset,
Target,
Count,
};
struct JumpTablePlacement final {
bool InTextSection = true;
bool UniqueSection = false;
std::optional<std::uint64_t> MaximumDistance;
std::uint64_t TargetFlags = 0;
friend bool operator==(const JumpTablePlacement &Left, const JumpTablePlacement &Right) = default;
};
struct MachineJumpTableDesc final {
JumpTableEntryEncoding Encoding = JumpTableEntryEncoding::AbsoluteAddress;
std::uint8_t EntrySize = 8;
Alignment Align;
std::vector<MachineBasicBlock *> Targets;
JumpTablePlacement Placement;
std::uint32_t TargetEncoding = 0;
friend bool operator==(const MachineJumpTableDesc &Left,
const MachineJumpTableDesc &Right) = default;
};
class MachineJumpTableEntry final {
public:
[[nodiscard]] JumpTableIndex index() const noexcept {
return Index;
}
[[nodiscard]] bool isTombstone() const noexcept {
return std::holds_alternative<std::monostate>(Description);
}
[[nodiscard]] const MachineJumpTableDesc *description() const noexcept {
return std::get_if<MachineJumpTableDesc>(&Description);
}
private:
MachineJumpTableEntry(JumpTableIndex Index, MachineJumpTableDesc Description)
: Index(Index), Description(std::move(Description)) {}
JumpTableIndex Index;
std::variant<std::monostate, MachineJumpTableDesc> Description;
friend class MachineJumpTableInfo;
};
class MachineJumpTableInfo final {
public:
explicit MachineJumpTableInfo(MachineFunction &Owner) noexcept : Owner(&Owner) {}
MachineJumpTableInfo(const MachineJumpTableInfo &) = delete;
MachineJumpTableInfo &operator=(const MachineJumpTableInfo &) = delete;
MachineJumpTableInfo(MachineJumpTableInfo &&) = delete;
MachineJumpTableInfo &operator=(MachineJumpTableInfo &&) = delete;
~MachineJumpTableInfo() = default;
[[nodiscard]] Expected<JumpTableIndex> createTable(MachineJumpTableDesc Description);
[[nodiscard]] Expected<void> updateTable(JumpTableIndex Index, MachineJumpTableDesc Description);
[[nodiscard]] Expected<void> eraseTable(JumpTableIndex Index);
[[nodiscard]] const MachineJumpTableEntry *table(JumpTableIndex Index) const noexcept;
[[nodiscard]] std::span<const MachineJumpTableEntry> tables() const noexcept {
return Tables;
}
[[nodiscard]] std::size_t liveTableCount() const noexcept;
[[nodiscard]] bool isFrozen() const noexcept {
return Frozen;
}
[[nodiscard]] Expected<void> freeze();
[[nodiscard]] Expected<void> verify() const;
private:
[[nodiscard]] Expected<void> verifyDescription(const MachineJumpTableDesc &Description) const;
[[nodiscard]] Expected<MachineJumpTableEntry *> mutableTable(JumpTableIndex Index);
MachineFunction *Owner;
std::vector<MachineJumpTableEntry> Tables;
bool Frozen = false;
};
} // namespace rcc
#endif // RCC_CODEGEN_MACHINEJUMPTABLEINFO_H
|