blob: e9f8752c1dc41472ded1a96a5deba5fb81001de8 [file] [log] [blame]
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001//===- subzero/src/IceRegAlloc.h - Linear-scan reg. allocation --*- C++ -*-===//
2//
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 the LinearScan data structure used during linear-scan
12/// register allocation.
13///
14/// This holds the various work queues for the linear-scan algorithm.
Andrew Scull9612d322015-07-06 14:53:25 -070015///
Jim Stichnothd97c7df2014-06-04 11:57:08 -070016//===----------------------------------------------------------------------===//
17
18#ifndef SUBZERO_SRC_ICEREGALLOC_H
19#define SUBZERO_SRC_ICEREGALLOC_H
20
21#include "IceDefs.h"
John Portoe82b5602016-02-24 15:58:55 -080022#include "IceBitVector.h"
Andrew Sculld24cfda2015-08-25 10:31:15 -070023#include "IceOperand.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070024#include "IceTypes.h"
25
26namespace Ice {
27
Jim Stichnothd97c7df2014-06-04 11:57:08 -070028class LinearScan {
Jim Stichnothc6ead202015-02-24 09:30:30 -080029 LinearScan() = delete;
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -070030 LinearScan(const LinearScan &) = delete;
31 LinearScan &operator=(const LinearScan &) = delete;
32
Jim Stichnothd97c7df2014-06-04 11:57:08 -070033public:
Andrew Sculld24cfda2015-08-25 10:31:15 -070034 explicit LinearScan(Cfg *Func);
Manasij Mukherjee7cd926d2016-08-04 12:33:23 -070035 void init(RegAllocKind Kind, CfgSet<Variable *> ExcludeVars = {});
John Portoe82b5602016-02-24 15:58:55 -080036 void scan(const SmallBitVector &RegMask, bool Randomized);
Jim Stichnoth4001c932015-10-09 14:33:26 -070037 // Returns the number of times some variable has been assigned a register but
38 // later evicted because of a higher-priority allocation. The idea is that we
39 // can implement "second-chance bin-packing" by rerunning register allocation
40 // until there are no more evictions.
41 SizeT getNumEvictions() const { return Evicted.size(); }
42 bool hasEvictions() const { return !Evicted.empty(); }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070043 void dump(Cfg *Func) const;
44
Andrew Sculld24cfda2015-08-25 10:31:15 -070045 // TODO(stichnot): Statically choose the size based on the target being
Jim Stichnoth843142f2016-03-09 15:19:40 -080046 // compiled. For now, choose a value large enough to fit into the
47 // SmallVector's fixed portion, which is 32 for x86-32, 84 for x86-64, and 102
48 // for ARM32.
49 static constexpr size_t REGS_SIZE = 128;
Andrew Sculld24cfda2015-08-25 10:31:15 -070050
Jim Stichnothd97c7df2014-06-04 11:57:08 -070051private:
Andrew Scull00741a02015-09-16 19:04:09 -070052 using OrderedRanges = CfgVector<Variable *>;
53 using UnorderedRanges = CfgVector<Variable *>;
Jim Stichnoth230d4102015-09-25 17:40:32 -070054 using DefUseErrorList = llvm::SmallVector<SizeT, 10>;
Jim Stichnoth4ead35a2014-12-03 20:30:34 -080055
Andrew Sculld24cfda2015-08-25 10:31:15 -070056 class IterationState {
57 IterationState(const IterationState &) = delete;
58 IterationState operator=(const IterationState &) = delete;
59
60 public:
61 IterationState() = default;
62 Variable *Cur = nullptr;
63 Variable *Prefer = nullptr;
Reed Kotler5fa0a5f2016-02-15 20:01:24 -080064 RegNumT PreferReg;
Andrew Sculld24cfda2015-08-25 10:31:15 -070065 bool AllowOverlap = false;
John Portoe82b5602016-02-24 15:58:55 -080066 SmallBitVector RegMask;
67 SmallBitVector RegMaskUnfiltered;
68 SmallBitVector Free;
69 SmallBitVector FreeUnfiltered;
70 SmallBitVector PrecoloredUnhandledMask; // Note: only used for dumping
Andrew Sculld24cfda2015-08-25 10:31:15 -070071 llvm::SmallVector<RegWeight, REGS_SIZE> Weights;
72 };
73
Jim Stichnoth230d4102015-09-25 17:40:32 -070074 bool livenessValidateIntervals(const DefUseErrorList &DefsWithoutUses,
75 const DefUseErrorList &UsesBeforeDefs,
76 const CfgVector<InstNumberT> &LRBegin,
Jim Stichnoth318f4cd2015-10-01 21:02:37 -070077 const CfgVector<InstNumberT> &LREnd) const;
Jim Stichnoth70d0a052014-11-14 15:53:46 -080078 void initForGlobal();
79 void initForInfOnly();
Jim Stichnoth4001c932015-10-09 14:33:26 -070080 void initForSecondChance();
Andrew Scull57e12682015-09-16 11:30:19 -070081 /// Move an item from the From set to the To set. From[Index] is pushed onto
Andrew Sculld24cfda2015-08-25 10:31:15 -070082 /// the end of To[], then the item is efficiently removed from From[] by
83 /// effectively swapping it with the last item in From[] and then popping it
Andrew Scull57e12682015-09-16 11:30:19 -070084 /// from the back. As such, the caller is best off iterating over From[] in
Andrew Sculld24cfda2015-08-25 10:31:15 -070085 /// reverse order to avoid the need for special handling of the iterator.
Jim Stichnoth4ead35a2014-12-03 20:30:34 -080086 void moveItem(UnorderedRanges &From, SizeT Index, UnorderedRanges &To) {
87 To.push_back(From[Index]);
88 From[Index] = From.back();
89 From.pop_back();
90 }
Jim Stichnoth70d0a052014-11-14 15:53:46 -080091
Andrew Sculld24cfda2015-08-25 10:31:15 -070092 /// \name scan helper functions.
93 /// @{
94 /// Free up a register for infinite-weight Cur by spilling and reloading some
95 /// register that isn't used during Cur's live range.
96 void addSpillFill(IterationState &Iter);
97 /// Check for active ranges that have expired or become inactive.
98 void handleActiveRangeExpiredOrInactive(const Variable *Cur);
99 /// Check for inactive ranges that have expired or reactivated.
100 void handleInactiveRangeExpiredOrReactivated(const Variable *Cur);
101 void findRegisterPreference(IterationState &Iter);
102 void filterFreeWithInactiveRanges(IterationState &Iter);
103 void filterFreeWithPrecoloredRanges(IterationState &Iter);
104 void allocatePrecoloredRegister(Variable *Cur);
105 void allocatePreferredRegister(IterationState &Iter);
Jim Stichnothb40595a2016-01-29 06:14:31 -0800106 void allocateFreeRegister(IterationState &Iter, bool Filtered);
Andrew Sculld24cfda2015-08-25 10:31:15 -0700107 void handleNoFreeRegisters(IterationState &Iter);
John Portoe82b5602016-02-24 15:58:55 -0800108 void assignFinalRegisters(const SmallBitVector &RegMaskFull,
109 const SmallBitVector &PreDefinedRegisters,
Andrew Sculld24cfda2015-08-25 10:31:15 -0700110 bool Randomized);
111 /// @}
112
113 void dumpLiveRangeTrace(const char *Label, const Variable *Item);
114
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700115 Cfg *const Func;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700116 GlobalContext *const Ctx;
John Portobb0a5fe2015-09-04 11:23:41 -0700117 TargetLowering *const Target;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700118
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700119 OrderedRanges Unhandled;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700120 /// UnhandledPrecolored is a subset of Unhandled, specially collected for
121 /// faster processing.
Jim Stichnoth541ba662014-10-02 12:58:21 -0700122 OrderedRanges UnhandledPrecolored;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700123 UnorderedRanges Active, Inactive, Handled;
Jim Stichnoth4001c932015-10-09 14:33:26 -0700124 UnorderedRanges Evicted;
Andrew Scull00741a02015-09-16 19:04:09 -0700125 CfgVector<InstNumberT> Kills;
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700126 RegAllocKind Kind = RAK_Unknown;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700127 /// RegUses[I] is the number of live ranges (variables) that register I is
128 /// currently assigned to. It can be greater than 1 as a result of
129 /// AllowOverlap inference.
130 llvm::SmallVector<int32_t, REGS_SIZE> RegUses;
John Portoe82b5602016-02-24 15:58:55 -0800131 llvm::SmallVector<const SmallBitVector *, REGS_SIZE> RegAliases;
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700132 bool FindPreference = false;
133 bool FindOverlap = false;
Andrew Sculld24cfda2015-08-25 10:31:15 -0700134 const bool Verbose;
Jim Stichnothb40595a2016-01-29 06:14:31 -0800135 const bool UseReserve;
Manasij Mukherjee7cd926d2016-08-04 12:33:23 -0700136 CfgVector<Variable *> Vars;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700137};
138
139} // end of namespace Ice
140
141#endif // SUBZERO_SRC_ICEREGALLOC_H