blob: d9c0c234784e0d569ae6c83ed109bb981d37749f [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
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Declares various useful types and classes that have widespread use
12/// across Subzero.
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
John Portoe82b5602016-02-24 15:58:55 -080020#include "IceMemory.h"
John Porto67f8de92015-06-25 10:14:17 -070021#include "IceTLS.h"
22
Jan Voungb17f61d2014-08-28 16:00:53 -070023#include "llvm/ADT/ArrayRef.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 Stichnoth586d4c22014-12-05 16:43:08 -080027#include "llvm/ADT/SmallVector.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070028#include "llvm/ADT/STLExtras.h"
29#include "llvm/Support/Casting.h"
Jan Voung08c3bcd2014-12-01 17:55:16 -080030#include "llvm/Support/ELF.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070031#include "llvm/Support/raw_ostream.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070032
John Porto67f8de92015-06-25 10:14:17 -070033#include <cassert>
34#include <cstdint>
35#include <cstdio> // snprintf
36#include <functional> // std::less
37#include <limits>
38#include <list>
39#include <map>
40#include <memory>
41#include <mutex>
42#include <string>
43#include <system_error>
Karl Schimpfac7d7342015-08-06 12:55:23 -070044#include <unordered_map>
John Portoe82b5602016-02-24 15:58:55 -080045#include <unordered_set>
46#include <utility>
John Porto67f8de92015-06-25 10:14:17 -070047#include <vector>
Jim Stichnoth7d538252015-01-23 10:22:56 -080048
Jim Stichnothf7c9a142014-04-29 10:52:43 -070049namespace Ice {
50
Jan Voungec270732015-01-12 17:00:22 -080051class Assembler;
John Porto36d6aa62016-02-26 07:19:59 -080052class BitVector;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070053class Cfg;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070054class CfgNode;
55class Constant;
Jan Voungec270732015-01-12 17:00:22 -080056class ELFObjectWriter;
57class ELFStreamer;
Karl Schimpf9d98d792014-10-13 15:01:08 -070058class FunctionDeclaration;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070059class GlobalContext;
Karl Schimpf9d98d792014-10-13 15:01:08 -070060class GlobalDeclaration;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070061class Inst;
Jim Stichnoth336f6c42014-10-30 15:01:31 -070062class InstAssign;
Andrew Scull86df4e92015-07-30 13:54:44 -070063class InstJumpTable;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070064class InstPhi;
Andrew Scull86df4e92015-07-30 13:54:44 -070065class InstSwitch;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070066class InstTarget;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070067class LiveRange;
68class Liveness;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070069class Operand;
Jan Voung72984d82015-01-29 14:42:38 -080070class TargetDataLowering;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070071class TargetLowering;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070072class Variable;
Karl Schimpf9d98d792014-10-13 15:01:08 -070073class VariableDeclaration;
Jim Stichnoth144cdce2014-09-22 16:02:59 -070074class VariablesMetadata;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070075
John Porto6e8d3fa2016-02-04 10:35:20 -080076constexpr char GlobalOffsetTable[] = "_GLOBAL_OFFSET_TABLE_";
John Porto1bec8bc2015-06-22 10:51:13 -070077// makeUnique should be used when memory is expected to be allocated from the
Andrew Scull57e12682015-09-16 11:30:19 -070078// heap (as opposed to allocated from some Allocator.) It is intended to be
79// used instead of new.
John Porto1bec8bc2015-06-22 10:51:13 -070080//
81// The expected usage is as follows
82//
83// class MyClass {
84// public:
85// static std::unique_ptr<MyClass> create(<ctor_args>) {
86// return makeUnique<MyClass>(<ctor_args>);
87// }
88//
89// private:
90// ENABLE_MAKE_UNIQUE;
91//
92// MyClass(<ctor_args>) ...
93// }
94//
95// ENABLE_MAKE_UNIQUE is a trick that is necessary if MyClass' ctor is private.
96// Private ctors are highly encouraged when you're writing a class that you'd
97// like to have allocated with makeUnique as it would prevent users from
98// declaring stack allocated variables.
99namespace Internal {
100struct MakeUniqueEnabler {
101 template <class T, class... Args>
102 static std::unique_ptr<T> create(Args &&... TheArgs) {
103 std::unique_ptr<T> Unique(new T(std::forward<Args>(TheArgs)...));
104 return Unique;
105 }
106};
107} // end of namespace Internal
108
109template <class T, class... Args>
110static std::unique_ptr<T> makeUnique(Args &&... TheArgs) {
111 return ::Ice::Internal::MakeUniqueEnabler::create<T>(
112 std::forward<Args>(TheArgs)...);
113}
114
115#define ENABLE_MAKE_UNIQUE friend struct ::Ice::Internal::MakeUniqueEnabler
116
Andrew Scull8072bae2015-09-14 16:01:26 -0700117using IceString = std::string;
118using InstList = llvm::ilist<Inst>;
Andrew Scull57e12682015-09-16 11:30:19 -0700119// Ideally PhiList would be llvm::ilist<InstPhi>, and similar for AssignList,
120// but this runs into issues with SFINAE.
Andrew Scull8072bae2015-09-14 16:01:26 -0700121using PhiList = InstList;
122using AssignList = InstList;
Karl Schimpf209318a2015-08-20 13:24:02 -0700123
Andrew Scull00741a02015-09-16 19:04:09 -0700124// Standard library containers with CfgLocalAllocator.
Andrew Scull00741a02015-09-16 19:04:09 -0700125template <typename T> using CfgList = std::list<T, CfgLocalAllocator<T>>;
John Portoe82b5602016-02-24 15:58:55 -0800126template <typename T, typename H = std::hash<T>, typename Eq = std::equal_to<T>>
127using CfgUnorderedSet = std::unordered_set<T, H, Eq, CfgLocalAllocator<T>>;
128template <typename T, typename U, typename H = std::hash<T>,
129 typename Eq = std::equal_to<T>>
130using CfgUnorderedMap =
131 std::unordered_map<T, U, H, Eq, CfgLocalAllocator<std::pair<const T, U>>>;
132template <typename T> using CfgVector = std::vector<T, CfgLocalAllocator<T>>;
Andrew Scull00741a02015-09-16 19:04:09 -0700133
Karl Schimpf209318a2015-08-20 13:24:02 -0700134// Containers that are arena-allocated from the Cfg's allocator.
Andrew Scull00741a02015-09-16 19:04:09 -0700135using OperandList = CfgVector<Operand *>;
136using VarList = CfgVector<Variable *>;
137using NodeList = CfgVector<CfgNode *>;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700138
John Portoe82b5602016-02-24 15:58:55 -0800139// Containers that use the default (global) allocator.
Andrew Scull8072bae2015-09-14 16:01:26 -0700140using ConstantList = std::vector<Constant *>;
141using FunctionDeclarationList = std::vector<FunctionDeclaration *>;
142using VariableDeclarationList = std::vector<VariableDeclaration *>;
Jan Voung72984d82015-01-29 14:42:38 -0800143
Andrew Scull57e12682015-09-16 11:30:19 -0700144/// SizeT is for holding small-ish limits like number of source operands in an
145/// instruction. It is used instead of size_t (which may be 64-bits wide) when
146/// we want to save space.
Andrew Scull8072bae2015-09-14 16:01:26 -0700147using SizeT = uint32_t;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700148
Andrew Scull57e12682015-09-16 11:30:19 -0700149/// InstNumberT is for holding an instruction number. Instruction numbers are
150/// used for representing Variable live ranges.
Andrew Scull8072bae2015-09-14 16:01:26 -0700151using InstNumberT = int32_t;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700152
Andrew Scull57e12682015-09-16 11:30:19 -0700153/// 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
155/// range.
Andrew Scull8072bae2015-09-14 16:01:26 -0700156using LiveBeginEndMapEntry = std::pair<SizeT, InstNumberT>;
Andrew Scull00741a02015-09-16 19:04:09 -0700157using LiveBeginEndMap = CfgVector<LiveBeginEndMapEntry>;
John Porto36d6aa62016-02-26 07:19:59 -0800158using LivenessBV = BitVector;
Jim Stichnoth47752552014-10-13 17:15:08 -0700159
Andrew Scull8072bae2015-09-14 16:01:26 -0700160using TimerStackIdT = uint32_t;
161using TimerIdT = uint32_t;
Jim Stichnothc4554d72014-09-30 16:49:38 -0700162
Andrew Scull57e12682015-09-16 11:30:19 -0700163/// Use alignas(MaxCacheLineSize) to isolate variables/fields that might be
164/// contended while multithreading. Assumes the maximum cache line size is 64.
Jim Stichnothdd842db2015-01-27 12:53:53 -0800165enum { MaxCacheLineSize = 64 };
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800166// Use ICE_CACHELINE_BOUNDARY to force the next field in a declaration
167// list to be aligned to the next cache line.
JF Bastien867684e2015-01-28 15:07:38 -0800168// Note: zero is added to work around the following GCC 4.8 bug (fixed in 4.9):
169// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55382
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800170#define ICE_CACHELINE_BOUNDARY \
JF Bastien867684e2015-01-28 15:07:38 -0800171 __attribute__((aligned(MaxCacheLineSize + 0))) int : 0
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800172
Andrew Scull9612d322015-07-06 14:53:25 -0700173/// PNaCl is ILP32, so theoretically we should only need 32-bit offsets.
Andrew Scull8072bae2015-09-14 16:01:26 -0700174using RelocOffsetT = int32_t;
Jan Voungc0d965f2014-11-04 16:55:01 -0800175enum { RelocAddrSize = 4 };
Jan Voungfe14fb82014-10-13 15:56:32 -0700176
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700177enum LivenessMode {
Andrew Scull57e12682015-09-16 11:30:19 -0700178 /// Basic version of live-range-end calculation. Marks the last uses of
179 /// variables based on dataflow analysis. Records the set of live-in and
180 /// live-out variables for each block. Identifies and deletes dead
181 /// instructions (primarily stores).
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700182 Liveness_Basic,
183
Andrew Scull57e12682015-09-16 11:30:19 -0700184 /// In addition to Liveness_Basic, also calculate the complete live range for
185 /// each variable in a form suitable for interference calculation and register
186 /// allocation.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700187 Liveness_Intervals
188};
189
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800190enum RegAllocKind {
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700191 RAK_Unknown,
Jim Stichnoth4001c932015-10-09 14:33:26 -0700192 RAK_Global, /// full, global register allocation
193 RAK_SecondChance, /// second-chance bin-packing after full regalloc attempt
194 RAK_Phi, /// infinite-weight Variables with active spilling/filling
195 RAK_InfOnly /// allocation only for infinite-weight Variables
Jim Stichnoth70d0a052014-11-14 15:53:46 -0800196};
197
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700198enum VerboseItem {
199 IceV_None = 0,
200 IceV_Instructions = 1 << 0,
201 IceV_Deleted = 1 << 1,
202 IceV_InstNumbers = 1 << 2,
203 IceV_Preds = 1 << 3,
204 IceV_Succs = 1 << 4,
205 IceV_Liveness = 1 << 5,
Jim Stichnoth769be682015-01-15 09:05:08 -0800206 IceV_RegOrigins = 1 << 6,
207 IceV_LinearScan = 1 << 7,
208 IceV_Frame = 1 << 8,
209 IceV_AddrOpt = 1 << 9,
210 IceV_Random = 1 << 10,
Jim Stichnotha59ae6f2015-05-17 10:11:41 -0700211 IceV_Folding = 1 << 11,
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700212 IceV_RMW = 1 << 12,
Andrew Scullaa6c1092015-09-03 17:50:30 -0700213 IceV_Loop = 1 << 13,
Jim Stichnoth9f9aa2c2016-03-07 08:25:24 -0800214 IceV_Mem = 1 << 14,
215 // Leave some extra space to make it easier to add new per-pass items.
216 IceV_NO_PER_PASS_DUMP_BEYOND = 1 << 19,
217 // Items greater than IceV_NO_PER_PASS_DUMP_BEYOND don't by themselves trigger
218 // per-pass Cfg dump output.
219 IceV_Status = 1 << 20,
220 IceV_AvailableRegs = 1 << 21,
221 IceV_GlobalInit = 1 << 22,
222 IceV_ConstPoolStats = 1 << 23,
Jim Stichnothad403532014-09-25 12:44:17 -0700223 IceV_All = ~IceV_None,
Jim Stichnoth9f9aa2c2016-03-07 08:25:24 -0800224 IceV_Most =
225 IceV_All & ~IceV_LinearScan & ~IceV_GlobalInit & IceV_ConstPoolStats
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700226};
Andrew Scull8072bae2015-09-14 16:01:26 -0700227using VerboseMask = uint32_t;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700228
Jim Stichnothd442e7e2015-02-12 14:01:48 -0800229enum FileType {
Andrew Scull9612d322015-07-06 14:53:25 -0700230 FT_Elf, /// ELF .o file
231 FT_Asm, /// Assembly .s file
232 FT_Iasm /// "Integrated assembler" .byte-style .s file
Jim Stichnothd442e7e2015-02-12 14:01:48 -0800233};
234
Andrew Scull8072bae2015-09-14 16:01:26 -0700235using Ostream = llvm::raw_ostream;
236using Fdstream = llvm::raw_fd_ostream;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700237
Andrew Scull8072bae2015-09-14 16:01:26 -0700238using GlobalLockType = std::mutex;
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800239
Jim Stichnothdd842db2015-01-27 12:53:53 -0800240enum ErrorCodes { EC_None = 0, EC_Args, EC_Bitcode, EC_Translation };
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800241
Andrew Scull57e12682015-09-16 11:30:19 -0700242/// Wrapper around std::error_code for allowing multiple errors to be folded
243/// into one. The current implementation keeps track of the first error, which
244/// is likely to be the most useful one, and this could be extended to e.g.
245/// collect a vector of errors.
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800246class ErrorCode : public std::error_code {
247 ErrorCode(const ErrorCode &) = delete;
248 ErrorCode &operator=(const ErrorCode &) = delete;
249
250public:
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700251 ErrorCode() = default;
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800252 void assign(ErrorCodes Code) {
253 if (!HasError) {
254 HasError = true;
255 std::error_code::assign(Code, std::generic_category());
256 }
257 }
258 void assign(int Code) { assign(static_cast<ErrorCodes>(Code)); }
259
260private:
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700261 bool HasError = false;
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800262};
263
Andrew Scull9612d322015-07-06 14:53:25 -0700264/// Reverse range adaptors written in terms of llvm::make_range().
Jim Stichnoth7e571362015-01-09 11:43:26 -0800265template <typename T>
266llvm::iterator_range<typename T::const_reverse_iterator>
267reverse_range(const T &Container) {
268 return llvm::make_range(Container.rbegin(), Container.rend());
269}
270template <typename T>
271llvm::iterator_range<typename T::reverse_iterator> reverse_range(T &Container) {
272 return llvm::make_range(Container.rbegin(), Container.rend());
273}
274
Andrew Scull9612d322015-07-06 14:53:25 -0700275/// Options for pooling and randomization of immediates.
Qining Lu253dc8a2015-06-22 10:10:23 -0700276enum RandomizeAndPoolImmediatesEnum { RPI_None, RPI_Randomize, RPI_Pool };
277
Qining Luaee5fa82015-08-20 14:59:03 -0700278/// Salts for Random number generator for different randomization passes.
279enum RandomizationPassesEnum {
280 RPE_BasicBlockReordering,
281 RPE_ConstantBlinding,
282 RPE_FunctionReordering,
283 RPE_GlobalVariableReordering,
284 RPE_NopInsertion,
285 RPE_PooledConstantReordering,
286 RPE_RegAllocRandomization,
287 RPE_num
288};
289
John Porto27fddcc2016-02-02 15:06:09 -0800290using RelocOffsetArray = llvm::SmallVector<class RelocOffset *, 4>;
291
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700292} // end of namespace Ice
293
294#endif // SUBZERO_SRC_ICEDEFS_H