[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