| 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 |
| 11 /// This file declares various useful types and classes that have widespread use | 11 /// This file declares various useful types and classes that have widespread use |
| 12 /// across Subzero. Every Subzero source file is expected to include IceDefs.h. | 12 /// across Subzero. Every Subzero source file is expected to include IceDefs.h. |
| 13 /// | 13 /// |
| 14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 15 | 15 |
| 16 #ifndef SUBZERO_SRC_ICEDEFS_H | 16 #ifndef SUBZERO_SRC_ICEDEFS_H |
| 17 #define SUBZERO_SRC_ICEDEFS_H | 17 #define SUBZERO_SRC_ICEDEFS_H |
| 18 | 18 |
| 19 #include "IceBuildDefs.h" // TODO(stichnot): move into individual files | 19 #include "IceBuildDefs.h" // TODO(stichnot): move into individual files |
| 20 #include "IceTLS.h" | 20 #include "IceTLS.h" |
| 21 | 21 |
| 22 #include "llvm/ADT/ArrayRef.h" | 22 #include "llvm/ADT/ArrayRef.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 const CfgLocalAllocator<U> &) { | 92 const CfgLocalAllocator<U> &) { |
| 93 return true; | 93 return true; |
| 94 } | 94 } |
| 95 template <typename T, typename U> | 95 template <typename T, typename U> |
| 96 inline bool operator!=(const CfgLocalAllocator<T> &, | 96 inline bool operator!=(const CfgLocalAllocator<T> &, |
| 97 const CfgLocalAllocator<U> &) { | 97 const CfgLocalAllocator<U> &) { |
| 98 return false; | 98 return false; |
| 99 } | 99 } |
| 100 | 100 |
| 101 // makeUnique should be used when memory is expected to be allocated from the | 101 // makeUnique should be used when memory is expected to be allocated from the |
| 102 // heap (as opposed to allocated from some Allocator.) It is intended to be used | 102 // heap (as opposed to allocated from some Allocator.) It is intended to be |
| 103 // instead of new. | 103 // used instead of new. |
| 104 // | 104 // |
| 105 // The expected usage is as follows | 105 // The expected usage is as follows |
| 106 // | 106 // |
| 107 // class MyClass { | 107 // class MyClass { |
| 108 // public: | 108 // public: |
| 109 // static std::unique_ptr<MyClass> create(<ctor_args>) { | 109 // static std::unique_ptr<MyClass> create(<ctor_args>) { |
| 110 // return makeUnique<MyClass>(<ctor_args>); | 110 // return makeUnique<MyClass>(<ctor_args>); |
| 111 // } | 111 // } |
| 112 // | 112 // |
| 113 // private: | 113 // private: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 133 template <class T, class... Args> | 133 template <class T, class... Args> |
| 134 static std::unique_ptr<T> makeUnique(Args &&... TheArgs) { | 134 static std::unique_ptr<T> makeUnique(Args &&... TheArgs) { |
| 135 return ::Ice::Internal::MakeUniqueEnabler::create<T>( | 135 return ::Ice::Internal::MakeUniqueEnabler::create<T>( |
| 136 std::forward<Args>(TheArgs)...); | 136 std::forward<Args>(TheArgs)...); |
| 137 } | 137 } |
| 138 | 138 |
| 139 #define ENABLE_MAKE_UNIQUE friend struct ::Ice::Internal::MakeUniqueEnabler | 139 #define ENABLE_MAKE_UNIQUE friend struct ::Ice::Internal::MakeUniqueEnabler |
| 140 | 140 |
| 141 using IceString = std::string; | 141 using IceString = std::string; |
| 142 using InstList = llvm::ilist<Inst>; | 142 using InstList = llvm::ilist<Inst>; |
| 143 // Ideally PhiList would be llvm::ilist<InstPhi>, and similar for | 143 // Ideally PhiList would be llvm::ilist<InstPhi>, and similar for AssignList, |
| 144 // AssignList, but this runs into issues with SFINAE. | 144 // but this runs into issues with SFINAE. |
| 145 using PhiList = InstList; | 145 using PhiList = InstList; |
| 146 using AssignList = InstList; | 146 using AssignList = InstList; |
| 147 | 147 |
| 148 // Containers that are arena-allocated from the Cfg's allocator. | 148 // Containers that are arena-allocated from the Cfg's allocator. |
| 149 using OperandList = std::vector<Operand *, CfgLocalAllocator<Operand *>>; | 149 using OperandList = std::vector<Operand *, CfgLocalAllocator<Operand *>>; |
| 150 using VarList = std::vector<Variable *, CfgLocalAllocator<Variable *>>; | 150 using VarList = std::vector<Variable *, CfgLocalAllocator<Variable *>>; |
| 151 using NodeList = std::vector<CfgNode *, CfgLocalAllocator<CfgNode *>>; | 151 using NodeList = std::vector<CfgNode *, CfgLocalAllocator<CfgNode *>>; |
| 152 | 152 |
| 153 // Contains that use the default (global) allocator. | 153 // Contains that use the default (global) allocator. |
| 154 using ConstantList = std::vector<Constant *>; | 154 using ConstantList = std::vector<Constant *>; |
| 155 using FunctionDeclarationList = std::vector<FunctionDeclaration *>; | 155 using FunctionDeclarationList = std::vector<FunctionDeclaration *>; |
| 156 using VariableDeclarationList = std::vector<VariableDeclaration *>; | 156 using VariableDeclarationList = std::vector<VariableDeclaration *>; |
| 157 | 157 |
| 158 /// SizeT is for holding small-ish limits like number of source | 158 /// SizeT is for holding small-ish limits like number of source operands in an |
| 159 /// operands in an instruction. It is used instead of size_t (which | 159 /// instruction. It is used instead of size_t (which may be 64-bits wide) when |
| 160 /// may be 64-bits wide) when we want to save space. | 160 /// we want to save space. |
| 161 using SizeT = uint32_t; | 161 using SizeT = uint32_t; |
| 162 | 162 |
| 163 /// InstNumberT is for holding an instruction number. Instruction | 163 /// InstNumberT is for holding an instruction number. Instruction numbers are |
| 164 /// numbers are used for representing Variable live ranges. | 164 /// used for representing Variable live ranges. |
| 165 using InstNumberT = int32_t; | 165 using InstNumberT = int32_t; |
| 166 | 166 |
| 167 /// A LiveBeginEndMapEntry maps a Variable::Number value to an | 167 /// A LiveBeginEndMapEntry maps a Variable::Number value to an Inst::Number |
| 168 /// Inst::Number value, giving the instruction number that begins or | 168 /// value, giving the instruction number that begins or ends a variable's live |
| 169 /// ends a variable's live range. | 169 /// range. |
| 170 using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>; | 170 using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>; |
| 171 using LiveBeginEndMap = | 171 using LiveBeginEndMap = |
| 172 std::vector<LiveBeginEndMapEntry, CfgLocalAllocator<LiveBeginEndMapEntry>>; | 172 std::vector<LiveBeginEndMapEntry, CfgLocalAllocator<LiveBeginEndMapEntry>>; |
| 173 using LivenessBV = llvm::BitVector; | 173 using LivenessBV = llvm::BitVector; |
| 174 | 174 |
| 175 using TimerStackIdT = uint32_t; | 175 using TimerStackIdT = uint32_t; |
| 176 using TimerIdT = uint32_t; | 176 using TimerIdT = uint32_t; |
| 177 | 177 |
| 178 /// Use alignas(MaxCacheLineSize) to isolate variables/fields that | 178 /// Use alignas(MaxCacheLineSize) to isolate variables/fields that might be |
| 179 /// might be contended while multithreading. Assumes the maximum cache | 179 /// contended while multithreading. Assumes the maximum cache line size is 64. |
| 180 /// line size is 64. | |
| 181 enum { MaxCacheLineSize = 64 }; | 180 enum { MaxCacheLineSize = 64 }; |
| 182 // Use ICE_CACHELINE_BOUNDARY to force the next field in a declaration | 181 // Use ICE_CACHELINE_BOUNDARY to force the next field in a declaration |
| 183 // list to be aligned to the next cache line. | 182 // list to be aligned to the next cache line. |
| 184 // Note: zero is added to work around the following GCC 4.8 bug (fixed in 4.9): | 183 // Note: zero is added to work around the following GCC 4.8 bug (fixed in 4.9): |
| 185 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382 | 184 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382 |
| 186 #define ICE_CACHELINE_BOUNDARY \ | 185 #define ICE_CACHELINE_BOUNDARY \ |
| 187 __attribute__((aligned(MaxCacheLineSize + 0))) int : 0 | 186 __attribute__((aligned(MaxCacheLineSize + 0))) int : 0 |
| 188 | 187 |
| 189 /// PNaCl is ILP32, so theoretically we should only need 32-bit offsets. | 188 /// PNaCl is ILP32, so theoretically we should only need 32-bit offsets. |
| 190 using RelocOffsetT = int32_t; | 189 using RelocOffsetT = int32_t; |
| 191 enum { RelocAddrSize = 4 }; | 190 enum { RelocAddrSize = 4 }; |
| 192 | 191 |
| 193 enum LivenessMode { | 192 enum LivenessMode { |
| 194 /// Basic version of live-range-end calculation. Marks the last uses | 193 /// Basic version of live-range-end calculation. Marks the last uses of |
| 195 /// of variables based on dataflow analysis. Records the set of | 194 /// variables based on dataflow analysis. Records the set of live-in and |
| 196 /// live-in and live-out variables for each block. Identifies and | 195 /// live-out variables for each block. Identifies and deletes dead |
| 197 /// deletes dead instructions (primarily stores). | 196 /// instructions (primarily stores). |
| 198 Liveness_Basic, | 197 Liveness_Basic, |
| 199 | 198 |
| 200 /// In addition to Liveness_Basic, also calculate the complete | 199 /// In addition to Liveness_Basic, also calculate the complete live range for |
| 201 /// live range for each variable in a form suitable for interference | 200 /// each variable in a form suitable for interference calculation and register |
| 202 /// calculation and register allocation. | 201 /// allocation. |
| 203 Liveness_Intervals | 202 Liveness_Intervals |
| 204 }; | 203 }; |
| 205 | 204 |
| 206 enum RegAllocKind { | 205 enum RegAllocKind { |
| 207 RAK_Unknown, | 206 RAK_Unknown, |
| 208 RAK_Global, /// full, global register allocation | 207 RAK_Global, /// full, global register allocation |
| 209 RAK_Phi, /// infinite-weight Variables with active spilling/filling | 208 RAK_Phi, /// infinite-weight Variables with active spilling/filling |
| 210 RAK_InfOnly /// allocation only for infinite-weight Variables | 209 RAK_InfOnly /// allocation only for infinite-weight Variables |
| 211 }; | 210 }; |
| 212 | 211 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 237 FT_Iasm /// "Integrated assembler" .byte-style .s file | 236 FT_Iasm /// "Integrated assembler" .byte-style .s file |
| 238 }; | 237 }; |
| 239 | 238 |
| 240 using Ostream = llvm::raw_ostream; | 239 using Ostream = llvm::raw_ostream; |
| 241 using Fdstream = llvm::raw_fd_ostream; | 240 using Fdstream = llvm::raw_fd_ostream; |
| 242 | 241 |
| 243 using GlobalLockType = std::mutex; | 242 using GlobalLockType = std::mutex; |
| 244 | 243 |
| 245 enum ErrorCodes { EC_None = 0, EC_Args, EC_Bitcode, EC_Translation }; | 244 enum ErrorCodes { EC_None = 0, EC_Args, EC_Bitcode, EC_Translation }; |
| 246 | 245 |
| 247 /// Wrapper around std::error_code for allowing multiple errors to be | 246 /// Wrapper around std::error_code for allowing multiple errors to be folded |
| 248 /// folded into one. The current implementation keeps track of the | 247 /// into one. The current implementation keeps track of the first error, which |
| 249 /// first error, which is likely to be the most useful one, and this | 248 /// is likely to be the most useful one, and this could be extended to e.g. |
| 250 /// could be extended to e.g. collect a vector of errors. | 249 /// collect a vector of errors. |
| 251 class ErrorCode : public std::error_code { | 250 class ErrorCode : public std::error_code { |
| 252 ErrorCode(const ErrorCode &) = delete; | 251 ErrorCode(const ErrorCode &) = delete; |
| 253 ErrorCode &operator=(const ErrorCode &) = delete; | 252 ErrorCode &operator=(const ErrorCode &) = delete; |
| 254 | 253 |
| 255 public: | 254 public: |
| 256 ErrorCode() = default; | 255 ErrorCode() = default; |
| 257 void assign(ErrorCodes Code) { | 256 void assign(ErrorCodes Code) { |
| 258 if (!HasError) { | 257 if (!HasError) { |
| 259 HasError = true; | 258 HasError = true; |
| 260 std::error_code::assign(Code, std::generic_category()); | 259 std::error_code::assign(Code, std::generic_category()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 288 RPE_GlobalVariableReordering, | 287 RPE_GlobalVariableReordering, |
| 289 RPE_NopInsertion, | 288 RPE_NopInsertion, |
| 290 RPE_PooledConstantReordering, | 289 RPE_PooledConstantReordering, |
| 291 RPE_RegAllocRandomization, | 290 RPE_RegAllocRandomization, |
| 292 RPE_num | 291 RPE_num |
| 293 }; | 292 }; |
| 294 | 293 |
| 295 } // end of namespace Ice | 294 } // end of namespace Ice |
| 296 | 295 |
| 297 #endif // SUBZERO_SRC_ICEDEFS_H | 296 #endif // SUBZERO_SRC_ICEDEFS_H |
| OLD | NEW |