Skip to content

Commit

Permalink
Merge pull request #443 from bluescarni/pr/llvm_type_cleanup
Browse files Browse the repository at this point in the history
Intern cleanups around LLVM type handling
  • Loading branch information
bluescarni authored Aug 6, 2024
2 parents b349f64 + 8528a5d commit 11e4287
Show file tree
Hide file tree
Showing 23 changed files with 293 additions and 238 deletions.
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

0 comments on commit 11e4287

Please sign in to comment.