blob: 9da0b6daa49d93d31c53d8d6a0a43a0762c2a46a [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
8#include "src/v8.h"
9
10#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
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019class CFGBuilder;
20class ControlEquivalence;
21class SpecialRPONumberer;
22
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023// Computes a schedule from a graph, placing nodes into basic blocks and
24// ordering the basic blocks in the special RPO order.
25class Scheduler {
26 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040027 // The complete scheduling algorithm. Creates a new schedule and places all
28 // nodes from the graph into it.
29 static Schedule* ComputeSchedule(Zone* zone, Graph* graph);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030
31 // Compute the RPO of blocks in an existing schedule.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040032 static BasicBlockVector* ComputeSpecialRPO(Zone* zone, Schedule* schedule);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033
34 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040035 // Placement of a node changes during scheduling. The placement state
36 // transitions over time while the scheduler is choosing a position:
37 //
38 // +---------------------+-----+----> kFixed
39 // / / /
40 // kUnknown ----+------> kCoupled ----+ /
41 // \ /
42 // +----> kSchedulable ----+--------> kScheduled
43 //
44 // 1) GetPlacement(): kUnknown -> kCoupled|kSchedulable|kFixed
45 // 2) UpdatePlacement(): kCoupled|kSchedulable -> kFixed|kScheduled
46 enum Placement { kUnknown, kSchedulable, kFixed, kCoupled, kScheduled };
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047
48 // Per-node data tracked during scheduling.
49 struct SchedulerData {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040050 BasicBlock* minimum_block_; // Minimum legal RPO placement.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051 int unscheduled_count_; // Number of unscheduled uses of this node.
Emily Bernierd0a1eb72015-03-24 16:35:39 -040052 Placement placement_; // Whether the node is fixed, schedulable,
53 // coupled to another node, or not yet known.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054 };
55
56 Zone* zone_;
57 Graph* graph_;
58 Schedule* schedule_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059 NodeVectorVector scheduled_nodes_; // Per-block list of nodes in reverse.
60 NodeVector schedule_root_nodes_; // Fixed root nodes seed the worklist.
61 ZoneQueue<Node*> schedule_queue_; // Worklist of schedulable nodes.
62 ZoneVector<SchedulerData> node_data_; // Per-node data for all nodes.
63 CFGBuilder* control_flow_builder_; // Builds basic blocks for controls.
64 SpecialRPONumberer* special_rpo_; // Special RPO numbering of blocks.
65 ControlEquivalence* equivalence_; // Control dependence equivalence.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066
67 Scheduler(Zone* zone, Graph* graph, Schedule* schedule);
68
Emily Bernierd0a1eb72015-03-24 16:35:39 -040069 inline SchedulerData DefaultSchedulerData();
70 inline SchedulerData* GetData(Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071
72 Placement GetPlacement(Node* node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040073 void UpdatePlacement(Node* node, Placement placement);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074
Emily Bernierd0a1eb72015-03-24 16:35:39 -040075 inline bool IsCoupledControlEdge(Node* node, int index);
76 void IncrementUnscheduledUseCount(Node* node, int index, Node* from);
77 void DecrementUnscheduledUseCount(Node* node, int index, Node* from);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079 BasicBlock* GetCommonDominator(BasicBlock* b1, BasicBlock* b2);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040080 void PropagateImmediateDominators(BasicBlock* block);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081
Emily Bernierd0a1eb72015-03-24 16:35:39 -040082 // Phase 1: Build control-flow graph.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083 friend class CFGBuilder;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040084 void BuildCFG();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000085
Emily Bernierd0a1eb72015-03-24 16:35:39 -040086 // Phase 2: Compute special RPO and dominator tree.
87 friend class SpecialRPONumberer;
88 void ComputeSpecialRPONumbering();
89 void GenerateImmediateDominatorTree();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090
Emily Bernierd0a1eb72015-03-24 16:35:39 -040091 // Phase 3: Prepare use counts for nodes.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092 friend class PrepareUsesVisitor;
93 void PrepareUses();
94
Emily Bernierd0a1eb72015-03-24 16:35:39 -040095 // Phase 4: Schedule nodes early.
96 friend class ScheduleEarlyNodeVisitor;
97 void ScheduleEarly();
98
99 // Phase 5: Schedule nodes late.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100 friend class ScheduleLateNodeVisitor;
101 void ScheduleLate();
102
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103 // Phase 6: Seal the final schedule.
104 void SealFinalSchedule();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106 void FuseFloatingControl(BasicBlock* block, Node* node);
107 void MovePlannedNodes(BasicBlock* from, BasicBlock* to);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108};
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400109
110} // namespace compiler
111} // namespace internal
112} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113
114#endif // V8_COMPILER_SCHEDULER_H_