From: Quentin Colombet Date: Sat, 24 Sep 2016 04:53:52 +0000 (+0000) Subject: [RegisterBankInfo] Uniquely generate ValueMapping. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9545266289f5f0d6d43edc2812ec1755e7f769b6;p=llvm [RegisterBankInfo] Uniquely generate ValueMapping. This is a step toward statically allocate ValueMapping. Like the previous few commits, the goal is to move toward a TableGen'ed like structure with no dynamic allocation at all. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282324 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index dd9572e60c8..8ccc0421c54 100644 --- a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -120,11 +120,11 @@ public: unsigned Cost; /// Mapping of all the operands. /// Note: Use a SmallVector to avoid heap allocation in most cases. - SmallVector OperandsMapping; + SmallVector OperandsMapping; /// Number of operands. unsigned NumOperands; - ValueMapping &getOperandMapping(unsigned i) { + const ValueMapping *&getOperandMapping(unsigned i) { assert(i < getNumOperands() && "Out of bound operand"); return OperandsMapping[i]; } @@ -142,7 +142,7 @@ public: : ID(ID), Cost(Cost), NumOperands(NumOperands) { assert(getID() != InvalidMappingID && "Use the default constructor for invalid mapping"); - OperandsMapping.resize(getNumOperands()); + OperandsMapping.resize(getNumOperands(), nullptr); } /// Default constructor. @@ -159,13 +159,24 @@ public: unsigned getNumOperands() const { return NumOperands; } /// Get the value mapping of the ith operand. + /// \pre The mapping for the ith operand has been set. + /// \pre The ith operand is a register. const ValueMapping &getOperandMapping(unsigned i) const { - return const_cast(this)->getOperandMapping(i); + const ValueMapping *&ValMapping = + const_cast(this)->getOperandMapping(i); + assert(ValMapping && "Trying to get the mapping for a non-reg operand?"); + return *ValMapping; + } + + /// Check if the value mapping of the ith operand has been set. + bool isOperandMappingSet(unsigned i) const { + return const_cast(this)->getOperandMapping(i) != + nullptr; } /// Get the value mapping of the ith operand. void setOperandMapping(unsigned i, const ValueMapping &ValMapping) { - getOperandMapping(i) = ValMapping; + getOperandMapping(i) = &ValMapping; } /// Check whether this object is valid. @@ -300,6 +311,10 @@ protected: /// This shouldn't be needed when everything gets TableGen'ed. mutable DenseMap MapOfPartialMappings; + /// Keep dynamically allocated ValueMapping in a separate map. + /// This shouldn't be needed when everything gets TableGen'ed. + mutable DenseMap MapOfValueMappings; + /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks /// RegisterBank instances. /// @@ -373,6 +388,19 @@ protected: const PartialMapping &getPartialMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const; + /// Methods to get a uniquely generated ValueMapping. + /// @{ + + /// The most common ValueMapping consists of a single PartialMapping. + /// Feature a method for that. + const ValueMapping &getValueMapping(unsigned StartIdx, unsigned Length, + const RegisterBank &RegBank) const; + + /// Get the ValueMapping for the given arguments. + const ValueMapping &getValueMapping(const PartialMapping *BreakDown, + unsigned NumBreakDowns) const; + /// @} + /// Get the register bank for the \p OpIdx-th operand of \p MI form /// the encoding constraints, if any. /// @@ -578,6 +606,10 @@ operator<<(raw_ostream &OS, const RegisterBankInfo::OperandsMapper &OpdMapper) { OpdMapper.print(OS, /*ForDebug*/ false); return OS; } + +/// Hashing function for PartialMapping. +/// It is required for the hashing of ValueMapping. +hash_code hash_value(const RegisterBankInfo::PartialMapping &PartMapping); } // End namespace llvm. #endif diff --git a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 172067233a1..9c1f97e4c87 100644 --- a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -57,6 +57,8 @@ RegisterBankInfo::RegisterBankInfo(RegisterBank **RegBanks, RegisterBankInfo::~RegisterBankInfo() { for (auto It : MapOfPartialMappings) delete It.second; + for (auto It : MapOfValueMappings) + delete It.second; } bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const { @@ -283,8 +285,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { } RegBank = CurRegBank; RegSize = getSizeInBits(Reg, MRI, TRI); - Mapping.setOperandMapping( - OpIdx, ValueMapping{&getPartialMapping(0, RegSize, *CurRegBank), 1}); + Mapping.setOperandMapping(OpIdx, getValueMapping(0, RegSize, *CurRegBank)); } if (CompleteMapping) @@ -306,23 +307,33 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { continue; // If a mapping already exists, do not touch it. - if (static_cast(&Mapping) - ->getOperandMapping(OpIdx) - .NumBreakDowns) + if (Mapping.isOperandMappingSet(OpIdx)) continue; - Mapping.setOperandMapping( - OpIdx, ValueMapping{&getPartialMapping(0, RegSize, *RegBank), 1}); + Mapping.setOperandMapping(OpIdx, getValueMapping(0, RegSize, *RegBank)); } return Mapping; } +/// Hashing function for PartialMapping. +static hash_code hashPartialMapping(unsigned StartIdx, unsigned Length, + const RegisterBank *RegBank) { + return hash_combine(StartIdx, Length, RegBank ? RegBank->getID() : 0); +} + +/// Overloaded version of hash_value for a PartialMapping. +hash_code +llvm::hash_value(const RegisterBankInfo::PartialMapping &PartMapping) { + return hashPartialMapping(PartMapping.StartIdx, PartMapping.Length, + PartMapping.RegBank); +} + const RegisterBankInfo::PartialMapping & RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const { ++NumPartialMappingsAccessed; - hash_code Hash = hash_combine(StartIdx, Length, RegBank.getID()); + hash_code Hash = hashPartialMapping(StartIdx, Length, &RegBank); const auto &It = MapOfPartialMappings.find(Hash); if (It != MapOfPartialMappings.end()) return *It->second; @@ -334,6 +345,34 @@ RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length, return *PartMapping; } +const RegisterBankInfo::ValueMapping & +RegisterBankInfo::getValueMapping(unsigned StartIdx, unsigned Length, + const RegisterBank &RegBank) const { + return getValueMapping(&getPartialMapping(StartIdx, Length, RegBank), 1); +} + +const RegisterBankInfo::ValueMapping & +RegisterBankInfo::getValueMapping(const PartialMapping *BreakDown, + unsigned NumBreakDowns) const { + hash_code Hash; + if (LLVM_LIKELY(NumBreakDowns == 1)) + Hash = hash_value(*BreakDown); + else { + SmallVector Hashes; + for (unsigned Idx = 0; Idx != NumBreakDowns; ++Idx) + Hashes.push_back(hash_value(BreakDown[Idx])); + Hash = hash_combine_range(Hashes.begin(), Hashes.end()); + } + + const auto &It = MapOfValueMappings.find(Hash); + if (It != MapOfValueMappings.end()) + return *It->second; + + ValueMapping *&ValMapping = MapOfValueMappings[Hash]; + ValMapping = new ValueMapping{BreakDown, NumBreakDowns}; + return *ValMapping; +} + RegisterBankInfo::InstructionMapping RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI); @@ -496,16 +535,18 @@ bool RegisterBankInfo::InstructionMapping::verify( for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { const MachineOperand &MO = MI.getOperand(Idx); - const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx); - (void)MOMapping; if (!MO.isReg()) { - assert(!MOMapping.NumBreakDowns && + assert(!isOperandMappingSet(Idx) && "We should not care about non-reg mapping"); continue; } unsigned Reg = MO.getReg(); if (!Reg) continue; + assert(isOperandMappingSet(Idx) && + "We must have a mapping for reg operands"); + const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx); + (void)MOMapping; // Register size in bits. // This size must match what the mapping expects. assert(MOMapping.verify(getSizeInBits( diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 1ef79e961df..de66c817bc0 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -205,15 +205,15 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings( InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3); for (unsigned Idx = 0; Idx != 3; ++Idx) { GPRMapping.setOperandMapping( - Idx, - ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) + - AArch64::FirstGPR], - 1}); + Idx, getValueMapping( + &AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) + + AArch64::FirstGPR], + 1)); FPRMapping.setOperandMapping( - Idx, - ValueMapping{&AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) + - AArch64::FirstFPR], - 1}); + Idx, getValueMapping( + &AArch64::PartMappings[AArch64::getRegBankBaseIdx(Size) + + AArch64::FirstFPR], + 1)); } AltMappings.emplace_back(std::move(GPRMapping)); AltMappings.emplace_back(std::move(FPRMapping)); @@ -325,7 +325,7 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) if (MI.getOperand(Idx).isReg()) Mapping.setOperandMapping( - Idx, ValueMapping{&AArch64::PartMappings[OpFinalIdx[Idx]], 1}); + Idx, getValueMapping(&AArch64::PartMappings[OpFinalIdx[Idx]], 1)); return Mapping; }