1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Evan Cheng and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the ScheduleDAG class, which is used as the common
// base class for SelectionDAG-based instruction scheduler.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
#define LLVM_CODEGEN_SCHEDULEDAG_H
#include "llvm/CodeGen/SelectionDAG.h"
namespace llvm {
struct InstrStage;
class MachineConstantPool;
class MachineDebugInfo;
class MachineInstr;
class MRegisterInfo;
class SelectionDAG;
class SSARegMap;
class TargetInstrInfo;
class TargetInstrDescriptor;
class TargetMachine;
/// HazardRecognizer - This determines whether or not an instruction can be
/// issued this cycle, and whether or not a noop needs to be inserted to handle
/// the hazard.
class HazardRecognizer {
public:
virtual ~HazardRecognizer();
enum HazardType {
NoHazard, // This instruction can be emitted at this cycle.
Hazard, // This instruction can't be emitted at this cycle.
NoopHazard, // This instruction can't be emitted, and needs noops.
};
/// getHazardType - Return the hazard type of emitting this node. There are
/// three possible results. Either:
/// * NoHazard: it is legal to issue this instruction on this cycle.
/// * Hazard: issuing this instruction would stall the machine. If some
/// other instruction is available, issue it first.
/// * NoopHazard: issuing this instruction would break the program. If
/// some other instruction can be issued, do so, otherwise issue a noop.
virtual HazardType getHazardType(SDNode *Node) {
return NoHazard;
}
/// EmitInstruction - This callback is invoked when an instruction is
/// emitted, to advance the hazard state.
virtual void EmitInstruction(SDNode *Node) {
}
/// AdvanceCycle - This callback is invoked when no instructions can be
/// issued on this cycle without a hazard. This should increment the
/// internal state of the hazard recognizer so that previously "Hazard"
/// instructions will now not be hazards.
virtual void AdvanceCycle() {
}
/// EmitNoop - This callback is invoked when a noop was added to the
/// instruction stream.
virtual void EmitNoop() {
}
};
class ScheduleDAG {
public:
SelectionDAG &DAG; // DAG of the current basic block
MachineBasicBlock *BB; // Current basic block
const TargetMachine &TM; // Target processor
const TargetInstrInfo *TII; // Target instruction information
const MRegisterInfo *MRI; // Target processor register info
SSARegMap *RegMap; // Virtual/real register map
MachineConstantPool *ConstPool; // Target constant pool
ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
const TargetMachine &tm)
: DAG(dag), BB(bb), TM(tm) {}
virtual ~ScheduleDAG() {}
/// Run - perform scheduling.
///
MachineBasicBlock *Run();
/// isPassiveNode - Return true if the node is a non-scheduled leaf.
///
static bool isPassiveNode(SDNode *Node) {
if (isa<ConstantSDNode>(Node)) return true;
if (isa<RegisterSDNode>(Node)) return true;
if (isa<GlobalAddressSDNode>(Node)) return true;
if (isa<BasicBlockSDNode>(Node)) return true;
if (isa<FrameIndexSDNode>(Node)) return true;
if (isa<ConstantPoolSDNode>(Node)) return true;
if (isa<JumpTableSDNode>(Node)) return true;
if (isa<ExternalSymbolSDNode>(Node)) return true;
return false;
}
/// EmitNode - Generate machine code for an node and needed dependencies.
/// VRBaseMap contains, for each already emitted node, the first virtual
/// register number for the results of the node.
///
void EmitNode(SDNode *Node, std::map<SDNode*, unsigned> &VRBaseMap);
/// EmitNoop - Emit a noop instruction.
///
void EmitNoop();
/// Schedule - Order nodes according to selected style.
///
virtual void Schedule() {}
private:
void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
const TargetInstrDescriptor *II,
std::map<SDNode*, unsigned> &VRBaseMap);
};
ScheduleDAG *createBFS_DAGScheduler(SelectionDAG &DAG, MachineBasicBlock *BB);
/// createSimpleDAGScheduler - This creates a simple two pass instruction
/// scheduler.
ScheduleDAG* createSimpleDAGScheduler(bool NoItins, SelectionDAG &DAG,
MachineBasicBlock *BB);
/// createBURRListDAGScheduler - This creates a bottom up register usage
/// reduction list scheduler.
ScheduleDAG* createBURRListDAGScheduler(SelectionDAG &DAG,
MachineBasicBlock *BB);
/// createTDListDAGScheduler - This creates a top-down list scheduler with
/// the specified hazard recognizer. This takes ownership of the hazard
/// recognizer and deletes it when done.
ScheduleDAG* createTDListDAGScheduler(SelectionDAG &DAG,
MachineBasicBlock *BB,
HazardRecognizer *HR);
}
#endif
|