[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:
dcarney@chromium.org 2014-10-29 12:34:51 +00:00
parent 8a250b2e77
commit 60909d1eaf
4 changed files with 92 additions and 86 deletions

View File

@ -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();

View File

@ -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);
}

View File

@ -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.

View File

@ -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) {