OLD | NEW |
1 //===- subzero/src/IceMemory.h - Memory management declarations -*- C++ -*-===// | 1 //===- subzero/src/IceMemory.h - Memory management declarations -*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
11 /// \brief Declares some useful data structures and routines dealing with | 11 /// \brief Declares some useful data structures and routines dealing with |
12 /// memory management in Subzero (mostly, allocator types.) | 12 /// memory management in Subzero (mostly, allocator types.) |
13 /// | 13 /// |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #ifndef SUBZERO_SRC_ICEMEMORY_H | 16 #ifndef SUBZERO_SRC_ICEMEMORY_H |
17 #define SUBZERO_SRC_ICEMEMORY_H | 17 #define SUBZERO_SRC_ICEMEMORY_H |
18 | 18 |
19 #include "IceTLS.h" | 19 #include "IceTLS.h" |
20 | 20 |
21 #include "llvm/Support/Allocator.h" | 21 #include "llvm/Support/Allocator.h" |
22 | 22 |
23 #include <cstddef> | 23 #include <cstddef> |
24 #include <mutex> | 24 #include <mutex> |
25 | 25 |
26 namespace Ice { | 26 namespace Ice { |
27 | 27 |
28 class Cfg; | 28 class Cfg; |
29 class GlobalContext; | 29 class GlobalContext; |
| 30 class Liveness; |
30 | 31 |
31 using ArenaAllocator = | 32 using ArenaAllocator = |
32 llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, /*SlabSize=*/1024 * 1024>; | 33 llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, /*SlabSize=*/1024 * 1024>; |
33 | 34 |
34 class LockedArenaAllocator { | 35 class LockedArenaAllocator { |
35 LockedArenaAllocator() = delete; | 36 LockedArenaAllocator() = delete; |
36 LockedArenaAllocator(const LockedArenaAllocator &) = delete; | 37 LockedArenaAllocator(const LockedArenaAllocator &) = delete; |
37 LockedArenaAllocator &operator=(const LockedArenaAllocator &) = delete; | 38 LockedArenaAllocator &operator=(const LockedArenaAllocator &) = delete; |
38 | 39 |
39 public: | 40 public: |
(...skipping 14 matching lines...) Loading... |
54 /// std::allocator interface implementation. | 55 /// std::allocator interface implementation. |
55 /// @{ | 56 /// @{ |
56 using value_type = T; | 57 using value_type = T; |
57 using pointer = T *; | 58 using pointer = T *; |
58 using const_pointer = const T *; | 59 using const_pointer = const T *; |
59 using reference = T &; | 60 using reference = T &; |
60 using const_reference = const T &; | 61 using const_reference = const T &; |
61 using size_type = std::size_t; | 62 using size_type = std::size_t; |
62 using difference_type = std::ptrdiff_t; | 63 using difference_type = std::ptrdiff_t; |
63 | 64 |
64 sz_allocator() = default; | 65 sz_allocator() : Current() {} |
65 template <class U> sz_allocator(const sz_allocator<U, Traits> &) {} | 66 template <class U> |
| 67 sz_allocator(const sz_allocator<U, Traits> &) |
| 68 : Current() {} |
66 | 69 |
67 pointer address(reference x) const { | 70 pointer address(reference x) const { |
68 return reinterpret_cast<pointer>(&reinterpret_cast<char &>(x)); | 71 return reinterpret_cast<pointer>(&reinterpret_cast<char &>(x)); |
69 } | 72 } |
70 const_pointer address(const_reference x) const { | 73 const_pointer address(const_reference x) const { |
71 return reinterpret_cast<const_pointer>(&reinterpret_cast<const char &>(x)); | 74 return reinterpret_cast<const_pointer>(&reinterpret_cast<const char &>(x)); |
72 } | 75 } |
73 | 76 |
74 pointer allocate(size_type num) { | 77 pointer allocate(size_type num) { |
| 78 assert(current() != nullptr); |
75 return current()->template Allocate<T>(num); | 79 return current()->template Allocate<T>(num); |
76 } | 80 } |
77 | 81 |
78 template <typename... A> void construct(pointer P, A &&... Args) { | 82 template <typename... A> void construct(pointer P, A &&... Args) { |
79 new (static_cast<void *>(P)) T(std::forward<A>(Args)...); | 83 new (static_cast<void *>(P)) T(std::forward<A>(Args)...); |
80 } | 84 } |
81 | 85 |
82 void deallocate(pointer, size_type) {} | 86 void deallocate(pointer, size_type) {} |
83 | 87 |
84 template <class U> struct rebind { typedef sz_allocator<U, Traits> other; }; | 88 template <class U> struct rebind { typedef sz_allocator<U, Traits> other; }; |
85 | 89 |
86 void destroy(pointer P) { P->~T(); } | 90 void destroy(pointer P) { P->~T(); } |
87 /// @} | 91 /// @} |
88 | 92 |
89 /// Manages the current underlying allocator. | 93 /// Manages the current underlying allocator. |
90 /// @{ | 94 /// @{ |
91 static typename Traits::allocator_type current() { return Traits::current(); } | 95 typename Traits::allocator_type current() { |
| 96 if (!Traits::cache_allocator) { |
| 97 // TODO(jpp): allocators should always be cacheable... maybe. Investigate. |
| 98 return Traits::current(); |
| 99 } |
| 100 if (Current == nullptr) { |
| 101 Current = Traits::current(); |
| 102 } |
| 103 assert(Current == Traits::current()); |
| 104 return Current; |
| 105 } |
92 static void init() { Traits::init(); } | 106 static void init() { Traits::init(); } |
93 /// @} | 107 /// @} |
| 108 typename Traits::allocator_type Current; |
94 }; | 109 }; |
95 | 110 |
96 template <class Traits> struct sz_allocator_scope { | 111 template <class Traits> struct sz_allocator_scope { |
97 explicit sz_allocator_scope(typename Traits::manager_type *Manager) { | 112 explicit sz_allocator_scope(typename Traits::manager_type *Manager) { |
98 Traits::set_current(Manager); | 113 Traits::set_current(Manager); |
99 } | 114 } |
100 | 115 |
101 ~sz_allocator_scope() { Traits::set_current(nullptr); } | 116 ~sz_allocator_scope() { Traits::set_current(nullptr); } |
102 }; | 117 }; |
103 | 118 |
(...skipping 11 matching lines...) Loading... |
115 | 130 |
116 class CfgAllocatorTraits { | 131 class CfgAllocatorTraits { |
117 CfgAllocatorTraits() = delete; | 132 CfgAllocatorTraits() = delete; |
118 CfgAllocatorTraits(const CfgAllocatorTraits &) = delete; | 133 CfgAllocatorTraits(const CfgAllocatorTraits &) = delete; |
119 CfgAllocatorTraits &operator=(const CfgAllocatorTraits &) = delete; | 134 CfgAllocatorTraits &operator=(const CfgAllocatorTraits &) = delete; |
120 ~CfgAllocatorTraits() = delete; | 135 ~CfgAllocatorTraits() = delete; |
121 | 136 |
122 public: | 137 public: |
123 using allocator_type = ArenaAllocator *; | 138 using allocator_type = ArenaAllocator *; |
124 using manager_type = Cfg; | 139 using manager_type = Cfg; |
| 140 static constexpr bool cache_allocator = false; |
125 | 141 |
126 static void init() { ICE_TLS_INIT_FIELD(CfgAllocator); }; | 142 static void init() { ICE_TLS_INIT_FIELD(CfgAllocator); }; |
127 | 143 |
128 static allocator_type current(); | 144 static allocator_type current(); |
129 static void set_current(const manager_type *Manager); | 145 static void set_current(const manager_type *Manager); |
130 | 146 |
131 private: | 147 private: |
132 ICE_TLS_DECLARE_FIELD(ArenaAllocator *, CfgAllocator); | 148 ICE_TLS_DECLARE_FIELD(ArenaAllocator *, CfgAllocator); |
133 }; | 149 }; |
134 | 150 |
135 template <typename T> | 151 template <typename T> |
136 using CfgLocalAllocator = sz_allocator<T, CfgAllocatorTraits>; | 152 using CfgLocalAllocator = sz_allocator<T, CfgAllocatorTraits>; |
137 | 153 |
138 using CfgLocalAllocatorScope = sz_allocator_scope<CfgAllocatorTraits>; | 154 using CfgLocalAllocatorScope = sz_allocator_scope<CfgAllocatorTraits>; |
139 | 155 |
| 156 class LivenessAllocatorTraits { |
| 157 LivenessAllocatorTraits() = delete; |
| 158 LivenessAllocatorTraits(const LivenessAllocatorTraits &) = delete; |
| 159 LivenessAllocatorTraits &operator=(const LivenessAllocatorTraits &) = delete; |
| 160 ~LivenessAllocatorTraits() = delete; |
| 161 |
| 162 public: |
| 163 using allocator_type = ArenaAllocator *; |
| 164 using manager_type = Liveness; |
| 165 static constexpr bool cache_allocator = true; |
| 166 |
| 167 static void init() { ICE_TLS_INIT_FIELD(LivenessAllocator); }; |
| 168 |
| 169 static allocator_type current(); |
| 170 static void set_current(const manager_type *Manager); |
| 171 |
| 172 private: |
| 173 ICE_TLS_DECLARE_FIELD(ArenaAllocator *, LivenessAllocator); |
| 174 }; |
| 175 |
| 176 template <typename T> |
| 177 using LivenessAllocator = sz_allocator<T, LivenessAllocatorTraits>; |
| 178 |
| 179 using LivenessAllocatorScope = sz_allocator_scope<LivenessAllocatorTraits>; |
| 180 |
140 } // end of namespace Ice | 181 } // end of namespace Ice |
141 | 182 |
142 #endif // SUBZERO_SRC_ICEMEMORY_H | 183 #endif // SUBZERO_SRC_ICEMEMORY_H |
OLD | NEW |