Skip to content

Commit 40b4ac2

Browse files
authored
[ORC] Refactor executor symbol lookup to use ExecutorSymbolDef (NFC) (#76989)
This migrates the dylib manager lookup and related APIs to replace ExecutorAddress with ExecutorSymbolDef so that in the future we can model JITSymbolFlags for these symbols. The current change should be NFC as we are only setting the Exported symbol flag.
1 parent a8cb4f7 commit 40b4ac2

17 files changed

+300
-44
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
//===--------- ExecutorSymbolDef.h - (Addr, Flags) pair ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Represents a defining location for a symbol in the executing program.
10+
//
11+
// This file was derived from
12+
// llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h.
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
#ifndef ORC_RT_EXECUTOR_SYMBOL_DEF_H
17+
#define ORC_RT_EXECUTOR_SYMBOL_DEF_H
18+
19+
#include "bitmask_enum.h"
20+
#include "executor_address.h"
21+
#include "simple_packed_serialization.h"
22+
23+
namespace __orc_rt {
24+
25+
/// Flags for symbols in the JIT.
26+
class JITSymbolFlags {
27+
public:
28+
using UnderlyingType = uint8_t;
29+
using TargetFlagsType = uint8_t;
30+
31+
/// These values must be kept in sync with \c JITSymbolFlags in the JIT.
32+
enum FlagNames : UnderlyingType {
33+
None = 0,
34+
HasError = 1U << 0,
35+
Weak = 1U << 1,
36+
Common = 1U << 2,
37+
Absolute = 1U << 3,
38+
Exported = 1U << 4,
39+
Callable = 1U << 5,
40+
MaterializationSideEffectsOnly = 1U << 6,
41+
ORC_RT_MARK_AS_BITMASK_ENUM( // LargestValue =
42+
MaterializationSideEffectsOnly)
43+
};
44+
45+
/// Default-construct a JITSymbolFlags instance.
46+
JITSymbolFlags() = default;
47+
48+
/// Construct a JITSymbolFlags instance from the given flags and target
49+
/// flags.
50+
JITSymbolFlags(FlagNames Flags, TargetFlagsType TargetFlags)
51+
: TargetFlags(TargetFlags), Flags(Flags) {}
52+
53+
bool operator==(const JITSymbolFlags &RHS) const {
54+
return Flags == RHS.Flags && TargetFlags == RHS.TargetFlags;
55+
}
56+
57+
/// Get the underlying flags value as an integer.
58+
UnderlyingType getRawFlagsValue() const {
59+
return static_cast<UnderlyingType>(Flags);
60+
}
61+
62+
/// Return a reference to the target-specific flags.
63+
TargetFlagsType &getTargetFlags() { return TargetFlags; }
64+
65+
/// Return a reference to the target-specific flags.
66+
const TargetFlagsType &getTargetFlags() const { return TargetFlags; }
67+
68+
private:
69+
TargetFlagsType TargetFlags = 0;
70+
FlagNames Flags = None;
71+
};
72+
73+
/// Represents a defining location for a JIT symbol.
74+
class ExecutorSymbolDef {
75+
public:
76+
ExecutorSymbolDef() = default;
77+
ExecutorSymbolDef(ExecutorAddr Addr, JITSymbolFlags Flags)
78+
: Addr(Addr), Flags(Flags) {}
79+
80+
const ExecutorAddr &getAddress() const { return Addr; }
81+
82+
const JITSymbolFlags &getFlags() const { return Flags; }
83+
84+
friend bool operator==(const ExecutorSymbolDef &LHS,
85+
const ExecutorSymbolDef &RHS) {
86+
return LHS.getAddress() == RHS.getAddress() &&
87+
LHS.getFlags() == RHS.getFlags();
88+
}
89+
90+
private:
91+
ExecutorAddr Addr;
92+
JITSymbolFlags Flags;
93+
};
94+
95+
using SPSJITSymbolFlags =
96+
SPSTuple<JITSymbolFlags::UnderlyingType, JITSymbolFlags::TargetFlagsType>;
97+
98+
/// SPS serializatior for JITSymbolFlags.
99+
template <> class SPSSerializationTraits<SPSJITSymbolFlags, JITSymbolFlags> {
100+
using FlagsArgList = SPSJITSymbolFlags::AsArgList;
101+
102+
public:
103+
static size_t size(const JITSymbolFlags &F) {
104+
return FlagsArgList::size(F.getRawFlagsValue(), F.getTargetFlags());
105+
}
106+
107+
static bool serialize(SPSOutputBuffer &BOB, const JITSymbolFlags &F) {
108+
return FlagsArgList::serialize(BOB, F.getRawFlagsValue(),
109+
F.getTargetFlags());
110+
}
111+
112+
static bool deserialize(SPSInputBuffer &BIB, JITSymbolFlags &F) {
113+
JITSymbolFlags::UnderlyingType RawFlags;
114+
JITSymbolFlags::TargetFlagsType TargetFlags;
115+
if (!FlagsArgList::deserialize(BIB, RawFlags, TargetFlags))
116+
return false;
117+
F = JITSymbolFlags{static_cast<JITSymbolFlags::FlagNames>(RawFlags),
118+
TargetFlags};
119+
return true;
120+
}
121+
};
122+
123+
using SPSExecutorSymbolDef = SPSTuple<SPSExecutorAddr, SPSJITSymbolFlags>;
124+
125+
/// SPS serializatior for ExecutorSymbolDef.
126+
template <>
127+
class SPSSerializationTraits<SPSExecutorSymbolDef, ExecutorSymbolDef> {
128+
using DefArgList = SPSExecutorSymbolDef::AsArgList;
129+
130+
public:
131+
static size_t size(const ExecutorSymbolDef &ESD) {
132+
return DefArgList::size(ESD.getAddress(), ESD.getFlags());
133+
}
134+
135+
static bool serialize(SPSOutputBuffer &BOB, const ExecutorSymbolDef &ESD) {
136+
return DefArgList::serialize(BOB, ESD.getAddress(), ESD.getFlags());
137+
}
138+
139+
static bool deserialize(SPSInputBuffer &BIB, ExecutorSymbolDef &ESD) {
140+
ExecutorAddr Addr;
141+
JITSymbolFlags Flags;
142+
if (!DefArgList::deserialize(BIB, Addr, Flags))
143+
return false;
144+
ESD = ExecutorSymbolDef{Addr, Flags};
145+
return true;
146+
}
147+
};
148+
149+
} // End namespace __orc_rt
150+
151+
#endif // ORC_RT_EXECUTOR_SYMBOL_DEF_H

compiler-rt/lib/orc/tests/unit/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set(UNITTEST_SOURCES
55
endian_test.cpp
66
error_test.cpp
77
executor_address_test.cpp
8+
executor_symbol_def_test.cpp
89
extensible_rtti_test.cpp
910
interval_map_test.cpp
1011
interval_set_test.cpp
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===-- executor_symbol_def_test.cpp --------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "executor_symbol_def.h"
10+
#include "simple_packed_serialization_utils.h"
11+
#include "gtest/gtest.h"
12+
13+
using namespace __orc_rt;
14+
15+
TEST(ExecutorSymbolDefTest, Serialization) {
16+
blobSerializationRoundTrip<SPSExecutorSymbolDef>(ExecutorSymbolDef{});
17+
blobSerializationRoundTrip<SPSExecutorSymbolDef>(
18+
ExecutorSymbolDef{ExecutorAddr{0x70}, {JITSymbolFlags::Callable, 9}});
19+
}

compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "simple_packed_serialization.h"
14+
#include "simple_packed_serialization_utils.h"
1415
#include "gtest/gtest.h"
1516

1617
using namespace __orc_rt;
@@ -48,25 +49,6 @@ TEST(SimplePackedSerializationTest, SPSInputBuffer) {
4849
EXPECT_FALSE(IB.read(&C, 1));
4950
}
5051

51-
template <typename SPSTagT, typename T>
52-
static void blobSerializationRoundTrip(const T &Value) {
53-
using BST = SPSSerializationTraits<SPSTagT, T>;
54-
55-
size_t Size = BST::size(Value);
56-
auto Buffer = std::make_unique<char[]>(Size);
57-
SPSOutputBuffer OB(Buffer.get(), Size);
58-
59-
EXPECT_TRUE(BST::serialize(OB, Value));
60-
61-
SPSInputBuffer IB(Buffer.get(), Size);
62-
63-
T DSValue;
64-
EXPECT_TRUE(BST::deserialize(IB, DSValue));
65-
66-
EXPECT_EQ(Value, DSValue)
67-
<< "Incorrect value after serialization/deserialization round-trip";
68-
}
69-
7052
template <typename T> static void testFixedIntegralTypeSerialization() {
7153
blobSerializationRoundTrip<T, T>(0);
7254
blobSerializationRoundTrip<T, T>(static_cast<T>(1));
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===-- simple_packed_serialization_utils.h -------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef ORC_RT_TEST_SIMPLE_PACKED_SERIALIZATION_UTILS_H
10+
#define ORC_RT_TEST_SIMPLE_PACKED_SERIALIZATION_UTILS_H
11+
12+
#include "simple_packed_serialization.h"
13+
#include "gtest/gtest.h"
14+
15+
template <typename SPSTagT, typename T>
16+
static void blobSerializationRoundTrip(const T &Value) {
17+
using BST = __orc_rt::SPSSerializationTraits<SPSTagT, T>;
18+
19+
size_t Size = BST::size(Value);
20+
auto Buffer = std::make_unique<char[]>(Size);
21+
__orc_rt::SPSOutputBuffer OB(Buffer.get(), Size);
22+
23+
EXPECT_TRUE(BST::serialize(OB, Value));
24+
25+
__orc_rt::SPSInputBuffer IB(Buffer.get(), Size);
26+
27+
T DSValue;
28+
EXPECT_TRUE(BST::deserialize(IB, DSValue));
29+
30+
EXPECT_EQ(Value, DSValue)
31+
<< "Incorrect value after serialization/deserialization round-trip";
32+
}
33+
34+
#endif // ORC_RT_TEST_SIMPLE_PACKED_SERIALIZATION_UTILS_H

llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define LLVM_EXECUTIONENGINE_ORC_EPCGENERICDYLIBMANAGER_H
2020

2121
#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
22+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
2223
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
2324

2425
namespace llvm {
@@ -49,11 +50,11 @@ class EPCGenericDylibManager {
4950
Expected<tpctypes::DylibHandle> open(StringRef Path, uint64_t Mode);
5051

5152
/// Looks up symbols within the given dylib.
52-
Expected<std::vector<ExecutorAddr>> lookup(tpctypes::DylibHandle H,
53-
const SymbolLookupSet &Lookup);
53+
Expected<std::vector<ExecutorSymbolDef>>
54+
lookup(tpctypes::DylibHandle H, const SymbolLookupSet &Lookup);
5455

5556
/// Looks up symbols within the given dylib.
56-
Expected<std::vector<ExecutorAddr>>
57+
Expected<std::vector<ExecutorSymbolDef>>
5758
lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &Lookup);
5859

5960
private:

llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "llvm/ExecutionEngine/JITSymbol.h"
1717
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
18+
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
1819

1920
namespace llvm {
2021
namespace orc {
@@ -48,6 +49,63 @@ class ExecutorSymbolDef {
4849
JITSymbolFlags Flags;
4950
};
5051

52+
namespace shared {
53+
54+
using SPSJITSymbolFlags =
55+
SPSTuple<JITSymbolFlags::UnderlyingType, JITSymbolFlags::TargetFlagsType>;
56+
57+
/// SPS serializatior for JITSymbolFlags.
58+
template <> class SPSSerializationTraits<SPSJITSymbolFlags, JITSymbolFlags> {
59+
using FlagsArgList = SPSJITSymbolFlags::AsArgList;
60+
61+
public:
62+
static size_t size(const JITSymbolFlags &F) {
63+
return FlagsArgList::size(F.getRawFlagsValue(), F.getTargetFlags());
64+
}
65+
66+
static bool serialize(SPSOutputBuffer &BOB, const JITSymbolFlags &F) {
67+
return FlagsArgList::serialize(BOB, F.getRawFlagsValue(),
68+
F.getTargetFlags());
69+
}
70+
71+
static bool deserialize(SPSInputBuffer &BIB, JITSymbolFlags &F) {
72+
JITSymbolFlags::UnderlyingType RawFlags;
73+
JITSymbolFlags::TargetFlagsType TargetFlags;
74+
if (!FlagsArgList::deserialize(BIB, RawFlags, TargetFlags))
75+
return false;
76+
F = JITSymbolFlags{static_cast<JITSymbolFlags::FlagNames>(RawFlags),
77+
TargetFlags};
78+
return true;
79+
}
80+
};
81+
82+
using SPSExecutorSymbolDef = SPSTuple<SPSExecutorAddr, SPSJITSymbolFlags>;
83+
84+
/// SPS serializatior for ExecutorSymbolDef.
85+
template <>
86+
class SPSSerializationTraits<SPSExecutorSymbolDef, ExecutorSymbolDef> {
87+
using DefArgList = SPSExecutorSymbolDef::AsArgList;
88+
89+
public:
90+
static size_t size(const ExecutorSymbolDef &ESD) {
91+
return DefArgList::size(ESD.getAddress(), ESD.getFlags());
92+
}
93+
94+
static bool serialize(SPSOutputBuffer &BOB, const ExecutorSymbolDef &ESD) {
95+
return DefArgList::serialize(BOB, ESD.getAddress(), ESD.getFlags());
96+
}
97+
98+
static bool deserialize(SPSInputBuffer &BIB, ExecutorSymbolDef &ESD) {
99+
ExecutorAddr Addr;
100+
JITSymbolFlags Flags;
101+
if (!DefArgList::deserialize(BIB, Addr, Flags))
102+
return false;
103+
ESD = ExecutorSymbolDef{Addr, Flags};
104+
return true;
105+
}
106+
};
107+
108+
} // End namespace shared.
51109
} // End namespace orc.
52110
} // End namespace llvm.
53111

llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define LLVM_EXECUTIONENGINE_ORC_SHARED_ORCRTBRIDGE_H
1515

1616
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
17+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
1718
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
1819
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
1920

@@ -54,7 +55,7 @@ using SPSSimpleExecutorDylibManagerOpenSignature =
5455
shared::SPSString, uint64_t);
5556

5657
using SPSSimpleExecutorDylibManagerLookupSignature =
57-
shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorAddr>>(
58+
shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorSymbolDef>>(
5859
shared::SPSExecutorAddr, shared::SPSExecutorAddr,
5960
shared::SPSRemoteSymbolLookupSet);
6061

llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ExecutionEngine/JITSymbol.h"
2020
#include "llvm/ExecutionEngine/Orc/Shared/AllocationActions.h"
2121
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
22+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
2223
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
2324
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
2425
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
@@ -113,7 +114,7 @@ struct PointerWrite {
113114
/// A handle used to represent a loaded dylib in the target process.
114115
using DylibHandle = ExecutorAddr;
115116

116-
using LookupResult = std::vector<ExecutorAddr>;
117+
using LookupResult = std::vector<ExecutorSymbolDef>;
117118

118119
} // end namespace tpctypes
119120

llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "llvm/ADT/DenseSet.h"
2020
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
21+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h"
2122
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
2223
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
2324
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
@@ -37,8 +38,8 @@ class SimpleExecutorDylibManager : public ExecutorBootstrapService {
3738
virtual ~SimpleExecutorDylibManager();
3839

3940
Expected<tpctypes::DylibHandle> open(const std::string &Path, uint64_t Mode);
40-
Expected<std::vector<ExecutorAddr>> lookup(tpctypes::DylibHandle H,
41-
const RemoteSymbolLookupSet &L);
41+
Expected<std::vector<ExecutorSymbolDef>>
42+
lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &L);
4243

4344
Error shutdown() override;
4445
void addBootstrapSymbols(StringMap<ExecutorAddr> &M) override;

0 commit comments

Comments
 (0)