[turbofan] Instruction scheduler: keep ready nodes list sorted by latency.

This significantly speed-up the instruction scheduler when the ready list
contains a large number of instruction.

R=jarin@chromium.org, bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/2281523002
Cr-Commit-Position: refs/heads/master@{#38919}
This commit is contained in:
baptiste.afsa 2016-08-25 11:04:58 -07:00 committed by Commit bot
parent 51c186dd98
commit f93ca29cac
2 changed files with 14 additions and 18 deletions

View File

@ -11,11 +11,16 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
// Compare the two nodes and return true if node1 is a better candidate than void InstructionScheduler::SchedulingQueueBase::AddNode(
// node2 (i.e. node1 should be scheduled before node2). ScheduleGraphNode* node) {
bool InstructionScheduler::CriticalPathFirstQueue::CompareNodes( // We keep the ready list sorted by total latency so that we can quickly find
ScheduleGraphNode *node1, ScheduleGraphNode *node2) const { // the next best candidate to schedule.
return node1->total_latency() > node2->total_latency(); auto it = nodes_.begin();
while ((it != nodes_.end()) &&
((*it)->total_latency() > node->total_latency())) {
++it;
}
nodes_.insert(it, node);
} }
@ -24,12 +29,10 @@ InstructionScheduler::CriticalPathFirstQueue::PopBestCandidate(int cycle) {
DCHECK(!IsEmpty()); DCHECK(!IsEmpty());
auto candidate = nodes_.end(); auto candidate = nodes_.end();
for (auto iterator = nodes_.begin(); iterator != nodes_.end(); ++iterator) { for (auto iterator = nodes_.begin(); iterator != nodes_.end(); ++iterator) {
// We only consider instructions that have all their operands ready and // We only consider instructions that have all their operands ready.
// we try to schedule the critical path first.
if (cycle >= (*iterator)->start_cycle()) { if (cycle >= (*iterator)->start_cycle()) {
if ((candidate == nodes_.end()) || CompareNodes(*iterator, *candidate)) {
candidate = iterator; candidate = iterator;
} break;
} }
} }

View File

@ -101,9 +101,7 @@ class InstructionScheduler final : public ZoneObject {
nodes_(scheduler->zone()) { nodes_(scheduler->zone()) {
} }
void AddNode(ScheduleGraphNode* node) { void AddNode(ScheduleGraphNode* node);
nodes_.push_back(node);
}
bool IsEmpty() const { bool IsEmpty() const {
return nodes_.empty(); return nodes_.empty();
@ -125,11 +123,6 @@ class InstructionScheduler final : public ZoneObject {
// Look for the best candidate to schedule, remove it from the queue and // Look for the best candidate to schedule, remove it from the queue and
// return it. // return it.
ScheduleGraphNode* PopBestCandidate(int cycle); ScheduleGraphNode* PopBestCandidate(int cycle);
private:
// Compare the two nodes and return true if node1 is a better candidate than
// node2 (i.e. node1 should be scheduled before node2).
bool CompareNodes(ScheduleGraphNode *node1, ScheduleGraphNode *node2) const;
}; };
// A queue which pop a random node from the queue to perform stress tests on // A queue which pop a random node from the queue to perform stress tests on