LLVM: lib/MCA/HardwareUnits/RegisterFile.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

19

20#define DEBUG_TYPE "llvm-mca"

21

22namespace llvm {

23namespace mca {

24

25const unsigned WriteRef::INVALID_IID = std::numeric_limits::max();

26

31

33 : IID(SourceIndex), WriteBackCycle(), WriteResID(), RegisterID(),

34 Write(WS) {}

35

37 assert(Write && Write->isExecuted() && "Cannot commit before write back!");

38 RegisterID = Write->getRegisterID();

39 WriteResID = Write->getWriteResourceID();

40 Write = nullptr;

41}

42

44 assert(Write && Write->isExecuted() && "Not executed!");

45 WriteBackCycle = Cycle;

46}

47

49 return isValid() && (!Write || Write->isExecuted());

50}

51

56

58 if (Write)

59 return Write->getWriteResourceID();

60 return WriteResID;

61}

62

64 if (Write)

65 return Write->getRegisterID();

66 return RegisterID;

67}

68

70 unsigned NumRegs)

71 : MRI(mri),

72 RegisterMappings(mri.getNumRegs(), {WriteRef(), RegisterRenamingInfo()}),

73 ZeroRegisters(mri.getNumRegs(), false), CurrentCycle() {

75}

76

77void RegisterFile::initialize(const MCSchedModel &SM, unsigned NumRegs) {

78

79

80

81

84 return;

85

86

87

88

90

91

92 for (unsigned I = 1, E = Info.NumRegisterFiles; I < E; ++I) {

94 assert(RF.NumPhysRegs && "Invalid PRF with zero physical registers!");

95

96

97

102 }

103}

104

106 for (RegisterMappingTracker &RMT : RegisterFiles)

107 RMT.NumMoveEliminated = 0;

108}

109

111 assert(IS && IS->isExecuted() && "Unexpected internal state found!");

113 if (WS.isEliminated())

114 return;

115

116 MCPhysReg RegID = WS.getRegisterID();

117

118

119

120 if (!RegID)

121 continue;

122

124 "The number of cycles should be known at this point!");

125 assert(WS.getCyclesLeft() <= 0 && "Invalid cycles left for this write!");

126

127 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs;

128 if (RenameAs && RenameAs != RegID)

129 RegID = RenameAs;

130

131 WriteRef &WR = RegisterMappings[RegID].first;

134

135 for (MCPhysReg I : MRI.subregs(RegID)) {

136 WriteRef &OtherWR = RegisterMappings[I].first;

139 }

140

141 if (!WS.clearsSuperRegisters())

142 continue;

143

144 for (MCPhysReg I : MRI.superregs(RegID)) {

145 WriteRef &OtherWR = RegisterMappings[I].first;

148 }

149 }

150}

151

154

155

156

157

158

159 unsigned RegisterFileIndex = RegisterFiles.size();

162

163

164

165

166

167

168

169 if (Entries.empty())

170 return;

171

172

176 RegisterRenamingInfo &Entry = RegisterMappings[Reg].second;

177 IndexPlusCostPairTy &IPC = Entry.IndexPlusCost;

178 if (IPC.first && IPC.first != RegisterFileIndex) {

179

180

181

182 errs() << "warning: register " << MRI.getName(Reg)

183 << " defined in multiple register files.";

184 }

185 IPC = std::make_pair(RegisterFileIndex, RCE.Cost);

186 Entry.RenameAs = Reg;

187 Entry.AllowMoveElimination = RCE.AllowMoveElimination;

188

189

191 RegisterRenamingInfo &OtherEntry = RegisterMappings[I].second;

192 if (!OtherEntry.IndexPlusCost.first &&

193 (!OtherEntry.RenameAs ||

194 MRI.isSuperRegister(I, OtherEntry.RenameAs))) {

195 OtherEntry.IndexPlusCost = IPC;

196 OtherEntry.RenameAs = Reg;

197 }

198 }

199 }

200 }

201}

202

203void RegisterFile::allocatePhysRegs(const RegisterRenamingInfo &Entry,

205 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;

206 unsigned Cost = Entry.IndexPlusCost.second;

207 if (RegisterFileIndex) {

208 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];

209 RMT.NumUsedPhysRegs += Cost;

210 UsedPhysRegs[RegisterFileIndex] += Cost;

211 }

