LLVM: lib/CodeGen/SelectionDAG/ScheduleDAGVLIW.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

31using namespace llvm;

32

33#define DEBUG_TYPE "pre-RA-sched"

34

35STATISTIC(NumNoops , "Number of noops inserted");

36STATISTIC(NumStalls, "Number of pipeline stalls");

37

41

42namespace {

43

44

45

46

48private:

49

50

52

53

54

55

56

57 std::vector<SUnit*> PendingQueue;

58

59

61

62public:

66 HazardRec = STI.getInstrInfo()->CreateTargetHazardRecognizer(&STI, this);

67 }

68

69 ~ScheduleDAGVLIW() override {

70 delete HazardRec;

71 delete AvailableQueue;

72 }

73

74 void Schedule() override;

75

76private:

77 void releaseSucc(SUnit *SU, const SDep &D);

78 void releaseSuccessors(SUnit *SU);

79 void scheduleNodeTopDown(SUnit *SU, unsigned CurCycle);

80 void listScheduleTopDown();

81};

82}

83

84

85void ScheduleDAGVLIW::Schedule() {

87 << " '" << BB->getName() << "' **********\n");

88

89

90 BuildSchedGraph();

91

92 AvailableQueue->initNodes(SUnits);

93

94 listScheduleTopDown();

95

97}

98

99

100

101

102

103

104

105void ScheduleDAGVLIW::releaseSucc(SUnit *SU, const SDep &D) {

106 SUnit *SuccSU = D.getSUnit();

107

108#ifndef NDEBUG

110 dbgs() << "*** Scheduling failed! ***\n";

111 dumpNode(*SuccSU);

112 dbgs() << " has been released too many times!\n";

114 }

115#endif

116 assert(D.isWeak() && "unexpected artificial DAG edge");

117

119

121

122

123

124 if (SuccSU->NumPredsLeft == 0 && SuccSU != &ExitSU) {

125 PendingQueue.push_back(SuccSU);

126 }

127}

128

129void ScheduleDAGVLIW::releaseSuccessors(SUnit *SU) {

130

131 for (SDep &Succ : SU->Succs) {

133 "The list-td scheduler doesn't yet support physreg dependencies!");

134

135 releaseSucc(SU, Succ);

136 }

137}

138

139

140

141

142void ScheduleDAGVLIW::scheduleNodeTopDown(SUnit *SU, unsigned CurCycle) {

143 LLVM_DEBUG(dbgs() << "*** Scheduling [" << CurCycle << "]: ");

145

147 assert(CurCycle >= SU->getDepth() && "Node scheduled above its depth!");

149

150 releaseSuccessors(SU);

153}

154

155

156

157void ScheduleDAGVLIW::listScheduleTopDown() {

158 unsigned CurCycle = 0;

159

160

161 releaseSuccessors(&EntrySU);

162

163

164 for (SUnit &SU : SUnits) {

165

166 if (SU.Preds.empty()) {

167 AvailableQueue->push(&SU);

169 }

170 }

171

172

173

174 std::vector<SUnit*> NotReady;

175 Sequence.reserve(SUnits.size());

176 while (!AvailableQueue->empty() || !PendingQueue.empty()) {

177

178

179 for (unsigned i = 0, e = PendingQueue.size(); i != e; ++i) {

180 if (PendingQueue[i]->getDepth() == CurCycle) {

181 AvailableQueue->push(PendingQueue[i]);

182 PendingQueue[i]->isAvailable = true;

183 PendingQueue[i] = PendingQueue.back();

184 PendingQueue.pop_back();

185 --i; --e;

186 }

187 else {

188 assert(PendingQueue[i]->getDepth() > CurCycle && "Negative latency?");

189 }

190 }

191

192

193

194 if (AvailableQueue->empty()) {

195

197 ++CurCycle;

198 continue;

199 }

200

201 SUnit *FoundSUnit = nullptr;

202

203 bool HasNoopHazards = false;

204 while (!AvailableQueue->empty()) {

205 SUnit *CurSUnit = AvailableQueue->pop();

206

208 HazardRec->getHazardType(CurSUnit, 0);

210 FoundSUnit = CurSUnit;

211 break;

212 }

213

214

216

217 NotReady.push_back(CurSUnit);

218 }

219

220

221 if (!NotReady.empty()) {

222 AvailableQueue->push_all(NotReady);

223 NotReady.clear();

224 }

225

226

227 if (FoundSUnit) {

228 scheduleNodeTopDown(FoundSUnit, CurCycle);

230

231

232

233 if (FoundSUnit->Latency)

234 ++CurCycle;

235 } else if (!HasNoopHazards) {

236

237

238 LLVM_DEBUG(dbgs() << "*** Advancing cycle, no work to do\n");

240 ++NumStalls;

241 ++CurCycle;

242 } else {

243

244

245

248 Sequence.push_back(nullptr);

249 ++NumNoops;

250 ++CurCycle;

251 }

252 }

253

254#ifndef NDEBUG

255 VerifyScheduledSequence(false);

256#endif

257}

258

259

260

261

262

263

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static RegisterScheduler VLIWScheduler("vliw-td", "VLIW scheduler", createVLIWDAGScheduler)

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

bool isAssignedRegDep() const

Tests if this is a Data dependence that is associated with a register.

unsigned short Latency

Node latency.

unsigned getDepth() const

Returns the depth of this node, which is the length of the maximum path up to any node which has no p...

bool isScheduled

True once scheduled.

bool isAvailable

True once available.

SmallVector< SDep, 4 > Succs

All sunit successors.

SmallVector< SDep, 4 > Preds

All sunit predecessors.

LLVM_ABI void setDepthToAtLeast(unsigned NewDepth)

If NewDepth is greater than this node's depth value, sets it to be the new depth value.

ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.

HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...

virtual void EmitInstruction(SUnit *)

EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...

virtual void EmitNoop()

EmitNoop - This callback is invoked when a noop was added to the instruction stream.

virtual void AdvanceCycle()

AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...

virtual HazardType getHazardType(SUnit *, int Stalls=0)

getHazardType - Return the hazard type of emitting this node.

This interface is used to plug different priorities computation algorithms into the list scheduler.

virtual void releaseState()=0

virtual void scheduledNode(SUnit *)

As each node is scheduled, this method is invoked.

virtual void initNodes(std::vector< SUnit > &SUnits)=0

virtual bool empty() const =0

void push_all(const std::vector< SUnit * > &Nodes)

virtual void push(SUnit *U)=0

SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...

TargetSubtargetInfo - Generic base class for all target subtargets.

virtual const TargetInstrInfo * getInstrInfo() const

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

Sequence

A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

CodeGenOptLevel

Code generation optimization level.

LLVM_ABI ScheduleDAGSDNodes * createVLIWDAGScheduler(SelectionDAGISel *IS, CodeGenOptLevel OptLevel)

createVLIWDAGScheduler - Scheduler for VLIW targets.

Definition ScheduleDAGVLIW.cpp:264

LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.