Commit d24cfda1 by Andrew Scull

Refactor LinearScan::scan from one huge function into smaller functions.

BUG= R=jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/1310833003.
parent 0042fea3
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// ///
/// \file /// \file
/// This file declares the LinearScan data structure used during /// This file declares the LinearScan data structure used during linear-scan
/// linear-scan register allocation, which holds the various work /// register allocation, which holds the various work queues for the linear-scan
/// queues for the linear-scan algorithm. /// algorithm.
/// ///
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#define SUBZERO_SRC_ICEREGALLOC_H #define SUBZERO_SRC_ICEREGALLOC_H
#include "IceDefs.h" #include "IceDefs.h"
#include "IceOperand.h"
#include "IceTypes.h" #include "IceTypes.h"
namespace Ice { namespace Ice {
...@@ -28,42 +29,89 @@ class LinearScan { ...@@ -28,42 +29,89 @@ class LinearScan {
LinearScan &operator=(const LinearScan &) = delete; LinearScan &operator=(const LinearScan &) = delete;
public: public:
explicit LinearScan(Cfg *Func) : Func(Func) {} explicit LinearScan(Cfg *Func);
void init(RegAllocKind Kind); void init(RegAllocKind Kind);
void scan(const llvm::SmallBitVector &RegMask, bool Randomized); void scan(const llvm::SmallBitVector &RegMask, bool Randomized);
void dump(Cfg *Func) const; void dump(Cfg *Func) const;
// TODO(stichnot): Statically choose the size based on the target being
// compiled.
static constexpr size_t REGS_SIZE = 32;
private: private:
typedef std::vector<Variable *> OrderedRanges; typedef std::vector<Variable *> OrderedRanges;
typedef std::vector<Variable *> UnorderedRanges; typedef std::vector<Variable *> UnorderedRanges;
class IterationState {
IterationState(const IterationState &) = delete;
IterationState operator=(const IterationState &) = delete;
public:
IterationState() = default;
Variable *Cur = nullptr;
Variable *Prefer = nullptr;
int32_t PreferReg = Variable::NoRegister;
bool AllowOverlap = false;
llvm::SmallBitVector RegMask;
llvm::SmallBitVector Free;
llvm::SmallBitVector PrecoloredUnhandledMask; // Note: only used for dumping
llvm::SmallVector<RegWeight, REGS_SIZE> Weights;
};
void initForGlobal(); void initForGlobal();
void initForInfOnly(); void initForInfOnly();
/// Free up a register for infinite-weight Cur by spilling and reloading some /// Move an item from the From set to the To set. From[Index] is pushed onto
/// register that isn't used during Cur's live range. /// the end of To[], then the item is efficiently removed from From[] by
void addSpillFill(Variable *Cur, llvm::SmallBitVector RegMask); /// effectively swapping it with the last item in From[] and then popping it
/// Move an item from the From set to the To set. From[Index] is /// from the back. As such, the caller is best off iterating over From[] in
/// pushed onto the end of To[], then the item is efficiently removed /// reverse order to avoid the need for special handling of the iterator.
/// 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) { void moveItem(UnorderedRanges &From, SizeT Index, UnorderedRanges &To) {
To.push_back(From[Index]); To.push_back(From[Index]);
From[Index] = From.back(); From[Index] = From.back();
From.pop_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);
void handleNoFreeRegisters(IterationState &Iter);
void assignFinalRegisters(const llvm::SmallBitVector &RegMaskFull,
const llvm::SmallBitVector &PreDefinedRegisters,
bool Randomized);
/// @}
void dumpLiveRangeTrace(const char *Label, const Variable *Item);
Cfg *const Func; Cfg *const Func;
GlobalContext *const Ctx;
OrderedRanges Unhandled; OrderedRanges Unhandled;
/// UnhandledPrecolored is a subset of Unhandled, specially collected /// UnhandledPrecolored is a subset of Unhandled, specially collected for
/// for faster processing. /// faster processing.
OrderedRanges UnhandledPrecolored; OrderedRanges UnhandledPrecolored;
UnorderedRanges Active, Inactive, Handled; UnorderedRanges Active, Inactive, Handled;
std::vector<InstNumberT> Kills; std::vector<InstNumberT> Kills;
RegAllocKind Kind = RAK_Unknown; 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;
bool FindPreference = false; bool FindPreference = false;
bool FindOverlap = false; bool FindOverlap = false;
const bool Verbose;
}; };
} // end of namespace Ice } // end of namespace Ice
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment