Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(493)

Unified Diff: src/compiler/instruction-scheduler.cc

Issue 1714753004: [turbofan] Refactoring around the instruction scheduler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/instruction-scheduler.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/instruction-scheduler.cc
diff --git a/src/compiler/instruction-scheduler.cc b/src/compiler/instruction-scheduler.cc
index 829e883f49a20f12d006df43d0678c1748a4030a..5369f6060e9ad2bce9249832f5075c82620adba6 100644
--- a/src/compiler/instruction-scheduler.cc
+++ b/src/compiler/instruction-scheduler.cc
@@ -5,11 +5,57 @@
#include "src/compiler/instruction-scheduler.h"
#include "src/base/adapters.h"
+#include "src/base/utils/random-number-generator.h"
namespace v8 {
namespace internal {
namespace compiler {
+// Compare the two nodes and return true if node1 is a better candidate than
+// node2 (i.e. node1 should be scheduled before node2).
+bool InstructionScheduler::CriticalPathFirstQueue::CompareNodes(
+ ScheduleGraphNode *node1, ScheduleGraphNode *node2) const {
+ return node1->total_latency() > node2->total_latency();
+}
+
+
+InstructionScheduler::ScheduleGraphNode*
+InstructionScheduler::CriticalPathFirstQueue::PopBestCandidate(int cycle) {
+ DCHECK(!IsEmpty());
+ auto candidate = nodes_.end();
+ for (auto iterator = nodes_.begin(); iterator != nodes_.end(); ++iterator) {
+ // We only consider instructions that have all their operands ready and
+ // we try to schedule the critical path first.
+ if (cycle >= (*iterator)->start_cycle()) {
+ if ((candidate == nodes_.end()) || CompareNodes(*iterator, *candidate)) {
+ candidate = iterator;
+ }
+ }
+ }
+
+ if (candidate != nodes_.end()) {
+ ScheduleGraphNode *result = *candidate;
+ nodes_.erase(candidate);
+ return result;
+ }
+
+ return nullptr;
+}
+
+
+InstructionScheduler::ScheduleGraphNode*
+InstructionScheduler::StressSchedulerQueue::PopBestCandidate(int cycle) {
+ DCHECK(!IsEmpty());
+ // Choose a random element from the ready list.
+ auto candidate = nodes_.begin();
+ std::advance(candidate, isolate()->random_number_generator()->NextInt(
+ static_cast<int>(nodes_.size())));
+ ScheduleGraphNode *result = *candidate;
+ nodes_.erase(candidate);
+ return result;
+}
+
+
InstructionScheduler::ScheduleGraphNode::ScheduleGraphNode(
Zone* zone,
Instruction* instr)
@@ -50,7 +96,11 @@ void InstructionScheduler::StartBlock(RpoNumber rpo) {
void InstructionScheduler::EndBlock(RpoNumber rpo) {
- ScheduleBlock();
+ if (FLAG_turbo_stress_instruction_scheduling) {
+ ScheduleBlock<StressSchedulerQueue>();
+ } else {
+ ScheduleBlock<CriticalPathFirstQueue>();
+ }
sequence()->EndBlock(rpo);
graph_.clear();
last_side_effect_instr_ = nullptr;
@@ -110,14 +160,9 @@ void InstructionScheduler::AddInstruction(Instruction* instr) {
}
-bool InstructionScheduler::CompareNodes(ScheduleGraphNode *node1,
- ScheduleGraphNode *node2) const {
- return node1->total_latency() > node2->total_latency();
-}
-
-
+template <typename QueueType>
void InstructionScheduler::ScheduleBlock() {
- ZoneLinkedList<ScheduleGraphNode*> ready_list(zone());
+ QueueType ready_list(this);
// Compute total latencies so that we can schedule the critical path first.
ComputeTotalLatencies();
@@ -125,43 +170,28 @@ void InstructionScheduler::ScheduleBlock() {
// Add nodes which don't have dependencies to the ready list.
for (auto node : graph_) {
if (!node->HasUnscheduledPredecessor()) {
- ready_list.push_back(node);
+ ready_list.AddNode(node);
}
}
// Go through the ready list and schedule the instructions.
int cycle = 0;
- while (!ready_list.empty()) {
- auto candidate = ready_list.end();
- for (auto iterator = ready_list.begin(); iterator != ready_list.end();
- ++iterator) {
- // Look for the best candidate to schedule.
- // We only consider instructions that have all their operands ready and
- // we try to schedule the critical path first (we look for the instruction
- // with the highest latency on the path to reach the end of the graph).
- if (cycle >= (*iterator)->start_cycle()) {
- if ((candidate == ready_list.end()) ||
- CompareNodes(*iterator, *candidate)) {
- candidate = iterator;
- }
- }
- }
+ while (!ready_list.IsEmpty()) {
+ auto candidate = ready_list.PopBestCandidate(cycle);
- if (candidate != ready_list.end()) {
- sequence()->AddInstruction((*candidate)->instruction());
+ if (candidate != nullptr) {
+ sequence()->AddInstruction(candidate->instruction());
- for (auto successor : (*candidate)->successors()) {
+ for (auto successor : candidate->successors()) {
successor->DropUnscheduledPredecessor();
successor->set_start_cycle(
std::max(successor->start_cycle(),
- cycle + (*candidate)->latency()));
+ cycle + candidate->latency()));
if (!successor->HasUnscheduledPredecessor()) {
- ready_list.push_back(successor);
+ ready_list.AddNode(successor);
}
}
-
- ready_list.erase(candidate);
}
cycle++;
« no previous file with comments | « src/compiler/instruction-scheduler.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698