212

213

214 RegisterFiles[0].NumUsedPhysRegs += Cost;

215 UsedPhysRegs[0] += Cost;

216}

217

218void RegisterFile::freePhysRegs(const RegisterRenamingInfo &Entry,

220 unsigned RegisterFileIndex = Entry.IndexPlusCost.first;

221 unsigned Cost = Entry.IndexPlusCost.second;

222 if (RegisterFileIndex) {

223 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];

224 RMT.NumUsedPhysRegs -= Cost;

225 FreedPhysRegs[RegisterFileIndex] += Cost;

226 }

227

228

229 RegisterFiles[0].NumUsedPhysRegs -= Cost;

230 FreedPhysRegs[0] += Cost;

231}

232

237

238

239

240 if (!RegID)

241 return;

242

244 dbgs() << "[PRF] addRegisterWrite [ " << Write.getSourceIndex() << ", "

245 << MRI.getName(RegID) << "]\n";

246 });

247

248

249

250

251

252

253

254

255

256

257

258

259

260

263 bool ShouldAllocatePhysRegs = !IsWriteZero && !IsEliminated;

264 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;

265 WS.setPRF(RRI.IndexPlusCost.first);

266

267 if (RRI.RenameAs && RRI.RenameAs != RegID) {

268 RegID = RRI.RenameAs;

269 WriteRef &OtherWrite = RegisterMappings[RegID].first;

270

272

273

274

275 ShouldAllocatePhysRegs = false;

276

278 if (OtherWS && (OtherWrite.getSourceIndex() != Write.getSourceIndex())) {

279

280 assert(!IsEliminated && "Unexpected partial update!");

282 }

283 }

284 }

285

286

289 ZeroRegisters.setBitVal(ZeroRegisterID, IsWriteZero);

292 ZeroRegisters.setBitVal(I, IsWriteZero);

293

294

295

296 if (!IsEliminated) {

297

298

299 const WriteRef &OtherWrite = RegisterMappings[RegID].first;

303

304 if (ShouldAllocatePhysRegs)

305 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs);

306 return;

307 }

308 }

309

310

311 RegisterMappings[RegID].first = Write;

312 RegisterMappings[RegID].second.AliasRegID = 0U;

315 RegisterMappings[I].first = Write;

316 RegisterMappings[I].second.AliasRegID = 0U;

317 }

318

319

320

321

322 if (ShouldAllocatePhysRegs)

323 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs);

324 }

325

327 return;

328

329 for (MCPhysReg I : MRI.superregs(RegID)) {

330 if (!IsEliminated) {

331 RegisterMappings[I].first = Write;

332 RegisterMappings[I].second.AliasRegID = 0U;

333 }

334

335 ZeroRegisters.setBitVal(I, IsWriteZero);

336 }

337}

338

341

342

344 return;

345

347

348

349

350 if (!RegID)

351 return;

352

354 "Invalidating a write of unknown cycles!");

355 assert(WS.getCyclesLeft() <= 0 && "Invalid cycles left for this write!");

356

357 bool ShouldFreePhysRegs = !WS.isWriteZero();

358 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs;

359 if (RenameAs && RenameAs != RegID) {

360 RegID = RenameAs;

361

363

364 ShouldFreePhysRegs = false;

365 }

366 }

367

368 if (ShouldFreePhysRegs)

369 freePhysRegs(RegisterMappings[RegID].second, FreedPhysRegs);

370

371 WriteRef &WR = RegisterMappings[RegID].first;

374

375 for (MCPhysReg I : MRI.subregs(RegID)) {

376 WriteRef &OtherWR = RegisterMappings[I].first;

379 }

380

382 return;

383

384 for (MCPhysReg I : MRI.superregs(RegID)) {

385 WriteRef &OtherWR = RegisterMappings[I].first;

388 }

389}

390

392 unsigned RegisterFileIndex) const {

393 const RegisterMapping &RMFrom = RegisterMappings[RS.getRegisterID()];

394 const RegisterMapping &RMTo = RegisterMappings[WS.getRegisterID()];

395 const RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];

396

397

398 const RegisterRenamingInfo &RRIFrom = RMFrom.second;

399 if (RRIFrom.IndexPlusCost.first != RegisterFileIndex)

