Chromium Code Reviews

Side by Side Diff: src/IceDefs.h

Issue 1776473007: Subzero. Allocate global initializers from a dedicated arena. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: fixes ther llvm2ice converter; fixes the VariableDeclarationList destructor. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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...)
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...)
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...)
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
OLDNEW
« src/IceCompiler.cpp ('K') | « src/IceConverter.cpp ('k') | src/IceELFObjectWriter.h » ('j') | no next file with comments »

Powered by Google App Engine