diff options
Diffstat (limited to 'llvm/lib/Target/AArch64')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index dad18fd8e88..d9469faddd6 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -39,6 +39,53 @@ AArch64InstructionSelector::AArch64InstructionSelector( : InstructionSelector(), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI) {} +/// Check whether \p I is a currently unsupported binary operation: +/// - it has an unsized type +/// - an operand is not a vreg +/// - all operands are not in the same bank +/// These are checks that should someday live in the verifier, but right now, +/// these are mostly limitations of the aarch64 selector. +static bool unsupportedBinOp(const MachineInstr &I, + const AArch64RegisterBankInfo &RBI, + const MachineRegisterInfo &MRI, + const AArch64RegisterInfo &TRI) { + if (!I.getType().isSized()) { + DEBUG(dbgs() << "Generic binop should be sized\n"); + return true; + } + + const RegisterBank *PrevOpBank = nullptr; + for (auto &MO : I.operands()) { + // FIXME: Support non-register operands. + if (!MO.isReg()) { + DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n"); + return true; + } + + // FIXME: Can generic operations have physical registers operands? If + // so, this will need to be taught about that, and we'll need to get the + // bank out of the minimal class for the register. + // Either way, this needs to be documented (and possibly verified). + if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) { + DEBUG(dbgs() << "Generic inst has physical register operand\n"); + return true; + } + + const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI); + if (!OpBank) { + DEBUG(dbgs() << "Generic register has no bank or class\n"); + return true; + } + + if (PrevOpBank && OpBank != PrevOpBank) { + DEBUG(dbgs() << "Generic inst operands have different banks\n"); + return true; + } + PrevOpBank = OpBank; + } + return false; +} + /// Select the AArch64 opcode for the basic binary operation \p GenericOpc /// (such as G_OR or G_ADD), appropriate for the register bank \p RegBankID /// and of size \p OpSize. @@ -135,7 +182,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { return false; } - LLT Ty = I.getType(); + const LLT Ty = I.getType(); assert(Ty.isValid() && "Generic instruction doesn't have a type"); switch (I.getOpcode()) { @@ -207,49 +254,12 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { case TargetOpcode::G_ASHR: case TargetOpcode::G_ADD: case TargetOpcode::G_SUB: { - DEBUG(dbgs() << "AArch64: Selecting: binop\n"); - - if (!Ty.isSized()) { - DEBUG(dbgs() << "Generic binop should be sized\n"); + // Reject the various things we don't support yet. + if (unsupportedBinOp(I, RBI, MRI, TRI)) return false; - } - // The size (in bits) of the operation, or 0 for the label type. const unsigned OpSize = Ty.getSizeInBits(); - // Reject the various things we don't support yet. - { - const RegisterBank *PrevOpBank = nullptr; - for (auto &MO : I.operands()) { - // FIXME: Support non-register operands. - if (!MO.isReg()) { - DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n"); - return false; - } - - // FIXME: Can generic operations have physical registers operands? If - // so, this will need to be taught about that, and we'll need to get the - // bank out of the minimal class for the register. - // Either way, this needs to be documented (and possibly verified). - if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) { - DEBUG(dbgs() << "Generic inst has physical register operand\n"); - return false; - } - - const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI); - if (!OpBank) { - DEBUG(dbgs() << "Generic register has no bank or class\n"); - return false; - } - - if (PrevOpBank && OpBank != PrevOpBank) { - DEBUG(dbgs() << "Generic inst operands have different banks\n"); - return false; - } - PrevOpBank = OpBank; - } - } - const unsigned DefReg = I.getOperand(0).getReg(); const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); |

