Skip to content

Commit 5d7dd50

Browse files
Implementing hook_LIST_getMInt codegen with support to MInt{64}
Implementing `hook_LIST_get64` in bytes.cpp Adding `list-get` unit test
1 parent 3669211 commit 5d7dd50

File tree

6 files changed

+3147
-0
lines changed

6 files changed

+3147
-0
lines changed

lib/codegen/CreateTerm.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,48 @@ llvm::Value *create_term::create_hardcoded_hook(
446446
current_block_ = merge_block;
447447
return phi;
448448
}
449+
450+
if (name == "LIST.getMInt") {
451+
llvm::Value *list = alloc_arg(pattern, 0, location_stack);
452+
args.push_back(list);
453+
llvm::Value *index = alloc_arg(pattern, 1, location_stack);
454+
args.push_back(index);
455+
auto *index_type = llvm::dyn_cast<llvm::IntegerType>(index->getType());
456+
if (!index_type) {
457+
throw std::invalid_argument(
458+
"LIST.getMInt: index argument is not a machine integer type");
459+
}
460+
unsigned index_bits = index_type->getBitWidth();
461+
llvm::CallInst *result = nullptr;
462+
switch (index_bits) {
463+
case 64: {
464+
result = llvm::CallInst::Create(
465+
get_or_insert_function(
466+
module_, "hook_LIST_get64", ptr_ty, list->getType(), index_type),
467+
{list, index}, "hook_LIST_get64", current_block_);
468+
break;
469+
}
470+
case 256: {
471+
// As immer does not support 256-bit integers, we need to truncate
472+
// the index to 64 bits.
473+
auto *truncated_index = llvm::CastInst::CreateTruncOrBitCast(
474+
index, llvm::Type::getInt64Ty(ctx_), "truncated_index",
475+
current_block_);
476+
result = llvm::CallInst::Create(
477+
get_or_insert_function(
478+
module_, "hook_LIST_get64", ptr_ty, list->getType(),
479+
llvm::Type::getInt64Ty(ctx_)),
480+
{list, truncated_index}, "hook_LIST_get64", current_block_);
481+
break;
482+
}
483+
default: {
484+
throw std::invalid_argument(
485+
fmt::format("LIST.getMInt: unsupported size {}", index_bits));
486+
}
487+
}
488+
set_debug_loc(result);
489+
return result;
490+
}
449491
if (name == "LIST.sizeMInt") {
450492
llvm::Value *list = alloc_arg(pattern, 0, location_stack);
451493
args.push_back(list);

runtime/collections/lists.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ SortKItem hook_LIST_get_null(SortList list, SortInt index) {
6666
return list->at(abs_idx);
6767
}
6868

69+
SortKItem hook_LIST_get64(SortList list, ssize_t index) {
70+
if (index < INT64_MIN || index > INT64_MAX) {
71+
KLLVM_HOOK_INVALID_ARGUMENT("Index is too large for get: {}", index);
72+
}
73+
size_t size = list->size();
74+
size_t abs_index = index < 0 ? (long)size + index : index;
75+
return list->at(abs_index);
76+
}
77+
6978
SortKItem hook_LIST_get(SortList list, SortInt index) {
7079
if (!mpz_fits_slong_p(index)) {
7180
KLLVM_HOOK_INVALID_ARGUMENT(
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module LIST-GET
2+
3+
imports INT
4+
imports MINT
5+
imports BOOL
6+
imports LIST
7+
imports K-EQUAL
8+
9+
syntax MInt{64}
10+
syntax MInt{256}
11+
12+
syntax List ::= "listOfMInt" [macro]
13+
rule listOfMInt => ListItem(2p64) (ListItem(3p64) (ListItem(4p64) .List))
14+
15+
syntax Bool ::= "getMInt" [function]
16+
rule getMInt => listOfMInt[1]:KItem ==K listOfMInt[1p64]:KItem andBool
17+
listOfMInt[1]:KItem ==K listOfMInt[1p256]:KItem
18+
19+
endmodule

0 commit comments

Comments
 (0)