"src/compiler/raw-machine-assembler.h",
"src/compiler/register-allocator.cc",
"src/compiler/register-allocator.h",
+ "src/compiler/register-configuration.cc",
+ "src/compiler/register-configuration.h",
"src/compiler/representation-change.h",
"src/compiler/schedule.cc",
"src/compiler/schedule.h",
for (int j = instruction_block->first_instruction_index();
j <= instruction_block->last_instruction_index(); j++) {
PrintIndent();
- os_ << j << " " << *instructions->InstructionAt(j) << " <|@\n";
+ PrintableInstruction printable = {RegisterConfiguration::ArchDefault(),
+ instructions->InstructionAt(j)};
+ os_ << j << " " << printable << " <|@\n";
}
}
}
#include "src/compiler/generic-node-inl.h"
#include "src/compiler/graph.h"
#include "src/compiler/instruction.h"
-#include "src/macro-assembler.h"
namespace v8 {
namespace internal {
namespace compiler {
-STATIC_ASSERT(kMaxGeneralRegisters >= Register::kNumRegisters);
-STATIC_ASSERT(kMaxDoubleRegisters >= DoubleRegister::kMaxNumRegisters);
-
-
-std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) {
+std::ostream& operator<<(std::ostream& os,
+ const PrintableInstructionOperand& printable) {
+ const InstructionOperand& op = *printable.op_;
+ const RegisterConfiguration* conf = printable.register_configuration_;
switch (op.kind()) {
case InstructionOperand::INVALID:
return os << "(0)";
case UnallocatedOperand::NONE:
return os;
case UnallocatedOperand::FIXED_REGISTER:
- return os << "(=" << Register::AllocationIndexToString(
+ return os << "(=" << conf->general_register_name(
unalloc->fixed_register_index()) << ")";
case UnallocatedOperand::FIXED_DOUBLE_REGISTER:
- return os << "(=" << DoubleRegister::AllocationIndexToString(
+ return os << "(=" << conf->double_register_name(
unalloc->fixed_register_index()) << ")";
case UnallocatedOperand::MUST_HAVE_REGISTER:
return os << "(R)";
case InstructionOperand::DOUBLE_STACK_SLOT:
return os << "[double_stack:" << op.index() << "]";
case InstructionOperand::REGISTER:
- return os << "[" << Register::AllocationIndexToString(op.index())
- << "|R]";
+ return os << "[" << conf->general_register_name(op.index()) << "|R]";
case InstructionOperand::DOUBLE_REGISTER:
- return os << "[" << DoubleRegister::AllocationIndexToString(op.index())
- << "|R]";
+ return os << "[" << conf->double_register_name(op.index()) << "|R]";
}
UNREACHABLE();
return os;
}
-std::ostream& operator<<(std::ostream& os, const MoveOperands& mo) {
- os << *mo.destination();
- if (!mo.source()->Equals(mo.destination())) os << " = " << *mo.source();
+std::ostream& operator<<(std::ostream& os,
+ const PrintableMoveOperands& printable) {
+ const MoveOperands& mo = *printable.move_operands_;
+ PrintableInstructionOperand printable_op = {printable.register_configuration_,
+ mo.destination()};
+
+ os << printable_op;
+ if (!mo.source()->Equals(mo.destination())) {
+ printable_op.op_ = mo.source();
+ os << " = " << printable_op;
+ }
return os << ";";
}
}
-std::ostream& operator<<(std::ostream& os, const ParallelMove& pm) {
+std::ostream& operator<<(std::ostream& os,
+ const PrintableParallelMove& printable) {
+ const ParallelMove& pm = *printable.parallel_move_;
bool first = true;
for (ZoneList<MoveOperands>::iterator move = pm.move_operands()->begin();
move != pm.move_operands()->end(); ++move) {
if (move->IsEliminated()) continue;
if (!first) os << " ";
first = false;
- os << *move;
+ PrintableMoveOperands pmo = {printable.register_configuration_, move};
+ os << pmo;
}
return os;
}
}
-std::ostream& operator<<(std::ostream& os, const Instruction& instr) {
+std::ostream& operator<<(std::ostream& os,
+ const PrintableInstruction& printable) {
+ const Instruction& instr = *printable.instr_;
+ PrintableInstructionOperand printable_op = {printable.register_configuration_,
+ NULL};
if (instr.OutputCount() > 1) os << "(";
for (size_t i = 0; i < instr.OutputCount(); i++) {
if (i > 0) os << ", ";
- os << *instr.OutputAt(i);
+ printable_op.op_ = instr.OutputAt(i);
+ os << printable_op;
}
if (instr.OutputCount() > 1) os << ") = ";
for (int i = GapInstruction::FIRST_INNER_POSITION;
i <= GapInstruction::LAST_INNER_POSITION; i++) {
os << "(";
- if (gap->parallel_moves_[i] != NULL) os << *gap->parallel_moves_[i];
+ if (gap->parallel_moves_[i] != NULL) {
+ PrintableParallelMove ppm = {printable.register_configuration_,
+ gap->parallel_moves_[i]};
+ os << ppm;
+ }
os << ") ";
}
} else if (instr.IsSourcePosition()) {
}
if (instr.InputCount() > 0) {
for (size_t i = 0; i < instr.InputCount(); i++) {
- os << " " << *instr.InputAt(i);
+ printable_op.op_ = instr.InputAt(i);
+ os << " " << printable_op;
}
}
return os;
}
-std::ostream& operator<<(std::ostream& os, const InstructionSequence& code) {
+std::ostream& operator<<(std::ostream& os,
+ const PrintableInstructionSequence& printable) {
+ const InstructionSequence& code = *printable.sequence_;
for (size_t i = 0; i < code.immediates_.size(); ++i) {
Constant constant = code.immediates_[i];
os << "IMM#" << i << ": " << constant << "\n";
}
ScopedVector<char> buf(32);
+ PrintableInstruction printable_instr;
+ printable_instr.register_configuration_ = printable.register_configuration_;
for (int j = block->first_instruction_index();
j <= block->last_instruction_index(); j++) {
// TODO(svenpanne) Add some basic formatting to our streams.
SNPrintF(buf, "%5d", j);
- os << " " << buf.start() << ": " << *code.InstructionAt(j) << "\n";
+ printable_instr.instr_ = code.InstructionAt(j);
+ os << " " << buf.start() << ": " << printable_instr << "\n";
}
- // TODO(dcarney): add this back somehow?
- // os << " " << block->control();
-
- // if (block->control_input() != NULL) {
- // os << " v" << block->control_input()->id();
- // }
-
for (auto succ : block->successors()) {
const InstructionBlock* succ_block = code.InstructionBlockAt(succ);
os << " B" << succ_block->id();
#include "src/compiler/frame.h"
#include "src/compiler/instruction-codes.h"
#include "src/compiler/opcodes.h"
+#include "src/compiler/register-configuration.h"
#include "src/compiler/schedule.h"
#include "src/compiler/source-position.h"
#include "src/zone-allocator.h"
const InstructionCode kBlockStartInstruction = -2;
const InstructionCode kSourcePositionInstruction = -3;
-// Platform independent maxes.
-static const int kMaxGeneralRegisters = 32;
-static const int kMaxDoubleRegisters = 32;
-
-
-#define INSTRUCTION_OPERAND_LIST(V) \
- V(Constant, CONSTANT, 0) \
- V(Immediate, IMMEDIATE, 0) \
- V(StackSlot, STACK_SLOT, 128) \
- V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \
- V(Register, REGISTER, kMaxGeneralRegisters) \
- V(DoubleRegister, DOUBLE_REGISTER, kMaxDoubleRegisters)
+#define INSTRUCTION_OPERAND_LIST(V) \
+ V(Constant, CONSTANT, 0) \
+ V(Immediate, IMMEDIATE, 0) \
+ V(StackSlot, STACK_SLOT, 128) \
+ V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \
+ V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \
+ V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters)
class InstructionOperand : public ZoneObject {
public:
typedef ZoneVector<InstructionOperand*> InstructionOperandVector;
-std::ostream& operator<<(std::ostream& os, const InstructionOperand& op);
+struct PrintableInstructionOperand {
+ const RegisterConfiguration* register_configuration_;
+ const InstructionOperand* op_;
+};
+
+std::ostream& operator<<(std::ostream& os,
+ const PrintableInstructionOperand& op);
class UnallocatedOperand : public InstructionOperand {
public:
InstructionOperand* destination_;
};
-std::ostream& operator<<(std::ostream& os, const MoveOperands& mo);
+
+struct PrintableMoveOperands {
+ const RegisterConfiguration* register_configuration_;
+ const MoveOperands* move_operands_;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo);
+
template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
class SubKindOperand FINAL : public InstructionOperand {
ZoneList<MoveOperands> move_operands_;
};
-std::ostream& operator<<(std::ostream& os, const ParallelMove& pm);
+
+struct PrintableParallelMove {
+ const RegisterConfiguration* register_configuration_;
+ const ParallelMove* parallel_move_;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& pm);
+
class PointerMap FINAL : public ZoneObject {
public:
InstructionOperand* operands_[1];
};
-std::ostream& operator<<(std::ostream& os, const Instruction& instr);
+
+struct PrintableInstruction {
+ const RegisterConfiguration* register_configuration_;
+ const Instruction* instr_;
+};
+std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr);
+
// Represents moves inserted before an instruction due to register allocation.
// TODO(titzer): squash GapInstruction back into Instruction, since essentially
}
private:
- friend std::ostream& operator<<(std::ostream& os, const Instruction& instr);
+ friend std::ostream& operator<<(std::ostream& os,
+ const PrintableInstruction& instr);
ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
};
typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
typedef ZoneVector<InstructionBlock*> InstructionBlocks;
+struct PrintableInstructionSequence;
+
+
// Represents architecture-specific generated code before, during, and after
// register allocation.
// TODO(titzer): s/IsDouble/IsFloat64/
private:
friend std::ostream& operator<<(std::ostream& os,
- const InstructionSequence& code);
+ const PrintableInstructionSequence& code);
typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet;
DeoptimizationVector deoptimization_entries_;
};
-std::ostream& operator<<(std::ostream& os, const InstructionSequence& code);
+
+struct PrintableInstructionSequence {
+ const RegisterConfiguration* register_configuration_;
+ const InstructionSequence* sequence_;
+};
+
+
+std::ostream& operator<<(std::ostream& os,
+ const PrintableInstructionSequence& code);
} // namespace compiler
} // namespace internal
if (FLAG_trace_turbo) {
OFStream os(stdout);
+ PrintableInstructionSequence printable = {
+ RegisterConfiguration::ArchDefault(), &sequence};
os << "----- Instruction sequence before register allocation -----\n"
- << sequence;
+ << printable;
TurboCfgFile tcf(isolate());
tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
&sequence);
#endif
- RegisterAllocator allocator(RegisterAllocator::PlatformConfig(),
+ RegisterAllocator allocator(RegisterConfiguration::ArchDefault(),
zone_scope.zone(), &frame, &sequence,
debug_name.get());
if (!allocator.Allocate(data->pipeline_statistics())) {
if (FLAG_trace_turbo) {
OFStream os(stdout);
+ PrintableInstructionSequence printable = {
+ RegisterConfiguration::ArchDefault(), &sequence};
os << "----- Instruction sequence after register allocation -----\n"
- << sequence;
+ << printable;
}
if (data->pipeline_statistics() != NULL) {
#include "src/compiler/linkage.h"
#include "src/compiler/pipeline-statistics.h"
#include "src/compiler/register-allocator.h"
-#include "src/macro-assembler.h" // TODO(dcarney): remove this.
#include "src/string-stream.h"
namespace v8 {
}
-RegisterAllocator::Config RegisterAllocator::PlatformConfig() {
- DCHECK_EQ(Register::kMaxNumAllocatableRegisters,
- Register::NumAllocatableRegisters());
- Config config;
- config.num_general_registers_ = Register::kMaxNumAllocatableRegisters;
- config.num_double_registers_ = DoubleRegister::kMaxNumAllocatableRegisters;
- config.num_aliased_double_registers_ =
- DoubleRegister::NumAllocatableAliasedRegisters();
- config.GeneralRegisterName = Register::AllocationIndexToString;
- config.DoubleRegisterName = DoubleRegister::AllocationIndexToString;
- return config;
-}
-
-
-RegisterAllocator::RegisterAllocator(const Config& config, Zone* local_zone,
- Frame* frame, InstructionSequence* code,
+RegisterAllocator::RegisterAllocator(const RegisterConfiguration* config,
+ Zone* local_zone, Frame* frame,
+ InstructionSequence* code,
const char* debug_name)
: zone_(local_zone),
frame_(frame),
config_(config),
live_in_sets_(code->InstructionBlockCount(), zone()),
live_ranges_(code->VirtualRegisterCount() * 2, zone()),
- fixed_live_ranges_(this->config().num_general_registers_, NULL, zone()),
- fixed_double_live_ranges_(this->config().num_double_registers_, NULL,
+ fixed_live_ranges_(this->config()->num_general_registers(), NULL, zone()),
+ fixed_double_live_ranges_(this->config()->num_double_registers(), NULL,
zone()),
unhandled_live_ranges_(code->VirtualRegisterCount() * 2, zone()),
active_live_ranges_(8, zone()),
mode_(UNALLOCATED_REGISTERS),
num_registers_(-1),
allocation_ok_(true) {
- DCHECK(this->config().num_general_registers_ <= kMaxGeneralRegisters);
- DCHECK(this->config().num_double_registers_ <= kMaxDoubleRegisters);
+ DCHECK(this->config()->num_general_registers() <=
+ RegisterConfiguration::kMaxGeneralRegisters);
+ DCHECK(this->config()->num_double_registers() <=
+ RegisterConfiguration::kMaxDoubleRegisters);
// TryAllocateFreeReg and AllocateBlockedReg assume this
// when allocating local arrays.
- DCHECK(this->config().num_double_registers_ >=
- this->config().num_general_registers_);
+ DCHECK(this->config()->num_double_registers() >=
+ this->config()->num_general_registers());
}
int RegisterAllocator::FixedDoubleLiveRangeID(int index) {
- return -index - 1 - config().num_general_registers_;
+ return -index - 1 - config()->num_general_registers();
}
LiveRange* RegisterAllocator::FixedLiveRangeFor(int index) {
- DCHECK(index < config().num_general_registers_);
+ DCHECK(index < config()->num_general_registers());
LiveRange* result = fixed_live_ranges_[index];
if (result == NULL) {
// TODO(titzer): add a utility method to allocate a new LiveRange:
LiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) {
- DCHECK(index < config().num_aliased_double_registers_);
+ DCHECK(index < config()->num_aliased_double_registers());
LiveRange* result = fixed_double_live_ranges_[index];
if (result == NULL) {
result = new (zone()) LiveRange(FixedDoubleLiveRangeID(index), code_zone());
}
if (instr->ClobbersRegisters()) {
- for (int i = 0; i < config().num_general_registers_; ++i) {
+ for (int i = 0; i < config()->num_general_registers(); ++i) {
if (!IsOutputRegisterOf(instr, i)) {
LiveRange* range = FixedLiveRangeFor(i);
range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
}
if (instr->ClobbersDoubleRegisters()) {
- for (int i = 0; i < config().num_aliased_double_registers_; ++i) {
+ for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
if (!IsOutputDoubleRegisterOf(instr, i)) {
LiveRange* range = FixedDoubleLiveRangeFor(i);
range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
bool RegisterAllocator::Allocate(PipelineStatistics* stats) {
- assigned_registers_ =
- new (code_zone()) BitVector(config().num_general_registers_, code_zone());
+ assigned_registers_ = new (code_zone())
+ BitVector(config()->num_general_registers(), code_zone());
assigned_double_registers_ = new (code_zone())
- BitVector(config().num_aliased_double_registers_, code_zone());
+ BitVector(config()->num_aliased_double_registers(), code_zone());
{
PhaseScope phase_scope(stats, "meet register constraints");
MeetRegisterConstraints();
void RegisterAllocator::AllocateGeneralRegisters() {
- num_registers_ = config().num_general_registers_;
+ num_registers_ = config()->num_general_registers();
mode_ = GENERAL_REGISTERS;
AllocateRegisters();
}
void RegisterAllocator::AllocateDoubleRegisters() {
- num_registers_ = config().num_aliased_double_registers_;
+ num_registers_ = config()->num_aliased_double_registers();
mode_ = DOUBLE_REGISTERS;
AllocateRegisters();
}
DCHECK(inactive_live_ranges_.is_empty());
if (mode_ == DOUBLE_REGISTERS) {
- for (int i = 0; i < config().num_aliased_double_registers_; ++i) {
+ for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
LiveRange* current = fixed_double_live_ranges_.at(i);
if (current != NULL) {
AddToInactive(current);
const char* RegisterAllocator::RegisterName(int allocation_index) {
if (mode_ == GENERAL_REGISTERS) {
- return config().GeneralRegisterName(allocation_index);
+ return config()->general_register_name(allocation_index);
} else {
- return config().DoubleRegisterName(allocation_index);
+ return config()->double_register_name(allocation_index);
}
}
bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) {
- LifetimePosition free_until_pos[kMaxDoubleRegisters];
+ LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
for (int i = 0; i < num_registers_; i++) {
free_until_pos[i] = LifetimePosition::MaxPosition();
return;
}
- LifetimePosition use_pos[kMaxGeneralRegisters];
- LifetimePosition block_pos[kMaxDoubleRegisters];
+ LifetimePosition use_pos[RegisterConfiguration::kMaxGeneralRegisters];
+ LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters];
for (int i = 0; i < num_registers_; i++) {
use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
class RegisterAllocator FINAL {
public:
- class Config {
- public:
- int num_general_registers_;
- int num_double_registers_;
- int num_aliased_double_registers_;
- const char* (*GeneralRegisterName)(int allocation_index);
- const char* (*DoubleRegisterName)(int allocation_index);
- };
-
- static Config PlatformConfig();
-
- explicit RegisterAllocator(const Config& config, Zone* local_zone,
- Frame* frame, InstructionSequence* code,
+ explicit RegisterAllocator(const RegisterConfiguration* config,
+ Zone* local_zone, Frame* frame,
+ InstructionSequence* code,
const char* debug_name = nullptr);
bool Allocate(PipelineStatistics* stats = NULL);
Frame* frame() const { return frame_; }
const char* debug_name() const { return debug_name_; }
- const Config& config() const { return config_; }
+ const RegisterConfiguration* config() const { return config_; }
Zone* const zone_;
Frame* const frame_;
InstructionSequence* const code_;
const char* const debug_name_;
- const Config config_;
+ const RegisterConfiguration* config_;
// During liveness analysis keep a mapping from block id to live_in sets
// for blocks already analyzed.
--- /dev/null
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/register-configuration.h"
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
+ Register::kNumRegisters);
+STATIC_ASSERT(RegisterConfiguration::kMaxDoubleRegisters >=
+ DoubleRegister::kMaxNumRegisters);
+
+class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
+ public:
+ ArchDefaultRegisterConfiguration()
+ : RegisterConfiguration(Register::kMaxNumAllocatableRegisters,
+ DoubleRegister::kMaxNumAllocatableRegisters,
+ DoubleRegister::NumAllocatableAliasedRegisters(),
+ general_register_name_table_,
+ double_register_name_table_) {
+ DCHECK_EQ(Register::kMaxNumAllocatableRegisters,
+ Register::NumAllocatableRegisters());
+ for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) {
+ general_register_name_table_[i] = Register::AllocationIndexToString(i);
+ }
+ for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) {
+ double_register_name_table_[i] =
+ DoubleRegister::AllocationIndexToString(i);
+ }
+ }
+
+ const char*
+ general_register_name_table_[Register::kMaxNumAllocatableRegisters];
+ const char*
+ double_register_name_table_[DoubleRegister::kMaxNumAllocatableRegisters];
+};
+
+
+static base::LazyInstance<ArchDefaultRegisterConfiguration>::type
+ kDefaultRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
+
+} // namepace
+
+
+const RegisterConfiguration* RegisterConfiguration::ArchDefault() {
+ return &kDefaultRegisterConfiguration.Get();
+}
+
+RegisterConfiguration::RegisterConfiguration(
+ int num_general_registers, int num_double_registers,
+ int num_aliased_double_registers, const char* const* general_register_names,
+ const char* const* double_register_names)
+ : num_general_registers_(num_general_registers),
+ num_double_registers_(num_double_registers),
+ num_aliased_double_registers_(num_aliased_double_registers),
+ general_register_names_(general_register_names),
+ double_register_names_(double_register_names) {}
+
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
--- /dev/null
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_REGISTER_CONFIGURATION_H_
+#define V8_COMPILER_REGISTER_CONFIGURATION_H_
+
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// An architecture independent representation of the sets of registers available
+// for instruction creation.
+class RegisterConfiguration {
+ public:
+ // Architecture independent maxes.
+ static const int kMaxGeneralRegisters = 32;
+ static const int kMaxDoubleRegisters = 32;
+
+ static const RegisterConfiguration* ArchDefault();
+
+ RegisterConfiguration(int num_general_registers, int num_double_registers,
+ int num_aliased_double_registers,
+ const char* const* general_register_name,
+ const char* const* double_register_name);
+
+ int num_general_registers() const { return num_general_registers_; }
+ int num_double_registers() const { return num_double_registers_; }
+ int num_aliased_double_registers() const {
+ return num_aliased_double_registers_;
+ }
+
+ const char* general_register_name(int offset) const {
+ DCHECK(offset >= 0 && offset < kMaxGeneralRegisters);
+ return general_register_names_[offset];
+ }
+ const char* double_register_name(int offset) const {
+ DCHECK(offset >= 0 && offset < kMaxDoubleRegisters);
+ return double_register_names_[offset];
+ }
+
+ private:
+ const int num_general_registers_;
+ const int num_double_registers_;
+ const int num_aliased_double_registers_;
+ const char* const* general_register_names_;
+ const char* const* double_register_names_;
+};
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_COMPILER_REGISTER_CONFIGURATION_H_
selector.SelectInstructions();
if (FLAG_trace_turbo) {
+ PrintableInstructionSequence printable = {
+ RegisterConfiguration::ArchDefault(), code};
os << "----- Instruction sequence before register allocation -----\n"
- << *code;
+ << printable;
}
Frame frame;
- RegisterAllocator allocator(RegisterAllocator::PlatformConfig(),
+ RegisterAllocator allocator(RegisterConfiguration::ArchDefault(),
scope_->main_zone(), &frame, code);
CHECK(allocator.Allocate());
if (FLAG_trace_turbo) {
+ PrintableInstructionSequence printable = {
+ RegisterConfiguration::ArchDefault(), code};
os << "----- Instruction sequence after register allocation -----\n"
- << *code;
+ << printable;
}
compiler::CodeGenerator generator(&frame, linkage, code, &info);
if (it != is.values_.begin()) os << " ";
InstructionOperand source(it->first.first, it->first.second);
InstructionOperand destination(it->second.first, it->second.second);
- os << MoveOperands(&source, &destination);
+ MoveOperands mo(&source, &destination);
+ PrintableMoveOperands pmo = {RegisterConfiguration::ArchDefault(), &mo};
+ os << pmo;
}
return os;
}
selector.SelectInstructions();
if (FLAG_trace_turbo) {
OFStream out(stdout);
+ PrintableInstructionSequence printable = {
+ RegisterConfiguration::ArchDefault(), &sequence};
out << "=== Code sequence after instruction selection ===" << std::endl
- << sequence;
+ << printable;
}
Stream s;
// Map virtual registers.
namespace {
-static const char* general_register_names_[kMaxGeneralRegisters];
-static const char* double_register_names_[kMaxDoubleRegisters];
-static char register_names_[10 * (kMaxGeneralRegisters + kMaxDoubleRegisters)];
-
-
-static const char* GeneralRegisterName(int allocation_index) {
- return general_register_names_[allocation_index];
-}
-
-
-static const char* DoubleRegisterName(int allocation_index) {
- return double_register_names_[allocation_index];
-}
+static const char*
+ general_register_names_[RegisterConfiguration::kMaxGeneralRegisters];
+static const char*
+ double_register_names_[RegisterConfiguration::kMaxDoubleRegisters];
+static char register_names_[10 * (RegisterConfiguration::kMaxGeneralRegisters +
+ RegisterConfiguration::kMaxDoubleRegisters)];
static void InitializeRegisterNames() {
char* loc = register_names_;
- for (int i = 0; i < kMaxGeneralRegisters; ++i) {
+ for (int i = 0; i < RegisterConfiguration::kMaxGeneralRegisters; ++i) {
general_register_names_[i] = loc;
loc += base::OS::SNPrintF(loc, 100, "gp_%d", i);
*loc++ = 0;
}
- for (int i = 0; i < kMaxDoubleRegisters; ++i) {
+ for (int i = 0; i < RegisterConfiguration::kMaxDoubleRegisters; ++i) {
double_register_names_[i] = loc;
loc += base::OS::SNPrintF(loc, 100, "fp_%d", i) + 1;
*loc++ = 0;
static const int kDefaultNRegs = 4;
RegisterAllocatorTest()
- : basic_blocks_(zone()),
+ : num_general_registers_(kDefaultNRegs),
+ num_double_registers_(kDefaultNRegs),
+ basic_blocks_(zone()),
instruction_blocks_(zone()),
current_block_(NULL) {
InitializeRegisterNames();
- config_.num_general_registers_ = kDefaultNRegs;
- config_.num_double_registers_ = kDefaultNRegs;
- config_.num_aliased_double_registers_ = kDefaultNRegs;
- config_.GeneralRegisterName = GeneralRegisterName;
- config_.DoubleRegisterName = DoubleRegisterName;
+ }
+
+ RegisterConfiguration* config() {
+ if (config_.is_empty()) {
+ config_.Reset(new RegisterConfiguration(
+ num_general_registers_, num_double_registers_, num_double_registers_,
+ general_register_names_, double_register_names_));
+ }
+ return config_.get();
}
Frame* frame() {
RegisterAllocator* allocator() {
if (allocator_.is_empty()) {
allocator_.Reset(
- new RegisterAllocator(config_, zone(), frame(), sequence()));
+ new RegisterAllocator(config(), zone(), frame(), sequence()));
}
return allocator_.get();
}
void Allocate() {
if (FLAG_trace_alloc) {
OFStream os(stdout);
- os << "Before: " << std::endl << *sequence() << std::endl;
+ PrintableInstructionSequence printable = {config(), sequence()};
+ os << "Before: " << std::endl << printable << std::endl;
}
allocator()->Allocate();
if (FLAG_trace_alloc) {
OFStream os(stdout);
- os << "After: " << std::endl << *sequence() << std::endl;
+ PrintableInstructionSequence printable = {config(), sequence()};
+ os << "After: " << std::endl << printable << std::endl;
}
}
return op;
}
- RegisterAllocator::Config config_;
+ int num_general_registers_;
+ int num_double_registers_;
+ SmartPointer<RegisterConfiguration> config_;
ZoneVector<BasicBlock*> basic_blocks_;
InstructionBlocks instruction_blocks_;
InstructionBlock* current_block_;
'../../src/compiler/raw-machine-assembler.h',
'../../src/compiler/register-allocator.cc',
'../../src/compiler/register-allocator.h',
+ '../../src/compiler/register-configuration.cc',
+ '../../src/compiler/register-configuration.h',
'../../src/compiler/representation-change.h',
'../../src/compiler/schedule.cc',
'../../src/compiler/schedule.h',