blob: 269c271ae5996aa580f4d50608c5ca6523a4f5ea [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_SCHEDULER_H_
6#define V8_COMPILER_SCHEDULER_H_
7
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/base/flags.h"
9#include "src/compiler/node.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/compiler/opcodes.h"
11#include "src/compiler/schedule.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040012#include "src/compiler/zone-pool.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000013#include "src/zone-containers.h"
14
15namespace v8 {
16namespace internal {
17namespace compiler {
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019// Forward declarations.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040020class CFGBuilder;
21class ControlEquivalence;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022class Graph;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040023class SpecialRPONumberer;
24
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026// Computes a schedule from a graph, placing nodes into basic blocks and
27// ordering the basic blocks in the special RPO order.
28class Scheduler {
29 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030 // Flags that control the mode of operation.
31 enum Flag { kNoFlags = 0u, kSplitNodes = 1u << 1 };
32 typedef base::Flags<Flag> Flags;
33
Emily Bernierd0a1eb72015-03-24 16:35:39 -040034 // The complete scheduling algorithm. Creates a new schedule and places all
35 // nodes from the graph into it.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036 static Schedule* ComputeSchedule(Zone* zone, Graph* graph, Flags flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037
38 // Compute the RPO of blocks in an existing schedule.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040039 static BasicBlockVector* ComputeSpecialRPO(Zone* zone, Schedule* schedule);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040
41 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042 // Placement of a node changes during scheduling. The placement state
43 // transitions over time while the scheduler is choosing a position:
44 //
45 // +---------------------+-----+----> kFixed
46 // / / /
47 // kUnknown ----+------> kCoupled ----+ /
48 // \ /
49 // +----> kSchedulable ----+--------> kScheduled
50 //
51 // 1) GetPlacement(): kUnknown -> kCoupled|kSchedulable|kFixed
52 // 2) UpdatePlacement(): kCoupled|kSchedulable -> kFixed|kScheduled
53 enum Placement { kUnknown, kSchedulable, kFixed, kCoupled, kScheduled };
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054
55 // Per-node data tracked during scheduling.
56 struct SchedulerData {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040057 BasicBlock* minimum_block_; // Minimum legal RPO placement.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058 int unscheduled_count_; // Number of unscheduled uses of this node.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059 Placement placement_; // Whether the node is fixed, schedulable,
60 // coupled to another node, or not yet known.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 };
62
63 Zone* zone_;
64 Graph* graph_;
65 Schedule* schedule_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000066 Flags flags_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040067 NodeVectorVector scheduled_nodes_; // Per-block list of nodes in reverse.
68 NodeVector schedule_root_nodes_; // Fixed root nodes seed the worklist.
69 ZoneQueue<Node*> schedule_queue_; // Worklist of schedulable nodes.
70 ZoneVector<SchedulerData> node_data_; // Per-node data for all nodes.
71 CFGBuilder* control_flow_builder_; // Builds basic blocks for controls.
72 SpecialRPONumberer* special_rpo_; // Special RPO numbering of blocks.
73 ControlEquivalence* equivalence_; // Control dependence equivalence.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076
Emily Bernierd0a1eb72015-03-24 16:35:39 -040077 inline SchedulerData DefaultSchedulerData();
78 inline SchedulerData* GetData(Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079
80 Placement GetPlacement(Node* node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040081 void UpdatePlacement(Node* node, Placement placement);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082
Emily Bernierd0a1eb72015-03-24 16:35:39 -040083 inline bool IsCoupledControlEdge(Node* node, int index);
84 void IncrementUnscheduledUseCount(Node* node, int index, Node* from);
85 void DecrementUnscheduledUseCount(Node* node, int index, Node* from);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086
Emily Bernierd0a1eb72015-03-24 16:35:39 -040087 void PropagateImmediateDominators(BasicBlock* block);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088
Emily Bernierd0a1eb72015-03-24 16:35:39 -040089 // Phase 1: Build control-flow graph.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090 friend class CFGBuilder;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040091 void BuildCFG();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093 // Phase 2: Compute special RPO and dominator tree.
94 friend class SpecialRPONumberer;
95 void ComputeSpecialRPONumbering();
96 void GenerateImmediateDominatorTree();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097
Emily Bernierd0a1eb72015-03-24 16:35:39 -040098 // Phase 3: Prepare use counts for nodes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099 friend class PrepareUsesVisitor;
100 void PrepareUses();
101
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400102 // Phase 4: Schedule nodes early.
103 friend class ScheduleEarlyNodeVisitor;
104 void ScheduleEarly();
105
106 // Phase 5: Schedule nodes late.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107 friend class ScheduleLateNodeVisitor;
108 void ScheduleLate();
109
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110 // Phase 6: Seal the final schedule.
111 void SealFinalSchedule();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113 void FuseFloatingControl(BasicBlock* block, Node* node);
114 void MovePlannedNodes(BasicBlock* from, BasicBlock* to);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400116
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117
118DEFINE_OPERATORS_FOR_FLAGS(Scheduler::Flags)
119
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400120} // namespace compiler
121} // namespace internal
122} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123
124#endif // V8_COMPILER_SCHEDULER_H_