LLVM: include/llvm/MCA/HardwareUnits/LSUnit.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15#ifndef LLVM_MCA_HARDWAREUNITS_LSUNIT_H

16#define LLVM_MCA_HARDWAREUNITS_LSUNIT_H

17

24

25namespace llvm {

26namespace mca {

27

28

30

31

32

33

34

35

36 unsigned LQSize;

37

38

39

40

41

42

43

44 unsigned SQSize;

45

46 unsigned UsedLQEntries;

47 unsigned UsedSQEntries;

48

49

50

51

52

53

54 const bool NoAlias;

55

56public:

58 unsigned StoreQueueSize, bool AssumeNoAlias);

59

61

62

64

65

67

74

76

82

83

84

85

86

87

89

90

91

92

93

94

95

97

98 bool isSQEmpty() const { return !UsedSQEntries; }

99 bool isLQEmpty() const { return !UsedLQEntries; }

100 bool isSQFull() const { return SQSize && SQSize == UsedSQEntries; }

101 bool isLQFull() const { return LQSize && LQSize == UsedLQEntries; }

102

103

105

106

107

109

110

111

113

115

117

119

120

121

122

123

125

127

129

130#ifndef NDEBUG

131 virtual void dump() const = 0;

132#endif

133};

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237protected:

238

239

240

241

242

243

244

245

246 class MemoryGroup {

247 unsigned NumPredecessors = 0;

248 unsigned NumExecutingPredecessors = 0;

249 unsigned NumExecutedPredecessors = 0;

250

251 unsigned NumInstructions = 0;

252 unsigned NumExecuting = 0;

253 unsigned NumExecuted = 0;

254

256

258

260 InstRef CriticalMemoryInstruction;

261

262 MemoryGroup(const MemoryGroup &) = delete;

263 MemoryGroup &operator=(const MemoryGroup &) = delete;

264

265 public:

268

270 return OrderSucc.size() + DataSucc.size();

271 }

274 return NumExecutingPredecessors;

275 }

277 return NumExecutedPredecessors;

278 }

282

284 return CriticalMemoryInstruction;

285 }

287 return CriticalPredecessor;

288 }

289

290 void addSuccessor(MemoryGroup *Group, bool IsDataDependent) {

291

292

293

295 return;

296

297 Group->NumPredecessors++;

300 Group->onGroupIssued(CriticalMemoryInstruction, IsDataDependent);

301

302 if (IsDataDependent)

303 DataSucc.emplace_back(Group);

304 else

305 OrderSucc.emplace_back(Group);

306 }

307

309 return NumPredecessors >

310 (NumExecutingPredecessors + NumExecutedPredecessors);

311 }

313 return NumExecutingPredecessors &&

314 ((NumExecutedPredecessors + NumExecutingPredecessors) ==

315 NumPredecessors);

316 }

317 bool isReady() const { return NumExecutedPredecessors == NumPredecessors; }

319 return NumExecuting && (NumExecuting == (NumInstructions - NumExecuted));

320 }

321 bool isExecuted() const { return NumInstructions == NumExecuted; }

322

324 assert(isReady() && "Unexpected group-start event!");

325 NumExecutingPredecessors++;

326

327 if (!ShouldUpdateCriticalDep)

328 return;

329

330 unsigned Cycles = IR.getInstruction()->getCyclesLeft();

331 if (CriticalPredecessor.Cycles < Cycles) {

332 CriticalPredecessor.IID = IR.getSourceIndex();

333 CriticalPredecessor.Cycles = Cycles;

334 }

335 }

336

338 assert(isReady() && "Inconsistent state found!");

339 NumExecutingPredecessors--;

340 NumExecutedPredecessors++;

341 }

342

345 ++NumExecuting;

346

347

349 if ((bool)CriticalMemoryInstruction) {

351 *CriticalMemoryInstruction.getInstruction();

353 CriticalMemoryInstruction = IR;

354 } else {

355 CriticalMemoryInstruction = IR;

356 }

357

359 return;

360

361

362 for (MemoryGroup *MG : OrderSucc) {

363 MG->onGroupIssued(CriticalMemoryInstruction, false);

364

365 MG->onGroupExecuted();

366 }

367

368 for (MemoryGroup *MG : DataSucc)

369 MG->onGroupIssued(CriticalMemoryInstruction, true);

370 }

371

