[llvm-mca] Move the RegisterFile class into its own translation unit. NFC

Summary: This change will help us turn the DispatchUnit into its own stage.

Reviewers: andreadb, RKSimon, courbet

Reviewed By: andreadb, courbet

Subscribers: mgorny, tschuett, gbedwell, llvm-commits

Differential Revision: https://reviews.llvm.org/D46916

llvm-svn: 332493
diff --git a/llvm/tools/llvm-mca/Dispatch.cpp b/llvm/tools/llvm-mca/Dispatch.cpp
index 4153173..9f61034 100644
--- a/llvm/tools/llvm-mca/Dispatch.cpp
+++ b/llvm/tools/llvm-mca/Dispatch.cpp
@@ -8,8 +8,7 @@
 //===----------------------------------------------------------------------===//
 /// \file
 ///
-/// This file implements methods declared by class RegisterFile and
-/// DispatchUnit.
+/// This file implements methods declared by the DispatchUnit class.
 ///
 //===----------------------------------------------------------------------===//
 
@@ -25,240 +24,6 @@
 
 namespace mca {
 
-void RegisterFile::initialize(const MCSchedModel &SM, unsigned NumRegs) {
-  // Create a default register file that "sees" all the machine registers
-  // declared by the target. The number of physical registers in the default
-  // register file is set equal to `NumRegs`. A value of zero for `NumRegs`
-  // means: this register file has an unbounded number of physical registers.
-  addRegisterFile({} /* all registers */, NumRegs);
-  if (!SM.hasExtraProcessorInfo())
-    return;
-
-  // For each user defined register file, allocate a RegisterMappingTracker
-  // object. The size of every register file, as well as the mapping between
-  // register files and register classes is specified via tablegen.
-  const MCExtraProcessorInfo &Info = SM.getExtraProcessorInfo();
-  for (unsigned I = 0, E = Info.NumRegisterFiles; I < E; ++I) {
-    const MCRegisterFileDesc &RF = Info.RegisterFiles[I];
-    // Skip invalid register files with zero physical registers.
-    unsigned Length = RF.NumRegisterCostEntries;
-    if (!RF.NumPhysRegs)
-      continue;
-    // The cost of a register definition is equivalent to the number of
-    // physical registers that are allocated at register renaming stage.
-    const MCRegisterCostEntry *FirstElt =
-        &Info.RegisterCostTable[RF.RegisterCostEntryIdx];
-    addRegisterFile(ArrayRef<MCRegisterCostEntry>(FirstElt, Length),
-                    RF.NumPhysRegs);
-  }
-}
-
-void RegisterFile::addRegisterFile(ArrayRef<MCRegisterCostEntry> Entries,
-                                   unsigned NumPhysRegs) {
-  // A default register file is always allocated at index #0. That register file
-  // is mainly used to count the total number of mappings created by all
-  // register files at runtime. Users can limit the number of available physical
-  // registers in register file #0 through the command line flag
-  // `-register-file-size`.
-  unsigned RegisterFileIndex = RegisterFiles.size();
-  RegisterFiles.emplace_back(NumPhysRegs);
-
-  // Special case where there is no register class identifier in the set.
-  // An empty set of register classes means: this register file contains all
-  // the physical registers specified by the target.
-  if (Entries.empty()) {
-    for (std::pair<WriteState *, IndexPlusCostPairTy> &Mapping :
-         RegisterMappings)
-      Mapping.second = std::make_pair(RegisterFileIndex, 1U);
-    return;
-  }
-
-  // Now update the cost of individual registers.
-  for (const MCRegisterCostEntry &RCE : Entries) {
-    const MCRegisterClass &RC = MRI.getRegClass(RCE.RegisterClassID);
-    for (const MCPhysReg Reg : RC) {
-      IndexPlusCostPairTy &Entry = RegisterMappings[Reg].second;
-      if (Entry.first) {
-        // The only register file that is allowed to overlap is the default
-        // register file at index #0. The analysis is inaccurate if register
-        // files overlap.
-        errs() << "warning: register " << MRI.getName(Reg)
-               << " defined in multiple register files.";
-      }
-      Entry.first = RegisterFileIndex;
-      Entry.second = RCE.Cost;
-    }
-  }
-}
-
-void RegisterFile::allocatePhysRegs(IndexPlusCostPairTy Entry,
-                                    MutableArrayRef<unsigned> UsedPhysRegs) {
-  unsigned RegisterFileIndex = Entry.first;
-  unsigned Cost = Entry.second;
-  if (RegisterFileIndex) {
-    RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
-    RMT.NumUsedMappings += Cost;
-    UsedPhysRegs[RegisterFileIndex] += Cost;
-  }
-
-  // Now update the default register mapping tracker.
-  RegisterFiles[0].NumUsedMappings += Cost;
-  UsedPhysRegs[0] += Cost;
-}
-
-void RegisterFile::freePhysRegs(IndexPlusCostPairTy Entry,
-                                MutableArrayRef<unsigned> FreedPhysRegs) {
-  unsigned RegisterFileIndex = Entry.first;
-  unsigned Cost = Entry.second;
-  if (RegisterFileIndex) {
-    RegisterMappingTracker &RMT = RegisterFiles[RegisterFileIndex];
-    RMT.NumUsedMappings -= Cost;
-    FreedPhysRegs[RegisterFileIndex] += Cost;
-  }
-
-  // Now update the default register mapping tracker.
-  RegisterFiles[0].NumUsedMappings -= Cost;
-  FreedPhysRegs[0] += Cost;
-}
-
-void RegisterFile::addRegisterWrite(WriteState &WS,
-                                    MutableArrayRef<unsigned> UsedPhysRegs,
-                                    bool ShouldAllocatePhysRegs) {
-  unsigned RegID = WS.getRegisterID();
-  assert(RegID && "Adding an invalid register definition?");
-
-  RegisterMapping &Mapping = RegisterMappings[RegID];
-  Mapping.first = &WS;
-  for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I)
-    RegisterMappings[*I].first = &WS;
-
-  // No physical registers are allocated for instructions that are optimized in
-  // hardware. For example, zero-latency data-dependency breaking instructions
-  // don't consume physical registers.
-  if (ShouldAllocatePhysRegs)
-    allocatePhysRegs(Mapping.second, UsedPhysRegs);
-
-  // If this is a partial update, then we are done.
-  if (!WS.fullyUpdatesSuperRegs())
-    return;
-
-  for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I)
-    RegisterMappings[*I].first = &WS;
-}
-
-void RegisterFile::removeRegisterWrite(const WriteState &WS,
-                                       MutableArrayRef<unsigned> FreedPhysRegs,
-                                       bool ShouldFreePhysRegs) {
-  unsigned RegID = WS.getRegisterID();
-  bool ShouldInvalidateSuperRegs = WS.fullyUpdatesSuperRegs();
-
-  assert(RegID != 0 && "Invalidating an already invalid register?");
-  assert(WS.getCyclesLeft() != -512 &&
-         "Invalidating a write of unknown cycles!");
-  assert(WS.getCyclesLeft() <= 0 && "Invalid cycles left for this write!");
-  RegisterMapping &Mapping = RegisterMappings[RegID];
-  if (!Mapping.first)
-    return;
-
-  if (ShouldFreePhysRegs)
-    freePhysRegs(Mapping.second, FreedPhysRegs);
-
-  if (Mapping.first == &WS)
-    Mapping.first = nullptr;
-
-  for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I)
-    if (RegisterMappings[*I].first == &WS)
-      RegisterMappings[*I].first = nullptr;
-
-  if (!ShouldInvalidateSuperRegs)
-    return;
-
-  for (MCSuperRegIterator I(RegID, &MRI); I.isValid(); ++I)
-    if (RegisterMappings[*I].first == &WS)
-      RegisterMappings[*I].first = nullptr;
-}
-
-void RegisterFile::collectWrites(SmallVectorImpl<WriteState *> &Writes,
-                                 unsigned RegID) const {
-  assert(RegID && RegID < RegisterMappings.size());
-  WriteState *WS = RegisterMappings[RegID].first;
-  if (WS) {
-    LLVM_DEBUG(dbgs() << "Found a dependent use of RegID=" << RegID << '\n');
-    Writes.push_back(WS);
-  }
-
-  // Handle potential partial register updates.
-  for (MCSubRegIterator I(RegID, &MRI); I.isValid(); ++I) {
-    WS = RegisterMappings[*I].first;
-    if (WS && std::find(Writes.begin(), Writes.end(), WS) == Writes.end()) {
-      LLVM_DEBUG(dbgs() << "Found a dependent use of subReg " << *I
-                        << " (part of " << RegID << ")\n");
-      Writes.push_back(WS);
-    }
-  }
-}
-
-unsigned RegisterFile::isAvailable(ArrayRef<unsigned> Regs) const {
-  SmallVector<unsigned, 4> NumPhysRegs(getNumRegisterFiles());
-
-  // Find how many new mappings must be created for each register file.
-  for (const unsigned RegID : Regs) {
-    const IndexPlusCostPairTy &Entry = RegisterMappings[RegID].second;
-    if (Entry.first)
-      NumPhysRegs[Entry.first] += Entry.second;
-    NumPhysRegs[0] += Entry.second;
-  }
-
-  unsigned Response = 0;
-  for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) {
-    unsigned NumRegs = NumPhysRegs[I];
-    if (!NumRegs)
-      continue;
-
-    const RegisterMappingTracker &RMT = RegisterFiles[I];
-    if (!RMT.TotalMappings) {
-      // The register file has an unbounded number of microarchitectural
-      // registers.
-      continue;
-    }
-
-    if (RMT.TotalMappings < NumRegs) {
-      // The current register file is too small. This may occur if the number of
-      // microarchitectural registers in register file #0 was changed by the
-      // users via flag -reg-file-size. Alternatively, the scheduling model
-      // specified a too small number of registers for this register file.
-      report_fatal_error(
-          "Not enough microarchitectural registers in the register file");
-    }
-
-    if (RMT.TotalMappings < (RMT.NumUsedMappings + NumRegs))
-      Response |= (1U << I);
-  }
-
-  return Response;
-}
-
-#ifndef NDEBUG
-void RegisterFile::dump() const {
-  for (unsigned I = 0, E = MRI.getNumRegs(); I < E; ++I) {
-    const RegisterMapping &RM = RegisterMappings[I];
-    dbgs() << MRI.getName(I) << ", " << I << ", Map=" << RM.second.first
-           << ", ";
-    if (RM.first)
-      RM.first->dump();
-    else
-      dbgs() << "(null)\n";
-  }
-
-  for (unsigned I = 0, E = getNumRegisterFiles(); I < E; ++I) {
-    dbgs() << "Register File #" << I;
-    const RegisterMappingTracker &RMT = RegisterFiles[I];
-    dbgs() << "\n  TotalMappings:        " << RMT.TotalMappings
-           << "\n  NumUsedMappings:      " << RMT.NumUsedMappings << '\n';
-  }
-}
-#endif
-
 void DispatchUnit::notifyInstructionDispatched(const InstRef &IR,
                                                ArrayRef<unsigned> UsedRegs) {
   LLVM_DEBUG(dbgs() << "[E] Instruction Dispatched: " << IR << '\n');