diff --git a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h index 06a38770b8f..f610bc02b6f 100644 --- a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h +++ b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h @@ -561,7 +561,7 @@ private: /// Find the best mapping for \p MI from \p PossibleMappings. /// \return a reference on the best mapping in \p PossibleMappings. - RegisterBankInfo::InstructionMapping & + const RegisterBankInfo::InstructionMapping & findBestMapping(MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, SmallVectorImpl &RepairPts); diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index 1153e529d11..f32233b3a9e 100644 --- a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -264,7 +264,7 @@ public: /// 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; + typedef SmallVector InstructionMappings; /// Helper class used to get/create the virtual registers that will be used /// to replace the MachineOperand when applying a mapping. @@ -391,6 +391,11 @@ protected: mutable DenseMap> MapOfOperandsMappings; + /// Keep dynamically allocated InstructionMapping in a separate map. + /// This shouldn't be needed when everything gets TableGen'ed. + mutable DenseMap> + MapOfInstructionMappings; + /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks /// RegisterBank instances. RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks); @@ -428,7 +433,7 @@ protected: /// register, a register class, or a register bank. /// In other words, this method will likely fail to find a mapping for /// any generic opcode that has not been lowered by target specific code. - InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const; + const InstructionMapping &getInstrMappingImpl(const MachineInstr &MI) const; /// Get the uniquely generated PartialMapping for the /// given arguments. @@ -481,6 +486,33 @@ protected: std::initializer_list OpdsMapping) const; /// @} + /// \name Methods to get a uniquely generated InstructionMapping. + /// @{ + +private: + /// Method to get a uniquely generated InstructionMapping. + const InstructionMapping & + getInstructionMappingImpl(bool IsInvalid, unsigned ID = InvalidMappingID, + unsigned Cost = 0, + const ValueMapping *OperandsMapping = nullptr, + unsigned NumOperands = 0) const; + +public: + /// Method to get a uniquely generated InstructionMapping. + const InstructionMapping & + getInstructionMapping(unsigned ID, unsigned Cost, + const ValueMapping *OperandsMapping, + unsigned NumOperands) const { + return getInstructionMappingImpl(/*IsInvalid*/ false, ID, Cost, + OperandsMapping, NumOperands); + } + + /// Method to get a uniquely generated invalid InstructionMapping. + const InstructionMapping &getInvalidInstructionMapping() const { + return getInstructionMappingImpl(/*IsInvalid*/ true); + } + /// @} + /// Get the register bank for the \p OpIdx-th operand of \p MI form /// the encoding constraints, if any. /// @@ -606,7 +638,8 @@ public: /// /// \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; + virtual const InstructionMapping & + getInstrMapping(const MachineInstr &MI) const; /// Get the alternative mappings for \p MI. /// Alternative in the sense different from getInstrMapping. diff --git a/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/lib/CodeGen/GlobalISel/RegBankSelect.cpp index f935390a8d1..7248f50945d 100644 --- a/lib/CodeGen/GlobalISel/RegBankSelect.cpp +++ b/lib/CodeGen/GlobalISel/RegBankSelect.cpp @@ -213,21 +213,23 @@ uint64_t RegBankSelect::getRepairCost( return UINT_MAX; } -RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( +const RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, SmallVectorImpl &RepairPts) { assert(!PossibleMappings.empty() && "Do not know how to map this instruction"); - RegisterBankInfo::InstructionMapping *BestMapping = nullptr; + const RegisterBankInfo::InstructionMapping *BestMapping = nullptr; MappingCost Cost = MappingCost::ImpossibleCost(); SmallVector LocalRepairPts; - for (RegisterBankInfo::InstructionMapping &CurMapping : PossibleMappings) { - MappingCost CurCost = computeMapping(MI, CurMapping, LocalRepairPts, &Cost); + for (const RegisterBankInfo::InstructionMapping *CurMapping : + PossibleMappings) { + MappingCost CurCost = + computeMapping(MI, *CurMapping, LocalRepairPts, &Cost); if (CurCost < Cost) { DEBUG(dbgs() << "New best: " << CurCost << '\n'); Cost = CurCost; - BestMapping = &CurMapping; + BestMapping = CurMapping; RepairPts.clear(); for (RepairingPlacement &RepairPt : LocalRepairPts) RepairPts.emplace_back(std::move(RepairPt)); @@ -237,7 +239,7 @@ RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping( // If none of the mapping worked that means they are all impossible. // Thus, pick the first one and set an impossible repairing point. // It will trigger the failed isel mode. - BestMapping = &(*PossibleMappings.begin()); + BestMapping = *PossibleMappings.begin(); RepairPts.emplace_back( RepairingPlacement(MI, 0, *TRI, *this, RepairingPlacement::Impossible)); } else @@ -543,10 +545,10 @@ bool RegBankSelect::assignInstr(MachineInstr &MI) { // Remember the repairing placement for all the operands. SmallVector RepairPts; - RegisterBankInfo::InstructionMapping BestMapping; + const RegisterBankInfo::InstructionMapping *BestMapping; if (OptMode == RegBankSelect::Mode::Fast) { - BestMapping = RBI->getInstrMapping(MI); - MappingCost DefaultCost = computeMapping(MI, BestMapping, RepairPts); + BestMapping = &RBI->getInstrMapping(MI); + MappingCost DefaultCost = computeMapping(MI, *BestMapping, RepairPts); (void)DefaultCost; if (DefaultCost == MappingCost::ImpossibleCost()) return false; @@ -555,16 +557,16 @@ bool RegBankSelect::assignInstr(MachineInstr &MI) { RBI->getInstrPossibleMappings(MI); if (PossibleMappings.empty()) return false; - BestMapping = std::move(findBestMapping(MI, PossibleMappings, RepairPts)); + BestMapping = &findBestMapping(MI, PossibleMappings, RepairPts); } // Make sure the mapping is valid for MI. - assert(BestMapping.verify(MI) && "Invalid instruction mapping"); + assert(BestMapping->verify(MI) && "Invalid instruction mapping"); - DEBUG(dbgs() << "Best Mapping: " << BestMapping << '\n'); + DEBUG(dbgs() << "Best Mapping: " << *BestMapping << '\n'); // After this call, MI may not be valid anymore. // Do not use it. - return applyMapping(MI, BestMapping, RepairPts); + return applyMapping(MI, *BestMapping, RepairPts); } bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) { diff --git a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index d5ae9a6776a..a841902feed 100644 --- a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -45,6 +45,10 @@ STATISTIC(NumOperandsMappingsCreated, "Number of operands mappings dynamically created"); STATISTIC(NumOperandsMappingsAccessed, "Number of operands mappings dynamically accessed"); +STATISTIC(NumInstructionMappingsCreated, + "Number of instruction mappings dynamically created"); +STATISTIC(NumInstructionMappingsAccessed, + "Number of instruction mappings dynamically accessed"); const unsigned RegisterBankInfo::DefaultMappingID = UINT_MAX; const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1; @@ -137,7 +141,7 @@ static bool isCopyLike(const MachineInstr &MI) { MI.getOpcode() == TargetOpcode::REG_SEQUENCE; } -RegisterBankInfo::InstructionMapping +const RegisterBankInfo::InstructionMapping & RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { // For copies we want to walk over the operands and try to find one // that has a register bank since the instruction itself will not get @@ -147,9 +151,6 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { // is important. The rest is not constrained. unsigned NumOperandsForMapping = IsCopyLike ? 1 : MI.getNumOperands(); - RegisterBankInfo::InstructionMapping Mapping(DefaultMappingID, /*Cost*/ 1, - /*OperandsMapping*/ nullptr, - NumOperandsForMapping); const MachineFunction &MF = *MI.getParent()->getParent(); const TargetSubtargetInfo &STI = MF.getSubtarget(); const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); @@ -190,7 +191,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { if (!IsCopyLike) // MI does not carry enough information to guess the mapping. - return InstructionMapping(); + return getInvalidInstructionMapping(); continue; } } @@ -206,11 +207,13 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { if (IsCopyLike && !CompleteMapping) // No way to deduce the type from what we have. - return InstructionMapping(); + return getInvalidInstructionMapping(); assert(CompleteMapping && "Setting an uncomplete mapping"); - Mapping.setOperandsMapping(getOperandsMapping(OperandsMapping)); - return Mapping; + return getInstructionMapping( + DefaultMappingID, /*Cost*/ 1, + /*OperandsMapping*/ getOperandsMapping(OperandsMapping), + NumOperandsForMapping); } /// Hashing function for PartialMapping. @@ -320,9 +323,44 @@ const RegisterBankInfo::ValueMapping *RegisterBankInfo::getOperandsMapping( return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end()); } -RegisterBankInfo::InstructionMapping +static hash_code +hashInstructionMapping(unsigned ID, unsigned Cost, + const RegisterBankInfo::ValueMapping *OperandsMapping, + unsigned NumOperands) { + return hash_combine(ID, Cost, OperandsMapping, NumOperands); +} + +const RegisterBankInfo::InstructionMapping & +RegisterBankInfo::getInstructionMappingImpl( + bool IsInvalid, unsigned ID, unsigned Cost, + const RegisterBankInfo::ValueMapping *OperandsMapping, + unsigned NumOperands) const { + assert(((IsInvalid && ID == InvalidMappingID && Cost == 0 && + OperandsMapping == nullptr && NumOperands == 0) || + !IsInvalid) && + "Mismatch argument for invalid input"); + ++NumInstructionMappingsAccessed; + + hash_code Hash = + hashInstructionMapping(ID, Cost, OperandsMapping, NumOperands); + const auto &It = MapOfInstructionMappings.find(Hash); + if (It != MapOfInstructionMappings.end()) + return *It->second; + + ++NumInstructionMappingsCreated; + + auto &InstrMapping = MapOfInstructionMappings[Hash]; + if (IsInvalid) + InstrMapping = llvm::make_unique(); + else + InstrMapping = llvm::make_unique( + ID, Cost, OperandsMapping, NumOperands); + return *InstrMapping; +} + +const RegisterBankInfo::InstructionMapping & RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { - RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI); + const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); if (Mapping.isValid()) return Mapping; llvm_unreachable("The target must implement this"); @@ -332,14 +370,14 @@ RegisterBankInfo::InstructionMappings RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const { InstructionMappings PossibleMappings; // Put the default mapping first. - PossibleMappings.push_back(getInstrMapping(MI)); + 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)); + for (const InstructionMapping *AltMapping : AltMappings) + PossibleMappings.push_back(AltMapping); #ifndef NDEBUG - for (const InstructionMapping &Mapping : PossibleMappings) - assert(Mapping.verify(MI) && "Mapping is invalid"); + for (const InstructionMapping *Mapping : PossibleMappings) + assert(Mapping->verify(MI) && "Mapping is invalid"); #endif return PossibleMappings; } diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 6f9021c4a03..5f895903da6 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -260,15 +260,15 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings( if (MI.getNumOperands() != 3) break; InstructionMappings AltMappings; - InstructionMapping GPRMapping( + const InstructionMapping &GPRMapping = getInstructionMapping( /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size), /*NumOperands*/ 3); - InstructionMapping FPRMapping( + const InstructionMapping &FPRMapping = getInstructionMapping( /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size), /*NumOperands*/ 3); - AltMappings.emplace_back(std::move(GPRMapping)); - AltMappings.emplace_back(std::move(FPRMapping)); + AltMappings.push_back(&GPRMapping); + AltMappings.push_back(&FPRMapping); return AltMappings; } case TargetOpcode::G_BITCAST: { @@ -282,29 +282,29 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings( break; InstructionMappings AltMappings; - InstructionMapping GPRMapping( + const InstructionMapping &GPRMapping = getInstructionMapping( /*ID*/ 1, /*Cost*/ 1, getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size), /*NumOperands*/ 2); - InstructionMapping FPRMapping( + const InstructionMapping &FPRMapping = getInstructionMapping( /*ID*/ 2, /*Cost*/ 1, getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size), /*NumOperands*/ 2); - InstructionMapping GPRToFPRMapping( + const InstructionMapping &GPRToFPRMapping = getInstructionMapping( /*ID*/ 3, /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size), getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size), /*NumOperands*/ 2); - InstructionMapping FPRToGPRMapping( + const InstructionMapping &FPRToGPRMapping = getInstructionMapping( /*ID*/ 3, /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size), getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size), /*NumOperands*/ 2); - AltMappings.emplace_back(std::move(GPRMapping)); - AltMappings.emplace_back(std::move(FPRMapping)); - AltMappings.emplace_back(std::move(GPRToFPRMapping)); - AltMappings.emplace_back(std::move(FPRToGPRMapping)); + AltMappings.push_back(&GPRMapping); + AltMappings.push_back(&FPRMapping); + AltMappings.push_back(&GPRToFPRMapping); + AltMappings.push_back(&FPRToGPRMapping); return AltMappings; } case TargetOpcode::G_LOAD: { @@ -318,21 +318,21 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings( break; InstructionMappings AltMappings; - InstructionMapping GPRMapping( + const InstructionMapping &GPRMapping = getInstructionMapping( /*ID*/ 1, /*Cost*/ 1, getOperandsMapping({getValueMapping(PMI_FirstGPR, Size), // Addresses are GPR 64-bit. getValueMapping(PMI_FirstGPR, 64)}), /*NumOperands*/ 2); - InstructionMapping FPRMapping( + const InstructionMapping &FPRMapping = getInstructionMapping( /*ID*/ 2, /*Cost*/ 1, getOperandsMapping({getValueMapping(PMI_FirstFPR, Size), // Addresses are GPR 64-bit. getValueMapping(PMI_FirstGPR, 64)}), /*NumOperands*/ 2); - AltMappings.emplace_back(std::move(GPRMapping)); - AltMappings.emplace_back(std::move(FPRMapping)); + AltMappings.push_back(&GPRMapping); + AltMappings.push_back(&FPRMapping); return AltMappings; } default: @@ -373,8 +373,9 @@ static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) { return false; } -RegisterBankInfo::InstructionMapping -AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) { +const RegisterBankInfo::InstructionMapping & +AArch64RegisterBankInfo::getSameKindOfOperandsMapping( + const MachineInstr &MI) const { const unsigned Opc = MI.getOpcode(); const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); @@ -411,11 +412,11 @@ AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) { } #endif // End NDEBUG. - return InstructionMapping{DefaultMappingID, 1, getValueMapping(RBIdx, Size), - NumOperands}; + return getInstructionMapping(DefaultMappingID, 1, + getValueMapping(RBIdx, Size), NumOperands); } -RegisterBankInfo::InstructionMapping +const RegisterBankInfo::InstructionMapping & AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const unsigned Opc = MI.getOpcode(); const MachineFunction &MF = *MI.getParent()->getParent(); @@ -424,7 +425,8 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { // Try the default logic for non-generic instructions that are either copies // or already have some operands assigned to banks. if (!isPreISelGenericOpcode(Opc)) { - RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI); + const RegisterBankInfo::InstructionMapping &Mapping = + getInstrMappingImpl(MI); if (Mapping.isValid()) return Mapping; } @@ -462,15 +464,15 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank; const RegisterBank &SrcRB = SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank; - return InstructionMapping{ + return getInstructionMapping( DefaultMappingID, copyCost(DstRB, SrcRB, Size), getCopyMapping(DstRB.getID(), SrcRB.getID(), Size), - /*NumOperands*/ 2}; + /*NumOperands*/ 2); } case TargetOpcode::G_SEQUENCE: // FIXME: support this, but the generic code is really not going to do // anything sane. - return InstructionMapping(); + return getInvalidInstructionMapping(); default: break; } @@ -533,19 +535,17 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { } // Finally construct the computed mapping. - RegisterBankInfo::InstructionMapping Mapping = - InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands}; SmallVector OpdsMapping(NumOperands); for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) { auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]); if (!Mapping->isValid()) - return InstructionMapping(); + return getInvalidInstructionMapping(); OpdsMapping[Idx] = Mapping; } } - Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping)); - return Mapping; + return getInstructionMapping(DefaultMappingID, Cost, + getOperandsMapping(OpdsMapping), NumOperands); } diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.h b/lib/Target/AArch64/AArch64RegisterBankInfo.h index 0a795a42c0b..6d74a47095a 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.h +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.h @@ -98,8 +98,8 @@ class AArch64RegisterBankInfo final : public AArch64GenRegisterBankInfo { /// /// \return An InstructionMappings with a statically allocated /// OperandsMapping. - static InstructionMapping - getSameKindOfOperandsMapping(const MachineInstr &MI); + const InstructionMapping & + getSameKindOfOperandsMapping(const MachineInstr &MI) const; public: AArch64RegisterBankInfo(const TargetRegisterInfo &TRI); @@ -113,7 +113,8 @@ public: InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override; - InstructionMapping getInstrMapping(const MachineInstr &MI) const override; + const InstructionMapping & + getInstrMapping(const MachineInstr &MI) const override; }; } // End llvm namespace. #endif diff --git a/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp b/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp index a5edc0c3b93..623b2c88ab8 100644 --- a/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp +++ b/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp @@ -82,25 +82,28 @@ AMDGPURegisterBankInfo::getInstrAlternativeMappings( switch (MI.getOpcode()) { case TargetOpcode::G_LOAD: { // FIXME: Should we be hard coding the size for these mappings? - InstructionMapping SSMapping(1, 1, - getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), - AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}), - 2); // Num Operands - AltMappings.emplace_back(std::move(SSMapping)); + const InstructionMapping &SSMapping = getInstructionMapping( + 1, 1, getOperandsMapping( + {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), + AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}), + 2); // Num Operands + AltMappings.push_back(&SSMapping); - InstructionMapping VVMapping(2, 1, - getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), - AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}), - 2); // Num Operands - AltMappings.emplace_back(std::move(VVMapping)); + const InstructionMapping &VVMapping = getInstructionMapping( + 2, 1, getOperandsMapping( + {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), + AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}), + 2); // Num Operands + AltMappings.push_back(&VVMapping); // FIXME: Should this be the pointer-size (64-bits) or the size of the // register that will hold the bufffer resourc (128-bits). - InstructionMapping VSMapping(3, 1, - getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), - AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}), - 2); // Num Operands - AltMappings.emplace_back(std::move(VSMapping)); + const InstructionMapping &VSMapping = getInstructionMapping( + 3, 1, getOperandsMapping( + {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), + AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}), + 2); // Num Operands + AltMappings.push_back(&VSMapping); return AltMappings; @@ -124,13 +127,11 @@ static bool isInstrUniform(const MachineInstr &MI) { return AMDGPU::isUniformMMO(MMO); } -RegisterBankInfo::InstructionMapping +const RegisterBankInfo::InstructionMapping & AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const { const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); - RegisterBankInfo::InstructionMapping Mapping = - InstructionMapping{1, 1, nullptr, MI.getNumOperands()}; SmallVector OpdsMapping(MI.getNumOperands()); unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); @@ -150,32 +151,34 @@ AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const { OpdsMapping[0] = ValMapping; OpdsMapping[1] = PtrMapping; - Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping)); + const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping( + 1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands()); return Mapping; // FIXME: Do we want to add a mapping for FLAT load, or should we just // handle that during instruction selection? } -RegisterBankInfo::InstructionMapping +const RegisterBankInfo::InstructionMapping & AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { - RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI); + const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); if (Mapping.isValid()) return Mapping; const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); - Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()}; SmallVector OpdsMapping(MI.getNumOperands()); + bool IsComplete = true; switch (MI.getOpcode()) { - default: break; + default: + IsComplete = false; + break; case AMDGPU::G_CONSTANT: { unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); - Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping)); - return Mapping; + break; } case AMDGPU::G_GEP: { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { @@ -185,8 +188,7 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits(); OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); } - Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping)); - return Mapping; + break; } case AMDGPU::G_STORE: { assert(MI.getOperand(0).isReg()); @@ -203,28 +205,27 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { OpdsMapping[0] = ValMapping; OpdsMapping[1] = PtrMapping; - Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping)); - return Mapping; + break; } case AMDGPU::G_LOAD: return getInstrMappingForLoad(MI); } - unsigned BankID = AMDGPU::SGPRRegBankID; + if (!IsComplete) { + unsigned BankID = AMDGPU::SGPRRegBankID; - Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()}; - unsigned Size = 0; - for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) { - // If the operand is not a register default to the size of the previous - // operand. - // FIXME: Can't we pull the types from the MachineInstr rather than the - // operands. - if (MI.getOperand(Idx).isReg()) - Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI); - OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size)); + unsigned Size = 0; + for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) { + // If the operand is not a register default to the size of the previous + // operand. + // FIXME: Can't we pull the types from the MachineInstr rather than the + // operands. + if (MI.getOperand(Idx).isReg()) + Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI); + OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size)); + } } - Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping)); - - return Mapping; + return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), + MI.getNumOperands()); } diff --git a/lib/Target/AMDGPU/AMDGPURegisterBankInfo.h b/lib/Target/AMDGPU/AMDGPURegisterBankInfo.h index f13bde87ef2..7c198a1b8a3 100644 --- a/lib/Target/AMDGPU/AMDGPURegisterBankInfo.h +++ b/lib/Target/AMDGPU/AMDGPURegisterBankInfo.h @@ -44,7 +44,7 @@ class AMDGPURegisterBankInfo : public AMDGPUGenRegisterBankInfo { /// See RegisterBankInfo::applyMapping. void applyMappingImpl(const OperandsMapper &OpdMapper) const override; - RegisterBankInfo::InstructionMapping + const RegisterBankInfo::InstructionMapping & getInstrMappingForLoad(const MachineInstr &MI) const; public: @@ -59,7 +59,8 @@ public: InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const override; - InstructionMapping getInstrMapping(const MachineInstr &MI) const override; + const InstructionMapping & + getInstrMapping(const MachineInstr &MI) const override; }; } // End llvm namespace. #endif diff --git a/lib/Target/ARM/ARMRegisterBankInfo.cpp b/lib/Target/ARM/ARMRegisterBankInfo.cpp index 7325817d446..13a32211f88 100644 --- a/lib/Target/ARM/ARMRegisterBankInfo.cpp +++ b/lib/Target/ARM/ARMRegisterBankInfo.cpp @@ -196,14 +196,14 @@ const RegisterBank &ARMRegisterBankInfo::getRegBankFromRegClass( llvm_unreachable("Switch should handle all register classes"); } -RegisterBankInfo::InstructionMapping +const RegisterBankInfo::InstructionMapping & ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { auto Opc = MI.getOpcode(); // Try the default logic for non-generic instructions that are either copies // or already have some operands assigned to banks. if (!isPreISelGenericOpcode(Opc)) { - InstructionMapping Mapping = getInstrMappingImpl(MI); + const InstructionMapping &Mapping = getInstrMappingImpl(MI); if (Mapping.isValid()) return Mapping; } @@ -258,7 +258,7 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { LLT Ty2 = MRI.getType(MI.getOperand(3).getReg()); if (Ty.getSizeInBits() != 64 || Ty1.getSizeInBits() != 32 || Ty2.getSizeInBits() != 32) - return InstructionMapping{}; + return getInvalidInstructionMapping(); OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx], &ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr, @@ -271,14 +271,14 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { LLT Ty1 = MRI.getType(MI.getOperand(1).getReg()); if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 64 || MI.getOperand(2).getImm() % 32 != 0) - return InstructionMapping{}; + return getInvalidInstructionMapping(); OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], &ARM::ValueMappings[ARM::DPR3OpsIdx], nullptr, nullptr}); break; } default: - return InstructionMapping{}; + return getInvalidInstructionMapping(); } #ifndef NDEBUG @@ -292,6 +292,6 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { } #endif - return InstructionMapping{DefaultMappingID, /*Cost=*/1, OperandsMapping, - NumOperands}; + return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, + NumOperands); } diff --git a/lib/Target/ARM/ARMRegisterBankInfo.h b/lib/Target/ARM/ARMRegisterBankInfo.h index 5222c1e6389..9650b358f31 100644 --- a/lib/Target/ARM/ARMRegisterBankInfo.h +++ b/lib/Target/ARM/ARMRegisterBankInfo.h @@ -36,7 +36,8 @@ public: const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC) const override; - InstructionMapping getInstrMapping(const MachineInstr &MI) const override; + const InstructionMapping & + getInstrMapping(const MachineInstr &MI) const override; }; } // End llvm namespace. #endif diff --git a/lib/Target/X86/X86RegisterBankInfo.cpp b/lib/Target/X86/X86RegisterBankInfo.cpp index 0f8a750a023..efd3df26dd4 100644 --- a/lib/Target/X86/X86RegisterBankInfo.cpp +++ b/lib/Target/X86/X86RegisterBankInfo.cpp @@ -139,8 +139,9 @@ bool X86RegisterBankInfo::getInstrValueMapping( return true; } -RegisterBankInfo::InstructionMapping -X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, bool isFP) { +const RegisterBankInfo::InstructionMapping & +X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, + bool isFP) const { const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); @@ -152,10 +153,10 @@ X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, bool isFP) { llvm_unreachable("Unsupported operand mapping yet."); auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3); - return InstructionMapping{DefaultMappingID, 1, Mapping, NumOperands}; + return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands); } -RegisterBankInfo::InstructionMapping +const RegisterBankInfo::InstructionMapping & X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); @@ -164,7 +165,7 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { // Try the default logic for non-generic instructions that are either copies // or already have some operands assigned to banks. if (!isPreISelGenericOpcode(Opc)) { - InstructionMapping Mapping = getInstrMappingImpl(MI); + const InstructionMapping &Mapping = getInstrMappingImpl(MI); if (Mapping.isValid()) return Mapping; } @@ -193,10 +194,10 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { // Finally construct the computed mapping. SmallVector OpdsMapping(NumOperands); if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping)) - return InstructionMapping(); + return getInvalidInstructionMapping(); - return InstructionMapping{DefaultMappingID, /* Cost */ 1, - getOperandsMapping(OpdsMapping), NumOperands}; + return getInstructionMapping(DefaultMappingID, /* Cost */ 1, + getOperandsMapping(OpdsMapping), NumOperands); } void X86RegisterBankInfo::applyMappingImpl( @@ -231,10 +232,10 @@ X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const { if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping)) break; - RegisterBankInfo::InstructionMapping Mapping = InstructionMapping{ - /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands}; + const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping( + /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands); InstructionMappings AltMappings; - AltMappings.emplace_back(std::move(Mapping)); + AltMappings.push_back(&Mapping); return AltMappings; } default: diff --git a/lib/Target/X86/X86RegisterBankInfo.h b/lib/Target/X86/X86RegisterBankInfo.h index a1e01a9ab94..e227880427f 100644 --- a/lib/Target/X86/X86RegisterBankInfo.h +++ b/lib/Target/X86/X86RegisterBankInfo.h @@ -46,8 +46,8 @@ private: /// Get an instruction mapping. /// \return An InstructionMappings with a statically allocated /// OperandsMapping. - static InstructionMapping getSameOperandsMapping(const MachineInstr &MI, - bool isFP); + const InstructionMapping &getSameOperandsMapping(const MachineInstr &MI, + bool isFP) const; /// Track the bank of each instruction operand(register) static void @@ -74,7 +74,8 @@ public: /// See RegisterBankInfo::applyMapping. void applyMappingImpl(const OperandsMapper &OpdMapper) const override; - InstructionMapping getInstrMapping(const MachineInstr &MI) const override; + const InstructionMapping & + getInstrMapping(const MachineInstr &MI) const override; }; } // namespace llvm