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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef RCC_CODEGEN_MACHINECONSTANTPOOL_H
#define RCC_CODEGEN_MACHINECONSTANTPOOL_H
#include "rcc/CodeGen/MachineIRTypes.h"
#include "rcc/CodeGen/MachineMemOperand.h"
#include "rcc/CodeGen/TargetConstant.h"
#include "rcc/IR/Constants.h"
#include "rcc/Support/Error.h"
#include <cstddef>
#include <cstdint>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include <variant>
#include <vector>
namespace rcc {
enum class ConstantPoolEntryKind : std::uint8_t {
Generic,
Target,
SymbolDifference,
BlockAddress,
TargetExpression,
};
enum class ConstantPoolMergeKind : std::uint8_t {
Never,
Exact,
};
enum class ConstantPoolRelocationMode : std::uint8_t {
None,
Static,
PositionIndependent,
Target,
};
enum class ConstantPoolSectionKind : std::uint8_t {
TargetDefault,
ReadOnly,
MergeableReadOnly,
Data,
TextAdjacent,
Target,
Count,
};
struct ConstantPoolPlacement final {
ConstantPoolSectionKind Section = ConstantPoolSectionKind::TargetDefault;
bool UniqueSection = false;
std::optional<std::uint64_t> MaximumDistance;
std::uint64_t TargetFlags = 0;
friend bool operator==(const ConstantPoolPlacement &Left,
const ConstantPoolPlacement &Right) = default;
};
struct SymbolDifferenceConstant final {
std::string Minuend;
std::string Subtrahend;
std::int64_t Addend = 0;
friend bool operator==(const SymbolDifferenceConstant &Left,
const SymbolDifferenceConstant &Right) = default;
};
struct BlockAddressConstant final {
std::string FunctionName;
std::string BlockName;
std::int64_t Addend = 0;
friend bool operator==(const BlockAddressConstant &Left,
const BlockAddressConstant &Right) = default;
};
struct TargetExpressionConstant final {
TargetConstant Expression;
};
using MachineConstantPoolValue =
std::variant<GenericConstantData, TargetConstant, SymbolDifferenceConstant,
BlockAddressConstant, TargetExpressionConstant>;
struct MachineConstantPoolEntryDesc final {
MachineConstantPoolEntryDesc() = default;
MachineConstantPoolEntryDesc(const MachineConstantPoolEntryDesc &) = delete;
MachineConstantPoolEntryDesc &operator=(const MachineConstantPoolEntryDesc &) = delete;
MachineConstantPoolEntryDesc(MachineConstantPoolEntryDesc &&) noexcept = default;
MachineConstantPoolEntryDesc &operator=(MachineConstantPoolEntryDesc &&) noexcept = default;
~MachineConstantPoolEntryDesc() = default;
MachineConstantPoolValue Value;
std::uint64_t Size = 0;
Alignment Align;
ConstantPoolMergeKind Merge = ConstantPoolMergeKind::Never;
ConstantPoolRelocationMode Relocation = ConstantPoolRelocationMode::None;
ConstantPoolPlacement Placement;
[[nodiscard]] ConstantPoolEntryKind kind() const noexcept;
[[nodiscard]] Expected<void> verify() const;
[[nodiscard]] Expected<MachineConstantPoolEntryDesc> clone() const;
[[nodiscard]] bool semanticallyEquals(const MachineConstantPoolEntryDesc &Other) const noexcept;
};
class MachineConstantPoolEntry final {
public:
[[nodiscard]] ConstantPoolIndex index() const noexcept {
return Index;
}
[[nodiscard]] bool isTombstone() const noexcept {
return std::holds_alternative<std::monostate>(Description);
}
[[nodiscard]] const MachineConstantPoolEntryDesc *description() const noexcept {
return std::get_if<MachineConstantPoolEntryDesc>(&Description);
}
[[nodiscard]] Expected<MachineConstantPoolEntryDesc> cloneDescription() const;
private:
MachineConstantPoolEntry(ConstantPoolIndex Index, MachineConstantPoolEntryDesc Description)
: Index(Index), Description(std::move(Description)) {}
ConstantPoolIndex Index;
std::variant<std::monostate, MachineConstantPoolEntryDesc> Description;
friend class MachineConstantPool;
};
class MachineConstantPool final {
public:
MachineConstantPool() = default;
MachineConstantPool(const MachineConstantPool &) = delete;
MachineConstantPool &operator=(const MachineConstantPool &) = delete;
MachineConstantPool(MachineConstantPool &&) noexcept = default;
MachineConstantPool &operator=(MachineConstantPool &&) noexcept = default;
~MachineConstantPool() = default;
[[nodiscard]] Expected<ConstantPoolIndex> addEntry(MachineConstantPoolEntryDesc Description);
[[nodiscard]] Expected<void> updateEntry(ConstantPoolIndex Index,
MachineConstantPoolEntryDesc Description);
[[nodiscard]] Expected<void> eraseEntry(ConstantPoolIndex Index);
[[nodiscard]] const MachineConstantPoolEntry *entry(ConstantPoolIndex Index) const noexcept;
[[nodiscard]] std::span<const MachineConstantPoolEntry> entries() const noexcept {
return Entries;
}
[[nodiscard]] std::size_t liveEntryCount() const noexcept;
[[nodiscard]] bool isFrozen() const noexcept {
return Frozen;
}
[[nodiscard]] Expected<void> freeze();
[[nodiscard]] Expected<void> verify() const;
private:
[[nodiscard]] Expected<MachineConstantPoolEntry *> mutableEntry(ConstantPoolIndex Index);
[[nodiscard]] const MachineConstantPoolEntry *
findEquivalent(const MachineConstantPoolEntryDesc &Description,
std::optional<ConstantPoolIndex> Excluded = std::nullopt) const noexcept;
std::vector<MachineConstantPoolEntry> Entries;
bool Frozen = false;
};
} // namespace rcc
#endif // RCC_CODEGEN_MACHINECONSTANTPOOL_H
|