diff --git a/include/kllvm/codegen/Util.h b/include/kllvm/codegen/Util.h index fe80c50c4..75947e096 100644 --- a/include/kllvm/codegen/Util.h +++ b/include/kllvm/codegen/Util.h @@ -1,6 +1,8 @@ #ifndef KLLVM_UTIL_H #define KLLVM_UTIL_H +#include + #include #include #include @@ -38,6 +40,8 @@ llvm::Function *get_or_insert_function(llvm::Module *module, Ts &&...args) { return func; } +char const *get_collection_alloc_fn(sort_category cat); + } // namespace kllvm #endif // KLLVM_UTIL_H diff --git a/include/runtime/collect.h b/include/runtime/collect.h index 1686cebf6..2cb265d80 100644 --- a/include/runtime/collect.h +++ b/include/runtime/collect.h @@ -39,14 +39,6 @@ void migrate_set(void *s); void migrate_collection_node(void **node_ptr); void set_kore_memory_functions_for_gmp(void); void kore_collect(void **, uint8_t, layoutitem *); -void store_map_for_gc(void **, map *); -void store_set_for_gc(void **, set *); -void store_list_for_gc(void **, list *); -void store_rangemap_for_gc(void **, rangemap *); -map *load_map_for_gc(void **); -set *load_set_for_gc(void **); -list *load_list_for_gc(void **); -rangemap *load_rangemap_for_gc(void **); } #ifdef GC_DBG diff --git a/lib/codegen/CreateTerm.cpp b/lib/codegen/CreateTerm.cpp index 60213224f..b4181e2fd 100644 --- a/lib/codegen/CreateTerm.cpp +++ b/lib/codegen/CreateTerm.cpp @@ -777,8 +777,8 @@ llvm::Value *create_term::create_function_call( if (sret) { // we don't use alloca here because the tail call optimization pass for llvm // doesn't handle correctly functions with alloca - alloc_sret - = allocate_term(return_type, current_block_, "kore_alloc_always_gc"); + alloc_sret = allocate_term( + return_type, current_block_, get_collection_alloc_fn(return_cat.cat)); sret_type = return_type; real_args.insert(real_args.begin(), alloc_sret); types.insert(types.begin(), alloc_sret->getType()); @@ -1244,7 +1244,7 @@ std::string make_apply_rule_function( if (!arg->getType()->isPointerTy()) { auto *ptr = allocate_term( arg->getType(), creator.get_current_block(), - "kore_alloc_always_gc"); + get_collection_alloc_fn(cat.cat)); new llvm::StoreInst(arg, ptr, creator.get_current_block()); arg = ptr; } diff --git a/lib/codegen/Decision.cpp b/lib/codegen/Decision.cpp index c014927a5..212a1e69f 100644 --- a/lib/codegen/Decision.cpp +++ b/lib/codegen/Decision.cpp @@ -904,7 +904,8 @@ void add_owise( ->get_category(d); if (is_collection_sort(return_sort)) { auto *temp_alloc = allocate_term( - retval->getType(), creator.get_current_block(), "kore_alloc_always_gc"); + retval->getType(), creator.get_current_block(), + get_collection_alloc_fn(return_sort.cat)); new llvm::StoreInst(retval, temp_alloc, creator.get_current_block()); retval = temp_alloc; } @@ -929,58 +930,16 @@ static void store_ptrs_for_gc( std::vector> &root_ptrs) { auto *zero = llvm::ConstantInt::get(llvm::Type::getInt64Ty(module->getContext()), 0); - llvm::Type *voidptrptr = llvm::PointerType::getUnqual( - llvm::PointerType::getUnqual(module->getContext())); for (unsigned i = 0; i < nroots; i++) { auto *ptr = llvm::GetElementPtrInst::CreateInBounds( root_ty, arr, {zero, llvm::ConstantInt::get( llvm::Type::getInt64Ty(module->getContext()), i)}, "", collect); - switch (types[i].cat) { - case sort_category::Map: - llvm::CallInst::Create( - get_or_insert_function( - module, "store_map_for_gc", - llvm::Type::getInt1Ty(module->getContext()), voidptrptr, - ptr_types[i]), - {ptr, roots[i]}, "", collect); - root_ptrs.emplace_back(ptr, ptr_types[i]); - break; - case sort_category::RangeMap: - llvm::CallInst::Create( - get_or_insert_function( - module, "store_rangemap_for_gc", - llvm::Type::getInt1Ty(module->getContext()), voidptrptr, - ptr_types[i]), - {ptr, roots[i]}, "", collect); - root_ptrs.emplace_back(ptr, ptr_types[i]); - break; - case sort_category::List: - llvm::CallInst::Create( - get_or_insert_function( - module, "store_list_for_gc", - llvm::Type::getInt1Ty(module->getContext()), voidptrptr, - ptr_types[i]), - {ptr, roots[i]}, "", collect); - root_ptrs.emplace_back(ptr, ptr_types[i]); - break; - case sort_category::Set: - llvm::CallInst::Create( - get_or_insert_function( - module, "store_set_for_gc", - llvm::Type::getInt1Ty(module->getContext()), voidptrptr, - ptr_types[i]), - {ptr, roots[i]}, "", collect); - root_ptrs.emplace_back(ptr, ptr_types[i]); - break; - default: - auto *casted = new llvm::BitCastInst( - ptr, llvm::PointerType::getUnqual(ptr_types[i]), "", collect); - new llvm::StoreInst(roots[i], casted, collect); - root_ptrs.emplace_back(casted, ptr_types[i]); - break; - } + auto *casted = new llvm::BitCastInst( + ptr, llvm::PointerType::getUnqual(ptr_types[i]), "", collect); + new llvm::StoreInst(roots[i], casted, collect); + root_ptrs.emplace_back(casted, ptr_types[i]); } } @@ -992,42 +951,9 @@ static void load_ptrs_for_gc( std::vector &phis, std::vector const &roots, std::vector> const &root_ptrs, std::vector const &types) { - llvm::Type *voidptrptr = llvm::PointerType::getUnqual( - llvm::PointerType::getUnqual(module->getContext())); unsigned i = 0; for (auto [ptr, pointee_ty] : root_ptrs) { - llvm::Value *loaded = nullptr; - switch (types[i].cat) { - case sort_category::Map: - loaded = llvm::CallInst::Create( - get_or_insert_function( - module, "load_map_for_gc", pointee_ty, voidptrptr, - llvm::Type::getInt1Ty(module->getContext())), - {ptr}, "", collect); - break; - case sort_category::RangeMap: - loaded = llvm::CallInst::Create( - get_or_insert_function( - module, "load_rangemap_for_gc", pointee_ty, voidptrptr, - llvm::Type::getInt1Ty(module->getContext())), - {ptr}, "", collect); - break; - case sort_category::List: - loaded = llvm::CallInst::Create( - get_or_insert_function( - module, "load_list_for_gc", pointee_ty, voidptrptr, - llvm::Type::getInt1Ty(module->getContext())), - {ptr}, "", collect); - break; - case sort_category::Set: - loaded = llvm::CallInst::Create( - get_or_insert_function( - module, "load_set_for_gc", pointee_ty, voidptrptr, - llvm::Type::getInt1Ty(module->getContext())), - {ptr}, "", collect); - break; - default: loaded = new llvm::LoadInst(pointee_ty, ptr, "", collect); - } + llvm::Value *loaded = new llvm::LoadInst(pointee_ty, ptr, "", collect); auto *phi = llvm::PHINode::Create(loaded->getType(), 2, "phi", merge); phi->addIncoming(loaded, collect); phi->addIncoming(roots[i++], check_collect); diff --git a/lib/codegen/Util.cpp b/lib/codegen/Util.cpp index 45f333dc2..4b160087e 100644 --- a/lib/codegen/Util.cpp +++ b/lib/codegen/Util.cpp @@ -58,4 +58,14 @@ llvm::Constant *get_offset_of_member( #endif } +char const *get_collection_alloc_fn(sort_category cat) { + switch (cat) { + case sort_category::Map: return "kore_alloc_map"; + case sort_category::Set: return "kore_alloc_set"; + case sort_category::List: return "kore_alloc_list"; + case sort_category::RangeMap: return "kore_alloc_rangemap"; + default: abort(); + } +} + } // namespace kllvm diff --git a/runtime/alloc/alloc.cpp b/runtime/alloc/alloc.cpp index d1787bc15..603748978 100644 --- a/runtime/alloc/alloc.cpp +++ b/runtime/alloc/alloc.cpp @@ -157,4 +157,37 @@ __attribute__((always_inline)) void *kore_alloc_floating_old(size_t requested) { init_with_len(result, sizeof(floating_hdr) - sizeof(blockheader)); return &result->f; } + +extern "C++" { +template +static inline void *kore_alloc_collection(kllvm::sort_category cat) { + void *mem + = kore_alloc(sizeof(blockheader) + sizeof(collection) + sizeof(uint64_t)); + auto *hdr = (blockheader *)mem; + static std::string name = get_raw_symbol_name(cat) + "{}"; + static blockheader hdr_val + = get_block_header_for_symbol(get_tag_for_symbol_name(name.c_str())); + *hdr = hdr_val; + auto *offset = (uint64_t *)(hdr + 1); + *offset = 16; + auto *child = hdr + 2; + return child; +} +} + +void *kore_alloc_map(size_t requested) { + return kore_alloc_collection(kllvm::sort_category::Map); +} + +void *kore_alloc_set(size_t requested) { + return kore_alloc_collection(kllvm::sort_category::Set); +} + +void *kore_alloc_list(size_t requested) { + return kore_alloc_collection(kllvm::sort_category::List); +} + +void *kore_alloc_rangemap(size_t requested) { + return kore_alloc_collection(kllvm::sort_category::RangeMap); +} } diff --git a/runtime/collect/collect.cpp b/runtime/collect/collect.cpp index 9b3fb3c71..cdd427276 100644 --- a/runtime/collect/collect.cpp +++ b/runtime/collect/collect.cpp @@ -360,89 +360,4 @@ bool is_collection() { size_t threshold = get_gc_threshold(); return youngspace_almost_full(threshold); } - -void store_map_for_gc(void **roots, map *ptr) { - if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) { - *roots = ptr; - return; - } - void *mem = kore_alloc(sizeof(blockheader) + sizeof(map) + sizeof(uint64_t)); - auto *hdr = (blockheader *)mem; - std::string name = get_raw_symbol_name(kllvm::sort_category::Map) + "{}"; - *hdr = get_block_header_for_symbol(get_tag_for_symbol_name(name.c_str())); - auto *offset = (uint64_t *)(hdr + 1); - *offset = 16; - auto *child = (map *)(hdr + 2); - *child = std::move(*ptr); - *roots = child; -} - -void store_set_for_gc(void **roots, set *ptr) { - if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) { - *roots = ptr; - return; - } - void *mem = kore_alloc(sizeof(blockheader) + sizeof(set) + sizeof(uint64_t)); - auto *hdr = (blockheader *)mem; - std::string name = get_raw_symbol_name(kllvm::sort_category::Set) + "{}"; - *hdr = get_block_header_for_symbol(get_tag_for_symbol_name(name.c_str())); - auto *offset = (uint64_t *)(hdr + 1); - *offset = 16; - auto *child = (set *)(hdr + 2); - *child = std::move(*ptr); - *roots = child; -} - -void store_list_for_gc(void **roots, list *ptr) { - if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) { - *roots = ptr; - return; - } - void *mem = kore_alloc(sizeof(blockheader) + sizeof(list) + sizeof(uint64_t)); - auto *hdr = (blockheader *)mem; - std::string name = get_raw_symbol_name(kllvm::sort_category::List) + "{}"; - *hdr = get_block_header_for_symbol(get_tag_for_symbol_name(name.c_str())); - auto *offset = (uint64_t *)(hdr + 1); - *offset = 16; - auto *child = (list *)(hdr + 2); - *child = std::move(*ptr); - *roots = child; -} - -void store_rangemap_for_gc(void **roots, rangemap *ptr) { - if (get_arena_semispace_id_of_object(ptr) != ALWAYSGCSPACE_ID) { - *roots = ptr; - return; - } - void *mem - = kore_alloc(sizeof(blockheader) + sizeof(rangemap) + sizeof(uint64_t)); - auto *hdr = (blockheader *)mem; - std::string name = get_raw_symbol_name(kllvm::sort_category::RangeMap) + "{}"; - *hdr = get_block_header_for_symbol(get_tag_for_symbol_name(name.c_str())); - auto *offset = (uint64_t *)(hdr + 1); - *offset = 16; - auto *child = (rangemap *)(hdr + 2); - *child = std::move(*ptr); - *roots = child; -} - -map *load_map_for_gc(void **roots) { - void *mem = *roots; - return (map *)mem; -} - -set *load_set_for_gc(void **roots) { - void *mem = *roots; - return (set *)mem; -} - -list *load_list_for_gc(void **roots) { - void *mem = *roots; - return (list *)mem; -} - -rangemap *load_rangemap_for_gc(void **roots) { - void *mem = *roots; - return (rangemap *)mem; -} } diff --git a/unittests/runtime-strings/stringtest.cpp b/unittests/runtime-strings/stringtest.cpp index 83c226928..0c2b80cd3 100644 --- a/unittests/runtime-strings/stringtest.cpp +++ b/unittests/runtime-strings/stringtest.cpp @@ -67,6 +67,10 @@ floating *move_float(floating *i) { } void add_hash64(void *, uint64_t) { } + +struct blockheader get_block_header_for_symbol(uint32_t tag) { + return blockheader{tag}; +} } BOOST_AUTO_TEST_SUITE(StringTest)