[turbofan] cleanup register allocator interface a little
BUG= R=jarin@chromium.org Review URL: https://codereview.chromium.org/671043004 Cr-Commit-Position: refs/heads/master@{#24978} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24978 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8a250b2e77
commit
60909d1eaf
@ -259,6 +259,24 @@ static void TraceSchedule(Schedule* schedule) {
|
||||
}
|
||||
|
||||
|
||||
static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
|
||||
SmartArrayPointer<char> name;
|
||||
if (info->IsStub()) {
|
||||
if (info->code_stub() != NULL) {
|
||||
CodeStub::Major major_key = info->code_stub()->MajorKey();
|
||||
const char* major_name = CodeStub::MajorName(major_key, false);
|
||||
size_t len = strlen(major_name);
|
||||
name.Reset(new char[len]);
|
||||
memcpy(name.get(), major_name, len);
|
||||
}
|
||||
} else {
|
||||
AllowHandleDereference allow_deref;
|
||||
name = info->function()->debug_name()->ToCString();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> Pipeline::GenerateCode() {
|
||||
// This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc.
|
||||
if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
|
||||
@ -285,8 +303,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
if (FLAG_trace_turbo) {
|
||||
OFStream os(stdout);
|
||||
os << "---------------------------------------------------\n"
|
||||
<< "Begin compiling method "
|
||||
<< info()->function()->debug_name()->ToCString().get()
|
||||
<< "Begin compiling method " << GetDebugName(info()).get()
|
||||
<< " using Turbofan" << std::endl;
|
||||
TurboCfgFile tcf(isolate());
|
||||
tcf << AsC1VCompilation(info());
|
||||
@ -463,8 +480,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
if (FLAG_trace_turbo) {
|
||||
OFStream os(stdout);
|
||||
os << "--------------------------------------------------\n"
|
||||
<< "Finished compiling method "
|
||||
<< info()->function()->debug_name()->ToCString().get()
|
||||
<< "Finished compiling method " << GetDebugName(info()).get()
|
||||
<< " using Turbofan" << std::endl;
|
||||
}
|
||||
|
||||
@ -556,7 +572,14 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) {
|
||||
return Handle<Code>::null();
|
||||
}
|
||||
ZonePool::Scope zone_scope(data->zone_pool());
|
||||
RegisterAllocator allocator(zone_scope.zone(), &frame, info(), &sequence);
|
||||
|
||||
SmartArrayPointer<char> debug_name;
|
||||
#ifdef DEBUG
|
||||
debug_name = GetDebugName(info());
|
||||
#endif
|
||||
|
||||
RegisterAllocator allocator(zone_scope.zone(), &frame, &sequence,
|
||||
debug_name.get());
|
||||
if (!allocator.Allocate(data->pipeline_statistics())) {
|
||||
info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
|
||||
return Handle<Code>::null();
|
||||
|
@ -21,6 +21,16 @@ static inline LifetimePosition Max(LifetimePosition a, LifetimePosition b) {
|
||||
}
|
||||
|
||||
|
||||
static void TraceAlloc(const char* msg, ...) {
|
||||
if (FLAG_trace_alloc) {
|
||||
va_list arguments;
|
||||
va_start(arguments, msg);
|
||||
base::OS::VPrint(msg, arguments);
|
||||
va_end(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
|
||||
InstructionOperand* hint)
|
||||
: operand_(operand),
|
||||
@ -348,8 +358,7 @@ bool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const {
|
||||
|
||||
|
||||
void LiveRange::ShortenTo(LifetimePosition start) {
|
||||
RegisterAllocator::TraceAlloc("Shorten live range %d to [%d\n", id_,
|
||||
start.Value());
|
||||
TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value());
|
||||
DCHECK(first_interval_ != NULL);
|
||||
DCHECK(first_interval_->start().Value() <= start.Value());
|
||||
DCHECK(start.Value() < first_interval_->end().Value());
|
||||
@ -359,8 +368,8 @@ void LiveRange::ShortenTo(LifetimePosition start) {
|
||||
|
||||
void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end,
|
||||
Zone* zone) {
|
||||
RegisterAllocator::TraceAlloc("Ensure live range %d in interval [%d %d[\n",
|
||||
id_, start.Value(), end.Value());
|
||||
TraceAlloc("Ensure live range %d in interval [%d %d[\n", id_, start.Value(),
|
||||
end.Value());
|
||||
LifetimePosition new_end = end;
|
||||
while (first_interval_ != NULL &&
|
||||
first_interval_->start().Value() <= end.Value()) {
|
||||
@ -381,8 +390,8 @@ void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end,
|
||||
|
||||
void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end,
|
||||
Zone* zone) {
|
||||
RegisterAllocator::TraceAlloc("Add to live range %d interval [%d %d[\n", id_,
|
||||
start.Value(), end.Value());
|
||||
TraceAlloc("Add to live range %d interval [%d %d[\n", id_, start.Value(),
|
||||
end.Value());
|
||||
if (first_interval_ == NULL) {
|
||||
UseInterval* interval = new (zone) UseInterval(start, end);
|
||||
first_interval_ = interval;
|
||||
@ -409,8 +418,7 @@ void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end,
|
||||
void LiveRange::AddUsePosition(LifetimePosition pos,
|
||||
InstructionOperand* operand,
|
||||
InstructionOperand* hint, Zone* zone) {
|
||||
RegisterAllocator::TraceAlloc("Add to live range %d use position %d\n", id_,
|
||||
pos.Value());
|
||||
TraceAlloc("Add to live range %d use position %d\n", id_, pos.Value());
|
||||
UsePosition* use_pos = new (zone) UsePosition(pos, operand, hint);
|
||||
UsePosition* prev_hint = NULL;
|
||||
UsePosition* prev = NULL;
|
||||
@ -499,12 +507,12 @@ LifetimePosition LiveRange::FirstIntersection(LiveRange* other) {
|
||||
|
||||
|
||||
RegisterAllocator::RegisterAllocator(Zone* local_zone, Frame* frame,
|
||||
CompilationInfo* info,
|
||||
InstructionSequence* code)
|
||||
InstructionSequence* code,
|
||||
const char* debug_name)
|
||||
: zone_(local_zone),
|
||||
frame_(frame),
|
||||
info_(info),
|
||||
code_(code),
|
||||
debug_name_(debug_name),
|
||||
live_in_sets_(code->InstructionBlockCount(), zone()),
|
||||
live_ranges_(code->VirtualRegisterCount() * 2, zone()),
|
||||
fixed_live_ranges_(NULL),
|
||||
@ -1374,19 +1382,10 @@ void RegisterAllocator::BuildLiveRanges() {
|
||||
operand_index);
|
||||
LiveRange* range = LiveRangeFor(operand_index);
|
||||
PrintF(" (first use is at %d)\n", range->first_pos()->pos().Value());
|
||||
CompilationInfo* info = this->info();
|
||||
if (info->IsStub()) {
|
||||
if (info->code_stub() == NULL) {
|
||||
PrintF("\n");
|
||||
} else {
|
||||
CodeStub::Major major_key = info->code_stub()->MajorKey();
|
||||
PrintF(" (function: %s)\n", CodeStub::MajorName(major_key, false));
|
||||
}
|
||||
if (debug_name() == nullptr) {
|
||||
PrintF("\n");
|
||||
} else {
|
||||
DCHECK(info->IsOptimizing());
|
||||
AllowHandleDereference allow_deref;
|
||||
PrintF(" (function: %s)\n",
|
||||
info->function()->debug_name()->ToCString().get());
|
||||
PrintF(" (function: %s)\n", debug_name());
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
@ -1644,16 +1643,6 @@ const char* RegisterAllocator::RegisterName(int allocation_index) {
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocator::TraceAlloc(const char* msg, ...) {
|
||||
if (FLAG_trace_alloc) {
|
||||
va_list arguments;
|
||||
va_start(arguments, msg);
|
||||
base::OS::VPrint(msg, arguments);
|
||||
va_end(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool RegisterAllocator::HasTaggedValue(int virtual_register) const {
|
||||
return code()->IsReference(virtual_register);
|
||||
}
|
||||
|
@ -7,20 +7,11 @@
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/compiler/instruction.h"
|
||||
#include "src/compiler/zone-pool.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/zone.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// Forward declarations.
|
||||
class BitVector;
|
||||
class InstructionOperand;
|
||||
class UnallocatedOperand;
|
||||
class ParallelMove;
|
||||
class PointerMap;
|
||||
|
||||
namespace compiler {
|
||||
|
||||
class PipelineStatistics;
|
||||
@ -36,7 +27,7 @@ enum RegisterKind {
|
||||
// each instruction there are exactly two lifetime positions: the beginning and
|
||||
// the end of the instruction. Lifetime positions for different instructions are
|
||||
// disjoint.
|
||||
class LifetimePosition {
|
||||
class LifetimePosition FINAL {
|
||||
public:
|
||||
// Return the lifetime position that corresponds to the beginning of
|
||||
// the instruction with the given index.
|
||||
@ -115,7 +106,7 @@ class LifetimePosition {
|
||||
|
||||
|
||||
// Representation of the non-empty interval [start,end[.
|
||||
class UseInterval : public ZoneObject {
|
||||
class UseInterval FINAL : public ZoneObject {
|
||||
public:
|
||||
UseInterval(LifetimePosition start, LifetimePosition end)
|
||||
: start_(start), end_(end), next_(NULL) {
|
||||
@ -148,10 +139,14 @@ class UseInterval : public ZoneObject {
|
||||
LifetimePosition start_;
|
||||
LifetimePosition end_;
|
||||
UseInterval* next_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(UseInterval);
|
||||
};
|
||||
|
||||
|
||||
// Representation of a use position.
|
||||
class UsePosition : public ZoneObject {
|
||||
class UsePosition FINAL : public ZoneObject {
|
||||
public:
|
||||
UsePosition(LifetimePosition pos, InstructionOperand* operand,
|
||||
InstructionOperand* hint);
|
||||
@ -173,13 +168,17 @@ class UsePosition : public ZoneObject {
|
||||
InstructionOperand* const hint_;
|
||||
LifetimePosition const pos_;
|
||||
UsePosition* next_;
|
||||
bool requires_reg_;
|
||||
bool register_beneficial_;
|
||||
bool requires_reg_ : 1;
|
||||
bool register_beneficial_ : 1;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(UsePosition);
|
||||
};
|
||||
|
||||
|
||||
// Representation of SSA values' live ranges as a collection of (continuous)
|
||||
// intervals over the instruction ordering.
|
||||
class LiveRange : public ZoneObject {
|
||||
class LiveRange FINAL : public ZoneObject {
|
||||
public:
|
||||
static const int kInvalidAssignment = 0x7fffffff;
|
||||
|
||||
@ -315,25 +314,21 @@ class LiveRange : public ZoneObject {
|
||||
int spill_start_index_;
|
||||
|
||||
friend class RegisterAllocator; // Assigns to kind_.
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LiveRange);
|
||||
};
|
||||
|
||||
|
||||
class RegisterAllocator BASE_EMBEDDED {
|
||||
public:
|
||||
// TODO(dcarney): remove info
|
||||
explicit RegisterAllocator(Zone* local_zone, Frame* frame,
|
||||
CompilationInfo* info, InstructionSequence* code);
|
||||
|
||||
static void TraceAlloc(const char* msg, ...);
|
||||
|
||||
// Checks whether the value of a given virtual register is a reference.
|
||||
// TODO(titzer): rename this to IsReference.
|
||||
bool HasTaggedValue(int virtual_register) const;
|
||||
|
||||
// Returns the register kind required by the given virtual register.
|
||||
RegisterKind RequiredRegisterKind(int virtual_register) const;
|
||||
InstructionSequence* code,
|
||||
const char* debug_name = nullptr);
|
||||
|
||||
bool Allocate(PipelineStatistics* stats = NULL);
|
||||
bool AllocationOk() { return allocation_ok_; }
|
||||
BitVector* assigned_registers() { return assigned_registers_; }
|
||||
BitVector* assigned_double_registers() { return assigned_double_registers_; }
|
||||
|
||||
const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
|
||||
const Vector<LiveRange*>* fixed_live_ranges() const {
|
||||
@ -342,17 +337,9 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
const Vector<LiveRange*>* fixed_double_live_ranges() const {
|
||||
return &fixed_double_live_ranges_;
|
||||
}
|
||||
InstructionSequence* code() const { return code_; }
|
||||
|
||||
CompilationInfo* info() const { return info_; }
|
||||
inline InstructionSequence* code() const { return code_; }
|
||||
|
||||
// This zone is for datastructures only needed during register allocation.
|
||||
inline Zone* zone() const { return zone_; }
|
||||
|
||||
// This zone is for InstructionOperands and moves that live beyond register
|
||||
// allocation.
|
||||
inline Zone* code_zone() const { return code()->zone(); }
|
||||
|
||||
private:
|
||||
int GetVirtualRegister() {
|
||||
int vreg = code()->NextVirtualRegister();
|
||||
if (vreg >= UnallocatedOperand::kMaxVirtualRegisters) {
|
||||
@ -363,16 +350,24 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
return vreg;
|
||||
}
|
||||
|
||||
bool AllocationOk() { return allocation_ok_; }
|
||||
// Checks whether the value of a given virtual register is a reference.
|
||||
// TODO(titzer): rename this to IsReference.
|
||||
bool HasTaggedValue(int virtual_register) const;
|
||||
|
||||
// Returns the register kind required by the given virtual register.
|
||||
RegisterKind RequiredRegisterKind(int virtual_register) const;
|
||||
|
||||
// This zone is for datastructures only needed during register allocation.
|
||||
Zone* zone() const { return zone_; }
|
||||
|
||||
// This zone is for InstructionOperands and moves that live beyond register
|
||||
// allocation.
|
||||
Zone* code_zone() const { return code()->zone(); }
|
||||
|
||||
#ifdef DEBUG
|
||||
void Verify() const;
|
||||
#endif
|
||||
|
||||
BitVector* assigned_registers() { return assigned_registers_; }
|
||||
BitVector* assigned_double_registers() { return assigned_double_registers_; }
|
||||
|
||||
private:
|
||||
void MeetRegisterConstraints();
|
||||
void ResolvePhis();
|
||||
void BuildLiveRanges();
|
||||
@ -383,7 +378,7 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
void PopulatePointerMaps(); // TODO(titzer): rename to PopulateReferenceMaps.
|
||||
void AllocateRegisters();
|
||||
bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
|
||||
inline bool SafePointsAreInOrder() const;
|
||||
bool SafePointsAreInOrder() const;
|
||||
|
||||
// Liveness analysis support.
|
||||
void InitializeLivenessAnalysis();
|
||||
@ -474,7 +469,7 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
void ResolveControlFlow(LiveRange* range, const InstructionBlock* block,
|
||||
const InstructionBlock* pred);
|
||||
|
||||
inline void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
|
||||
void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
|
||||
|
||||
// Return parallel move that should be used to connect ranges split at the
|
||||
// given position.
|
||||
@ -494,16 +489,15 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
|
||||
const char* RegisterName(int allocation_index);
|
||||
|
||||
inline Instruction* InstructionAt(int index) {
|
||||
return code()->InstructionAt(index);
|
||||
}
|
||||
Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
|
||||
|
||||
Frame* frame() const { return frame_; }
|
||||
const char* debug_name() const { return debug_name_; }
|
||||
|
||||
Zone* const zone_;
|
||||
Frame* const frame_;
|
||||
CompilationInfo* const info_;
|
||||
InstructionSequence* const code_;
|
||||
const char* const debug_name_;
|
||||
|
||||
// During liveness analysis keep a mapping from block id to live_in sets
|
||||
// for blocks already analyzed.
|
||||
|
@ -78,7 +78,7 @@ class DeoptCodegenTester {
|
||||
}
|
||||
|
||||
Frame frame;
|
||||
RegisterAllocator allocator(scope_->main_zone(), &frame, &info, code);
|
||||
RegisterAllocator allocator(scope_->main_zone(), &frame, code);
|
||||
CHECK(allocator.Allocate());
|
||||
|
||||
if (FLAG_trace_turbo) {
|
||||
|
Loading…
Reference in New Issue
Block a user