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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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 -- |
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 /// Adapt the relevant parts of the std::vector<VariableDeclaration *> |
| 223 /// interface. |
| 224 /// @{ |
| 225 VariableDeclarationArray::iterator begin() { return Globals.begin(); } |
| 226 |
| 227 VariableDeclarationArray::iterator end() { return Globals.end(); } |
| 228 |
| 229 VariableDeclarationArray::const_iterator begin() const { |
| 230 return Globals.begin(); |
| 231 } |
| 232 |
| 233 VariableDeclarationArray::const_iterator end() const { return Globals.end(); } |
| 234 |
| 235 bool empty() const { return Globals.empty(); } |
| 236 |
| 237 VariableDeclarationArray::size_type size() const { return Globals.size(); } |
| 238 |
| 239 VariableDeclarationArray::reference |
| 240 at(VariableDeclarationArray::size_type Pos) { |
| 241 return Globals.at(Pos); |
| 242 } |
| 243 |
| 244 void push_back(VariableDeclaration *Global) { Globals.push_back(Global); } |
| 245 |
| 246 void reserve(VariableDeclarationArray::size_type Capacity) { |
| 247 Globals.reserve(Capacity); |
| 248 } |
| 249 |
| 250 void clear() { Globals.clear(); } |
| 251 |
| 252 VariableDeclarationArray::reference back() { return Globals.back(); } |
| 253 /// @} |
| 254 |
| 255 private: |
| 256 using ArenaPtr = std::unique_ptr<ArenaAllocator>; |
| 257 using DestructorsArray = std::vector<std::function<void()>>; |
| 258 |
| 259 void addArena(ArenaPtr NewArena) { |
| 260 MergedArenas.emplace_back(std::move(NewArena)); |
| 261 } |
| 262 |
| 263 ArenaPtr Arena; |
| 264 VariableDeclarationArray Globals; |
| 265 DestructorsArray Dtors; |
| 266 std::vector<ArenaPtr> MergedArenas; |
| 267 }; |
148 | 268 |
149 /// InstNumberT is for holding an instruction number. Instruction numbers are | 269 /// InstNumberT is for holding an instruction number. Instruction numbers are |
150 /// used for representing Variable live ranges. | 270 /// used for representing Variable live ranges. |
151 using InstNumberT = int32_t; | 271 using InstNumberT = int32_t; |
152 | 272 |
153 /// A LiveBeginEndMapEntry maps a Variable::Number value to an Inst::Number | 273 /// 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 | 274 /// value, giving the instruction number that begins or ends a variable's live |
155 /// range. | 275 /// range. |
156 using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>; | 276 using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>; |
157 using LiveBeginEndMap = CfgVector<LiveBeginEndMapEntry>; | 277 using LiveBeginEndMap = CfgVector<LiveBeginEndMapEntry>; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 RPE_PooledConstantReordering, | 405 RPE_PooledConstantReordering, |
286 RPE_RegAllocRandomization, | 406 RPE_RegAllocRandomization, |
287 RPE_num | 407 RPE_num |
288 }; | 408 }; |
289 | 409 |
290 using RelocOffsetArray = llvm::SmallVector<class RelocOffset *, 4>; | 410 using RelocOffsetArray = llvm::SmallVector<class RelocOffset *, 4>; |
291 | 411 |
292 } // end of namespace Ice | 412 } // end of namespace Ice |
293 | 413 |
294 #endif // SUBZERO_SRC_ICEDEFS_H | 414 #endif // SUBZERO_SRC_ICEDEFS_H |
OLD | NEW |