Commit a059e87e authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[TurboFan] Lazily allocate scheduled_nodes vectors since most remain empty.

The scheduled_nodes_ vector is used to maintain a per-block list of
non-fixed nodes. For most blocks this list remains empty, so lazily
initialize it instead of pre-allocating to save memory.

Also pre-reserve an extra 10% of blocks to avoid reallocting space in the
vector when fusing floating control creates new basic blocks.

BUG=chromium:700364

Change-Id: I9876e6a42bc90c9bff5838620365c18609ed1ee9
Reviewed-on: https://chromium-review.googlesource.com/458919Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44152}
parent 160f1dc0
...@@ -588,7 +588,9 @@ void Scheduler::BuildCFG() { ...@@ -588,7 +588,9 @@ void Scheduler::BuildCFG() {
control_flow_builder_->Run(); control_flow_builder_->Run();
// Initialize per-block data. // Initialize per-block data.
scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_)); // Reserve an extra 10% to avoid resizing vector when fusing floating control.
scheduled_nodes_.reserve(schedule_->BasicBlockCount() * 1.1);
scheduled_nodes_.resize(schedule_->BasicBlockCount());
} }
...@@ -1328,7 +1330,8 @@ void Scheduler::ScheduleEarly() { ...@@ -1328,7 +1330,8 @@ void Scheduler::ScheduleEarly() {
class ScheduleLateNodeVisitor { class ScheduleLateNodeVisitor {
public: public:
ScheduleLateNodeVisitor(Zone* zone, Scheduler* scheduler) ScheduleLateNodeVisitor(Zone* zone, Scheduler* scheduler)
: scheduler_(scheduler), : zone_(zone),
scheduler_(scheduler),
schedule_(scheduler_->schedule_), schedule_(scheduler_->schedule_),
marked_(scheduler->zone_), marked_(scheduler->zone_),
marking_queue_(scheduler->zone_) {} marking_queue_(scheduler->zone_) {}
...@@ -1621,7 +1624,12 @@ class ScheduleLateNodeVisitor { ...@@ -1621,7 +1624,12 @@ class ScheduleLateNodeVisitor {
void ScheduleNode(BasicBlock* block, Node* node) { void ScheduleNode(BasicBlock* block, Node* node) {
schedule_->PlanNode(block, node); schedule_->PlanNode(block, node);
scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node); size_t block_id = block->id().ToSize();
if (!scheduler_->scheduled_nodes_[block_id]) {
scheduler_->scheduled_nodes_[block_id] =
new (zone_->New(sizeof(NodeVector))) NodeVector(zone_);
}
scheduler_->scheduled_nodes_[block_id]->push_back(node);
scheduler_->UpdatePlacement(node, Scheduler::kScheduled); scheduler_->UpdatePlacement(node, Scheduler::kScheduled);
} }
...@@ -1640,6 +1648,7 @@ class ScheduleLateNodeVisitor { ...@@ -1640,6 +1648,7 @@ class ScheduleLateNodeVisitor {
return copy; return copy;
} }
Zone* zone_;
Scheduler* scheduler_; Scheduler* scheduler_;
Schedule* schedule_; Schedule* schedule_;
BoolVector marked_; BoolVector marked_;
...@@ -1676,11 +1685,13 @@ void Scheduler::SealFinalSchedule() { ...@@ -1676,11 +1685,13 @@ void Scheduler::SealFinalSchedule() {
// Add collected nodes for basic blocks to their blocks in the right order. // Add collected nodes for basic blocks to their blocks in the right order.
int block_num = 0; int block_num = 0;
for (NodeVector& nodes : scheduled_nodes_) { for (NodeVector* nodes : scheduled_nodes_) {
BasicBlock::Id id = BasicBlock::Id::FromInt(block_num++); BasicBlock::Id id = BasicBlock::Id::FromInt(block_num++);
BasicBlock* block = schedule_->GetBlockById(id); BasicBlock* block = schedule_->GetBlockById(id);
for (Node* node : base::Reversed(nodes)) { if (nodes) {
schedule_->AddNode(block, node); for (Node* node : base::Reversed(*nodes)) {
schedule_->AddNode(block, node);
}
} }
} }
} }
...@@ -1730,7 +1741,7 @@ void Scheduler::FuseFloatingControl(BasicBlock* block, Node* node) { ...@@ -1730,7 +1741,7 @@ void Scheduler::FuseFloatingControl(BasicBlock* block, Node* node) {
// Move previously planned nodes. // Move previously planned nodes.
// TODO(mstarzinger): Improve that by supporting bulk moves. // TODO(mstarzinger): Improve that by supporting bulk moves.
scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_)); scheduled_nodes_.resize(schedule_->BasicBlockCount());
MovePlannedNodes(block, schedule_->block(node)); MovePlannedNodes(block, schedule_->block(node));
if (FLAG_trace_turbo_scheduler) { if (FLAG_trace_turbo_scheduler) {
...@@ -1743,12 +1754,20 @@ void Scheduler::FuseFloatingControl(BasicBlock* block, Node* node) { ...@@ -1743,12 +1754,20 @@ void Scheduler::FuseFloatingControl(BasicBlock* block, Node* node) {
void Scheduler::MovePlannedNodes(BasicBlock* from, BasicBlock* to) { void Scheduler::MovePlannedNodes(BasicBlock* from, BasicBlock* to) {
TRACE("Move planned nodes from id:%d to id:%d\n", from->id().ToInt(), TRACE("Move planned nodes from id:%d to id:%d\n", from->id().ToInt(),
to->id().ToInt()); to->id().ToInt());
NodeVector* nodes = &(scheduled_nodes_[from->id().ToSize()]); NodeVector* from_nodes = scheduled_nodes_[from->id().ToSize()];
for (Node* const node : *nodes) { NodeVector* to_nodes = scheduled_nodes_[to->id().ToSize()];
if (!from_nodes) return;
for (Node* const node : *from_nodes) {
schedule_->SetBlockForNode(to, node); schedule_->SetBlockForNode(to, node);
scheduled_nodes_[to->id().ToSize()].push_back(node);
} }
nodes->clear(); if (to_nodes) {
to_nodes->insert(to_nodes->end(), from_nodes->begin(), from_nodes->end());
from_nodes->clear();
} else {
std::swap(scheduled_nodes_[from->id().ToSize()],
scheduled_nodes_[to->id().ToSize()]);
}
} }
} // namespace compiler } // namespace compiler
......
...@@ -65,7 +65,8 @@ class V8_EXPORT_PRIVATE Scheduler { ...@@ -65,7 +65,8 @@ class V8_EXPORT_PRIVATE Scheduler {
Graph* graph_; Graph* graph_;
Schedule* schedule_; Schedule* schedule_;
Flags flags_; Flags flags_;
NodeVectorVector scheduled_nodes_; // Per-block list of nodes in reverse. ZoneVector<NodeVector*>
scheduled_nodes_; // Per-block list of nodes in reverse.
NodeVector schedule_root_nodes_; // Fixed root nodes seed the worklist. NodeVector schedule_root_nodes_; // Fixed root nodes seed the worklist.
ZoneQueue<Node*> schedule_queue_; // Worklist of schedulable nodes. ZoneQueue<Node*> schedule_queue_; // Worklist of schedulable nodes.
ZoneVector<SchedulerData> node_data_; // Per-node data for all nodes. ZoneVector<SchedulerData> node_data_; // Per-node data for all nodes.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment