File indexing completed on 2026-05-10 08:43:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_MEMORYFLAGS_H
0015 #define LLVM_EXECUTIONENGINE_ORC_SHARED_MEMORYFLAGS_H
0016
0017 #include "llvm/ADT/BitmaskEnum.h"
0018 #include "llvm/ADT/DenseMapInfo.h"
0019 #include "llvm/ADT/STLExtras.h"
0020 #include "llvm/Support/Memory.h"
0021 #include "llvm/Support/raw_ostream.h"
0022
0023 namespace llvm {
0024 namespace orc {
0025
0026
0027 enum class MemProt {
0028 None = 0,
0029 Read = 1U << 0,
0030 Write = 1U << 1,
0031 Exec = 1U << 2,
0032 LLVM_MARK_AS_BITMASK_ENUM( Exec)
0033 };
0034
0035
0036 inline raw_ostream &operator<<(raw_ostream &OS, MemProt MP) {
0037 return OS << (((MP & MemProt::Read) != MemProt::None) ? 'R' : '-')
0038 << (((MP & MemProt::Write) != MemProt::None) ? 'W' : '-')
0039 << (((MP & MemProt::Exec) != MemProt::None) ? 'X' : '-');
0040 }
0041
0042
0043
0044 inline sys::Memory::ProtectionFlags toSysMemoryProtectionFlags(MemProt MP) {
0045 std::underlying_type_t<sys::Memory::ProtectionFlags> PF = 0;
0046 if ((MP & MemProt::Read) != MemProt::None)
0047 PF |= sys::Memory::MF_READ;
0048 if ((MP & MemProt::Write) != MemProt::None)
0049 PF |= sys::Memory::MF_WRITE;
0050 if ((MP & MemProt::Exec) != MemProt::None)
0051 PF |= sys::Memory::MF_EXEC;
0052 return static_cast<sys::Memory::ProtectionFlags>(PF);
0053 }
0054
0055
0056
0057 inline MemProt fromSysMemoryProtectionFlags(sys::Memory::ProtectionFlags PF) {
0058 MemProt MP = MemProt::None;
0059 if (PF & sys::Memory::MF_READ)
0060 MP |= MemProt::Read;
0061 if (PF & sys::Memory::MF_WRITE)
0062 MP |= MemProt::Write;
0063 if (PF & sys::Memory::MF_EXEC)
0064 MP |= MemProt::None;
0065 return MP;
0066 }
0067
0068
0069
0070
0071
0072
0073
0074
0075 enum class MemLifetime {
0076
0077
0078 Standard,
0079
0080
0081
0082
0083 Finalize,
0084
0085
0086
0087
0088 NoAlloc
0089 };
0090
0091
0092 inline raw_ostream &operator<<(raw_ostream &OS, MemLifetime MLP) {
0093 switch (MLP) {
0094 case MemLifetime::Standard:
0095 OS << "standard";
0096 break;
0097 case MemLifetime::Finalize:
0098 OS << "finalize";
0099 break;
0100 case MemLifetime::NoAlloc:
0101 OS << "noalloc";
0102 break;
0103 }
0104 return OS;
0105 }
0106
0107
0108
0109
0110 class AllocGroup {
0111 friend struct llvm::DenseMapInfo<AllocGroup>;
0112
0113 using underlying_type = uint8_t;
0114 static constexpr unsigned BitsForProt = 3;
0115 static constexpr unsigned BitsForLifetimePolicy = 2;
0116 static constexpr unsigned MaxIdentifiers =
0117 1U << (BitsForProt + BitsForLifetimePolicy);
0118
0119 public:
0120 static constexpr unsigned NumGroups = MaxIdentifiers;
0121
0122
0123
0124 AllocGroup() = default;
0125
0126
0127
0128 AllocGroup(MemProt MP) : Id(static_cast<underlying_type>(MP)) {}
0129
0130
0131 AllocGroup(MemProt MP, MemLifetime MLP)
0132 : Id(static_cast<underlying_type>(MP) |
0133 (static_cast<underlying_type>(MLP) << BitsForProt)) {}
0134
0135
0136 MemProt getMemProt() const {
0137 return static_cast<MemProt>(Id & ((1U << BitsForProt) - 1));
0138 }
0139
0140
0141 MemLifetime getMemLifetime() const {
0142 return static_cast<MemLifetime>(Id >> BitsForProt);
0143 }
0144
0145 friend bool operator==(const AllocGroup &LHS, const AllocGroup &RHS) {
0146 return LHS.Id == RHS.Id;
0147 }
0148
0149 friend bool operator!=(const AllocGroup &LHS, const AllocGroup &RHS) {
0150 return !(LHS == RHS);
0151 }
0152
0153 friend bool operator<(const AllocGroup &LHS, const AllocGroup &RHS) {
0154 return LHS.Id < RHS.Id;
0155 }
0156
0157 private:
0158 AllocGroup(underlying_type RawId) : Id(RawId) {}
0159 underlying_type Id = 0;
0160 };
0161
0162
0163
0164
0165 template <typename T> class AllocGroupSmallMap {
0166 private:
0167 using ElemT = std::pair<AllocGroup, T>;
0168 using VectorTy = SmallVector<ElemT, 4>;
0169
0170 static bool compareKey(const ElemT &E, const AllocGroup &G) {
0171 return E.first < G;
0172 }
0173
0174 public:
0175 using iterator = typename VectorTy::iterator;
0176
0177 AllocGroupSmallMap() = default;
0178 AllocGroupSmallMap(std::initializer_list<std::pair<AllocGroup, T>> Inits)
0179 : Elems(Inits) {
0180 llvm::sort(Elems, llvm::less_first());
0181 }
0182
0183 iterator begin() { return Elems.begin(); }
0184 iterator end() { return Elems.end(); }
0185 iterator find(AllocGroup G) {
0186 auto I = lower_bound(Elems, G, compareKey);
0187 return (I == end() || I->first == G) ? I : end();
0188 }
0189
0190 bool empty() const { return Elems.empty(); }
0191 size_t size() const { return Elems.size(); }
0192
0193 T &operator[](AllocGroup G) {
0194 auto I = lower_bound(Elems, G, compareKey);
0195 if (I == Elems.end() || I->first != G)
0196 I = Elems.insert(I, std::make_pair(G, T()));
0197 return I->second;
0198 }
0199
0200 private:
0201 VectorTy Elems;
0202 };
0203
0204
0205 inline raw_ostream &operator<<(raw_ostream &OS, AllocGroup AG) {
0206 return OS << '(' << AG.getMemProt() << ", " << AG.getMemLifetime() << ')';
0207 }
0208
0209 }
0210
0211 template <> struct DenseMapInfo<orc::MemProt> {
0212 static inline orc::MemProt getEmptyKey() { return orc::MemProt(~uint8_t(0)); }
0213 static inline orc::MemProt getTombstoneKey() {
0214 return orc::MemProt(~uint8_t(0) - 1);
0215 }
0216 static unsigned getHashValue(const orc::MemProt &Val) {
0217 using UT = std::underlying_type_t<orc::MemProt>;
0218 return DenseMapInfo<UT>::getHashValue(static_cast<UT>(Val));
0219 }
0220 static bool isEqual(const orc::MemProt &LHS, const orc::MemProt &RHS) {
0221 return LHS == RHS;
0222 }
0223 };
0224
0225 template <> struct DenseMapInfo<orc::AllocGroup> {
0226 static inline orc::AllocGroup getEmptyKey() {
0227 return orc::AllocGroup(~uint8_t(0));
0228 }
0229 static inline orc::AllocGroup getTombstoneKey() {
0230 return orc::AllocGroup(~uint8_t(0) - 1);
0231 }
0232 static unsigned getHashValue(const orc::AllocGroup &Val) {
0233 return DenseMapInfo<orc::AllocGroup::underlying_type>::getHashValue(Val.Id);
0234 }
0235 static bool isEqual(const orc::AllocGroup &LHS, const orc::AllocGroup &RHS) {
0236 return LHS == RHS;
0237 }
0238 };
0239
0240 }
0241
0242 #endif