400 return false;

401

402 const RegisterRenamingInfo &RRITo = RMTo.second;

403 if (RRITo.IndexPlusCost.first != RegisterFileIndex)

404 return false;

405

406

407

408 if (!RegisterMappings[RRITo.RenameAs].second.AllowMoveElimination)

409 return false;

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425 if (RRITo.RenameAs && RRITo.RenameAs != WS.getRegisterID())

427 return false;

428

429 bool IsZeroMove = ZeroRegisters[RS.getRegisterID()];

430 return (!RMT.AllowZeroMoveEliminationOnly || IsZeroMove);

431}

432

435 if (Writes.size() != Reads.size())

436 return false;

437

438

439

440

441

442 if (Writes.empty() || Writes.size() > 2)

443 return false;

444

445

446 const RegisterRenamingInfo &RRInfo =

447 RegisterMappings[Writes[0].getRegisterID()].second;

448 unsigned RegisterFileIndex = RRInfo.IndexPlusCost.first;

449 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];

450

451

452 if (RMT.MaxMoveEliminatedPerCycle &&

453 (RMT.NumMoveEliminated + Writes.size()) > RMT.MaxMoveEliminatedPerCycle)

454 return false;

455

456 for (size_t I = 0, E = Writes.size(); I < E; ++I) {

460 return false;

461 }

462

463 for (size_t I = 0, E = Writes.size(); I < E; ++I) {

466

467 const RegisterMapping &RMFrom = RegisterMappings[RS.getRegisterID()];

468 const RegisterMapping &RMTo = RegisterMappings[WS.getRegisterID()];

469 const RegisterRenamingInfo &RRIFrom = RMFrom.second;

470 const RegisterRenamingInfo &RRITo = RMTo.second;

471

472

474 RRIFrom.RenameAs ? RRIFrom.RenameAs : RS.getRegisterID();

476

477 const RegisterRenamingInfo &RMAlias = RegisterMappings[AliasedReg].second;

478 if (RMAlias.AliasRegID)

479 AliasedReg = RMAlias.AliasRegID;

480

481 RegisterMappings[AliasReg].second.AliasRegID = AliasedReg;

484 RegisterMappings[I].second.AliasRegID = AliasedReg;

485

486 if (ZeroRegisters[RS.getRegisterID()]) {

488 RS.setReadZero();

489 }

490

492 RMT.NumMoveEliminated++;

493 }

494

495 return true;

496}

497

500 assert((!Write || Write->getCyclesLeft() <= 0) &&

501 "Inconsistent state found!");

502 return WriteBackCycle;

503}

504

509

517 MCPhysReg RegID = RS.getRegisterID();

518 assert(RegID && RegID < RegisterMappings.size());

519 LLVM_DEBUG(dbgs() << "[PRF] collecting writes for register "

520 << MRI.getName(RegID) << '\n');

521

522

523 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;

524 if (RRI.AliasRegID)

525 RegID = RRI.AliasRegID;

526

527 const WriteRef &WR = RegisterMappings[RegID].first;

533 if (ReadAdvance < 0) {

535 if (Elapsed < static_cast<unsigned>(-ReadAdvance))

537 }

538 }

539

540

541 for (MCPhysReg I : MRI.subregs(RegID)) {

542 const WriteRef &WR = RegisterMappings[I].first;

548 if (ReadAdvance < 0) {

550 if (Elapsed < static_cast<unsigned>(-ReadAdvance))

552 }

553 }

554 }

555

556

557 if (Writes.size() > 1) {

560 });

562 Writes.resize(std::distance(Writes.begin(), It));

563 }

564

566 for (const WriteRef &WR : Writes) {

568 dbgs() << "[PRF] Found a dependent use of Register "

569 << MRI.getName(WS.getRegisterID()) << " (defined by instruction #"

571 }

572 });

573}

574

581

585

587 for (const WriteRef &WR : Writes) {

588 const WriteState *WS = WR.getWriteState();

591

594 continue;

595

596 Hazard.RegisterID = WR.getRegisterID();

598 continue;

599 }

600

601 int CyclesLeft = WS->getCyclesLeft() - ReadAdvance;

