|  | //===- subzero/src/IceRegAlloc.h - Linear-scan reg. allocation --*- C++ -*-===// | 
|  | // | 
|  | //                        The Subzero Code Generator | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | /// | 
|  | /// \file | 
|  | /// \brief Declares the LinearScan data structure used during linear-scan | 
|  | /// register allocation. | 
|  | /// | 
|  | /// This holds the various work queues for the linear-scan algorithm. | 
|  | /// | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef SUBZERO_SRC_ICEREGALLOC_H | 
|  | #define SUBZERO_SRC_ICEREGALLOC_H | 
|  |  | 
|  | #include "IceDefs.h" | 
|  | #include "IceBitVector.h" | 
|  | #include "IceOperand.h" | 
|  | #include "IceTypes.h" | 
|  |  | 
|  | namespace Ice { | 
|  |  | 
|  | class LinearScan { | 
|  | LinearScan() = delete; | 
|  | LinearScan(const LinearScan &) = delete; | 
|  | LinearScan &operator=(const LinearScan &) = delete; | 
|  |  | 
|  | public: | 
|  | explicit LinearScan(Cfg *Func); | 
|  | void init(RegAllocKind Kind, CfgSet<Variable *> ExcludeVars); | 
|  | void scan(const SmallBitVector &RegMask, bool Randomized); | 
|  | // Returns the number of times some variable has been assigned a register but | 
|  | // later evicted because of a higher-priority allocation.  The idea is that we | 
|  | // can implement "second-chance bin-packing" by rerunning register allocation | 
|  | // until there are no more evictions. | 
|  | SizeT getNumEvictions() const { return Evicted.size(); } | 
|  | bool hasEvictions() const { return !Evicted.empty(); } | 
|  | void dump(Cfg *Func) const; | 
|  |  | 
|  | // TODO(stichnot): Statically choose the size based on the target being | 
|  | // compiled.  For now, choose a value large enough to fit into the | 
|  | // SmallVector's fixed portion, which is 32 for x86-32, 84 for x86-64, and 102 | 
|  | // for ARM32. | 
|  | static constexpr size_t REGS_SIZE = 128; | 
|  |  | 
|  | private: | 
|  | using OrderedRanges = CfgVector<Variable *>; | 
|  | using UnorderedRanges = CfgVector<Variable *>; | 
|  | using DefUseErrorList = llvm::SmallVector<SizeT, 10>; | 
|  |  | 
|  | class IterationState { | 
|  | IterationState(const IterationState &) = delete; | 
|  | IterationState operator=(const IterationState &) = delete; | 
|  |  | 
|  | public: | 
|  | IterationState() = default; | 
|  | Variable *Cur = nullptr; | 
|  | Variable *Prefer = nullptr; | 
|  | RegNumT PreferReg; | 
|  | bool AllowOverlap = false; | 
|  | SmallBitVector RegMask; | 
|  | SmallBitVector RegMaskUnfiltered; | 
|  | SmallBitVector Free; | 
|  | SmallBitVector FreeUnfiltered; | 
|  | SmallBitVector PrecoloredUnhandledMask; // Note: only used for dumping | 
|  | llvm::SmallVector<RegWeight, REGS_SIZE> Weights; | 
|  | }; | 
|  |  | 
|  | bool livenessValidateIntervals(const DefUseErrorList &DefsWithoutUses, | 
|  | const DefUseErrorList &UsesBeforeDefs, | 
|  | const CfgVector<InstNumberT> &LRBegin, | 
|  | const CfgVector<InstNumberT> &LREnd) const; | 
|  | void initForGlobal(); | 
|  | void initForInfOnly(); | 
|  | void initForSecondChance(); | 
|  | /// Move an item from the From set to the To set. From[Index] is pushed onto | 
|  | /// the end of To[], then the item is efficiently removed from From[] by | 
|  | /// effectively swapping it with the last item in From[] and then popping it | 
|  | /// from the back. As such, the caller is best off iterating over From[] in | 
|  | /// reverse order to avoid the need for special handling of the iterator. | 
|  | void moveItem(UnorderedRanges &From, SizeT Index, UnorderedRanges &To) { | 
|  | To.push_back(From[Index]); | 
|  | From[Index] = From.back(); | 
|  | From.pop_back(); | 
|  | } | 
|  |  | 
|  | /// \name scan helper functions. | 
|  | /// @{ | 
|  | /// Free up a register for infinite-weight Cur by spilling and reloading some | 
|  | /// register that isn't used during Cur's live range. | 
|  | void addSpillFill(IterationState &Iter); | 
|  | /// Check for active ranges that have expired or become inactive. | 
|  | void handleActiveRangeExpiredOrInactive(const Variable *Cur); | 
|  | /// Check for inactive ranges that have expired or reactivated. | 
|  | void handleInactiveRangeExpiredOrReactivated(const Variable *Cur); | 
|  | void findRegisterPreference(IterationState &Iter); | 
|  | void filterFreeWithInactiveRanges(IterationState &Iter); | 
|  | void filterFreeWithPrecoloredRanges(IterationState &Iter); | 
|  | void allocatePrecoloredRegister(Variable *Cur); | 
|  | void allocatePreferredRegister(IterationState &Iter); | 
|  | void allocateFreeRegister(IterationState &Iter, bool Filtered); | 
|  | void handleNoFreeRegisters(IterationState &Iter); | 
|  | void assignFinalRegisters(const SmallBitVector &RegMaskFull, | 
|  | const SmallBitVector &PreDefinedRegisters, | 
|  | bool Randomized); | 
|  | /// @} | 
|  |  | 
|  | void dumpLiveRangeTrace(const char *Label, const Variable *Item); | 
|  |  | 
|  | Cfg *const Func; | 
|  | GlobalContext *const Ctx; | 
|  | TargetLowering *const Target; | 
|  |  | 
|  | OrderedRanges Unhandled; | 
|  | /// UnhandledPrecolored is a subset of Unhandled, specially collected for | 
|  | /// faster processing. | 
|  | OrderedRanges UnhandledPrecolored; | 
|  | UnorderedRanges Active, Inactive, Handled; | 
|  | UnorderedRanges Evicted; | 
|  | CfgVector<InstNumberT> Kills; | 
|  | RegAllocKind Kind = RAK_Unknown; | 
|  | /// RegUses[I] is the number of live ranges (variables) that register I is | 
|  | /// currently assigned to. It can be greater than 1 as a result of | 
|  | /// AllowOverlap inference. | 
|  | llvm::SmallVector<int32_t, REGS_SIZE> RegUses; | 
|  | llvm::SmallVector<const SmallBitVector *, REGS_SIZE> RegAliases; | 
|  | bool FindPreference = false; | 
|  | bool FindOverlap = false; | 
|  | const bool Verbose; | 
|  | const bool UseReserve; | 
|  | CfgVector<Variable *> Vars; | 
|  | }; | 
|  |  | 
|  | } // end of namespace Ice | 
|  |  | 
|  | #endif // SUBZERO_SRC_ICEREGALLOC_H |