From 7f7d585e95fcc7947a2c5fbd7e302723b2c17e6c Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Mon, 3 Oct 2016 20:20:13 +0000 Subject: [PATCH] [AArch64][RegisterBankInfo] Add getSameKindofOperandsMapping. Refactor the code so that the same function can be used for all instructions with all the same operands for up to 3 operands. This is going to be useful for cast instructions. NFC. llvm-svn: 283144 --- .../AArch64/AArch64RegisterBankInfo.cpp | 70 ++++++++++++------- lib/Target/AArch64/AArch64RegisterBankInfo.h | 10 +++ 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index fdd4de4deae..12b8db7d3e9 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -291,6 +291,47 @@ static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) { return false; } +RegisterBankInfo::InstructionMapping +AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) { + const unsigned Opc = MI.getOpcode(); + const MachineFunction &MF = *MI.getParent()->getParent(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); + + unsigned NumOperands = MI.getNumOperands(); + assert(NumOperands <= 3 && + "This code is for instructions with 3 or less operands"); + + LLT Ty = MRI.getType(MI.getOperand(0).getReg()); + unsigned Size = Ty.getSizeInBits(); + bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc); + +#ifndef NDEBUG + // Make sure all the operands are using similar size and type. + // Should probably be checked by the machine verifier. + // This code won't catch cases where the number of lanes is + // different between the operands. + // If we want to go to that level of details, it is probably + // best to check that the types are the same, period. + // Currently, we just check that the register banks are the same + // for each types. + for (unsigned Idx = 1; Idx != NumOperands; ++Idx) { + LLT OpTy = MRI.getType(MI.getOperand(Idx).getReg()); + assert(AArch64::getRegBankBaseIdxOffset(OpTy.getSizeInBits()) == + AArch64::getRegBankBaseIdxOffset(Size) && + "Operand has incompatible size"); + bool OpIsFPR = OpTy.isVector() || isPreISelGenericFloatingPointOpcode(Opc); + (void)OpIsFPR; + assert(IsFPR == OpIsFPR && "Operand has incompatible type"); + } +#endif // End NDEBUG. + + AArch64::PartialMappingIdx RBIdx = + IsFPR ? AArch64::FirstFPR : AArch64::FirstGPR; + + return InstructionMapping{DefaultMappingID, 1, + AArch64::getValueMapping(RBIdx, Size), NumOperands}; +} + RegisterBankInfo::InstructionMapping AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const unsigned Opc = MI.getOpcode(); @@ -305,7 +346,6 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { return Mapping; } - unsigned NumOperands = MI.getNumOperands(); switch (Opc) { // G_{F|S|U}REM are not listed because they are not legal. // Arithmetic ops. @@ -327,35 +367,13 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case TargetOpcode::G_FADD: case TargetOpcode::G_FSUB: case TargetOpcode::G_FMUL: - case TargetOpcode::G_FDIV:{ - assert(NumOperands == 3 && "This code is for 3-operands instructions"); - - LLT Ty = MRI.getType(MI.getOperand(0).getReg()); - unsigned Size = Ty.getSizeInBits(); - // Make sure all the operands are using similar size. - // Should probably be checked by the machine verifier. - assert(AArch64::getRegBankBaseIdxOffset( - MRI.getType(MI.getOperand(1).getReg()).getSizeInBits()) == - AArch64::getRegBankBaseIdxOffset(Size) && - "Operand 1 has incompatible size"); - assert(AArch64::getRegBankBaseIdxOffset( - MRI.getType(MI.getOperand(2).getReg()).getSizeInBits()) == - AArch64::getRegBankBaseIdxOffset(Size) && - "Operand 2 has incompatible size"); - - bool IsFPR = Ty.isVector() || isPreISelGenericFloatingPointOpcode(Opc); - - AArch64::PartialMappingIdx RBIdx = - IsFPR ? AArch64::FirstFPR : AArch64::FirstGPR; - - return InstructionMapping{DefaultMappingID, 1, - AArch64::getValueMapping(RBIdx, Size), - NumOperands}; - } + case TargetOpcode::G_FDIV: + return getSameKindOfOperandsMapping(MI); default: break; } + unsigned NumOperands = MI.getNumOperands(); RegisterBankInfo::InstructionMapping Mapping = InstructionMapping{DefaultMappingID, 1, nullptr, NumOperands}; diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.h b/lib/Target/AArch64/AArch64RegisterBankInfo.h index da04eebaa56..1dc87c10ad3 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.h +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.h @@ -38,6 +38,16 @@ class AArch64RegisterBankInfo final : public RegisterBankInfo { /// See RegisterBankInfo::applyMapping. void applyMappingImpl(const OperandsMapper &OpdMapper) const override; + /// Get an instruction mapping where all the operands map to + /// the same register bank and have similar size. + /// + /// \pre MI.getNumOperands() <= 3 + /// + /// \return An InstructionMappings with a statically allocated + /// OperandsMapping. + static InstructionMapping + getSameKindOfOperandsMapping(const MachineInstr &MI); + public: AArch64RegisterBankInfo(const TargetRegisterInfo &TRI); /// Get the cost of a copy from \p B to \p A, or put differently,