blob: 374b4b36efaefa7463235f6b66e5a8826374b450 [file] [log] [blame]
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001//===- subzero/src/IceDefs.h - Common Subzero declarations ------*- C++ -*-===//
Jim Stichnothf7c9a142014-04-29 10:52:43 -07002//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
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.
13///
Jim Stichnothf7c9a142014-04-29 10:52:43 -070014//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICEDEFS_H
17#define SUBZERO_SRC_ICEDEFS_H
18
John Porto67f8de92015-06-25 10:14:17 -070019#include "IceBuildDefs.h" // TODO(stichnot): move into individual files
20#include "IceTLS.h"
21
Jan Voungb17f61d2014-08-28 16:00:53 -070022#include "llvm/ADT/ArrayRef.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070023#include "llvm/ADT/BitVector.h"
Jim Stichnoth607e9f02014-11-06 13:32:05 -080024#include "llvm/ADT/ilist.h"
25#include "llvm/ADT/ilist_node.h"
Jim Stichnoth7e571362015-01-09 11:43:26 -080026#include "llvm/ADT/iterator_range.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070027#include "llvm/ADT/SmallBitVector.h"
Jim Stichnoth586d4c22014-12-05 16:43:08 -080028#include "llvm/ADT/SmallVector.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070029#include "llvm/ADT/STLExtras.h"
Jim Stichnoth31c95592014-12-19 12:51:35 -080030#include "llvm/Support/Allocator.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070031#include "llvm/Support/Casting.h"
Jan Voung08c3bcd2014-12-01 17:55:16 -080032#include "llvm/Support/ELF.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070033#include "llvm/Support/raw_ostream.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070034
John Porto67f8de92015-06-25 10:14:17 -070035#include <cassert>
36#include <cstdint>
37#include <cstdio> // snprintf
38#include <functional> // std::less
39#include <limits>
40#include <list>
41#include <map>
42#include <memory>
43#include <mutex>
44#include <string>
45#include <system_error>
46#include <vector>
Jim Stichnoth7d538252015-01-23 10:22:56 -080047
Jim Stichnothf7c9a142014-04-29 10:52:43 -070048namespace Ice {
49
Jan Voungec270732015-01-12 17:00:22 -080050class Assembler;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070051class Cfg;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070052class CfgNode;
53class Constant;
Jan Voungec270732015-01-12 17:00:22 -080054class ELFObjectWriter;
55class ELFStreamer;
Karl Schimpf9d98d792014-10-13 15:01:08 -070056class FunctionDeclaration;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070057class GlobalContext;
Karl Schimpf9d98d792014-10-13 15:01:08 -070058class GlobalDeclaration;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070059class Inst;
Jim Stichnoth336f6c42014-10-30 15:01:31 -070060class InstAssign;
Andrew Scull86df4e92015-07-30 13:54:44 -070061class InstJumpTable;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070062class InstPhi;
Andrew Scull86df4e92015-07-30 13:54:44 -070063class InstSwitch;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070064class InstTarget;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070065class LiveRange;
66class Liveness;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070067class Operand;
Jan Voung72984d82015-01-29 14:42:38 -080068class TargetDataLowering;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070069class TargetLowering;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070070class Variable;
Karl Schimpf9d98d792014-10-13 15:01:08 -070071class VariableDeclaration;
Jim Stichnoth144cdce2014-09-22 16:02:59 -070072class VariablesMetadata;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070073
Jan Voung1d62cf02015-01-09 14:57:32 -080074template <size_t SlabSize = 1024 * 1024>
75using ArenaAllocator =
76 llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, SlabSize>;
Jim Stichnoth31c95592014-12-19 12:51:35 -080077
Jan Voung1d62cf02015-01-09 14:57:32 -080078ArenaAllocator<> *getCurrentCfgAllocator();
Jim Stichnoth31c95592014-12-19 12:51:35 -080079
80template <typename T> struct CfgLocalAllocator {
81 using value_type = T;
82 CfgLocalAllocator() = default;
83 template <class U> CfgLocalAllocator(const CfgLocalAllocator<U> &) {}
84 T *allocate(std::size_t Num) {
85 return getCurrentCfgAllocator()->Allocate<T>(Num);
86 }
87 void deallocate(T *, std::size_t) {}
88};
89template <typename T, typename U>
90inline bool operator==(const CfgLocalAllocator<T> &,
91 const CfgLocalAllocator<U> &) {
92 return true;
93}
94template <typename T, typename U>
95inline bool operator!=(const CfgLocalAllocator<T> &,
96 const CfgLocalAllocator<U> &) {
97 return false;
98}
99
John Porto1bec8bc2015-06-22 10:51:13 -0700100// makeUnique should be used when memory is expected to be allocated from the
101// heap (as opposed to allocated from some Allocator.) It is intended to be used
102// instead of new.
103//
104// The expected usage is as follows
105//
106// class MyClass {
107// public:
108// static std::unique_ptr<MyClass> create(<ctor_args>) {
109// return makeUnique<MyClass>(<ctor_args>);
110// }
111//
112// private:
113// ENABLE_MAKE_UNIQUE;
114//
115// MyClass(<ctor_args>) ...
116// }
117//
118// ENABLE_MAKE_UNIQUE is a trick that is necessary if MyClass' ctor is private.
119// Private ctors are highly encouraged when you're writing a class that you'd
120// like to have allocated with makeUnique as it would prevent users from
121// declaring stack allocated variables.
122namespace Internal {
123struct MakeUniqueEnabler {
124 template <class T, class... Args>
125 static std::unique_ptr<T> create(Args &&... TheArgs) {
126 std::unique_ptr<T> Unique(new T(std::forward<Args>(TheArgs)...));
127 return Unique;
128 }
129};
130} // end of namespace Internal
131
132template <class T, class... Args>
133static std::unique_ptr<T> makeUnique(Args &&... TheArgs) {
134 return ::Ice::Internal::MakeUniqueEnabler::create<T>(
135 std::forward<Args>(TheArgs)...);
136}
137
138#define ENABLE_MAKE_UNIQUE friend struct ::Ice::Internal::MakeUniqueEnabler
139
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700140typedef std::string IceString;
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800141typedef llvm::ilist<Inst> InstList;
Jim Stichnoth1502e592014-12-11 09:22:45 -0800142// Ideally PhiList would be llvm::ilist<InstPhi>, and similar for
143// AssignList, but this runs into issues with SFINAE.
144typedef InstList PhiList;
145typedef InstList AssignList;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800146// VarList and NodeList are arena-allocated from the Cfg's allocator.
147typedef std::vector<Variable *, CfgLocalAllocator<Variable *>> VarList;
148typedef std::vector<CfgNode *, CfgLocalAllocator<CfgNode *>> NodeList;
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700149typedef std::vector<Constant *> ConstantList;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700150
Jan Voung72984d82015-01-29 14:42:38 -0800151typedef std::vector<VariableDeclaration *> VariableDeclarationList;
152
Andrew Scull9612d322015-07-06 14:53:25 -0700153/// SizeT is for holding small-ish limits like number of source
154/// operands in an instruction. It is used instead of size_t (which
155/// may be 64-bits wide) when we want to save space.
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700156typedef uint32_t SizeT;
157
Andrew Scull9612d322015-07-06 14:53:25 -0700158/// InstNumberT is for holding an instruction number. Instruction
159/// numbers are used for representing Variable live ranges.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700160typedef int32_t InstNumberT;
161
Andrew Scull9612d322015-07-06 14:53:25 -0700162/// A LiveBeginEndMapEntry maps a Variable::Number value to an
163/// Inst::Number value, giving the instruction number that begins or
164/// ends a variable's live range.
Jim Stichnoth47752552014-10-13 17:15:08 -0700165typedef std::pair<SizeT, InstNumberT> LiveBeginEndMapEntry;
Jim Stichnothc599e462015-01-08 16:56:49 -0800166typedef std::vector<LiveBeginEndMapEntry,
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800167 CfgLocalAllocator<LiveBeginEndMapEntry>> LiveBeginEndMap;
Jim Stichnoth47752552014-10-13 17:15:08 -0700168typedef llvm::BitVector LivenessBV;
169
Jim Stichnoth8363a062014-10-07 10:02:38 -0700170typedef uint32_t TimerStackIdT;
Jim Stichnothc4554d72014-09-30 16:49:38 -0700171typedef uint32_t TimerIdT;
172
Andrew Scull9612d322015-07-06 14:53:25 -0700173/// Use alignas(MaxCacheLineSize) to isolate variables/fields that
174/// might be contended while multithreading. Assumes the maximum cache
175/// line size is 64.
Jim Stichnothdd842db2015-01-27 12:53:53 -0800176enum { MaxCacheLineSize = 64 };
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800177// Use ICE_CACHELINE_BOUNDARY to force the next field in a declaration
178// list to be aligned to the next cache line.
JF Bastien867684e2015-01-28 15:07:38 -0800179// Note: zero is added to work around the following GCC 4.8 bug (fixed in 4.9):
180// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800181#define ICE_CACHELINE_BOUNDARY \
JF Bastien867684e2015-01-28 15:07:38 -0800182 __attribute__((aligned(MaxCacheLineSize + 0))) int : 0
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800183
Andrew Scull9612d322015-07-06 14:53:25 -0700184/// PNaCl is ILP32, so theoretically we should only need 32-bit offsets.
Jan Voungfe14fb82014-10-13 15:56:32 -0700185typedef int32_t RelocOffsetT;
Jan Voungc0d965f2014-11-04 16:55:01 -0800186enum { RelocAddrSize = 4 };
Jan Voungfe14fb82014-10-13 15:56:32 -0700187
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700188enum LivenessMode {
Andrew Scull9612d322015-07-06 14:53:25 -0700189 /// Basic version of live-range-end calculation. Marks the last uses
190 /// of variables based on dataflow analysis. Records the set of
191 /// live-in and live-out variables for each block. Identifies and
192 /// deletes dead instructions (primarily stores).
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700193 Liveness_Basic,
194
Andrew Scull9612d322015-07-06 14:53:25 -0700195 /// In addition to Liveness_Basic, also calculate the complete
196 /// live range for each variable in a form suitable for interference
197 /// calculation and register allocation.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700198 Liveness_Intervals
199};
200
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800201enum RegAllocKind {
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700202 RAK_Unknown,
Andrew Scull9612d322015-07-06 14:53:25 -0700203 RAK_Global, /// full, global register allocation
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700204 RAK_Phi, /// infinite-weight Variables with active spilling/filling
Andrew Scull9612d322015-07-06 14:53:25 -0700205 RAK_InfOnly /// allocation only for infinite-weight Variables
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800206};
207
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700208enum VerboseItem {
209 IceV_None = 0,
210 IceV_Instructions = 1 << 0,
211 IceV_Deleted = 1 << 1,
212 IceV_InstNumbers = 1 << 2,
213 IceV_Preds = 1 << 3,
214 IceV_Succs = 1 << 4,
215 IceV_Liveness = 1 << 5,
Jim Stichnoth769be682015-01-15 09:05:08 -0800216 IceV_RegOrigins = 1 << 6,
217 IceV_LinearScan = 1 << 7,
218 IceV_Frame = 1 << 8,
219 IceV_AddrOpt = 1 << 9,
220 IceV_Random = 1 << 10,
Jim Stichnotha59ae6f2015-05-17 10:11:41 -0700221 IceV_Folding = 1 << 11,
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700222 IceV_RMW = 1 << 12,
Jim Stichnothad403532014-09-25 12:44:17 -0700223 IceV_All = ~IceV_None,
Jim Stichnothc4554d72014-09-30 16:49:38 -0700224 IceV_Most = IceV_All & ~IceV_LinearScan
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700225};
226typedef uint32_t VerboseMask;
227
Jim Stichnothd442e7e2015-02-12 14:01:48 -0800228enum FileType {
Andrew Scull9612d322015-07-06 14:53:25 -0700229 FT_Elf, /// ELF .o file
230 FT_Asm, /// Assembly .s file
231 FT_Iasm /// "Integrated assembler" .byte-style .s file
Jim Stichnothd442e7e2015-02-12 14:01:48 -0800232};
233
Jim Stichnoth78282f62014-07-27 23:14:00 -0700234typedef llvm::raw_ostream Ostream;
Jan Voung08c3bcd2014-12-01 17:55:16 -0800235typedef llvm::raw_fd_ostream Fdstream;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700236
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800237typedef std::mutex GlobalLockType;
238
Jim Stichnothdd842db2015-01-27 12:53:53 -0800239enum ErrorCodes { EC_None = 0, EC_Args, EC_Bitcode, EC_Translation };
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800240
Andrew Scull9612d322015-07-06 14:53:25 -0700241/// Wrapper around std::error_code for allowing multiple errors to be
242/// folded into one. The current implementation keeps track of the
243/// first error, which is likely to be the most useful one, and this
244/// could be extended to e.g. collect a vector of errors.
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800245class ErrorCode : public std::error_code {
246 ErrorCode(const ErrorCode &) = delete;
247 ErrorCode &operator=(const ErrorCode &) = delete;
248
249public:
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700250 ErrorCode() = default;
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800251 void assign(ErrorCodes Code) {
252 if (!HasError) {
253 HasError = true;
254 std::error_code::assign(Code, std::generic_category());
255 }
256 }
257 void assign(int Code) { assign(static_cast<ErrorCodes>(Code)); }
258
259private:
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700260 bool HasError = false;
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800261};
262
Andrew Scull9612d322015-07-06 14:53:25 -0700263/// Reverse range adaptors written in terms of llvm::make_range().
Jim Stichnoth7e571362015-01-09 11:43:26 -0800264template <typename T>
265llvm::iterator_range<typename T::const_reverse_iterator>
266reverse_range(const T &Container) {
267 return llvm::make_range(Container.rbegin(), Container.rend());
268}
269template <typename T>
270llvm::iterator_range<typename T::reverse_iterator> reverse_range(T &Container) {
271 return llvm::make_range(Container.rbegin(), Container.rend());
272}
273
Andrew Scull9612d322015-07-06 14:53:25 -0700274/// Options for pooling and randomization of immediates.
Qining Lu253dc8a2015-06-22 10:10:23 -0700275enum RandomizeAndPoolImmediatesEnum { RPI_None, RPI_Randomize, RPI_Pool };
276
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700277} // end of namespace Ice
278
279#endif // SUBZERO_SRC_ICEDEFS_H