374 --NumExecuting;

375 ++NumExecuted;

376

377 if (CriticalMemoryInstruction &&

378 CriticalMemoryInstruction.getSourceIndex() == IR.getSourceIndex()) {

379 CriticalMemoryInstruction.invalidate();

380 }

381

383 return;

384

385

386

387 for (MemoryGroup *MG : DataSucc)

388 MG->onGroupExecuted();

389 }

390

393 ++NumInstructions;

394 }

395

397 if (isWaiting() && CriticalPredecessor.Cycles)

398 CriticalPredecessor.Cycles--;

399 }

400 };

401

404

409

410public:

419

420

421

423

425 unsigned GroupID = IR.getInstruction()->getLSUTokenID();

426 const MemoryGroup &Group = getGroup(GroupID);

428 }

429

431 unsigned GroupID = IR.getInstruction()->getLSUTokenID();

432 const MemoryGroup &Group = getGroup(GroupID);

434 }

435

437 unsigned GroupID = IR.getInstruction()->getLSUTokenID();

438 const MemoryGroup &Group = getGroup(GroupID);

440 }

441

443 unsigned GroupID = IR.getInstruction()->getLSUTokenID();

444 const MemoryGroup &Group = getGroup(GroupID);

446 }

447

449 const MemoryGroup &Group = getGroup(GroupId);

451 }

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466 unsigned dispatch(const InstRef &IR) override;

467

469 unsigned GroupID = IR.getInstruction()->getLSUTokenID();

470 Groups[GroupID]->onInstructionIssued(IR);

471 }

472

473 void onInstructionRetired(const InstRef &IR) override;

474

475 void onInstructionExecuted(const InstRef &IR) override;

476

477 void cycleEvent() override;

478

479#ifndef NDEBUG

480 void dump() const override;

481#endif

482

483private:

484 bool isValidGroupID(unsigned Index) const {

485 return Index && Groups.contains(Index);

486 }

487

488 const MemoryGroup &getGroup(unsigned Index) const {

489 assert(isValidGroupID(Index) && "Group doesn't exist!");

490 return *Groups.find(Index)->second;

491 }

492

493 MemoryGroup &getGroup(unsigned Index) {

494 assert(isValidGroupID(Index) && "Group doesn't exist!");

495 return *Groups.find(Index)->second;

496 }

497

498 unsigned createMemoryGroup() {

499 Groups.insert(std::make_pair(NextGroupID, std::make_unique()));

500 return NextGroupID++;

501 }

502};

503

504}

505}

506

507#endif

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

This file defines the DenseMap class.

This file defines a base class for describing a simulated hardware unit.

Legalize the Machine IR a function s Machine IR

This file defines abstractions used by the Pipeline to model register reads, register writes and inst...

This file defines the SmallVector class.

static const X86InstrFMA3Group Groups[]

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

An InstRef contains both a SourceMgr index and Instruction pair.

An instruction propagated through the simulated instruction pipeline.

int getCyclesLeft() const

virtual void dump() const =0

virtual unsigned dispatch(const InstRef &IR)=0

Allocates LS resources for instruction IR.

bool isLQFull() const

Definition LSUnit.h:101

unsigned getUsedSQEntries() const

Definition LSUnit.h:69

void acquireSQSlot()

Definition LSUnit.h:71

virtual bool isReady(const InstRef &IR) const =0

Check if a peviously dispatched instruction IR is now ready for execution.

void releaseLQSlot()

Definition LSUnit.h:72

virtual Status isAvailable(const InstRef &IR) const =0

This method checks the availability of the load/store buffers.

virtual void onInstructionRetired(const InstRef &IR)=0

virtual void onInstructionExecuted(const InstRef &IR)=0

virtual void cycleEvent()=0

unsigned getUsedLQEntries() const

Definition LSUnit.h:68

bool isSQEmpty() const

Definition LSUnit.h:98

bool assumeNoAlias() const

Definition LSUnit.h:75

unsigned getLoadQueueSize() const

Returns the total number of entries in the load queue.

Definition LSUnit.h:63

Status

Definition LSUnit.h:77

@ LSU_LQUEUE_FULL

Definition LSUnit.h:79

@ LSU_AVAILABLE

Definition LSUnit.h:78

@ LSU_SQUEUE_FULL

Definition LSUnit.h:80

virtual bool isWaiting(const InstRef &IR) const =0

