OLD | NEW |
---|---|
1 //===- subzero/src/IceDefs.h - Common Subzero declarations ------*- C++ -*-===// | 1 //===- subzero/src/IceDefs.h - Common Subzero 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 |
(...skipping 55 matching lines...) Loading... | |
66 class InstTarget; | 66 class InstTarget; |
67 class LiveRange; | 67 class LiveRange; |
68 class Liveness; | 68 class Liveness; |
69 class Operand; | 69 class Operand; |
70 class TargetDataLowering; | 70 class TargetDataLowering; |
71 class TargetLowering; | 71 class TargetLowering; |
72 class Variable; | 72 class Variable; |
73 class VariableDeclaration; | 73 class VariableDeclaration; |
74 class VariablesMetadata; | 74 class VariablesMetadata; |
75 | 75 |
76 /// SizeT is for holding small-ish limits like number of source operands in an | |
77 /// instruction. It is used instead of size_t (which may be 64-bits wide) when | |
78 /// we want to save space. | |
79 using SizeT = uint32_t; | |
80 | |
76 constexpr char GlobalOffsetTable[] = "_GLOBAL_OFFSET_TABLE_"; | 81 constexpr char GlobalOffsetTable[] = "_GLOBAL_OFFSET_TABLE_"; |
77 // makeUnique should be used when memory is expected to be allocated from the | 82 // makeUnique should be used when memory is expected to be allocated from the |
78 // heap (as opposed to allocated from some Allocator.) It is intended to be | 83 // heap (as opposed to allocated from some Allocator.) It is intended to be |
79 // used instead of new. | 84 // used instead of new. |
80 // | 85 // |
81 // The expected usage is as follows | 86 // The expected usage is as follows |
82 // | 87 // |
83 // class MyClass { | 88 // class MyClass { |
84 // public: | 89 // public: |
85 // static std::unique_ptr<MyClass> create(<ctor_args>) { | 90 // static std::unique_ptr<MyClass> create(<ctor_args>) { |
(...skipping 46 matching lines...) Loading... | |
132 template <typename T> using CfgVector = std::vector<T, CfgLocalAllocator<T>>; | 137 template <typename T> using CfgVector = std::vector<T, CfgLocalAllocator<T>>; |
133 | 138 |
134 // Containers that are arena-allocated from the Cfg's allocator. | 139 // Containers that are arena-allocated from the Cfg's allocator. |
135 using OperandList = CfgVector<Operand *>; | 140 using OperandList = CfgVector<Operand *>; |
136 using VarList = CfgVector<Variable *>; | 141 using VarList = CfgVector<Variable *>; |
137 using NodeList = CfgVector<CfgNode *>; | 142 using NodeList = CfgVector<CfgNode *>; |
138 | 143 |
139 // Containers that use the default (global) allocator. | 144 // Containers that use the default (global) allocator. |
140 using ConstantList = std::vector<Constant *>; | 145 using ConstantList = std::vector<Constant *>; |
141 using FunctionDeclarationList = std::vector<FunctionDeclaration *>; | 146 using FunctionDeclarationList = std::vector<FunctionDeclaration *>; |
142 using VariableDeclarationList = std::vector<VariableDeclaration *>; | |
143 | 147 |
144 /// SizeT is for holding small-ish limits like number of source operands in an | 148 /// VariableDeclarationList is a container for holding VariableDeclarations -- |
Jim Stichnoth
2016/03/14 22:21:31
Can this go somewhere besides IceDefs.h?
John
2016/03/15 15:07:18
It **should**, but because IceDefs moving it to a
Jim Stichnoth
2016/03/15 15:48:29
Ick ick ick, but whatevs. :)
| |
145 /// instruction. It is used instead of size_t (which may be 64-bits wide) when | 149 /// i.e., Global Variables. It is also used to create said variables, and their |
146 /// we want to save space. | 150 /// initializers in an arena. |
147 using SizeT = uint32_t; | 151 class VariableDeclarationList { |
152 VariableDeclarationList(const VariableDeclarationList &) = delete; | |
153 VariableDeclarationList &operator=(const VariableDeclarationList &) = delete; | |
154 VariableDeclarationList(VariableDeclarationList &&) = delete; | |
155 VariableDeclarationList &operator=(VariableDeclarationList &&) = delete; | |
156 | |
157 public: | |
158 using VariableDeclarationArray = std::vector<VariableDeclaration *>; | |
159 | |
160 VariableDeclarationList() : Arena(new ArenaAllocator()) {} | |
161 | |
162 ~VariableDeclarationList() { clearAndPurge(); } | |
163 | |
164 template <typename T> T *allocate_initializer(SizeT Count = 1) { | |
165 static_assert( | |
166 std::is_trivially_destructible<T>::value, | |
167 "allocate_initializer can only allocate trivially destructible types."); | |
168 return Arena->Allocate<T>(Count); | |
169 } | |
170 | |
171 template <typename T> T *allocate_variable_declaration() { | |
172 static_assert(!std::is_trivially_destructible<T>::value, | |
173 "allocate_variable_declaration expects non-trivially " | |
174 "destructible types."); | |
175 T *Ret = Arena->Allocate<T>(); | |
176 Dtors.emplace_back([Ret]() { Ret->~T(); }); | |
177 return Ret; | |
178 } | |
179 | |
180 // This do nothing method is invoked when a global variable is created, but it | |
181 // will not be emitted. If we ever need to track the created variabled, having | |
182 // this hook is handy. | |
183 void willNotBeEmitted(VariableDeclaration *) {} | |
184 | |
185 /// Merges Other with this, effectively resetting Other to an empty state. | |
186 void merge(VariableDeclarationList *Other) { | |
187 assert(Other != nullptr); | |
188 addArena(std::move(Other->Arena)); | |
189 for (std::size_t i = 0; i < Other->MergedArenas.size(); ++i) { | |
190 addArena(std::move(Other->MergedArenas[i])); | |
191 } | |
192 Other->MergedArenas.clear(); | |
193 | |
194 Dtors.insert(Dtors.end(), Other->Dtors.begin(), Other->Dtors.end()); | |
195 Other->Dtors.clear(); | |
196 | |
197 Globals.insert(Globals.end(), Other->Globals.begin(), Other->Globals.end()); | |
198 Other->Globals.clear(); | |
199 } | |
200 | |
201 /// Destroys all GlobalVariables and initializers that this knows about | |
202 /// (including those merged with it), and releases memory. | |
203 void clearAndPurge() { | |
204 if (Arena == nullptr) { | |
205 // Arena is only null if this was merged, so we ensure there's no state | |
206 // being held by this. | |
207 assert(Dtors.empty()); | |
208 assert(Globals.empty()); | |
209 assert(MergedArenas.empty()); | |
210 return; | |
211 } | |
212 // Invokes destructors in reverse creation order. | |
213 for (auto Dtor = Dtors.rbegin(); Dtor != Dtors.rend(); ++Dtor) { | |
214 (*Dtor)(); | |
215 } | |
216 Dtors.clear(); | |
217 Globals.clear(); | |
218 MergedArenas.clear(); | |
219 Arena->Reset(); | |
220 } | |
221 | |
222 /// Vector<VariableDeclaration *> interface. | |
Jim Stichnoth
2016/03/14 22:21:31
I assume this comment means either "VariableDeclar
John
2016/03/15 15:07:18
Done.
| |
223 /// @{ | |
224 VariableDeclarationArray::iterator begin() { return Globals.begin(); } | |
225 | |
226 VariableDeclarationArray::iterator end() { return Globals.end(); } | |
227 | |
228 VariableDeclarationArray::const_iterator begin() const { | |
229 return Globals.begin(); | |
230 } | |
231 | |
232 VariableDeclarationArray::const_iterator end() const { return Globals.end(); } | |
233 | |
234 bool empty() const { return Globals.empty(); } | |
235 | |
236 VariableDeclarationArray::size_type size() const { return Globals.size(); } | |
237 | |
238 VariableDeclarationArray::reference | |
239 at(VariableDeclarationArray::size_type Pos) { | |
240 return Globals.at(Pos); | |
241 } | |
242 | |
243 void push_back(VariableDeclaration *Global) { Globals.push_back(Global); } | |
244 | |
245 void reserve(VariableDeclarationArray::size_type Capacity) { | |
246 Globals.reserve(Capacity); | |
247 } | |
248 | |
249 void clear() { Globals.clear(); } | |
250 | |
251 VariableDeclarationArray::reference back() { return Globals.back(); } | |
252 /// @} | |
253 | |
254 private: | |
255 using ArenaPtr = std::unique_ptr<ArenaAllocator>; | |
256 using DestructorsArray = std::vector<std::function<void()>>; | |
257 | |
258 void addArena(ArenaPtr NewArena) { | |
259 MergedArenas.emplace_back(std::move(NewArena)); | |
260 } | |
261 | |
262 ArenaPtr Arena; | |
263 VariableDeclarationArray Globals; | |
264 DestructorsArray Dtors; | |
265 std::vector<ArenaPtr> MergedArenas; | |
266 }; | |
148 | 267 |
149 /// InstNumberT is for holding an instruction number. Instruction numbers are | 268 /// InstNumberT is for holding an instruction number. Instruction numbers are |
150 /// used for representing Variable live ranges. | 269 /// used for representing Variable live ranges. |
151 using InstNumberT = int32_t; | 270 using InstNumberT = int32_t; |
152 | 271 |
153 /// A LiveBeginEndMapEntry maps a Variable::Number value to an Inst::Number | 272 /// A LiveBeginEndMapEntry maps a Variable::Number value to an Inst::Number |
154 /// value, giving the instruction number that begins or ends a variable's live | 273 /// value, giving the instruction number that begins or ends a variable's live |
155 /// range. | 274 /// range. |
156 using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>; | 275 using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>; |
157 using LiveBeginEndMap = CfgVector<LiveBeginEndMapEntry>; | 276 using LiveBeginEndMap = CfgVector<LiveBeginEndMapEntry>; |
(...skipping 127 matching lines...) Loading... | |
285 RPE_PooledConstantReordering, | 404 RPE_PooledConstantReordering, |
286 RPE_RegAllocRandomization, | 405 RPE_RegAllocRandomization, |
287 RPE_num | 406 RPE_num |
288 }; | 407 }; |
289 | 408 |
290 using RelocOffsetArray = llvm::SmallVector<class RelocOffset *, 4>; | 409 using RelocOffsetArray = llvm::SmallVector<class RelocOffset *, 4>; |
291 | 410 |
292 } // end of namespace Ice | 411 } // end of namespace Ice |
293 | 412 |
294 #endif // SUBZERO_SRC_ICEDEFS_H | 413 #endif // SUBZERO_SRC_ICEDEFS_H |
OLD | NEW |