[turbofan] move Node to vreg mapping to InstructionSelector
BUG= R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/683933004 Cr-Commit-Position: refs/heads/master@{#25010} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25010 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
264b9aaa31
commit
ee9de33075
@ -46,7 +46,8 @@ class OperandGenerator {
|
||||
|
||||
InstructionOperand* DefineAsConstant(Node* node) {
|
||||
selector()->MarkAsDefined(node);
|
||||
int virtual_register = sequence()->AddConstant(node, ToConstant(node));
|
||||
int virtual_register = selector_->GetVirtualRegister(node);
|
||||
sequence()->AddConstant(virtual_register, ToConstant(node));
|
||||
return ConstantOperand::Create(virtual_register, zone());
|
||||
}
|
||||
|
||||
@ -172,8 +173,7 @@ class OperandGenerator {
|
||||
UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) {
|
||||
DCHECK_NOT_NULL(node);
|
||||
DCHECK_NOT_NULL(operand);
|
||||
operand->set_virtual_register(
|
||||
selector_->sequence()->GetVirtualRegister(node));
|
||||
operand->set_virtual_register(selector_->GetVirtualRegister(node));
|
||||
selector()->MarkAsDefined(node);
|
||||
return operand;
|
||||
}
|
||||
@ -181,8 +181,7 @@ class OperandGenerator {
|
||||
UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) {
|
||||
DCHECK_NOT_NULL(node);
|
||||
DCHECK_NOT_NULL(operand);
|
||||
operand->set_virtual_register(
|
||||
selector_->sequence()->GetVirtualRegister(node));
|
||||
operand->set_virtual_register(selector_->GetVirtualRegister(node));
|
||||
selector()->MarkAsUsed(node);
|
||||
return operand;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "src/compiler/instruction-selector.h"
|
||||
|
||||
#include "src/compiler/graph.h"
|
||||
#include "src/compiler/instruction-selector-impl.h"
|
||||
#include "src/compiler/node-matchers.h"
|
||||
#include "src/compiler/node-properties-inl.h"
|
||||
@ -13,7 +14,8 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
InstructionSelector::InstructionSelector(Zone* local_zone, Linkage* linkage,
|
||||
InstructionSelector::InstructionSelector(Zone* local_zone, Graph* graph,
|
||||
Linkage* linkage,
|
||||
InstructionSequence* sequence,
|
||||
Schedule* schedule,
|
||||
SourcePositionTable* source_positions,
|
||||
@ -24,10 +26,11 @@ InstructionSelector::InstructionSelector(Zone* local_zone, Linkage* linkage,
|
||||
source_positions_(source_positions),
|
||||
features_(features),
|
||||
schedule_(schedule),
|
||||
node_map_(graph->NodeCount(), kNodeUnmapped, zone()),
|
||||
current_block_(NULL),
|
||||
instructions_(zone()),
|
||||
defined_(sequence->node_count(), false, zone()),
|
||||
used_(sequence->node_count(), false, zone()) {}
|
||||
defined_(graph->NodeCount(), false, zone()),
|
||||
used_(graph->NodeCount(), false, zone()) {}
|
||||
|
||||
|
||||
void InstructionSelector::SelectInstructions() {
|
||||
@ -157,6 +160,19 @@ bool InstructionSelector::CanCover(Node* user, Node* node) const {
|
||||
}
|
||||
|
||||
|
||||
int InstructionSelector::GetVirtualRegister(const Node* node) {
|
||||
if (node_map_[node->id()] == kNodeUnmapped) {
|
||||
node_map_[node->id()] = sequence()->NextVirtualRegister();
|
||||
}
|
||||
return node_map_[node->id()];
|
||||
}
|
||||
|
||||
|
||||
int InstructionSelector::GetMappedVirtualRegister(const Node* node) const {
|
||||
return node_map_[node->id()];
|
||||
}
|
||||
|
||||
|
||||
bool InstructionSelector::IsDefined(Node* node) const {
|
||||
DCHECK_NOT_NULL(node);
|
||||
NodeId id = node->id();
|
||||
@ -195,27 +211,31 @@ void InstructionSelector::MarkAsUsed(Node* node) {
|
||||
|
||||
bool InstructionSelector::IsDouble(const Node* node) const {
|
||||
DCHECK_NOT_NULL(node);
|
||||
return sequence()->IsDouble(sequence()->GetVirtualRegister(node));
|
||||
int virtual_register = GetMappedVirtualRegister(node);
|
||||
if (virtual_register == kNodeUnmapped) return false;
|
||||
return sequence()->IsDouble(virtual_register);
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::MarkAsDouble(Node* node) {
|
||||
DCHECK_NOT_NULL(node);
|
||||
DCHECK(!IsReference(node));
|
||||
sequence()->MarkAsDouble(sequence()->GetVirtualRegister(node));
|
||||
sequence()->MarkAsDouble(GetVirtualRegister(node));
|
||||
}
|
||||
|
||||
|
||||
bool InstructionSelector::IsReference(const Node* node) const {
|
||||
DCHECK_NOT_NULL(node);
|
||||
return sequence()->IsReference(sequence()->GetVirtualRegister(node));
|
||||
int virtual_register = GetMappedVirtualRegister(node);
|
||||
if (virtual_register == kNodeUnmapped) return false;
|
||||
return sequence()->IsReference(virtual_register);
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::MarkAsReference(Node* node) {
|
||||
DCHECK_NOT_NULL(node);
|
||||
DCHECK(!IsDouble(node));
|
||||
sequence()->MarkAsReference(sequence()->GetVirtualRegister(node));
|
||||
sequence()->MarkAsReference(GetVirtualRegister(node));
|
||||
}
|
||||
|
||||
|
||||
@ -892,14 +912,14 @@ void InstructionSelector::VisitParameter(Node* node) {
|
||||
void InstructionSelector::VisitPhi(Node* node) {
|
||||
// TODO(bmeurer): Emit a PhiInstruction here.
|
||||
PhiInstruction* phi = new (instruction_zone())
|
||||
PhiInstruction(instruction_zone(), sequence()->GetVirtualRegister(node));
|
||||
PhiInstruction(instruction_zone(), GetVirtualRegister(node));
|
||||
sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi);
|
||||
const int input_count = node->op()->InputCount();
|
||||
phi->operands().reserve(static_cast<size_t>(input_count));
|
||||
for (int i = 0; i < input_count; ++i) {
|
||||
Node* const input = node->InputAt(i);
|
||||
MarkAsUsed(input);
|
||||
phi->operands().push_back(sequence()->GetVirtualRegister(input));
|
||||
phi->operands().push_back(GetVirtualRegister(input));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,12 +21,17 @@ struct CallBuffer; // TODO(bmeurer): Remove this.
|
||||
class FlagsContinuation;
|
||||
class Linkage;
|
||||
|
||||
typedef IntVector NodeToVregMap;
|
||||
|
||||
class InstructionSelector FINAL {
|
||||
public:
|
||||
static const int kNodeUnmapped = -1;
|
||||
|
||||
// Forward declarations.
|
||||
class Features;
|
||||
|
||||
InstructionSelector(Zone* local_zone, Linkage* linkage,
|
||||
// TODO(dcarney): pass in vreg mapping instead of graph.
|
||||
InstructionSelector(Zone* local_zone, Graph* graph, Linkage* linkage,
|
||||
InstructionSequence* sequence, Schedule* schedule,
|
||||
SourcePositionTable* source_positions,
|
||||
Features features = SupportedFeatures());
|
||||
@ -110,6 +115,11 @@ class InstructionSelector FINAL {
|
||||
// Checks if {node} is currently live.
|
||||
bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
|
||||
|
||||
int GetVirtualRegister(const Node* node);
|
||||
// Gets the current mapping if it exists, kNodeUnmapped otherwise.
|
||||
int GetMappedVirtualRegister(const Node* node) const;
|
||||
const NodeToVregMap& GetNodeMapForTesting() const { return node_map_; }
|
||||
|
||||
private:
|
||||
friend class OperandGenerator;
|
||||
|
||||
@ -206,6 +216,7 @@ class InstructionSelector FINAL {
|
||||
SourcePositionTable* const source_positions_;
|
||||
Features features_;
|
||||
Schedule* const schedule_;
|
||||
NodeToVregMap node_map_;
|
||||
BasicBlock* current_block_;
|
||||
ZoneDeque<Instruction*> instructions_;
|
||||
BoolVector defined_;
|
||||
|
@ -387,10 +387,8 @@ static void InitializeInstructionBlocks(Zone* zone, const Schedule* schedule,
|
||||
|
||||
|
||||
InstructionSequence::InstructionSequence(Zone* instruction_zone,
|
||||
const Graph* graph,
|
||||
const Schedule* schedule)
|
||||
: zone_(instruction_zone),
|
||||
node_map_(graph->NodeCount(), kNodeUnmapped, zone()),
|
||||
instruction_blocks_(static_cast<int>(schedule->rpo_order()->size()), NULL,
|
||||
zone()),
|
||||
constants_(ConstantMap::key_compare(),
|
||||
@ -406,14 +404,6 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone,
|
||||
}
|
||||
|
||||
|
||||
int InstructionSequence::GetVirtualRegister(const Node* node) {
|
||||
if (node_map_[node->id()] == kNodeUnmapped) {
|
||||
node_map_[node->id()] = NextVirtualRegister();
|
||||
}
|
||||
return node_map_[node->id()];
|
||||
}
|
||||
|
||||
|
||||
Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) {
|
||||
return GetBlockStart(rpo)->label();
|
||||
}
|
||||
|
@ -842,22 +842,17 @@ typedef ZoneDeque<Instruction*> InstructionDeque;
|
||||
typedef ZoneDeque<PointerMap*> PointerMapDeque;
|
||||
typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
|
||||
typedef ZoneVector<InstructionBlock*> InstructionBlocks;
|
||||
typedef IntVector NodeToVregMap;
|
||||
|
||||
// Represents architecture-specific generated code before, during, and after
|
||||
// register allocation.
|
||||
// TODO(titzer): s/IsDouble/IsFloat64/
|
||||
class InstructionSequence FINAL {
|
||||
public:
|
||||
static const int kNodeUnmapped = -1;
|
||||
|
||||
InstructionSequence(Zone* zone, const Graph* graph, const Schedule* schedule);
|
||||
InstructionSequence(Zone* zone, const Schedule* schedule);
|
||||
|
||||
int NextVirtualRegister() { return next_virtual_register_++; }
|
||||
int VirtualRegisterCount() const { return next_virtual_register_; }
|
||||
|
||||
int node_count() const { return static_cast<int>(node_map_.size()); }
|
||||
|
||||
const InstructionBlocks& instruction_blocks() const {
|
||||
return instruction_blocks_;
|
||||
}
|
||||
@ -882,9 +877,6 @@ class InstructionSequence FINAL {
|
||||
|
||||
const InstructionBlock* GetInstructionBlock(int instruction_index) const;
|
||||
|
||||
int GetVirtualRegister(const Node* node);
|
||||
const NodeToVregMap& GetNodeMapForTesting() const { return node_map_; }
|
||||
|
||||
bool IsReference(int virtual_register) const;
|
||||
bool IsDouble(int virtual_register) const;
|
||||
|
||||
@ -919,8 +911,8 @@ class InstructionSequence FINAL {
|
||||
void StartBlock(BasicBlock* block);
|
||||
void EndBlock(BasicBlock* block);
|
||||
|
||||
int AddConstant(Node* node, Constant constant) {
|
||||
int virtual_register = GetVirtualRegister(node);
|
||||
int AddConstant(int virtual_register, Constant constant) {
|
||||
DCHECK(virtual_register >= 0 && virtual_register < next_virtual_register_);
|
||||
DCHECK(constants_.find(virtual_register) == constants_.end());
|
||||
constants_.insert(std::make_pair(virtual_register, constant));
|
||||
return virtual_register;
|
||||
@ -967,7 +959,6 @@ class InstructionSequence FINAL {
|
||||
typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet;
|
||||
|
||||
Zone* const zone_;
|
||||
NodeToVregMap node_map_;
|
||||
InstructionBlocks instruction_blocks_;
|
||||
ConstantMap constants_;
|
||||
ConstantDeque immediates_;
|
||||
|
@ -538,15 +538,15 @@ Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) {
|
||||
data->schedule());
|
||||
}
|
||||
|
||||
InstructionSequence sequence(data->instruction_zone(), data->graph(),
|
||||
data->schedule());
|
||||
InstructionSequence sequence(data->instruction_zone(), data->schedule());
|
||||
|
||||
// Select and schedule instructions covering the scheduled graph.
|
||||
{
|
||||
PhaseScope phase_scope(data->pipeline_statistics(), "select instructions");
|
||||
ZonePool::Scope zone_scope(data->zone_pool());
|
||||
InstructionSelector selector(zone_scope.zone(), linkage, &sequence,
|
||||
data->schedule(), data->source_positions());
|
||||
InstructionSelector selector(zone_scope.zone(), data->graph(), linkage,
|
||||
&sequence, data->schedule(),
|
||||
data->source_positions());
|
||||
selector.SelectInstructions();
|
||||
}
|
||||
|
||||
|
@ -66,10 +66,10 @@ class DeoptCodegenTester {
|
||||
// Initialize the codegen and generate code.
|
||||
Linkage* linkage = new (scope_->main_zone()) Linkage(info.zone(), &info);
|
||||
code = new v8::internal::compiler::InstructionSequence(scope_->main_zone(),
|
||||
graph, schedule);
|
||||
schedule);
|
||||
SourcePositionTable source_positions(graph);
|
||||
InstructionSelector selector(scope_->main_zone(), linkage, code, schedule,
|
||||
&source_positions);
|
||||
InstructionSelector selector(scope_->main_zone(), graph, linkage, code,
|
||||
schedule, &source_positions);
|
||||
selector.SelectInstructions();
|
||||
|
||||
if (FLAG_trace_turbo) {
|
||||
|
@ -55,7 +55,7 @@ class InstructionTester : public HandleAndZoneScope {
|
||||
Scheduler::ComputeSpecialRPO(&zone_pool, &schedule);
|
||||
DCHECK(schedule.rpo_order()->size() > 0);
|
||||
}
|
||||
code = new TestInstrSeq(main_zone(), &graph, &schedule);
|
||||
code = new TestInstrSeq(main_zone(), &schedule);
|
||||
}
|
||||
|
||||
Node* Int32Constant(int32_t val) {
|
||||
@ -128,8 +128,6 @@ TEST(InstructionBasic) {
|
||||
|
||||
R.allocCode();
|
||||
|
||||
CHECK_EQ(R.graph.NodeCount(), R.code->node_count());
|
||||
|
||||
BasicBlockVector* blocks = R.schedule.rpo_order();
|
||||
CHECK_EQ(static_cast<int>(blocks->size()), R.code->InstructionBlockCount());
|
||||
|
||||
|
@ -37,10 +37,10 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
|
||||
EXPECT_NE(0, graph()->NodeCount());
|
||||
int initial_node_count = graph()->NodeCount();
|
||||
Linkage linkage(test_->zone(), call_descriptor());
|
||||
InstructionSequence sequence(test_->zone(), graph(), schedule);
|
||||
InstructionSequence sequence(test_->zone(), schedule);
|
||||
SourcePositionTable source_position_table(graph());
|
||||
InstructionSelector selector(test_->zone(), &linkage, &sequence, schedule,
|
||||
&source_position_table, features);
|
||||
InstructionSelector selector(test_->zone(), graph(), &linkage, &sequence,
|
||||
schedule, &source_position_table, features);
|
||||
selector.SelectInstructions();
|
||||
if (FLAG_trace_turbo) {
|
||||
OFStream out(stdout);
|
||||
@ -50,9 +50,9 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
|
||||
Stream s;
|
||||
// Map virtual registers.
|
||||
{
|
||||
const NodeToVregMap& node_map = sequence.GetNodeMapForTesting();
|
||||
const NodeToVregMap& node_map = selector.GetNodeMapForTesting();
|
||||
for (int i = 0; i < initial_node_count; ++i) {
|
||||
if (node_map[i] != InstructionSequence::kNodeUnmapped) {
|
||||
if (node_map[i] != InstructionSelector::kNodeUnmapped) {
|
||||
s.virtual_registers_.insert(std::make_pair(i, node_map[i]));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user