Skip to content

Commit

Permalink
[ORC] Add an ExecutorAddr::toPtr overload for function types.
Browse files Browse the repository at this point in the history
In the common case of converting an ExecutorAddr to a function pointer type,
this eliminates the need for the '(*)' boilerplate to explicitly specify a
function pointer. E.g.:

auto *F = A.toPtr<int(*)()>();

can now be written as

auto *F = A.toPtr<int()>();
  • Loading branch information
lhames committed May 5, 2022
1 parent c2a5a87 commit 98616cf
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
13 changes: 11 additions & 2 deletions llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h
Expand Up @@ -43,13 +43,22 @@ class ExecutorAddr {

/// Cast this ExecutorAddr to a pointer of the given type.
/// Warning: This should only be used when JITing in-process.
template <typename T> T toPtr() const {
static_assert(std::is_pointer<T>::value, "T must be a pointer type");
template <typename T>
std::enable_if_t<std::is_pointer<T>::value, T> toPtr() const {
uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
return reinterpret_cast<T>(IntPtr);
}

/// Cast this ExecutorAddr to a pointer of the given function type.
/// Warning: This should only be used when JITing in-process.
template <typename T>
std::enable_if_t<std::is_function<T>::value, T *> toPtr() const {
uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
return reinterpret_cast<T *>(IntPtr);
}

uint64_t getValue() const { return Addr; }
void setValue(uint64_t Addr) { this->Addr = Addr; }
bool isNull() const { return Addr == 0; }
Expand Down
11 changes: 11 additions & 0 deletions llvm/unittests/ExecutionEngine/Orc/ExecutorAddressTest.cpp
Expand Up @@ -47,6 +47,17 @@ TEST(ExecutorAddrTest, PtrConversion) {
EXPECT_EQ(XPtr, &X);
}

static void F() {}

TEST(ExecutorAddrTest, PtrConversionWithFunctionType) {
// Test that function types (as opposed to function pointer types) can be
// used with toPtr.
auto FAddr = ExecutorAddr::fromPtr(F);
void (*FPtr)() = FAddr.toPtr<void()>();

EXPECT_EQ(FPtr, &F);
}

TEST(ExecutorAddrTest, AddrRanges) {
ExecutorAddr A0(0), A1(1), A2(2), A3(3);
ExecutorAddrRange R0(A0, A1), R1(A1, A2), R2(A2, A3), R3(A0, A2), R4(A1, A3);
Expand Down

0 comments on commit 98616cf

Please sign in to comment.