}
+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 ||
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());
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;
}
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();
}
+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),
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());
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()) {
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;
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;
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),
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();
}
}
-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);
}
#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;
// 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.
// 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) {
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);
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;
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 {
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) {
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();
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();
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.
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.
}
Frame frame;
- RegisterAllocator allocator(scope_->main_zone(), &frame, &info, code);
+ RegisterAllocator allocator(scope_->main_zone(), &frame, code);
CHECK(allocator.Allocate());
if (FLAG_trace_turbo) {