1 //===--------------------- RegisterFile.cpp ---------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This file defines a register mapping file class. This class is responsible 11 /// for managing hardware register files and the tracking of data dependencies 12 /// between registers. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/MCA/HardwareUnits/RegisterFile.h" 17 #include "llvm/MCA/Instruction.h" 18 #include "llvm/Support/Debug.h" 19 20 #define DEBUG_TYPE "llvm-mca" 21 22 namespace llvm { 23 namespace mca { 24 25 const unsigned WriteRef::INVALID_IID = std::numeric_limits<unsigned>::max(); 26 27 WriteRef::WriteRef(unsigned SourceIndex, WriteState *WS) 28 : IID(SourceIndex), WriteBackCycle(), WriteResID(), Write(WS) {} 29 30 void WriteRef::commit() { 31 assert(Write && Write->isExecuted() && "Cannot commit before write back!"); 32 Write = nullptr; 33 } 34 35 void WriteRef::notifyExecuted(unsigned Cycle) { 36 assert(Write && Write->isExecuted() && "Not executed!"); 37 WriteBackCycle = Cycle; 38 } 39 40 bool WriteRef::hasKnownWriteBackCycle() const { 41 return isValid() && (!Write || Write->isExecuted()); 42 } 43 44 bool WriteRef::isWriteZero() const { 45 assert(isValid() && "Invalid null WriteState found!"); 46 return getWriteState()->isWriteZero(); 47 } 48 49 unsigned WriteRef::getWriteResourceID() const { 50 if (Write) 51 return Write->getWriteResourceID(); 52 return WriteResID; 53 } 54 55 MCPhysReg WriteRef::getRegisterID() const { 56 if (Write) 57 return Write->getRegisterID(); 58 return RegisterID; 59 } 60 61 RegisterFile::RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri, 62 unsigned NumRegs) 63 : MRI(mri), 64 RegisterMappings(mri.getNumRegs(), {WriteRef(), RegisterRenamingInfo()}), 65 ZeroRegisters(mri.getNumRegs(), false), CurrentCycle() { 66 initialize(SM, NumRegs); 67 } 68 69 void RegisterFile::initialize(const MCSchedModel &SM, unsigned NumRegs) { 70 // Create a default register file that "sees" all the machine registers 71 // declared by the target. The number of physical registers in the default 72 // register file is set equal to `NumRegs`. A value of zero for `NumRegs` 73 // means: this register file has an unbounded number of physical registers. 74 RegisterFiles.emplace_back(NumRegs); 75 if (!SM.hasExtraProcessorInfo()) 76 return; 77 78 // For each user defined register file, allocate a RegisterMappingTracker 79 // object. The size of every register file, as well as the mapping between 80 // register files and register classes is specified via tablegen. 81 const MCExtraProcessorInfo &Info = SM.getExtraProcessorInfo(); 82 83 // Skip invalid register file at index 0. 84 for (unsigned I = 1, E = Info.NumRegisterFiles; I < E; ++I) { 85 const MCRegisterFileDesc &RF = Info.RegisterFiles[I]; 86 assert(RF.NumPhysRegs && "Invalid PRF with zero physical registers!"); 87 88 // The cost of a register definition is equivalent to the number of 89 // physical registers that are allocated at register renaming stage. 90 unsigned Length = RF.NumRegisterCostEntries; 91 const MCRegisterCostEntry *FirstElt = 92 &Info.RegisterCostTable[RF.RegisterCostEntryIdx]; 93 addRegisterFile(RF, ArrayRef<MCRegisterCostEntry>(FirstElt, Length)); 94 } 95 } 96 97 void RegisterFile::cycleStart() { 98 for (RegisterMappingTracker &RMT : RegisterFiles) 99 RMT.NumMoveEliminated = 0; 100 } 101 102 void RegisterFile::onInstructionExecuted(Instruction *IS) { 103 assert(IS && IS->isExecuted() && "Unexpected internal state found!"); 104 for (WriteState &WS : IS->getDefs()) { 105 if (WS.isEliminated()) 106 return; 107 108 MCPhysReg RegID = WS.getRegisterID(); 109 assert(RegID != 0 && "A write of an invalid register?"); 110 assert(WS.getCyclesLeft() != UNKNOWN_CYCLES && 111 "The number of cycles should be known at this point!"); 112 assert(WS.getCyclesLeft() <= 0 && "Invalid cycles left for this write!"); 113 114 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs; 115 if (RenameAs && RenameAs != RegID) 116 RegID = RenameAs; 117 118 WriteRef &WR = RegisterMappings[RegID].first; 119 if (WR.getWriteState() == &WS) 120 WR.notifyExecuted(CurrentCycle); 121 122 for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) { 123 WriteRef &OtherWR = RegisterMappings[*I].first; 124 if (OtherWR.getWriteState() == &WS) 125 OtherWR.notifyExecuted(CurrentCycle); 126 } 127 128 if (!WS.clearsSuperRegisters()) 129 continue; 130 131 for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I) { 132 WriteRef &OtherWR = RegisterMappings[*I].first; 133 if (OtherWR.getWriteState() == &WS) 134 OtherWR.notifyExecuted(CurrentCycle); 135 } 136 } 137 } 138 139 void RegisterFile::addRegisterFile(const MCRegisterFileDesc &RF, 140 ArrayRef<MCRegisterCostEntry> Entries) { 141 // A default register file is always allocated at index #0. That register file 142 // is mainly used to count the total number of mappings created by all 143 // register files at runtime. Users can limit the number of available physical 144 // registers in register file #0 through the command line flag 145 // `-register-file-size`. 146 unsigned RegisterFileIndex = RegisterFiles.size(); 147 RegisterFiles.emplace_back(RF.NumPhysRegs, RF.MaxMovesEliminatedPerCycle, 148 RF.AllowZeroMoveEliminationOnly); 149 150 // Special case where there is no register class identifier in the set. 151 // An empty set of register classes means: this register file contains all 152 // the physical registers specified by the target. 153 // We optimistically assume that a register can be renamed at the cost of a 154 // single physical register. The constructor of RegisterFile ensures that 155 // a RegisterMapping exists for each logical register defined by the Target. 156 if (Entries.empty()) 157 return; 158 159 // Now update the cost of individual registers. 160 for (const MCRegisterCostEntry &RCE : Entries) { 161 const MCRegisterClass &RC = MRI.getRegClass(RCE.RegisterClassID); 162 for (const MCPhysReg Reg : RC) { 163 RegisterRenamingInfo &Entry = RegisterMappings[Reg].second; 164 IndexPlusCostPairTy &IPC = Entry.IndexPlusCost; 165 if (IPC.first && IPC.first != RegisterFileIndex) { 166 // The only register file that is allowed to overlap is the default 167 // register file at index #0. The analysis is inaccurate if register 168 // files overlap. 169 errs() << "warning: register " << MRI.getName(Reg) 170 << " defined in multiple register files."; 171 } 172 IPC = std::make_pair(RegisterFileIndex, RCE.Cost); 173 Entry.RenameAs = Reg; 174 Entry.AllowMoveElimination = RCE.AllowMoveElimination; 175 176 // Assume the same cost for each sub-register. 177 for (MCSubRegIterator I(Reg, &MRI); I.isValid(); ++I) { 178 RegisterRenamingInfo &OtherEntry = RegisterMappings[*I].second; 179 if (!OtherEntry.IndexPlusCost.first && 180 (!OtherEntry.RenameAs || 181 MRI.isSuperRegister(*I, OtherEntry.RenameAs))) { 182 OtherEntry.IndexPlusCost = IPC; 183 OtherEntry.RenameAs = Reg; 184 } 185 } 186 } 187 } 188 } 189 190 void RegisterFile::allocatePhysRegs(const RegisterRenamingInfo &Entry, 191 MutableArrayRef<unsigned> UsedPhysRegs) { 192 unsigned RegisterFileIndex = Entry.IndexPlusCost.first; 193 unsigned Cost = Entry.IndexPlusCost.second; 194 if (RegisterFileIndex) { 195 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex]; 196 RMT.NumUsedPhysRegs += Cost; 197 UsedPhysRegs[RegisterFileIndex] += Cost; 198 } 199 200 // Now update the default register mapping tracker. 201 RegisterFiles[0].NumUsedPhysRegs += Cost; 202 UsedPhysRegs[0] += Cost; 203 } 204 205 void RegisterFile::freePhysRegs(const RegisterRenamingInfo &Entry, 206 MutableArrayRef<unsigned> FreedPhysRegs) { 207 unsigned RegisterFileIndex = Entry.IndexPlusCost.first; 208 unsigned Cost = Entry.IndexPlusCost.second; 209 if (RegisterFileIndex) { 210 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex]; 211 RMT.NumUsedPhysRegs -= Cost; 212 FreedPhysRegs[RegisterFileIndex] += Cost; 213 } 214 215 // Now update the default register mapping tracker. 216 RegisterFiles[0].NumUsedPhysRegs -= Cost; 217 FreedPhysRegs[0] += Cost; 218 } 219 220 void RegisterFile::addRegisterWrite(WriteRef Write, 221 MutableArrayRef<unsigned> UsedPhysRegs) { 222 WriteState &WS = *Write.getWriteState(); 223 MCPhysReg RegID = WS.getRegisterID(); 224 assert(RegID && "Adding an invalid register definition?"); 225 226 LLVM_DEBUG({ 227 dbgs() << "RegisterFile: addRegisterWrite [ " << Write.getSourceIndex() 228 << ", " << MRI.getName(RegID) << "]\n"; 229 }); 230 231 // If RenameAs is equal to RegID, then RegID is subject to register renaming 232 // and false dependencies on RegID are all eliminated. 233 234 // If RenameAs references the invalid register, then we optimistically assume 235 // that it can be renamed. In the absence of tablegen descriptors for register 236 // files, RenameAs is always set to the invalid register ID. In all other 237 // cases, RenameAs must be either equal to RegID, or it must reference a 238 // super-register of RegID. 239 240 // If RenameAs is a super-register of RegID, then a write to RegID has always 241 // a false dependency on RenameAs. The only exception is for when the write 242 // implicitly clears the upper portion of the underlying register. 243 // If a write clears its super-registers, then it is renamed as `RenameAs`. 244 bool IsWriteZero = WS.isWriteZero(); 245 bool IsEliminated = WS.isEliminated(); 246 bool ShouldAllocatePhysRegs = !IsWriteZero && !IsEliminated; 247 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second; 248 WS.setPRF(RRI.IndexPlusCost.first); 249 250 if (RRI.RenameAs && RRI.RenameAs != RegID) { 251 RegID = RRI.RenameAs; 252 WriteRef &OtherWrite = RegisterMappings[RegID].first; 253 254 if (!WS.clearsSuperRegisters()) { 255 // The processor keeps the definition of `RegID` together with register 256 // `RenameAs`. Since this partial write is not renamed, no physical 257 // register is allocated. 258 ShouldAllocatePhysRegs = false; 259 260 WriteState *OtherWS = OtherWrite.getWriteState(); 261 if (OtherWS && (OtherWrite.getSourceIndex() != Write.getSourceIndex())) { 262 // This partial write has a false dependency on RenameAs. 263 assert(!IsEliminated && "Unexpected partial update!"); 264 OtherWS->addUser(OtherWrite.getSourceIndex(), &WS); 265 } 266 } 267 } 268 269 // Update zero registers. 270 MCPhysReg ZeroRegisterID = 271 WS.clearsSuperRegisters() ? RegID : WS.getRegisterID(); 272 ZeroRegisters.setBitVal(ZeroRegisterID, IsWriteZero); 273 for (MCSubRegIterator I(ZeroRegisterID, &MRI); I.isValid(); ++I) 274 ZeroRegisters.setBitVal(*I, IsWriteZero); 275 276 // If this is move has been eliminated, then the call to tryEliminateMove 277 // should have already updated all the register mappings. 278 if (!IsEliminated) { 279 // Update the mapping for register RegID including its sub-registers. 280 RegisterMappings[RegID].first = Write; 281 RegisterMappings[RegID].second.AliasRegID = 0U; 282 for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) { 283 RegisterMappings[*I].first = Write; 284 RegisterMappings[*I].second.AliasRegID = 0U; 285 } 286 287 // No physical registers are allocated for instructions that are optimized 288 // in hardware. For example, zero-latency data-dependency breaking 289 // instructions don't consume physical registers. 290 if (ShouldAllocatePhysRegs) 291 allocatePhysRegs(RegisterMappings[RegID].second, UsedPhysRegs); 292 } 293 294 if (!WS.clearsSuperRegisters()) 295 return; 296 297 for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I) { 298 if (!IsEliminated) { 299 RegisterMappings[*I].first = Write; 300 RegisterMappings[*I].second.AliasRegID = 0U; 301 } 302 303 ZeroRegisters.setBitVal(*I, IsWriteZero); 304 } 305 } 306 307 void RegisterFile::removeRegisterWrite( 308 const WriteState &WS, MutableArrayRef<unsigned> FreedPhysRegs) { 309 // Early exit if this write was eliminated. A write eliminated at register 310 // renaming stage generates an alias, and it is not added to the PRF. 311 if (WS.isEliminated()) 312 return; 313 314 MCPhysReg RegID = WS.getRegisterID(); 315 316 assert(RegID != 0 && "Invalidating an already invalid register?"); 317 assert(WS.getCyclesLeft() != UNKNOWN_CYCLES && 318 "Invalidating a write of unknown cycles!"); 319 assert(WS.getCyclesLeft() <= 0 && "Invalid cycles left for this write!"); 320 321 bool ShouldFreePhysRegs = !WS.isWriteZero(); 322 MCPhysReg RenameAs = RegisterMappings[RegID].second.RenameAs; 323 if (RenameAs && RenameAs != RegID) { 324 RegID = RenameAs; 325 326 if (!WS.clearsSuperRegisters()) { 327 // Keep the definition of `RegID` together with register `RenameAs`. 328 ShouldFreePhysRegs = false; 329 } 330 } 331 332 if (ShouldFreePhysRegs) 333 freePhysRegs(RegisterMappings[RegID].second, FreedPhysRegs); 334 335 WriteRef &WR = RegisterMappings[RegID].first; 336 if (WR.getWriteState() == &WS) 337 WR.commit(); 338 339 for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) { 340 WriteRef &OtherWR = RegisterMappings[*I].first; 341 if (OtherWR.getWriteState() == &WS) 342 OtherWR.commit(); 343 } 344 345 if (!WS.clearsSuperRegisters()) 346 return; 347 348 for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I) { 349 WriteRef &OtherWR = RegisterMappings[*I].first; 350 if (OtherWR.getWriteState() == &WS) 351 OtherWR.commit(); 352 } 353 } 354 355 bool RegisterFile::tryEliminateMove(WriteState &WS, ReadState &RS) { 356 const RegisterMapping &RMFrom = RegisterMappings[RS.getRegisterID()]; 357 const RegisterMapping &RMTo = RegisterMappings[WS.getRegisterID()]; 358 359 // From and To must be owned by the same PRF. 360 const RegisterRenamingInfo &RRIFrom = RMFrom.second; 361 const RegisterRenamingInfo &RRITo = RMTo.second; 362 unsigned RegisterFileIndex = RRIFrom.IndexPlusCost.first; 363 if (RegisterFileIndex != RRITo.IndexPlusCost.first) 364 return false; 365 366 // We only allow move elimination for writes that update a full physical 367 // register. On X86, move elimination is possible with 32-bit general purpose 368 // registers because writes to those registers are not partial writes. If a 369 // register move is a partial write, then we conservatively assume that move 370 // elimination fails, since it would either trigger a partial update, or the 371 // issue of a merge opcode. 372 // 373 // Note that this constraint may be lifted in future. For example, we could 374 // make this model more flexible, and let users customize the set of registers 375 // (i.e. register classes) that allow move elimination. 376 // 377 // For now, we assume that there is a strong correlation between registers 378 // that allow move elimination, and how those same registers are renamed in 379 // hardware. 380 if (RRITo.RenameAs && RRITo.RenameAs != WS.getRegisterID()) { 381 // Early exit if the PRF doesn't support move elimination for this register. 382 if (!RegisterMappings[RRITo.RenameAs].second.AllowMoveElimination) 383 return false; 384 if (!WS.clearsSuperRegisters()) 385 return false; 386 } 387 388 RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex]; 389 if (RMT.MaxMoveEliminatedPerCycle && 390 RMT.NumMoveEliminated == RMT.MaxMoveEliminatedPerCycle) 391 return false; 392 393 bool IsZeroMove = ZeroRegisters[RS.getRegisterID()]; 394 if (RMT.AllowZeroMoveEliminationOnly && !IsZeroMove) 395 return false; 396 397 // Construct an alias. 398 MCPhysReg AliasedReg = 399 RRIFrom.RenameAs ? RRIFrom.RenameAs : RS.getRegisterID(); 400 MCPhysReg AliasReg = RRITo.RenameAs ? RRITo.RenameAs : WS.getRegisterID(); 401 402 const RegisterRenamingInfo &RMAlias = RegisterMappings[AliasedReg].second; 403 if (RMAlias.AliasRegID) 404 AliasedReg = RMAlias.AliasRegID; 405 406 RegisterMappings[AliasReg].second.AliasRegID = AliasedReg; 407 for (MCSubRegIterator I(AliasReg, &MRI); I.isValid(); ++I) 408 RegisterMappings[*I].second.AliasRegID = AliasedReg; 409 410 if (IsZeroMove) { 411 WS.setWriteZero(); 412 RS.setReadZero(); 413 } 414 WS.setEliminated(); 415 RMT.NumMoveEliminated++; 416 417 return true; 418 } 419 420 unsigned WriteRef::getWriteBackCycle() const { 421 assert(hasKnownWriteBackCycle() && "Instruction not executed!"); 422 assert((!Write || Write->getCyclesLeft() <= 0) && 423 "Inconsistent state found!"); 424 return WriteBackCycle; 425 } 426 427 unsigned RegisterFile::getElapsedCyclesFromWriteBack(const WriteRef &WR) const { 428 assert(WR.hasKnownWriteBackCycle() && "Write hasn't been committed yet!"); 429 return CurrentCycle - WR.getWriteBackCycle(); 430 } 431 432 void RegisterFile::collectWrites( 433 const MCSubtargetInfo &STI, const ReadState &RS, 434 SmallVectorImpl<WriteRef> &Writes, 435 SmallVectorImpl<WriteRef> &CommittedWrites) const { 436 const ReadDescriptor &RD = RS.getDescriptor(); 437 const MCSchedModel &SM = STI.getSchedModel(); 438 const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID); 439 MCPhysReg RegID = RS.getRegisterID(); 440 assert(RegID && RegID < RegisterMappings.size()); 441 LLVM_DEBUG(dbgs() << "RegisterFile: collecting writes for register " 442 << MRI.getName(RegID) << '\n'); 443 444 // Check if this is an alias. 445 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second; 446 if (RRI.AliasRegID) 447 RegID = RRI.AliasRegID; 448 449 const WriteRef &WR = RegisterMappings[RegID].first; 450 if (WR.getWriteState()) { 451 Writes.push_back(WR); 452 } else if (WR.hasKnownWriteBackCycle()) { 453 unsigned WriteResID = WR.getWriteResourceID(); 454 int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID); 455 if (ReadAdvance < 0) { 456 unsigned Elapsed = getElapsedCyclesFromWriteBack(WR); 457 if (Elapsed < static_cast<unsigned>(-ReadAdvance)) 458 CommittedWrites.push_back(WR); 459 } 460 } 461 462 // Handle potential partial register updates. 463 for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) { 464 const WriteRef &WR = RegisterMappings[*I].first; 465 if (WR.getWriteState()) { 466 Writes.push_back(WR); 467 } else if (WR.hasKnownWriteBackCycle()) { 468 unsigned WriteResID = WR.getWriteResourceID(); 469 int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID); 470 if (ReadAdvance < 0) { 471 unsigned Elapsed = getElapsedCyclesFromWriteBack(WR); 472 if (Elapsed < static_cast<unsigned>(-ReadAdvance)) 473 CommittedWrites.push_back(WR); 474 } 475 } 476 } 477 478 // Remove duplicate entries and resize the input vector. 479 if (Writes.size() > 1) { 480 sort(Writes, [](const WriteRef &Lhs, const WriteRef &Rhs) { 481 return Lhs.getWriteState() < Rhs.getWriteState(); 482 }); 483 auto It = std::unique(Writes.begin(), Writes.end()); 484 Writes.resize(std::distance(Writes.begin(), It)); 485 } 486 487 LLVM_DEBUG({ 488 for (const WriteRef &WR : Writes) { 489 const WriteState &WS = *WR.getWriteState(); 490 dbgs() << "[PRF] Found a dependent use of Register " 491 << MRI.getName(WS.getRegisterID()) << " (defined by instruction #" 492 << WR.getSourceIndex() << ")\n"; 493 } 494 }); 495 } 496 497 void RegisterFile::addRegisterRead(ReadState &RS, 498 const MCSubtargetInfo &STI) const { 499 MCPhysReg RegID = RS.getRegisterID(); 500 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second; 501 RS.setPRF(RRI.IndexPlusCost.first); 502 if (RS.isIndependentFromDef()) 503 return; 504 505 if (ZeroRegisters[RS.getRegisterID()]) 506 RS.setReadZero(); 507 508 SmallVector<WriteRef, 4> DependentWrites; 509 SmallVector<WriteRef, 4> CompletedWrites; 510 collectWrites(STI, RS, DependentWrites, CompletedWrites); 511 RS.setDependentWrites(DependentWrites.size() + CompletedWrites.size()); 512 513 // We know that this read depends on all the writes in DependentWrites. 514 // For each write, check if we have ReadAdvance information, and use it 515 // to figure out in how many cycles this read will be available. 516 const ReadDescriptor &RD = RS.getDescriptor(); 517 const MCSchedModel &SM = STI.getSchedModel(); 518 const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID); 519 for (WriteRef &WR : DependentWrites) { 520 unsigned WriteResID = WR.getWriteResourceID(); 521 WriteState &WS = *WR.getWriteState(); 522 int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID); 523 WS.addUser(WR.getSourceIndex(), &RS, ReadAdvance); 524 } 525 526 for (WriteRef &WR : CompletedWrites) { 527 unsigned WriteResID = WR.getWriteResourceID(); 528 assert(WR.hasKnownWriteBackCycle() && "Invalid write!"); 529 assert(STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID) < 0); 530 unsigned ReadAdvance = static_cast<unsigned>( 531 -STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID)); 532 unsigned Elapsed = getElapsedCyclesFromWriteBack(WR); 533 assert(Elapsed < ReadAdvance && "Should not have been added to the set!"); 534 RS.writeStartEvent(WR.getSourceIndex(), WR.getRegisterID(), 535 ReadAdvance - Elapsed); 536 } 537 } 538 539 unsigned RegisterFile::isAvailable(ArrayRef<MCPhysReg> Regs) const { 540 SmallVector<unsigned, 4> NumPhysRegs(getNumRegisterFiles()); 541 542 // Find how many new mappings must be created for each register file. 543 for (const MCPhysReg RegID : Regs) { 544 const RegisterRenamingInfo &RRI = RegisterMappings[RegID].second; 545 const IndexPlusCostPairTy &Entry = RRI.IndexPlusCost; 546 if (Entry.first) 547 NumPhysRegs[Entry.first] += Entry.second; 548 NumPhysRegs[0] += Entry.second; 549 } 550 551 unsigned Response = 0; 552 for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) { 553 unsigned NumRegs = NumPhysRegs[I]; 554 if (!NumRegs) 555 continue; 556 557 const RegisterMappingTracker &RMT = RegisterFiles[I]; 558 if (!RMT.NumPhysRegs) { 559 // The register file has an unbounded number of microarchitectural 560 // registers. 561 continue; 562 } 563 564 if (RMT.NumPhysRegs < NumRegs) { 565 // The current register file is too small. This may occur if the number of 566 // microarchitectural registers in register file #0 was changed by the 567 // users via flag -reg-file-size. Alternatively, the scheduling model 568 // specified a too small number of registers for this register file. 569 LLVM_DEBUG(dbgs() << "Not enough registers in the register file.\n"); 570 571 // FIXME: Normalize the instruction register count to match the 572 // NumPhysRegs value. This is a highly unusual case, and is not expected 573 // to occur. This normalization is hiding an inconsistency in either the 574 // scheduling model or in the value that the user might have specified 575 // for NumPhysRegs. 576 NumRegs = RMT.NumPhysRegs; 577 } 578 579 if (RMT.NumPhysRegs < (RMT.NumUsedPhysRegs + NumRegs)) 580 Response |= (1U << I); 581 } 582 583 return Response; 584 } 585 586 #ifndef NDEBUG 587 void WriteRef::dump() const { 588 dbgs() << "IID=" << getSourceIndex() << ' '; 589 if (isValid()) 590 getWriteState()->dump(); 591 else 592 dbgs() << "(null)"; 593 } 594 595 void RegisterFile::dump() const { 596 for (unsigned I = 0, E = MRI.getNumRegs(); I < E; ++I) { 597 const RegisterMapping &RM = RegisterMappings[I]; 598 const RegisterRenamingInfo &RRI = RM.second; 599 if (ZeroRegisters[I]) { 600 dbgs() << MRI.getName(I) << ", " << I 601 << ", PRF=" << RRI.IndexPlusCost.first 602 << ", Cost=" << RRI.IndexPlusCost.second 603 << ", RenameAs=" << RRI.RenameAs << ", IsZero=" << ZeroRegisters[I] 604 << ","; 605 RM.first.dump(); 606 dbgs() << '\n'; 607 } 608 } 609 610 for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) { 611 dbgs() << "Register File #" << I; 612 const RegisterMappingTracker &RMT = RegisterFiles[I]; 613 dbgs() << "\n TotalMappings: " << RMT.NumPhysRegs 614 << "\n NumUsedMappings: " << RMT.NumUsedPhysRegs << '\n'; 615 } 616 } 617 #endif 618 619 } // namespace mca 620 } // namespace llvm 621