From 97fd5d3f33507f5a7fbb69d1403a8c29b05c84d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 10 Feb 2023 13:55:09 +0100 Subject: [PATCH] aco: make aco::monotonic_buffer_resource declaration visible for aco::IDSet Part-of: --- src/amd/compiler/aco_util.h | 318 ++++++++++++++++++------------------ 1 file changed, 159 insertions(+), 159 deletions(-) diff --git a/src/amd/compiler/aco_util.h b/src/amd/compiler/aco_util.h index a25f8483e2b..af67f140924 100644 --- a/src/amd/compiler/aco_util.h +++ b/src/amd/compiler/aco_util.h @@ -219,6 +219,165 @@ private: size_type length{0}; //!> Size of the span }; +/* + * Light-weight memory resource which allows to sequentially allocate from + * a buffer. Both, the release() method and the destructor release all managed + * memory. + * + * The memory resource is not thread-safe. + * This class mimics std::pmr::monotonic_buffer_resource + */ +class monotonic_buffer_resource final { +public: + explicit monotonic_buffer_resource(size_t size = initial_size) + { + /* The size parameter refers to the total size of the buffer. + * The usable data_size is size - sizeof(Buffer). + */ + size = MAX2(size, minimum_size); + buffer = (Buffer*)malloc(size); + buffer->next = nullptr; + buffer->data_size = size - sizeof(Buffer); + buffer->current_idx = 0; + } + + ~monotonic_buffer_resource() + { + release(); + free(buffer); + } + + /* Delete copy-constructor and -assignment to avoid double free() */ + monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; + monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete; + + void* allocate(size_t size, size_t alignment) + { + buffer->current_idx = align(buffer->current_idx, alignment); + if (buffer->current_idx + size <= buffer->data_size) { + uint8_t* ptr = &buffer->data[buffer->current_idx]; + buffer->current_idx += size; + return ptr; + } + + /* create new larger buffer */ + uint32_t total_size = buffer->data_size + sizeof(Buffer); + do { + total_size *= 2; + } while (total_size - sizeof(Buffer) < size); + Buffer* next = buffer; + buffer = (Buffer*)malloc(total_size); + buffer->next = next; + buffer->data_size = total_size - sizeof(Buffer); + buffer->current_idx = 0; + + return allocate(size, alignment); + } + + void release() + { + while (buffer->next) { + Buffer* next = buffer->next; + free(buffer); + buffer = next; + } + buffer->current_idx = 0; + } + + bool operator==(const monotonic_buffer_resource& other) { return buffer == other.buffer; } + +private: + struct Buffer { + Buffer* next; + uint32_t current_idx; + uint32_t data_size; + uint8_t data[]; + }; + + Buffer* buffer; + static constexpr size_t initial_size = 4096; + static constexpr size_t minimum_size = 128; + static_assert(minimum_size > sizeof(Buffer)); +}; + +/* + * Small memory allocator which wraps monotonic_buffer_resource + * in order to implement . + * + * This class mimics std::pmr::polymorphic_allocator with monotonic_buffer_resource + * as memory resource. The advantage of this specialization is the absence of + * virtual function calls and the propagation on swap, copy- and move assignment. + */ +template class monotonic_allocator { +public: + monotonic_allocator() = delete; + monotonic_allocator(monotonic_buffer_resource& m) : memory_resource(m) {} + template + explicit monotonic_allocator(const monotonic_allocator& rhs) + : memory_resource(rhs.memory_resource) + {} + + /* Memory Allocation */ + T* allocate(size_t size) + { + uint32_t bytes = sizeof(T) * size; + return (T*)memory_resource.get().allocate(bytes, alignof(T)); + } + + /* Memory will be freed on destruction of memory_resource */ + void deallocate(T* ptr, size_t size) {} + + /* Implement */ + using value_type = T; + template struct rebind { + using other = monotonic_allocator; + }; + + typedef std::true_type propagate_on_container_copy_assignment; + typedef std::true_type propagate_on_container_move_assignment; + typedef std::true_type propagate_on_container_swap; + + template friend class monotonic_allocator; + template + friend bool operator==(monotonic_allocator const& a, monotonic_allocator const& b); + template + friend bool operator!=(monotonic_allocator const& a, monotonic_allocator const& b); + +private: + std::reference_wrapper memory_resource; +}; + +/* Necessary for . */ +template +inline bool +operator==(monotonic_allocator const& a, monotonic_allocator const& b) +{ + return a.memory_resource.get() == b.memory_resource.get(); +} +template +inline bool +operator!=(monotonic_allocator const& a, monotonic_allocator const& b) +{ + return !(a == b); +} + +/* + * aco::map - alias for std::map with monotonic_allocator + * + * This template specialization mimics std::pmr::map. + */ +template > +using map = std::map>>; + +/* + * aco::unordered_map - alias for std::unordered_map with monotonic_allocator + * + * This template specialization mimics std::pmr::unordered_map. + */ +template , class Pred = std::equal_to> +using unordered_map = + std::unordered_map>>; + /* * Cache-friendly set of 32-bit IDs with fast insert/erase/lookup and * the ability to efficiently iterate over contained elements. @@ -413,165 +572,6 @@ IDSet::Iterator::operator*() const return id; } -/* - * Light-weight memory resource which allows to sequentially allocate from - * a buffer. Both, the release() method and the destructor release all managed - * memory. - * - * The memory resource is not thread-safe. - * This class mimics std::pmr::monotonic_buffer_resource - */ -class monotonic_buffer_resource final { -public: - explicit monotonic_buffer_resource(size_t size = initial_size) - { - /* The size parameter refers to the total size of the buffer. - * The usable data_size is size - sizeof(Buffer). - */ - size = MAX2(size, minimum_size); - buffer = (Buffer*)malloc(size); - buffer->next = nullptr; - buffer->data_size = size - sizeof(Buffer); - buffer->current_idx = 0; - } - - ~monotonic_buffer_resource() - { - release(); - free(buffer); - } - - /* Delete copy-constructor and -assignment to avoid double free() */ - monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; - monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete; - - void* allocate(size_t size, size_t alignment) - { - buffer->current_idx = align(buffer->current_idx, alignment); - if (buffer->current_idx + size <= buffer->data_size) { - uint8_t* ptr = &buffer->data[buffer->current_idx]; - buffer->current_idx += size; - return ptr; - } - - /* create new larger buffer */ - uint32_t total_size = buffer->data_size + sizeof(Buffer); - do { - total_size *= 2; - } while (total_size - sizeof(Buffer) < size); - Buffer* next = buffer; - buffer = (Buffer*)malloc(total_size); - buffer->next = next; - buffer->data_size = total_size - sizeof(Buffer); - buffer->current_idx = 0; - - return allocate(size, alignment); - } - - void release() - { - while (buffer->next) { - Buffer* next = buffer->next; - free(buffer); - buffer = next; - } - buffer->current_idx = 0; - } - - bool operator==(const monotonic_buffer_resource& other) { return buffer == other.buffer; } - -private: - struct Buffer { - Buffer* next; - uint32_t current_idx; - uint32_t data_size; - uint8_t data[]; - }; - - Buffer* buffer; - static constexpr size_t initial_size = 4096; - static constexpr size_t minimum_size = 128; - static_assert(minimum_size > sizeof(Buffer)); -}; - -/* - * Small memory allocator which wraps monotonic_buffer_resource - * in order to implement . - * - * This class mimics std::pmr::polymorphic_allocator with monotonic_buffer_resource - * as memory resource. The advantage of this specialization is the absence of - * virtual function calls and the propagation on swap, copy- and move assignment. - */ -template class monotonic_allocator { -public: - monotonic_allocator() = delete; - monotonic_allocator(monotonic_buffer_resource& m) : memory_resource(m) {} - template - explicit monotonic_allocator(const monotonic_allocator& rhs) - : memory_resource(rhs.memory_resource) - {} - - /* Memory Allocation */ - T* allocate(size_t size) - { - uint32_t bytes = sizeof(T) * size; - return (T*)memory_resource.get().allocate(bytes, alignof(T)); - } - - /* Memory will be freed on destruction of memory_resource */ - void deallocate(T* ptr, size_t size) {} - - /* Implement */ - using value_type = T; - template struct rebind { - using other = monotonic_allocator; - }; - - typedef std::true_type propagate_on_container_copy_assignment; - typedef std::true_type propagate_on_container_move_assignment; - typedef std::true_type propagate_on_container_swap; - - template friend class monotonic_allocator; - template - friend bool operator==(monotonic_allocator const& a, monotonic_allocator const& b); - template - friend bool operator!=(monotonic_allocator const& a, monotonic_allocator const& b); - -private: - std::reference_wrapper memory_resource; -}; - -/* Necessary for . */ -template -inline bool -operator==(monotonic_allocator const& a, monotonic_allocator const& b) -{ - return a.memory_resource.get() == b.memory_resource.get(); -} -template -inline bool -operator!=(monotonic_allocator const& a, monotonic_allocator const& b) -{ - return !(a == b); -} - -/* - * aco::map - alias for std::map with monotonic_allocator - * - * This template specialization mimics std::pmr::map. - */ -template > -using map = std::map>>; - -/* - * aco::unordered_map - alias for std::unordered_map with monotonic_allocator - * - * This template specialization mimics std::pmr::unordered_map. - */ -template , class Pred = std::equal_to> -using unordered_map = - std::unordered_map>>; - /* * Helper class for a integer/bool (access_type) packed into * a bigger integer (data_type) with an offset and size.