Commit f3c04aca authored by mtrofin's avatar mtrofin Committed by Commit bot

Reland: Introducing the LLVM greedy register allocator.

This change aims to introduce the separation of the RegisterAllocator model, using the initial prototype for GreedyAllocator as proof of concept.

Summary:
- new flag, turbo-greedy-regalloc, enabling the new allocator. Default
  false.
- initial, untested implementation for the GreedyAllocator.

BUG=

Review URL: https://codereview.chromium.org/1061923005

Cr-Commit-Position: refs/heads/master@{#28018}
parent 1a6f68e7
......@@ -742,23 +742,25 @@ struct BuildLiveRangesPhase {
};
template <typename RegAllocator>
struct AllocateGeneralRegistersPhase {
static const char* phase_name() { return "allocate general registers"; }
void Run(PipelineData* data, Zone* temp_zone) {
LinearScanAllocator allocator(data->register_allocation_data(),
GENERAL_REGISTERS, temp_zone);
RegAllocator allocator(data->register_allocation_data(), GENERAL_REGISTERS,
temp_zone);
allocator.AllocateRegisters();
}
};
template <typename RegAllocator>
struct AllocateDoubleRegistersPhase {
static const char* phase_name() { return "allocate double registers"; }
void Run(PipelineData* data, Zone* temp_zone) {
LinearScanAllocator allocator(data->register_allocation_data(),
DOUBLE_REGISTERS, temp_zone);
RegAllocator allocator(data->register_allocation_data(), DOUBLE_REGISTERS,
temp_zone);
allocator.AllocateRegisters();
}
};
......@@ -1269,8 +1271,13 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
if (verifier != nullptr) {
CHECK(!data->register_allocation_data()->ExistsUseWithoutDefinition());
}
Run<AllocateGeneralRegistersPhase>();
Run<AllocateDoubleRegistersPhase>();
if (FLAG_turbo_greedy_regalloc) {
Run<AllocateGeneralRegistersPhase<GreedyAllocator>>();
Run<AllocateDoubleRegistersPhase<GreedyAllocator>>();
} else {
Run<AllocateGeneralRegistersPhase<LinearScanAllocator>>();
Run<AllocateDoubleRegistersPhase<LinearScanAllocator>>();
}
Run<AssignSpillSlotsPhase>();
Run<CommitAssignmentPhase>();
......
This diff is collapsed.
......@@ -585,11 +585,14 @@ class LiveRangeBuilder final : public ZoneObject {
class RegisterAllocator : public ZoneObject {
public:
explicit RegisterAllocator(RegisterAllocationData* data);
explicit RegisterAllocator(RegisterAllocationData* data, RegisterKind kind);
protected:
RegisterAllocationData* data() const { return data_; }
InstructionSequence* code() const { return data()->code(); }
RegisterKind mode() const { return mode_; }
int num_registers() const { return num_registers_; }
Zone* allocation_zone() const { return data()->allocation_zone(); }
LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); }
......@@ -621,6 +624,8 @@ class RegisterAllocator : public ZoneObject {
private:
RegisterAllocationData* const data_;
const RegisterKind mode_;
const int num_registers_;
DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
};
......@@ -635,7 +640,6 @@ class LinearScanAllocator final : public RegisterAllocator {
void AllocateRegisters();
private:
int num_registers() const { return num_registers_; }
const char* RegisterName(int allocation_index) const;
ZoneVector<LiveRange*>& unhandled_live_ranges() {
......@@ -677,9 +681,6 @@ class LinearScanAllocator final : public RegisterAllocator {
void SplitAndSpillIntersecting(LiveRange* range);
const RegisterKind mode_;
const int num_registers_;
ZoneVector<LiveRange*> unhandled_live_ranges_;
ZoneVector<LiveRange*> active_live_ranges_;
ZoneVector<LiveRange*> inactive_live_ranges_;
......@@ -691,6 +692,46 @@ class LinearScanAllocator final : public RegisterAllocator {
DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator);
};
class CoallescedLiveRanges;
// A variant of the LLVM Greedy Register Allocator. See
// http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html
class GreedyAllocator final : public RegisterAllocator {
public:
explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind,
Zone* local_zone);
void AllocateRegisters();
private:
const RegisterConfiguration* config() const { return data()->config(); }
typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue;
unsigned GetLiveRangeSize(LiveRange* range);
void Enqueue(LiveRange* range);
void Evict(LiveRange* range);
float CalculateSpillWeight(LiveRange* range);
float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges);
bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting);
bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range,
ZoneSet<LiveRange*>* conflicting);
bool HandleSpillOperands(LiveRange* range);
bool AllocateBlockedRange(LiveRange*, const ZoneSet<LiveRange*>&);
LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start,
LifetimePosition until, LifetimePosition end);
void AssignRangeToRegister(int reg_id, LiveRange* range);
ZoneVector<CoallescedLiveRanges*> allocations_;
PQueue queue_;
DISALLOW_COPY_AND_ASSIGN(GreedyAllocator);
};
class OperandAssigner final : public ZoneObject {
public:
......
......@@ -382,6 +382,7 @@ DEFINE_BOOL(omit_map_checks_for_leaf_maps, true,
// Flags for TurboFan.
DEFINE_BOOL(turbo, false, "enable TurboFan compiler")
DEFINE_BOOL(turbo_greedy_regalloc, false, "use the greedy register allocator")
DEFINE_IMPLICATION(turbo, turbo_deoptimization)
DEFINE_IMPLICATION(turbo, turbo_type_feedback)
DEFINE_STRING(turbo_filter, "~~", "optimization filter for TurboFan compiler")
......
......@@ -63,6 +63,17 @@ class ZoneLinkedList : public std::list<T, zone_allocator<T>> {
};
// A wrapper subclass std::priority_queue to make it easy to construct one
// that uses a zone allocator.
template <typename T, typename Compare = std::less<T>>
class ZonePriorityQueue : public std::priority_queue<T, ZoneVector<T>> {
public:
// Constructs an empty list.
explicit ZonePriorityQueue(Zone* zone)
: std::priority_queue<T, ZoneVector<T>>(Compare(), ZoneVector<T>(zone)) {}
};
// A wrapper subclass for std::queue to make it easy to construct one
// that uses a zone allocator.
template <typename T>
......
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