Skip to content

Commit 1c477fa

Browse files
Baltolirv-jenkins
andauthored
Apply backwards-compatible changes for LLVM 18 (#1068)
This PR makes a series of small housekeeping changes to the backend that allow us to build against LLVM 18, which we will need soon to support Ubuntu 24.04. The changes required are all self-contained and can be reviewed commit-by commit: - Build system update to detect LLVM 18 and consistently use fmt's header-only distribution - Fully adopt the opaque pointer API everywhere it can be; the remaining places we were using typed pointers are removed in LLVM 18. - Conditional compilation to support the various different APIs LLVM has had for creating `malloc` calls; we'll be able to simplify this soon. - Conditional compilation for changed enum visibilities across LLVM versions. Note that we're not yet running CI against LLVM 18; that will require a Nixpkgs update which I'll handle in a separate PR. This PR is just backwards compatible changes that _allow_ us to adopt 18 with no extra work. --------- Co-authored-by: rv-jenkins <[email protected]>
1 parent 3060b54 commit 1c477fa

File tree

13 files changed

+153
-113
lines changed

13 files changed

+153
-113
lines changed

cmake/FindLLVM.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
find_package(LLVM 17 QUIET CONFIG)
1+
find_package(LLVM 18.1 QUIET CONFIG)
2+
3+
if (NOT LLVM_FOUND)
4+
find_package(LLVM 17 QUIET CONFIG)
5+
endif()
26

37
if (NOT LLVM_FOUND)
48
find_package(LLVM 16 QUIET CONFIG)

deps/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ file(
88
)
99

1010
add_subdirectory(base64)
11-
add_subdirectory(fmt)
11+
add_subdirectory(fmt EXCLUDE_FROM_ALL)
1212
add_subdirectory(pybind11)

include/kllvm/codegen/Util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ llvm::Constant *get_offset_of_member(llvm::Module *, llvm::StructType *, int);
1919
// one does not yet exist
2020
llvm::Function *kore_heap_alloc(std::string const &name, llvm::Module *module);
2121

22+
llvm::Instruction *create_malloc(
23+
llvm::BasicBlock *block, llvm::Type *int_ptr_ty, llvm::Type *alloc_ty,
24+
llvm::Value *alloc_size, llvm::Value *array_size, llvm::Function *malloc_f,
25+
std::string const &name = "");
26+
2227
// getOrInsertFunction on module, aborting on failure
2328
template <class... Ts>
2429
llvm::Function *get_or_insert_function(llvm::Module *module, Ts &&...args) {

lib/binary/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ add_library(BinaryKore
55
)
66

77
target_link_libraries(BinaryKore
8-
PUBLIC AST fmt::fmt
8+
PUBLIC AST fmt::fmt-header-only
99
)
1010

1111
install(

lib/codegen/ApplyPasses.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,20 @@ using namespace llvm;
2727

2828
namespace kllvm {
2929

30-
CodeGenOpt::Level get_opt_level() {
30+
#if LLVM_VERSION_MAJOR >= 18
31+
#define CODEGEN_OPT_LEVEL CodeGenOptLevel
32+
#define CODEGEN_OBJECT_FILE ObjectFile
33+
#else
34+
#define CODEGEN_OPT_LEVEL CodeGenOpt
35+
#define CODEGEN_OBJECT_FILE CGFT_ObjectFile
36+
#endif
37+
38+
auto get_opt_level() {
3139
switch (optimization_level) {
32-
case opt_level::O0: return CodeGenOpt::None;
33-
case opt_level::O1: return CodeGenOpt::Less;
34-
case opt_level::O2: return CodeGenOpt::Default;
35-
case opt_level::O3: return CodeGenOpt::Aggressive;
40+
case opt_level::O0: return CODEGEN_OPT_LEVEL::None;
41+
case opt_level::O1: return CODEGEN_OPT_LEVEL::Less;
42+
case opt_level::O2: return CODEGEN_OPT_LEVEL::Default;
43+
case opt_level::O3: return CODEGEN_OPT_LEVEL::Aggressive;
3644
}
3745
}
3846

@@ -88,8 +96,8 @@ void generate_object_file(llvm::Module &mod, llvm::raw_ostream &os) {
8896
auto pm = legacy::PassManager{};
8997
mod.setDataLayout(target_machine->createDataLayout());
9098
target_machine->addPassesToEmitFile(
91-
pm, (raw_pwrite_stream &)os, nullptr, CodeGenFileType::CGFT_ObjectFile,
92-
true, nullptr);
99+
pm, (raw_pwrite_stream &)os, nullptr,
100+
CodeGenFileType::CODEGEN_OBJECT_FILE, true, nullptr);
93101

94102
pm.run(mod);
95103
}

lib/codegen/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ add_library(Codegen
1313
)
1414

1515
target_link_libraries(Codegen
16-
PUBLIC AST fmt::fmt
16+
PUBLIC AST fmt::fmt-header-only
1717
PRIVATE base64)

lib/codegen/CreateStaticTerm.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ create_static_term::create_token(value_type sort, std::string contents) {
194194
module_->getContext(), int_struct),
195195
num_limbs, mp_size,
196196
llvm::ConstantExpr::getPointerCast(
197-
limbs_var, llvm::Type::getInt64PtrTy(ctx_)))));
197+
limbs_var, llvm::PointerType::getUnqual(ctx_)))));
198198
mpz_clear(value);
199199
}
200200
std::vector<llvm::Constant *> idxs
@@ -290,7 +290,7 @@ create_static_term::create_token(value_type sort, std::string contents) {
290290
llvm::ConstantStruct::getAnon(
291291
{mpfr_prec, mpfr_sign, mpfr_exp,
292292
llvm::ConstantExpr::getPointerCast(
293-
limbs_var, llvm::Type::getInt64PtrTy(ctx_))}))));
293+
limbs_var, llvm::PointerType::getUnqual(ctx_))}))));
294294
mpfr_clear(value);
295295
}
296296
std::vector<llvm::Constant *> idxs

lib/codegen/CreateTerm.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -265,20 +265,11 @@ llvm::Value *allocate_term(
265265
llvm::Value *allocate_term(
266266
llvm::Type *alloc_type, llvm::Value *len, llvm::BasicBlock *block,
267267
char const *alloc_fn) {
268-
llvm::Instruction *malloc = llvm::CallInst::CreateMalloc(
268+
auto *malloc = create_malloc(
269269
block, llvm::Type::getInt64Ty(block->getContext()), alloc_type, len,
270270
nullptr, kore_heap_alloc(alloc_fn, block->getModule()));
271271

272-
if (!block->empty()) {
273-
set_debug_loc(&block->back());
274-
}
275-
276-
#if LLVM_VERSION_MAJOR < 16
277-
malloc->insertAfter(&block->back());
278-
#else
279-
malloc->insertInto(block, block->end());
280-
#endif
281-
272+
set_debug_loc(malloc);
282273
return malloc;
283274
}
284275

@@ -521,7 +512,7 @@ llvm::Value *create_term::create_hook(
521512
get_or_insert_function(
522513
module_, "hook_MINT_import",
523514
getvalue_type({sort_category::Int, 0}, module_),
524-
llvm::Type::getInt64PtrTy(ctx_), llvm::Type::getInt64Ty(ctx_),
515+
llvm::PointerType::getUnqual(ctx_), llvm::Type::getInt64Ty(ctx_),
525516
llvm::Type::getInt1Ty(ctx_)),
526517
{ptr, llvm::ConstantInt::get(llvm::Type::getInt64Ty(ctx_), cat.bits),
527518
llvm::ConstantInt::getFalse(ctx_)},
@@ -573,7 +564,7 @@ llvm::Value *create_term::create_hook(
573564
get_or_insert_function(
574565
module_, "hook_MINT_import",
575566
getvalue_type({sort_category::Int, 0}, module_),
576-
llvm::Type::getInt64PtrTy(ctx_), llvm::Type::getInt64Ty(ctx_),
567+
llvm::PointerType::getUnqual(ctx_), llvm::Type::getInt64Ty(ctx_),
577568
llvm::Type::getInt1Ty(ctx_)),
578569
{ptr, llvm::ConstantInt::get(llvm::Type::getInt64Ty(ctx_), cat.bits),
579570
llvm::ConstantInt::getTrue(ctx_)},
@@ -589,7 +580,7 @@ llvm::Value *create_term::create_hook(
589580
auto *type = getvalue_type(cat, module_);
590581
llvm::Instruction *ptr = llvm::CallInst::Create(
591582
get_or_insert_function(
592-
module_, "hook_MINT_export", llvm::Type::getInt64PtrTy(ctx_),
583+
module_, "hook_MINT_export", llvm::PointerType::getUnqual(ctx_),
593584
getvalue_type({sort_category::Int, 0}, module_),
594585
llvm::Type::getInt64Ty(ctx_)),
595586
{mpz, llvm::ConstantInt::get(llvm::Type::getInt64Ty(ctx_), cat.bits)},

lib/codegen/Decision.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void decision::operator()(decision_node *entry) {
5454
"_1", getvalue_type({sort_category::Symbol, 0}, module_)));
5555
fail_subject_->addIncoming(
5656
new llvm::BitCastInst(
57-
val, llvm::Type::getInt8PtrTy(ctx_), "", current_block_),
57+
val, llvm::PointerType::getUnqual(ctx_), "", current_block_),
5858
current_block_);
5959
fail_pattern_->addIncoming(
6060
string_literal("\\bottom{SortGeneratedTopCell{}}()"), current_block_);
@@ -72,7 +72,7 @@ llvm::Value *decision::ptr_term(llvm::Value *val) {
7272
val = allocate_term(val->getType(), current_block_, "kore_alloc_always_gc");
7373
}
7474
return new llvm::BitCastInst(
75-
val, llvm::Type::getInt8PtrTy(ctx_), "", current_block_);
75+
val, llvm::PointerType::getUnqual(ctx_), "", current_block_);
7676
}
7777

7878
bool decision_node::begin_node(decision *d, std::string const &name) {
@@ -490,16 +490,16 @@ void function_node::codegen(decision *d) {
490490
function_args.push_back(d->string_literal(str));
491491
}
492492
function_args.push_back(
493-
llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(d->ctx_)));
493+
llvm::ConstantPointerNull::get(llvm::PointerType::getUnqual(d->ctx_)));
494494

495495
auto *call = llvm::CallInst::Create(
496496
get_or_insert_function(
497497
d->module_, "add_match_function",
498498
llvm::FunctionType::get(
499499
llvm::Type::getVoidTy(d->ctx_),
500-
{llvm::Type::getInt8PtrTy(d->ctx_),
501-
llvm::Type::getInt8PtrTy(d->ctx_),
502-
llvm::Type::getInt8PtrTy(d->ctx_)},
500+
{llvm::PointerType::getUnqual(d->ctx_),
501+
llvm::PointerType::getUnqual(d->ctx_),
502+
llvm::PointerType::getUnqual(d->ctx_)},
503503
true)),
504504
function_args, "", d->current_block_);
505505
set_debug_loc(call);
@@ -709,7 +709,7 @@ static void init_choice_buffer(
709709
std::unordered_set<leaf_node *> leaves;
710710
dt->preprocess(leaves);
711711
auto *ty = llvm::ArrayType::get(
712-
llvm::Type::getInt8PtrTy(module->getContext()),
712+
llvm::PointerType::getUnqual(module->getContext()),
713713
dt->get_choice_depth() + 1);
714714
auto *choice_buffer = new llvm::AllocaInst(ty, 0, "choiceBuffer", block);
715715
auto *choice_depth = new llvm::AllocaInst(
@@ -928,7 +928,7 @@ static void store_ptrs_for_gc(
928928
auto *zero
929929
= llvm::ConstantInt::get(llvm::Type::getInt64Ty(module->getContext()), 0);
930930
llvm::Type *voidptrptr = llvm::PointerType::getUnqual(
931-
llvm::Type::getInt8PtrTy(module->getContext()));
931+
llvm::PointerType::getUnqual(module->getContext()));
932932
for (unsigned i = 0; i < nroots; i++) {
933933
auto *ptr = llvm::GetElementPtrInst::CreateInBounds(
934934
root_ty, arr,
@@ -1031,7 +1031,7 @@ static void load_ptrs_for_gc(
10311031
std::vector<value_type> const &types,
10321032
std::vector<llvm::Value *> const &are_block) {
10331033
llvm::Type *voidptrptr = llvm::PointerType::getUnqual(
1034-
llvm::Type::getInt8PtrTy(module->getContext()));
1034+
llvm::PointerType::getUnqual(module->getContext()));
10351035
unsigned i = 0;
10361036
for (auto [ptr, pointee_ty] : root_ptrs) {
10371037
llvm::Value *loaded = nullptr;
@@ -1130,24 +1130,18 @@ std::pair<std::vector<llvm::Value *>, llvm::BasicBlock *> step_function_header(
11301130
i++;
11311131
}
11321132
auto *root_ty = llvm::ArrayType::get(
1133-
llvm::Type::getInt8PtrTy(module->getContext()), 256);
1133+
llvm::PointerType::getUnqual(module->getContext()), 256);
11341134
auto *arr = module->getOrInsertGlobal("gc_roots", root_ty);
11351135
std::vector<std::pair<llvm::Value *, llvm::Type *>> root_ptrs;
11361136
std::vector<llvm::Value *> are_block;
1137-
llvm::Instruction *are_block_val = llvm::CallInst::CreateMalloc(
1137+
auto *are_block_val = create_malloc(
11381138
collect, llvm::Type::getInt64Ty(block->getContext()),
11391139
llvm::Type::getInt1Ty(module->getContext()),
11401140
llvm::ConstantInt::get(llvm::Type::getInt64Ty(module->getContext()), 1),
11411141
llvm::ConstantInt::get(
11421142
llvm::Type::getInt64Ty(module->getContext()), nroots),
11431143
nullptr);
11441144

1145-
#if LLVM_VERSION_MAJOR < 16
1146-
are_block_val->insertAfter(&collect->back());
1147-
#else
1148-
are_block_val->insertInto(collect, collect->end());
1149-
#endif
1150-
11511145
store_ptrs_for_gc(
11521146
nroots, module, root_ty, arr, are_block_val, collect, roots, types,
11531147
ptr_types, root_ptrs, are_block);
@@ -1198,7 +1192,7 @@ std::pair<std::vector<llvm::Value *>, llvm::BasicBlock *> step_function_header(
11981192
llvm::FunctionType::get(
11991193
llvm::Type::getVoidTy(module->getContext()),
12001194
{arr->getType(), llvm::Type::getInt8Ty(module->getContext()), ptr_ty,
1201-
llvm::Type::getInt1PtrTy(module->getContext())},
1195+
llvm::PointerType::getUnqual(module->getContext())},
12021196
false));
12031197
auto *call = llvm::CallInst::Create(
12041198
kore_collect,
@@ -1379,11 +1373,22 @@ void make_match_reason_function(
13791373
llvm::BasicBlock *fail
13801374
= llvm::BasicBlock::Create(module->getContext(), "fail", match_func);
13811375
llvm::PHINode *fail_subject = llvm::PHINode::Create(
1382-
llvm::Type::getInt8PtrTy(module->getContext()), 0, "subject", fail);
1376+
llvm::PointerType::getUnqual(module->getContext()), 0, "subject", fail);
1377+
1378+
// The pointer types created here for the failure pattern and sort need to be
1379+
// given an explicit element type on LLVM 15 (LLVM_VERSION_MAJOR <= 15). This
1380+
// is because the constants that eventually flow into the Phi nodes still get
1381+
// type `i8*` on LLVM 15, rather than `ptr` as would be assigned here.
1382+
//
1383+
// In newer versions, the string constants also get type `ptr` and these
1384+
// explicit element types become no-ops that we can remove.
13831385
llvm::PHINode *fail_pattern = llvm::PHINode::Create(
1384-
llvm::Type::getInt8PtrTy(module->getContext()), 0, "pattern", fail);
1386+
llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(module->getContext())),
1387+
0, "pattern", fail);
13851388
llvm::PHINode *fail_sort = llvm::PHINode::Create(
1386-
llvm::Type::getInt8PtrTy(module->getContext()), 0, "sort", fail);
1389+
llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(module->getContext())),
1390+
0, "sort", fail);
1391+
13871392
auto *call = llvm::CallInst::Create(
13881393
get_or_insert_function(
13891394
module, "add_match_fail_reason",

0 commit comments

Comments
 (0)