Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal cleanups around LLVM type handling #443

Merged
merged 2 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmark/penc_comparison.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void run_benchmark(unsigned order)
auto &builder = s.builder();
auto &context = s.context();

auto val_t = detail::to_llvm_type<T>(context);
auto val_t = detail::to_external_llvm_type<T>(context);
auto ptr_val_t = llvm::PointerType::getUnqual(val_t);

// Fetch the current insertion block.
Expand Down
43 changes: 28 additions & 15 deletions include/heyoka/detail/llvm_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,42 @@ HEYOKA_BEGIN_NAMESPACE
namespace detail
{

HEYOKA_DLL_PUBLIC llvm::Type *to_llvm_type_impl(llvm::LLVMContext &, const std::type_info &, bool);
HEYOKA_DLL_PUBLIC llvm::Type *to_external_llvm_type_impl(llvm::LLVMContext &, const std::type_info &, bool);

// Helper to associate a C++ type to an LLVM type.
// Helper to fetch the external llvm type corresponding to the C++ type T.
//
// The external type is the type to be used in llvm when interfacing with the world
// outside JIT compiled code (e.g., when accessing in JITted code data which
// was created in C++). The external type must be identical (in terms
// of size, alignment and, for structures, layout) to the corresponding C++ type.
//
// In case no llvm type can be associated to T, if err_throw is true, an exception
// will be thrown, otherwise nullptr will be returned.
template <typename T>
inline llvm::Type *to_llvm_type(llvm::LLVMContext &c, bool err_throw = true)
inline llvm::Type *to_external_llvm_type(llvm::LLVMContext &c, bool err_throw = true)
{
return to_llvm_type_impl(c, typeid(T), err_throw);
return to_external_llvm_type_impl(c, typeid(T), err_throw);
}

// Helper to fetch the internal llvm type corresponding to the C++ type T.
//
// The internal type is the type used in the JITted code to manipulate
// values which in C++ are of type T. It coincides with the external llvm
// type for all supported types apart for mppp::real, which has a
// representation in the JITted code different from its C++ representation.
//
// Because mppp::real's precision is a runtime property (i.e., not encoded
// in the type), if T is mppp::real then the precision must be passed as
// second argument to this function.
template <typename T>
HEYOKA_DLL_PUBLIC llvm::Type *llvm_type_like(llvm_state &, const T &);

HEYOKA_DLL_PUBLIC llvm::Type *make_vector_type(llvm::Type *, std::uint32_t);
HEYOKA_DLL_PUBLIC llvm::Type *llvm_ext_type(llvm::Type *);
HEYOKA_DLL_PUBLIC llvm::Type *to_internal_llvm_type(llvm_state &, long long = 0);

// Helper to construct an LLVM vector type of size batch_size with elements
// of the LLVM type tp corresponding to the C++ type T. If batch_size is 1, tp
// will be returned. batch_size cannot be zero.
template <typename T>
inline llvm::Type *to_llvm_vector_type(llvm::LLVMContext &c, std::uint32_t batch_size)
{
return make_vector_type(to_llvm_type<T>(c), batch_size);
}
HEYOKA_DLL_PUBLIC llvm::Type *internal_llvm_type_like(llvm_state &, const T &);

HEYOKA_DLL_PUBLIC llvm::Type *make_external_llvm_type(llvm::Type *);

HEYOKA_DLL_PUBLIC llvm::Type *make_vector_type(llvm::Type *, std::uint32_t);

HEYOKA_DLL_PUBLIC std::string llvm_mangle_type(llvm::Type *);

Expand Down
6 changes: 3 additions & 3 deletions src/continuous_output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void continuous_output<T>::add_c_out_function(std::uint32_t order, std::uint32_t
auto &context = m_llvm_state.context();

// Fetch the internal floating-point type.
auto *fp_t = detail::llvm_type_like(m_llvm_state, m_output[0]);
auto *fp_t = detail::internal_llvm_type_like(m_llvm_state, m_output[0]);

// Fetch the current insertion block.
auto *orig_bb = builder.GetInsertBlock();
Expand Down Expand Up @@ -132,7 +132,7 @@ void continuous_output<T>::add_c_out_function(std::uint32_t order, std::uint32_t
// - the pointer to the hi times (read-only),
// - the pointer to the lo times (read-only).
// No overlap is allowed. All pointers are external.
auto *ext_fp_t = detail::to_llvm_type<T>(context);
auto *ext_fp_t = detail::to_external_llvm_type<T>(context);
auto *ptr_t = llvm::PointerType::getUnqual(ext_fp_t);
const std::vector<llvm::Type *> fargs(5u, ptr_t);
// The function does not return anything.
Expand Down Expand Up @@ -620,7 +620,7 @@ void continuous_output_batch<T>::add_c_out_function(std::uint32_t order, std::ui
// - the pointer to the hi times (read-only),
// - the pointer to the lo times (read-only).
// No overlap is allowed.
auto fp_t = detail::to_llvm_type<T>(context);
auto fp_t = detail::to_external_llvm_type<T>(context);
auto fp_vec_t = detail::make_vector_type(fp_t, m_batch_size);
auto ptr_t = llvm::PointerType::getUnqual(fp_t);
const std::vector<llvm::Type *> fargs(5, ptr_t);
Expand Down
10 changes: 5 additions & 5 deletions src/detail/event_detection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ llvm::Function *add_poly_translator_1(llvm_state &s, llvm::Type *fp_t, std::uint
auto &context = s.context();

// Fetch the external type corresponding to fp_t.
auto *ext_fp_t = llvm_ext_type(fp_t);
auto *ext_fp_t = make_external_llvm_type(fp_t);

// Helper to fetch the (i, j) binomial coefficient from
// a precomputed global array. The returned value is already
Expand Down Expand Up @@ -554,7 +554,7 @@ llvm::Function *llvm_add_poly_rtscc(llvm_state &s, llvm::Type *fp_t, std::uint32
auto &context = s.context();

// Fetch the external type.
auto *ext_fp_t = llvm_ext_type(fp_t);
auto *ext_fp_t = make_external_llvm_type(fp_t);

// Add the translator and the sign changes counting function.
auto *pt = add_poly_translator_1(s, fp_t, n, batch_size);
Expand Down Expand Up @@ -661,7 +661,7 @@ llvm::Function *llvm_add_fex_check(llvm_state &s, llvm::Type *fp_t, std::uint32_
auto &context = s.context();

// Fetch the external type.
auto *ext_fp_t = llvm_ext_type(fp_t);
auto *ext_fp_t = make_external_llvm_type(fp_t);

// Fetch the current insertion block.
auto *orig_bb = builder.GetInsertBlock();
Expand Down Expand Up @@ -851,7 +851,7 @@ taylor_adaptive<T>::ed_data::ed_data(llvm_state s, std::vector<t_event_t> tes, s
// Fetch the scalar FP type.
// NOTE: s0 is the first value in the state vector of the integrator,
// from which the internal floating-point type is deduced.
auto *fp_t = detail::llvm_type_like(m_state, s0);
auto *fp_t = detail::internal_llvm_type_like(m_state, s0);

// NOTE: the numeric cast will also ensure that we can
// index into the events using 32-bit ints.
Expand Down Expand Up @@ -1425,7 +1425,7 @@ taylor_adaptive_batch<T>::ed_data::ed_data(llvm_state s, std::vector<t_event_t>
assert(batch_size != 0u); // LCOV_EXCL_LINE

// Fetch the scalar FP type.
auto *fp_t = detail::to_llvm_type<T>(m_state.context());
auto *fp_t = detail::to_external_llvm_type<T>(m_state.context());

// NOTE: the numeric cast will also ensure that we can
// index into the events using 32-bit ints.
Expand Down
Loading
Loading