From 9af77135e5be77952ea9db5e394ba3c24a48e3b6 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Wed, 6 Apr 2016 17:45:40 +0000 Subject: [PATCH] [RegisterBankInfo] Add methods to get the possible mapping of an instruction on a register bank. This will be used by the register bank select pass to assign register banks for generic virtual registers. llvm-svn: 265573 --- .../llvm/CodeGen/GlobalISel/RegisterBankInfo.h | 69 ++++++++++++++++++++++ llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp | 11 ++++ 2 files changed, 80 insertions(+) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index 5634c21..6469806 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -16,6 +16,7 @@ #define LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H #include "llvm/ADT/APInt.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/GlobalISel/RegisterBank.h" #include "llvm/CodeGen/GlobalISel/Types.h" #include "llvm/Support/ErrorHandling.h" @@ -123,6 +124,11 @@ public: void verify(const MachineInstr &MI) const; }; + /// Convenient type to represent the alternatives for mapping an + /// instruction. + /// \todo When we move to TableGen this should be an array ref. + typedef SmallVector InstructionMappings; + protected: /// Hold the set of supported register banks. std::unique_ptr RegBanks; @@ -196,6 +202,69 @@ public: return 0; } + /// Identifier used when the related instruction mapping instance + /// is generated by target independent code. + /// Make sure not to use that identifier to avoid possible collision. + static const unsigned DefaultMappingID; + + /// Get the mapping of the different operands of \p MI + /// on the register bank. + /// This mapping should be the direct translation of \p MI. + /// The target independent implementation gives a mapping based on + /// the register classes for the target specific opcode. + /// It uses the ID RegisterBankInfo::DefaultMappingID for that mapping. + /// Make sure you do not use that ID for the alternative mapping + /// for MI. See getInstrAlternativeMappings for the alternative + /// mappings. + /// + /// For instance, if \p MI is a vector add, the mapping should + /// not be a scalarization of the add. + /// + /// \post returnedVal.verify(MI). + /// + /// \note If returnedVal does not verify MI, this would probably mean + /// that the target does not support that instruction. + virtual InstructionMapping getInstrMapping(const MachineInstr &MI) const; + + /// Get the alternative mappings for \p MI. + /// Alternative in the sense different from getInstrMapping. + virtual InstructionMappings + getInstrAlternativeMappings(const MachineInstr &MI) const { + // No alternative for MI. + return InstructionMappings(); + } + + /// Get the possible mapping for \p MI. + /// A mapping defines where the different operands may live and at what cost. + /// For instance, let us consider: + /// v0(16) = G_ADD <2 x i8> v1, v2 + /// The possible mapping could be: + /// + /// {/*ID*/VectorAdd, /*Cost*/1, /*v0*/{(0xFFFF, VPR)}, /*v1*/{(0xFFFF, VPR)}, + /// /*v2*/{(0xFFFF, VPR)}} + /// {/*ID*/ScalarAddx2, /*Cost*/2, /*v0*/{(0x00FF, GPR),(0xFF00, GPR)}, + /// /*v1*/{(0x00FF, GPR),(0xFF00, GPR)}, + /// /*v2*/{(0x00FF, GPR),(0xFF00, GPR)}} + /// + /// \note The first alternative of the returned mapping should be the + /// direct translation of \p MI current form. + /// + /// \post !returnedVal.empty(). + InstructionMappings getInstrPossibleMappings(const MachineInstr &MI) const { + InstructionMappings PossibleMappings; + // Put the default mapping first. + PossibleMappings.push_back(getInstrMapping(MI)); + // Then the alternative mapping, if any. + InstructionMappings AltMappings = getInstrAlternativeMappings(MI); + for (InstructionMapping &AltMapping : AltMappings) + PossibleMappings.emplace_back(std::move(AltMapping)); +#ifndef NDEBUG + for (const InstructionMapping &Mapping : PossibleMappings) + Mapping.verify(MI); +#endif + return PossibleMappings; + } + void verify(const TargetRegisterInfo &TRI) const; }; diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 6e83079..ee00894 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -19,6 +19,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetOpcodes.h" #include "llvm/Target/TargetRegisterInfo.h" #include // For std::max. @@ -27,6 +28,8 @@ using namespace llvm; +const unsigned RegisterBankInfo::DefaultMappingID = UINT_MAX; + RegisterBankInfo::RegisterBankInfo(unsigned NumRegBanks) : NumRegBanks(NumRegBanks) { RegBanks.reset(new RegisterBank[NumRegBanks]); @@ -176,6 +179,14 @@ void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId, } while (!WorkList.empty()); } +RegisterBankInfo::InstructionMapping +RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { + if (MI.getOpcode() > TargetOpcode::GENERIC_OP_END) { + // TODO. + } + llvm_unreachable("The target must implement this"); +} + //------------------------------------------------------------------------------ // Helper classes implementation. //------------------------------------------------------------------------------ -- 2.7.4