diff options
Diffstat (limited to 'lib/Target/ARM/ARMInstructionSelector.cpp')
-rw-r--r-- | lib/Target/ARM/ARMInstructionSelector.cpp | 128 |
1 files changed, 84 insertions, 44 deletions
diff --git a/lib/Target/ARM/ARMInstructionSelector.cpp b/lib/Target/ARM/ARMInstructionSelector.cpp index b0fd0b476920..6692a4d41420 100644 --- a/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/lib/Target/ARM/ARMInstructionSelector.cpp @@ -117,39 +117,47 @@ ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM, { } -static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, - MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, - const RegisterBankInfo &RBI) { - unsigned DstReg = I.getOperand(0).getReg(); - if (TargetRegisterInfo::isPhysicalRegister(DstReg)) - return true; - - const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI); - (void)RegBank; +static const TargetRegisterClass *guessRegClass(unsigned Reg, + MachineRegisterInfo &MRI, + const TargetRegisterInfo &TRI, + const RegisterBankInfo &RBI) { + const RegisterBank *RegBank = RBI.getRegBank(Reg, MRI, TRI); assert(RegBank && "Can't get reg bank for virtual register"); - const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); + const unsigned Size = MRI.getType(Reg).getSizeInBits(); assert((RegBank->getID() == ARM::GPRRegBankID || RegBank->getID() == ARM::FPRRegBankID) && "Unsupported reg bank"); - const TargetRegisterClass *RC = &ARM::GPRRegClass; - if (RegBank->getID() == ARM::FPRRegBankID) { - if (DstSize == 32) - RC = &ARM::SPRRegClass; - else if (DstSize == 64) - RC = &ARM::DPRRegClass; + if (Size == 32) + return &ARM::SPRRegClass; + else if (Size == 64) + return &ARM::DPRRegClass; + else if (Size == 128) + return &ARM::QPRRegClass; else llvm_unreachable("Unsupported destination size"); } + return &ARM::GPRRegClass; +} + +static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, + MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, + const RegisterBankInfo &RBI) { + unsigned DstReg = I.getOperand(0).getReg(); + if (TargetRegisterInfo::isPhysicalRegister(DstReg)) + return true; + + const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI); + // No need to constrain SrcReg. It will get constrained when // we hit another of its uses or its defs. // Copies do not have constraints. if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { - DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) - << " operand\n"); + LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) + << " operand\n"); return false; } return true; @@ -393,12 +401,12 @@ bool ARMInstructionSelector::validReg(MachineRegisterInfo &MRI, unsigned Reg, unsigned ExpectedSize, unsigned ExpectedRegBankID) const { if (MRI.getType(Reg).getSizeInBits() != ExpectedSize) { - DEBUG(dbgs() << "Unexpected size for register"); + LLVM_DEBUG(dbgs() << "Unexpected size for register"); return false; } if (RBI.getRegBank(Reg, MRI, TRI)->getID() != ExpectedRegBankID) { - DEBUG(dbgs() << "Unexpected register bank for register"); + LLVM_DEBUG(dbgs() << "Unexpected register bank for register"); return false; } @@ -490,13 +498,13 @@ bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo I, bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB, MachineRegisterInfo &MRI) const { if ((STI.isROPI() || STI.isRWPI()) && !STI.isTargetELF()) { - DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n"); + LLVM_DEBUG(dbgs() << "ROPI and RWPI only supported for ELF\n"); return false; } auto GV = MIB->getOperand(1).getGlobal(); if (GV->isThreadLocal()) { - DEBUG(dbgs() << "TLS variables not supported yet\n"); + LLVM_DEBUG(dbgs() << "TLS variables not supported yet\n"); return false; } @@ -505,7 +513,7 @@ bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB, bool UseMovt = STI.useMovt(MF); - unsigned Size = TM.getPointerSize(); + unsigned Size = TM.getPointerSize(0); unsigned Alignment = 4; auto addOpsForConstantPoolLoad = [&MF, Alignment, @@ -548,7 +556,7 @@ bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB, if (Indirect) MIB.addMemOperand(MF.getMachineMemOperand( MachinePointerInfo::getGOT(MF), MachineMemOperand::MOLoad, - TM.getPointerSize(), Alignment)); + TM.getProgramPointerSize(), Alignment)); return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); } @@ -601,7 +609,7 @@ bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB, else MIB->setDesc(TII.get(ARM::LDRLIT_ga_abs)); } else { - DEBUG(dbgs() << "Object format not supported yet\n"); + LLVM_DEBUG(dbgs() << "Object format not supported yet\n"); return false; } @@ -670,14 +678,6 @@ bool ARMInstructionSelector::select(MachineInstr &I, } using namespace TargetOpcode; - if (I.getOpcode() == G_CONSTANT) { - // Pointer constants should be treated the same as 32-bit integer constants. - // Change the type and let TableGen handle it. - unsigned ResultReg = I.getOperand(0).getReg(); - LLT Ty = MRI.getType(ResultReg); - if (Ty.isPointer()) - MRI.setType(ResultReg, LLT::scalar(32)); - } if (selectImpl(I, CoverageInfo)) return true; @@ -693,7 +693,7 @@ bool ARMInstructionSelector::select(MachineInstr &I, LLT DstTy = MRI.getType(I.getOperand(0).getReg()); // FIXME: Smaller destination sizes coming soon! if (DstTy.getSizeInBits() != 32) { - DEBUG(dbgs() << "Unsupported destination size for extension"); + LLVM_DEBUG(dbgs() << "Unsupported destination size for extension"); return false; } @@ -735,7 +735,7 @@ bool ARMInstructionSelector::select(MachineInstr &I, break; } default: - DEBUG(dbgs() << "Unsupported source size for extension"); + LLVM_DEBUG(dbgs() << "Unsupported source size for extension"); return false; } break; @@ -776,18 +776,45 @@ bool ARMInstructionSelector::select(MachineInstr &I, } if (SrcRegBank.getID() != DstRegBank.getID()) { - DEBUG(dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n"); + LLVM_DEBUG( + dbgs() << "G_TRUNC/G_ANYEXT operands on different register banks\n"); return false; } if (SrcRegBank.getID() != ARM::GPRRegBankID) { - DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n"); + LLVM_DEBUG(dbgs() << "G_TRUNC/G_ANYEXT on non-GPR not supported yet\n"); return false; } I.setDesc(TII.get(COPY)); return selectCopy(I, TII, MRI, TRI, RBI); } + case G_CONSTANT: { + if (!MRI.getType(I.getOperand(0).getReg()).isPointer()) { + // Non-pointer constants should be handled by TableGen. + LLVM_DEBUG(dbgs() << "Unsupported constant type\n"); + return false; + } + + auto &Val = I.getOperand(1); + if (Val.isCImm()) { + if (!Val.getCImm()->isZero()) { + LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n"); + return false; + } + Val.ChangeToImmediate(0); + } else { + assert(Val.isImm() && "Unexpected operand for G_CONSTANT"); + if (Val.getImm() != 0) { + LLVM_DEBUG(dbgs() << "Unsupported pointer constant value\n"); + return false; + } + } + + I.setDesc(TII.get(ARM::MOVi)); + MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); + break; + } case G_INTTOPTR: case G_PTRTOINT: { auto SrcReg = I.getOperand(1).getReg(); @@ -797,13 +824,15 @@ bool ARMInstructionSelector::select(MachineInstr &I, const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI); if (SrcRegBank.getID() != DstRegBank.getID()) { - DEBUG(dbgs() - << "G_INTTOPTR/G_PTRTOINT operands on different register banks\n"); + LLVM_DEBUG( + dbgs() + << "G_INTTOPTR/G_PTRTOINT operands on different register banks\n"); return false; } if (SrcRegBank.getID() != ARM::GPRRegBankID) { - DEBUG(dbgs() << "G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n"); + LLVM_DEBUG( + dbgs() << "G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n"); return false; } @@ -824,11 +853,11 @@ bool ARMInstructionSelector::select(MachineInstr &I, unsigned Size = MRI.getType(OpReg).getSizeInBits(); if (Size == 64 && STI.isFPOnlySP()) { - DEBUG(dbgs() << "Subtarget only supports single precision"); + LLVM_DEBUG(dbgs() << "Subtarget only supports single precision"); return false; } if (Size != 32 && Size != 64) { - DEBUG(dbgs() << "Unsupported size for G_FCMP operand"); + LLVM_DEBUG(dbgs() << "Unsupported size for G_FCMP operand"); return false; } @@ -859,7 +888,7 @@ bool ARMInstructionSelector::select(MachineInstr &I, case G_LOAD: { const auto &MemOp = **I.memoperands_begin(); if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { - DEBUG(dbgs() << "Atomic load/store not supported yet\n"); + LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n"); return false; } @@ -896,7 +925,7 @@ bool ARMInstructionSelector::select(MachineInstr &I, } case G_BRCOND: { if (!validReg(MRI, I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) { - DEBUG(dbgs() << "Unsupported condition register for G_BRCOND"); + LLVM_DEBUG(dbgs() << "Unsupported condition register for G_BRCOND"); return false; } @@ -917,6 +946,17 @@ bool ARMInstructionSelector::select(MachineInstr &I, I.eraseFromParent(); return true; } + case G_PHI: { + I.setDesc(TII.get(PHI)); + + unsigned DstReg = I.getOperand(0).getReg(); + const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI); + if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { + break; + } + + return true; + } default: return false; } |