diff --git a/include/vuk/IR.hpp b/include/vuk/IR.hpp index 1e522d2b..a89e6f23 100644 --- a/include/vuk/IR.hpp +++ b/include/vuk/IR.hpp @@ -109,16 +109,10 @@ namespace vuk { return v; case COMPOSITE_TY: { v = COMPOSITE_TY; - if (t->composite.types.size() == 9) - printf("%u\n", v); for (int i = 0; i < t->composite.types.size(); i++) { hash_combine_direct(v, Type::hash(t->composite.types[i])); - if (t->composite.types.size() == 9) - printf("%u\n", v); } hash_combine_direct(v, (uint32_t)t->composite.tag); - if (t->composite.types.size() == 9) - printf("%u\n", v); return v; } case OPAQUE_FN_TY: @@ -790,9 +784,9 @@ namespace vuk { offsetof(ImageAttachment, base_level), offsetof(ImageAttachment, level_count) }; auto image_type = emplace_type(Type{ .kind = Type::COMPOSITE_TY, - .size = sizeof(ImageAttachment), - .debug_info = allocate_type_debug_info("image"), - .composite = { .types = { image_, 9 }, .offsets = { image_offsets, 9 }, .tag = 0 } }); + .size = sizeof(ImageAttachment), + .debug_info = allocate_type_debug_info("image"), + .composite = { .types = { image_, 9 }, .offsets = { image_offsets, 9 }, .tag = 0 } }); builtin_image = Type::hash(image_type); return image_type; } @@ -806,9 +800,9 @@ namespace vuk { }; auto buffer_offsets = new size_t[1]{ offsetof(Buffer, size) }; auto buffer_type = emplace_type(Type{ .kind = Type::COMPOSITE_TY, - .size = sizeof(Buffer), - .debug_info = allocate_type_debug_info("buffer"), - .composite = { .types = { buffer_, 1 }, .offsets = { buffer_offsets, 1 }, .tag = 1 } }); + .size = sizeof(Buffer), + .debug_info = allocate_type_debug_info("buffer"), + .composite = { .types = { buffer_, 1 }, .offsets = { buffer_offsets, 1 }, .tag = 1 } }); builtin_buffer = Type::hash(buffer_type); return buffer_type; } @@ -826,9 +820,9 @@ namespace vuk { auto offsets = new size_t[1]{ 0 }; auto swapchain_type = emplace_type(Type{ .kind = Type::COMPOSITE_TY, - .size = sizeof(Swapchain), - .debug_info = allocate_type_debug_info("swapchain"), - .composite = { .types = { swp_, 1 }, .offsets = { offsets, 1 }, .tag = 2 } }); + .size = sizeof(Swapchain), + .debug_info = allocate_type_debug_info("swapchain"), + .composite = { .types = { swp_, 1 }, .offsets = { offsets, 1 }, .tag = 2 } }); builtin_swapchain = Type::hash(swapchain_type); return swapchain_type; } @@ -865,6 +859,44 @@ namespace vuk { return t; } + Type* copy_type(Type* type) { + auto make_type_copy = [this](Type*& t) { + t = emplace_type(*t); + if (t->debug_info) { + t->debug_info = new TypeDebugInfo(*t->debug_info); + } + }; + // copy outer type, then copy inner types as needed + make_type_copy(type); + + if (type->kind == Type::ALIASED_TY) { + make_type_copy(type->aliased.T); + } else if (type->kind == Type::IMBUED_TY) { + make_type_copy(type->imbued.T); + } else if (type->kind == Type::ARRAY_TY) { + type->array.T = copy_type(type->array.T); + } else if (type->kind == Type::COMPOSITE_TY) { + auto type_array = new Type*[type->composite.types.size()]; + auto type_offsets = new size_t[type->composite.types.size()]; + for (auto i = 0; i < type->composite.types.size(); i++) { + type_array[i] = copy_type(type->composite.types[i]); + type_offsets[i] = type->composite.offsets[i]; + } + type->composite.types = { type_array, type->composite.types.size() }; + type->composite.offsets = { type_offsets, type->composite.types.size() }; + } else if (type->kind == Type::OPAQUE_FN_TY) { + auto args = new Type*[type->opaque_fn.args.size()]; + std::copy(type->opaque_fn.args.begin(), type->opaque_fn.args.end(), args); + type->opaque_fn.args = { args, type->opaque_fn.args.size() }; + auto ret_ty_ptr = new Type*[type->opaque_fn.return_types.size()]; + std::copy(type->opaque_fn.return_types.begin(), type->opaque_fn.return_types.end(), ret_ty_ptr); + type->opaque_fn.return_types = { ret_ty_ptr, type->opaque_fn.return_types.size() }; + type->opaque_fn.callback = &*ucbs.emplace(*type->opaque_fn.callback); + } + + return type; + } + TypeDebugInfo* allocate_type_debug_info(std::string_view name) { return new TypeDebugInfo{ std::string(name) }; } @@ -1165,7 +1197,8 @@ namespace vuk { decltype(Node::call) call = { .args = std::span(args_ptr, sizeof...(args) + 1) }; Node n{}; n.kind = Node::CALL; - n.type = fn.type()->opaque_fn.return_types; + n.type = { new Type*[fn.type()->opaque_fn.return_types.size()], fn.type()->opaque_fn.return_types.size() }; + std::copy(fn.type()->opaque_fn.return_types.begin(), fn.type()->opaque_fn.return_types.end(), n.type.data()); n.call = call; return emplace_op(n); } @@ -1347,6 +1380,7 @@ namespace vuk { std::unique_ptr acqrel; std::vector> deps; IRModule* source_module; + private: Node* node; }; diff --git a/include/vuk/IRProcess.hpp b/include/vuk/IRProcess.hpp index f0a4b0ad..3c0c902e 100644 --- a/include/vuk/IRProcess.hpp +++ b/include/vuk/IRProcess.hpp @@ -7,6 +7,7 @@ #include #include +#include namespace vuk { @@ -32,6 +33,7 @@ namespace vuk { RGCImpl() : arena_(new arena(4 * 1024 * 1024)) {} RGCImpl(arena* a) : arena_(a) {} std::unique_ptr arena_; + std::pmr::monotonic_buffer_resource mbr; std::vector scheduled_execables; std::vector partitioned_execables; diff --git a/src/IRPasses.cpp b/src/IRPasses.cpp index 1860a78c..824ad19d 100644 --- a/src/IRPasses.cpp +++ b/src/IRPasses.cpp @@ -1041,10 +1041,13 @@ namespace vuk { enode->deps.clear(); // merge in any types that we are missing - for (auto& [k, v] : enode->source_module->type_map) { - auto local_ty = current_module->emplace_type(v); + if (enode->source_module != current_module.get()) { + for (auto& [k, v] : enode->source_module->type_map) { + current_module->copy_type(&v); + } + modules.emplace(enode->source_module); + } - modules.emplace(enode->source_module); impl->depnodes.push_back(std::move(enode)); } @@ -1064,7 +1067,7 @@ namespace vuk { std::sort(impl->depnodes.begin(), impl->depnodes.end()); impl->depnodes.erase(std::unique(impl->depnodes.begin(), impl->depnodes.end()), impl->depnodes.end()); - std::pmr::polymorphic_allocator allocator(std::pmr::new_delete_resource()); + std::pmr::polymorphic_allocator allocator(&impl->mbr); implicit_linking(current_module->op_arena.begin(), current_module->op_arena.end(), allocator); std::erase_if(impl->depnodes, [](std::shared_ptr& sp) { return sp.use_count() == 1 && sp->acqrel->status == Signal::Status::eDisarmed; }); diff --git a/src/runtime/vk/Backend.cpp b/src/runtime/vk/Backend.cpp index c20eda24..373a8c13 100644 --- a/src/runtime/vk/Backend.cpp +++ b/src/runtime/vk/Backend.cpp @@ -1830,6 +1830,7 @@ namespace vuk { switch (t->kind) { case Type::OPAQUE_FN_TY: { delete t->opaque_fn.args.data(); + delete t->opaque_fn.return_types.data(); auto it = current_module->ucbs.get_iterator(t->opaque_fn.callback); if (it != current_module->ucbs.end()) { current_module->ucbs.erase(it);