Check if instruction IR is still waiting on memory operations, and the wait time is still unknown.

bool isSQFull() const

Definition LSUnit.h:100

virtual const CriticalDependency getCriticalPredecessor(unsigned GroupId)=0

virtual bool isPending(const InstRef &IR) const =0

Check if instruction IR only depends on memory instructions that are currently executing.

virtual bool hasDependentUsers(const InstRef &IR) const =0

bool isLQEmpty() const

Definition LSUnit.h:99

LSUnitBase(const MCSchedModel &SM, unsigned LoadQueueSize, unsigned StoreQueueSize, bool AssumeNoAlias)

unsigned getStoreQueueSize() const

Returns the total number of entries in the store queue.

Definition LSUnit.h:66

void acquireLQSlot()

Definition LSUnit.h:70

virtual void onInstructionIssued(const InstRef &IR)=0

void releaseSQSlot()

Definition LSUnit.h:73

A node of a memory dependency graph.

Definition LSUnit.h:246

unsigned getNumInstructions() const

Definition LSUnit.h:279

unsigned getNumExecutingPredecessors() const

Definition LSUnit.h:273

void addInstruction()

Definition LSUnit.h:391

unsigned getNumExecuting() const

Definition LSUnit.h:280

void onGroupIssued(const InstRef &IR, bool ShouldUpdateCriticalDep)

Definition LSUnit.h:323

unsigned getNumPredecessors() const

Definition LSUnit.h:272

bool isExecuted() const

Definition LSUnit.h:321

void onInstructionExecuted(const InstRef &IR)

Definition LSUnit.h:372

bool isExecuting() const

Definition LSUnit.h:318

const CriticalDependency & getCriticalPredecessor() const

Definition LSUnit.h:286

bool isPending() const

Definition LSUnit.h:312

void addSuccessor(MemoryGroup *Group, bool IsDataDependent)

Definition LSUnit.h:290

unsigned getNumExecuted() const

Definition LSUnit.h:281

bool isWaiting() const

Definition LSUnit.h:308

unsigned getNumExecutedPredecessors() const

Definition LSUnit.h:276

void onGroupExecuted()

Definition LSUnit.h:337

bool isReady() const

Definition LSUnit.h:317

MemoryGroup(MemoryGroup &&)=default

size_t getNumSuccessors() const

Definition LSUnit.h:269

void onInstructionIssued(const InstRef &IR)

Definition LSUnit.h:343

void cycleEvent()

Definition LSUnit.h:396

const InstRef & getCriticalMemoryInstruction() const

Definition LSUnit.h:283

unsigned CurrentLoadGroupID

Definition LSUnit.h:405

bool isPending(const InstRef &IR) const override

Check if instruction IR only depends on memory instructions that are currently executing.

Definition LSUnit.h:430

void onInstructionIssued(const InstRef &IR) override

Definition LSUnit.h:468

bool isReady(const InstRef &IR) const override

Check if a peviously dispatched instruction IR is now ready for execution.

Definition LSUnit.h:424

DenseMap< unsigned, std::unique_ptr< MemoryGroup > > Groups

Used to map group identifiers to MemoryGroups.

Definition LSUnit.h:402

unsigned CurrentStoreGroupID

Definition LSUnit.h:407

LSUnit(const MCSchedModel &SM, unsigned LQ, unsigned SQ, bool AssumeNoAlias)

Definition LSUnit.h:415

unsigned CurrentLoadBarrierGroupID

Definition LSUnit.h:406

unsigned NextGroupID

Definition LSUnit.h:403

bool isWaiting(const InstRef &IR) const override

Check if instruction IR is still waiting on memory operations, and the wait time is still unknown.

Definition LSUnit.h:436

unsigned CurrentStoreBarrierGroupID

Definition LSUnit.h:408

LSUnit(const MCSchedModel &SM, unsigned LQ, unsigned SQ)

Definition LSUnit.h:413

const CriticalDependency getCriticalPredecessor(unsigned GroupId) override

Definition LSUnit.h:448

bool hasDependentUsers(const InstRef &IR) const override

Definition LSUnit.h:442

LSUnit(const MCSchedModel &SM)

Definition LSUnit.h:411

This is an optimization pass for GlobalISel generic memory operations.

void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)

Machine model for scheduling, bundling, and heuristics.

A critical data dependency descriptor.