602 if (CyclesLeft > 0) {

603 if (Hazard.CyclesLeft < CyclesLeft) {

604 Hazard.RegisterID = WR.getRegisterID();

606 }

607 }

608 }

610

611 for (const WriteRef &WR : CommittedWrites) {

612 unsigned WriteResID = WR.getWriteResourceID();

615 int CyclesLeft = NegReadAdvance - Elapsed;

616 assert(CyclesLeft > 0 && "Write should not be in the CommottedWrites set!");

617 if (Hazard.CyclesLeft < CyclesLeft) {

618 Hazard.RegisterID = WR.getRegisterID();

620 }

621 }

622

623 return Hazard;

624}

625

628 MCPhysReg RegID = RS.getRegisterID();

629 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;

630 RS.setPRF(RRI.IndexPlusCost.first);

631 if (RS.isIndependentFromDef())

632 return;

633

634 if (ZeroRegisters[RS.getRegisterID()])

635 RS.setReadZero();

636

639 collectWrites(STI, RS, DependentWrites, CompletedWrites);

640 RS.setDependentWrites(DependentWrites.size() + CompletedWrites.size());

641

642

643

644

648 for (WriteRef &WR : DependentWrites) {

649 unsigned WriteResID = WR.getWriteResourceID();

650 WriteState &WS = *WR.getWriteState();

652 WS.addUser(WR.getSourceIndex(), &RS, ReadAdvance);

653 }

654

655 for (WriteRef &WR : CompletedWrites) {

656 unsigned WriteResID = WR.getWriteResourceID();

657 assert(WR.hasKnownWriteBackCycle() && "Invalid write!");

659 unsigned ReadAdvance = static_cast<unsigned>(

662 assert(Elapsed < ReadAdvance && "Should not have been added to the set!");

663 RS.writeStartEvent(WR.getSourceIndex(), WR.getRegisterID(),

664 ReadAdvance - Elapsed);

665 }

666}

667

670

671

672 for (const MCPhysReg RegID : Regs) {

673 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second;

674 const IndexPlusCostPairTy &Entry = RRI.IndexPlusCost;

675 if (Entry.first)

676 NumPhysRegs[Entry.first] += Entry.second;

677 NumPhysRegs[0] += Entry.second;

678 }

679

680 unsigned Response = 0;

682 unsigned NumRegs = NumPhysRegs[I];

683 if (!NumRegs)

684 continue;

685

686 const RegisterMappingTracker &RMT = RegisterFiles[I];

687 if (!RMT.NumPhysRegs) {

688

689

690 continue;

691 }

692

693 if (RMT.NumPhysRegs < NumRegs) {

694

695

696

697

699 dbgs() << "[PRF] Not enough registers in the register file.\n");

700

701

702

703

704

705

706 NumRegs = RMT.NumPhysRegs;

707 }

708

709 if (RMT.NumPhysRegs < (RMT.NumUsedPhysRegs + NumRegs))

710 Response |= (1U << I);

711 }

712

713 return Response;

714}

715

716#ifndef NDEBUG

721 else

722 dbgs() << "(null)";

723}

724

726 for (unsigned I = 0, E = MRI.getNumRegs(); I < E; ++I) {

727 const RegisterMapping &RM = RegisterMappings[I];

728 const RegisterRenamingInfo &RRI = RM.second;

729 if (ZeroRegisters[I]) {

730 dbgs() << MRI.getName(I) << ", " << I

731 << ", PRF=" << RRI.IndexPlusCost.first

732 << ", Cost=" << RRI.IndexPlusCost.second

733 << ", RenameAs=" << RRI.RenameAs << ", IsZero=" << ZeroRegisters[I]

734 << ",";

735 RM.first.dump();

736 dbgs() << '\n';

737 }

738 }

739

741 dbgs() << "Register File #" << I;

742 const RegisterMappingTracker &RMT = RegisterFiles[I];

743 dbgs() << "\n TotalMappings: " << RMT.NumPhysRegs

744 << "\n NumUsedMappings: " << RMT.NumUsedPhysRegs << '\n';

745 }

746}

747#endif

748

749}

750}

unsigned const MachineRegisterInfo * MRI

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

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

Analysis containing CSE Info

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

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

This file defines a register mapping file class.

static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)

Initialize the set of available library functions based on the specified target triple.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

