diff --git a/src/amd/compiler/aco_util.h b/src/amd/compiler/aco_util.h index 676879fffdd..a046e5c123d 100644 --- a/src/amd/compiler/aco_util.h +++ b/src/amd/compiler/aco_util.h @@ -31,7 +31,10 @@ #include #include +#include #include +#include +#include #include namespace aco { @@ -423,7 +426,7 @@ public: free(buffer); } - /* delete copy-constructor and -assigment to avoid double free() */ + /* Delete copy-constructor and -assigment to avoid double free() */ monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; monotonic_buffer_resource& operator=(const monotonic_buffer_resource&) = delete; @@ -476,6 +479,84 @@ private: 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 final { +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>>; + } // namespace aco #endif // ACO_UTIL_H