[llvm] e9f22fd - [TableGen][GlobalISel] Account for HwMode in RegisterBank register sizes

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 19 07:51:54 PDT 2020


On Wed, Mar 18, 2020 at 8:54 PM via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
>
> Author: lewis-revill
> Date: 2020-03-18T19:52:23Z
> New Revision: e9f22fd4293a65bcdcf1b18b91c72f63e5e9e45b
>
> URL: https://github.com/llvm/llvm-project/commit/e9f22fd4293a65bcdcf1b18b91c72f63e5e9e45b
> DIFF: https://github.com/llvm/llvm-project/commit/e9f22fd4293a65bcdcf1b18b91c72f63e5e9e45b.diff
>
> LOG: [TableGen][GlobalISel] Account for HwMode in RegisterBank register sizes
>
> This patch generates TableGen descriptions for the specified register
> banks which contain a list of register sizes corresponding to the
> available HwModes. The appropriate size is used during codegen according
> to the current HwMode. As this HwMode was not available on generation,
> it is set upon construction of the RegisterBankInfo class. Targets
> simply need to provide the HwMode argument to the
> <target>GenRegisterBankInfo constructor.
>
> The RISC-V RegisterBankInfo constructor has been updated accordingly
> (plus an unused argument removed).
>
> Differential Revision: https://reviews.llvm.org/D76007
>
> Added:
>
>
> Modified:
>     llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
>     llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
>     llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp
>     llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
>     llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp
>     llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h
>     llvm/lib/Target/RISCV/RISCVSubtarget.cpp
>     llvm/utils/TableGen/RegisterBankEmitter.cpp
>
> Removed:
>
>
>
> ################################################################################
> diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
> index f528d1a46012..8a8d3ce20040 100644
> --- a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
> +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
> @@ -29,18 +29,23 @@ class RegisterBank {
>  private:
>    unsigned ID;
>    const char *Name;
> -  unsigned Size;
> +  const unsigned *Sizes;
>    BitVector ContainedRegClasses;
>
> -  /// Sentinel value used to recognize register bank not properly
> +  /// HwMode of the target. Not initialized by the constructor, initialized
> +  /// within generated RegisterBankInfo class constructor.
> +  unsigned HwMode;
> +
> +  /// Sentinel values used to recognize register bank not properly
>    /// initialized yet.
>    static const unsigned InvalidID;
> +  static const unsigned InvalidHwMode;
>
>    /// Only the RegisterBankInfo can initialize RegisterBank properly.
>    friend RegisterBankInfo;
>
>  public:
> -  RegisterBank(unsigned ID, const char *Name, unsigned Size,
> +  RegisterBank(unsigned ID, const char *Name, const unsigned *Sizes,
>                 const uint32_t *CoveredClasses, unsigned NumRegClasses);
>
>    /// Get the identifier of this register bank.
> @@ -51,7 +56,7 @@ class RegisterBank {
>    const char *getName() const { return Name; }
>
>    /// Get the maximal size in bits that fits in this register bank.
> -  unsigned getSize() const { return Size; }
> +  unsigned getSize() const { return Sizes[HwMode]; }
>
>    /// Check whether this instance is ready to be used.
>    bool isValid() const;
>
> diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
> index 8725d96efd82..b86d2d10322f 100644
> --- a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
> +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
> @@ -415,7 +415,8 @@ class RegisterBankInfo {
>
>    /// Create a RegisterBankInfo that can accommodate up to \p NumRegBanks
>    /// RegisterBank instances.
> -  RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
> +  RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks,
> +                   unsigned HwMode);
>
>    /// This constructor is meaningless.
>    /// It just provides a default constructor that can be used at link time
>
> diff  --git a/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp
> index fc9c802693ab..54e5d48edf27 100644
> --- a/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp
> +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp
> @@ -19,11 +19,12 @@
>  using namespace llvm;
>
>  const unsigned RegisterBank::InvalidID = UINT_MAX;
> +const unsigned RegisterBank::InvalidHwMode = UINT_MAX;
>
>  RegisterBank::RegisterBank(
> -    unsigned ID, const char *Name, unsigned Size,
> +    unsigned ID, const char *Name, const unsigned *Sizes,
>      const uint32_t *CoveredClasses, unsigned NumRegClasses)
> -    : ID(ID), Name(Name), Size(Size) {
> +    : ID(ID), Name(Name), Sizes(Sizes), HwMode(InvalidHwMode) {
>    ContainedRegClasses.resize(NumRegClasses);
>    ContainedRegClasses.setBitsInMask(CoveredClasses);
>  }
> @@ -63,7 +64,8 @@ bool RegisterBank::covers(const TargetRegisterClass &RC) const {
>  }
>
>  bool RegisterBank::isValid() const {
> -  return ID != InvalidID && Name != nullptr && Size != 0 &&
> +  return ID != InvalidID && Name != nullptr && Sizes != nullptr &&
> +         HwMode != InvalidID &&
>           // A register bank that does not cover anything is useless.
>           !ContainedRegClasses.empty();
>  }
>
> diff  --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
> index 255ea693b5c4..3a8d0a9d3c4f 100644
> --- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
> +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
> @@ -56,8 +56,11 @@ const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1;
>  // RegisterBankInfo implementation.
>  //------------------------------------------------------------------------------
>  RegisterBankInfo::RegisterBankInfo(RegisterBank **RegBanks,
> -                                   unsigned NumRegBanks)
> +                                   unsigned NumRegBanks, unsigned HwMode)
>      : RegBanks(RegBanks), NumRegBanks(NumRegBanks) {
> +  // Initialize HwMode for all RegBanks
> +  for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx)
> +    RegBanks[Idx]->HwMode = HwMode;

This can write to a global variable, which is thread-hostile. I see
tsan complain about concurrent writes to llvm::X86::GPRRegBank.

- Ben

>  #ifndef NDEBUG
>    for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) {
>      assert(RegBanks[Idx] != nullptr && "Invalid RegisterBank");
>
> diff  --git a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp
> index bd3b95a98b9f..9db3107da073 100644
> --- a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp
> +++ b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.cpp
> @@ -22,5 +22,5 @@
>
>  using namespace llvm;
>
> -RISCVRegisterBankInfo::RISCVRegisterBankInfo(const TargetRegisterInfo &TRI)
> -    : RISCVGenRegisterBankInfo() {}
> +RISCVRegisterBankInfo::RISCVRegisterBankInfo(unsigned HwMode)
> +    : RISCVGenRegisterBankInfo(HwMode) {}
>
> diff  --git a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h
> index 05fac992734d..71dddd28380d 100644
> --- a/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h
> +++ b/llvm/lib/Target/RISCV/RISCVRegisterBankInfo.h
> @@ -31,7 +31,7 @@ class RISCVGenRegisterBankInfo : public RegisterBankInfo {
>  /// This class provides the information for the target register banks.
>  class RISCVRegisterBankInfo final : public RISCVGenRegisterBankInfo {
>  public:
> -  RISCVRegisterBankInfo(const TargetRegisterInfo &TRI);
> +  RISCVRegisterBankInfo(unsigned HwMode);
>  };
>  } // end namespace llvm
>  #endif
>
> diff  --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
> index 47a48c820a29..9815a7852689 100644
> --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
> +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
> @@ -56,7 +56,7 @@ RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
>    CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
>    Legalizer.reset(new RISCVLegalizerInfo(*this));
>
> -  auto *RBI = new RISCVRegisterBankInfo(*getRegisterInfo());
> +  auto *RBI = new RISCVRegisterBankInfo(getHwMode());
>    RegBankInfo.reset(RBI);
>    InstSelector.reset(createRISCVInstructionSelector(
>        *static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
>
> diff  --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
> index 586f857b1fb0..5d0751d14451 100644
> --- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
> +++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
> @@ -37,12 +37,12 @@ class RegisterBank {
>    /// The register classes that are covered by the register bank.
>    RegisterClassesTy RCs;
>
> -  /// The register class with the largest register size.
> -  const CodeGenRegisterClass *RCWithLargestRegsSize;
> +  /// The register classes with the largest register size for each HwMode.
> +  std::vector<const CodeGenRegisterClass *> RCsWithLargestRegSize;
>
>  public:
> -  RegisterBank(const Record &TheDef)
> -      : TheDef(TheDef), RCs(), RCWithLargestRegsSize(nullptr) {}
> +  RegisterBank(const Record &TheDef, unsigned NumModeIds)
> +      : TheDef(TheDef), RCs(), RCsWithLargestRegSize(NumModeIds) {}
>
>    /// Get the human-readable name for the bank.
>    StringRef getName() const { return TheDef.getValueAsString("Name"); }
> @@ -54,6 +54,10 @@ class RegisterBank {
>      return (TheDef.getName() + "CoverageData").str();
>    }
>
> +  std::string getSizesArrayName() const {
> +    return (TheDef.getName() + "Sizes").str();
> +  }
> +
>    /// Get the name of the global instance variable.
>    StringRef getInstanceVarName() const { return TheDef.getName(); }
>
> @@ -83,18 +87,20 @@ class RegisterBank {
>      //        register size anywhere (we could sum the sizes of the subregisters
>      //        but there may be additional bits too) and we can't derive it from
>      //        the VT's reliably due to Untyped.
> -    if (RCWithLargestRegsSize == nullptr)
> -      RCWithLargestRegsSize = RC;
> -    else if (RCWithLargestRegsSize->RSI.get(DefaultMode).SpillSize <
> -             RC->RSI.get(DefaultMode).SpillSize)
> -      RCWithLargestRegsSize = RC;
> -    assert(RCWithLargestRegsSize && "RC was nullptr?");
> -
> +    unsigned NumModeIds = RCsWithLargestRegSize.size();
> +    for (unsigned M = 0; M < NumModeIds; ++M) {
> +      if (RCsWithLargestRegSize[M] == nullptr)
> +        RCsWithLargestRegSize[M] = RC;
> +      else if (RCsWithLargestRegSize[M]->RSI.get(M).SpillSize <
> +              RC->RSI.get(M).SpillSize)
> +        RCsWithLargestRegSize[M] = RC;
> +      assert(RCsWithLargestRegSize[M] && "RC was nullptr?");
> +    }
>      RCs.emplace_back(RC);
>    }
>
> -  const CodeGenRegisterClass *getRCWithLargestRegsSize() const {
> -    return RCWithLargestRegsSize;
> +  const CodeGenRegisterClass *getRCWithLargestRegsSize(unsigned HwMode) const {
> +    return RCsWithLargestRegSize[HwMode];
>    }
>
>    iterator_range<typename RegisterClassesTy::const_iterator>
> @@ -147,7 +153,7 @@ void RegisterBankEmitter::emitBaseClassDefinition(
>    OS << "private:\n"
>       << "  static RegisterBank *RegBanks[];\n\n"
>       << "protected:\n"
> -     << "  " << TargetName << "GenRegisterBankInfo();\n"
> +     << "  " << TargetName << "GenRegisterBankInfo(unsigned HwMode = 0);\n"
>       << "\n";
>  }
>
> @@ -213,6 +219,7 @@ void RegisterBankEmitter::emitBaseClassImplementation(
>      raw_ostream &OS, StringRef TargetName,
>      std::vector<RegisterBank> &Banks) {
>    const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
> +  const CodeGenHwModes &CGH = Target.getHwModes();
>
>    OS << "namespace llvm {\n"
>       << "namespace " << TargetName << " {\n";
> @@ -240,14 +247,30 @@ void RegisterBankEmitter::emitBaseClassImplementation(
>    }
>    OS << "\n";
>
> +  unsigned NumModeIds = CGH.getNumModeIds();
> +  for (const auto &Bank : Banks) {
> +    OS << "const unsigned " << Bank.getSizesArrayName() << "[] = {\n";
> +    for (unsigned M = 0; M < NumModeIds; ++M) {
> +      const CodeGenRegisterClass &RC = *Bank.getRCWithLargestRegsSize(M);
> +      unsigned Size = RC.RSI.get(M).SpillSize;
> +      OS << "    // Mode = " << M << " (";
> +      if (M == 0)
> +        OS << "Default";
> +      else
> +        OS << CGH.getMode(M).Name;
> +      OS << ")\n";
> +      OS << "    " << Size << ",\n";
> +    }
> +    OS << "};\n";
> +  }
> +  OS << "\n";
> +
>    for (const auto &Bank : Banks) {
>      std::string QualifiedBankID =
>          (TargetName + "::" + Bank.getEnumeratorName()).str();
> -    const CodeGenRegisterClass &RC = *Bank.getRCWithLargestRegsSize();
> -    unsigned Size = RC.RSI.get(DefaultMode).SpillSize;
>      OS << "RegisterBank " << Bank.getInstanceVarName() << "(/* ID */ "
>         << QualifiedBankID << ", /* Name */ \"" << Bank.getName()
> -       << "\", /* Size */ " << Size << ", "
> +       << "\", /* Sizes */ " << Bank.getInstanceVarName() << "Sizes, "
>         << "/* CoveredRegClasses */ " << Bank.getCoverageArrayName()
>         << ", /* NumRegClasses */ "
>         << RegisterClassHierarchy.getRegClasses().size() << ");\n";
> @@ -262,9 +285,9 @@ void RegisterBankEmitter::emitBaseClassImplementation(
>    OS << "};\n\n";
>
>    OS << TargetName << "GenRegisterBankInfo::" << TargetName
> -     << "GenRegisterBankInfo()\n"
> +     << "GenRegisterBankInfo(unsigned HwMode)\n"
>       << "    : RegisterBankInfo(RegBanks, " << TargetName
> -     << "::NumRegisterBanks) {\n"
> +     << "::NumRegisterBanks, HwMode) {\n"
>       << "  // Assert that RegBank indices match their ID's\n"
>       << "#ifndef NDEBUG\n"
>       << "  unsigned Index = 0;\n"
> @@ -278,11 +301,12 @@ void RegisterBankEmitter::emitBaseClassImplementation(
>  void RegisterBankEmitter::run(raw_ostream &OS) {
>    StringRef TargetName = Target.getName();
>    const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
> +  const CodeGenHwModes &CGH = Target.getHwModes();
>
>    std::vector<RegisterBank> Banks;
>    for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) {
>      SmallPtrSet<const CodeGenRegisterClass *, 8> VisitedRCs;
> -    RegisterBank Bank(*V);
> +    RegisterBank Bank(*V, CGH.getNumModeIds());
>
>      for (const CodeGenRegisterClass *RC :
>           Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list