MCRegisterClass - Base class of TargetRegisterClass.

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Generic base class for all target subtargets.

int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx, unsigned WriteResID) const

const MCSchedModel & getSchedModel() const

Get the machine model for this subtarget's CPU.

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

reference emplace_back(ArgTypes &&... Args)

void push_back(const T &Elt)

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

SmallVectorImpl< WriteState > & getDefs()

An instruction propagated through the simulated instruction pipeline.

Tracks register operand latency in cycles.

void collectWrites(const MCSubtargetInfo &STI, const ReadState &RS, SmallVectorImpl< WriteRef > &Writes, SmallVectorImpl< WriteRef > &CommittedWrites) const

Definition RegisterFile.cpp:510

unsigned getElapsedCyclesFromWriteBack(const WriteRef &WR) const

Definition RegisterFile.cpp:505

void dump() const

Definition RegisterFile.cpp:725

void addRegisterWrite(WriteRef Write, MutableArrayRef< unsigned > UsedPhysRegs)

Definition RegisterFile.cpp:233

unsigned isAvailable(ArrayRef< MCPhysReg > Regs) const

Definition RegisterFile.cpp:668

unsigned getNumRegisterFiles() const

void cycleStart()

Definition RegisterFile.cpp:105

RAWHazard checkRAWHazards(const MCSubtargetInfo &STI, const ReadState &RS) const

Definition RegisterFile.cpp:576

void removeRegisterWrite(const WriteState &WS, MutableArrayRef< unsigned > FreedPhysRegs)

Definition RegisterFile.cpp:339

bool tryEliminateMoveOrSwap(MutableArrayRef< WriteState > Writes, MutableArrayRef< ReadState > Reads)

Definition RegisterFile.cpp:433

RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri, unsigned NumRegs=0)

Definition RegisterFile.cpp:69

void addRegisterRead(ReadState &RS, const MCSubtargetInfo &STI) const

Definition RegisterFile.cpp:626

bool canEliminateMove(const WriteState &WS, const ReadState &RS, unsigned PRFIndex) const

Definition RegisterFile.cpp:391

void onInstructionExecuted(Instruction *IS)

Definition RegisterFile.cpp:110

A reference to a register write.

unsigned getSourceIndex() const

unsigned getWriteResourceID() const

Definition RegisterFile.cpp:57

void notifyExecuted(unsigned Cycle)

Definition RegisterFile.cpp:43

bool isWriteZero() const

Definition RegisterFile.cpp:52

void commit()

Definition RegisterFile.cpp:36

void dump() const

Definition RegisterFile.cpp:717

const WriteState * getWriteState() const

MCPhysReg getRegisterID() const

Definition RegisterFile.cpp:63

unsigned getWriteBackCycle() const

Definition RegisterFile.cpp:498

bool hasKnownWriteBackCycle() const

Definition RegisterFile.cpp:48

Tracks uses of a register definition (e.g.

bool isEliminated() const

unsigned getLatency() const

void setPRF(unsigned PRF)

int getCyclesLeft() const

bool clearsSuperRegisters() const

MCPhysReg getRegisterID() const

unsigned getWriteResourceID() const

LLVM_ABI void addUser(unsigned IID, ReadState *Use, int ReadAdvance)

static std::function< bool(MCPhysReg)> isNonArtificial(const MCRegisterInfo &MRI)

Definition RegisterFile.cpp:28

constexpr int UNKNOWN_CYCLES

This is an optimization pass for GlobalISel generic memory operations.

auto unique(Range &&R, Predicate P)

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

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

iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)

Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...

MutableArrayRef(T &OneElt) -> MutableArrayRef< T >

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

Specify the cost of a register definition in terms of number of physical register allocated at regist...

A register file descriptor.

uint16_t NumRegisterCostEntries

bool AllowZeroMoveEliminationOnly

uint16_t RegisterCostEntryIdx

uint16_t MaxMovesEliminatedPerCycle

Summarize the scheduling resources required for an instruction of a particular scheduling class.

Machine model for scheduling, bundling, and heuristics.

bool hasExtraProcessorInfo() const

const MCSchedClassDesc * getSchedClassDesc(unsigned SchedClassIdx) const

const MCExtraProcessorInfo & getExtraProcessorInfo() const

A register read descriptor.