diff options
| author | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2016-09-16 14:44:51 +0000 |
|---|---|---|
| committer | Ahmed Bougacha <ahmed.bougacha@gmail.com> | 2016-09-16 14:44:51 +0000 |
| commit | 7306313e6d6db1cb494bd82d2cf5537edd450c35 (patch) | |
| tree | a892aebe4c253a4030c561a805ed82e5804e3255 /llvm/lib | |
| parent | 02629aae3be67cd3ff72fcb5d945e0915723353a (diff) | |
| download | bcm5719-llvm-7306313e6d6db1cb494bd82d2cf5537edd450c35.tar.gz bcm5719-llvm-7306313e6d6db1cb494bd82d2cf5537edd450c35.zip | |
[AArch64][GlobalISel] Add default regbank mappings for mixed-type ops.
We used to only support instructions with same-type operands.
Instead, use the per-register type information to map each
operand more accurately.
llvm-svn: 281734
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 12fdb0d9cc6..15aef07a031 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -171,25 +171,43 @@ void AArch64RegisterBankInfo::applyMappingImpl( RegisterBankInfo::InstructionMapping AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { - RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI); - if (Mapping.isValid()) - return Mapping; - - // As a top-level guess, vectors go in FPRs, scalars in GPRs. Obviously this - // won't work for normal floating-point types (or NZCV). When such - // instructions exist we'll need to look at the MI's opcode. - auto &MRI = MI.getParent()->getParent()->getRegInfo(); - LLT Ty = MRI.getType(MI.getOperand(0).getReg()); - unsigned BankID; - if (Ty.isVector()) - BankID = AArch64::FPRRegBankID; - else - BankID = AArch64::GPRRegBankID; - - Mapping = InstructionMapping{DefaultMappingID, 1, MI.getNumOperands()}; - int Size = Ty.isValid() ? Ty.getSizeInBits() : 0; + const unsigned Opc = MI.getOpcode(); + const MachineFunction &MF = *MI.getParent()->getParent(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); + + // 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); + if (Mapping.isValid()) + return Mapping; + } + + RegisterBankInfo::InstructionMapping Mapping = + InstructionMapping{DefaultMappingID, 1, MI.getNumOperands()}; + + // Track the size and bank of each register. We don't do partial mappings. + SmallVector<unsigned, 4> OpSizes(MI.getNumOperands()); + SmallVector<unsigned, 4> OpBanks(MI.getNumOperands()); + for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) { + auto &MO = MI.getOperand(Idx); + if (!MO.isReg()) + continue; + + LLT Ty = MRI.getType(MO.getReg()); + OpSizes[Idx] = Ty.getSizeInBits(); + + // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs. + if (Ty.isVector()) + OpBanks[Idx] = AArch64::FPRRegBankID; + else + OpBanks[Idx] = AArch64::GPRRegBankID; + } + + // Finally construct the computed mapping. for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) - Mapping.setOperandMapping(Idx, Size, getRegBank(BankID)); + if (MI.getOperand(Idx).isReg()) + Mapping.setOperandMapping(Idx, OpSizes[Idx], getRegBank(OpBanks[Idx])); return Mapping; } |

