diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86CallLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86GenRegisterBankInfo.def | 26 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstructionSelector.cpp | 96 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstructionSelector.h | 9 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86LegalizerInfo.cpp | 39 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86RegisterBankInfo.cpp | 138 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86RegisterBankInfo.h | 16 |
7 files changed, 254 insertions, 74 deletions
diff --git a/llvm/lib/Target/X86/X86CallLowering.cpp b/llvm/lib/Target/X86/X86CallLowering.cpp index 5f8d7f46f39..137ef166aae 100644 --- a/llvm/lib/Target/X86/X86CallLowering.cpp +++ b/llvm/lib/Target/X86/X86CallLowering.cpp @@ -47,7 +47,9 @@ void X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, unsigned NumParts = TLI.getNumRegisters(Context, VT); if (NumParts == 1) { - SplitArgs.push_back(OrigArg); + // replace the original type ( pointer -> GPR ). + SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context), + OrigArg.Flags, OrigArg.IsFixed); return; } diff --git a/llvm/lib/Target/X86/X86GenRegisterBankInfo.def b/llvm/lib/Target/X86/X86GenRegisterBankInfo.def index bac483c0df2..06be142432f 100644 --- a/llvm/lib/Target/X86/X86GenRegisterBankInfo.def +++ b/llvm/lib/Target/X86/X86GenRegisterBankInfo.def @@ -15,7 +15,7 @@ #error "You shouldn't build this" #endif -namespace llvm { +#ifdef GET_TARGET_REGBANK_INFO_IMPL RegisterBankInfo::PartialMapping X86GenRegisterBankInfo::PartMappings[]{ /* StartIdx, Length, RegBank */ // GPR value @@ -31,7 +31,9 @@ RegisterBankInfo::PartialMapping X86GenRegisterBankInfo::PartMappings[]{ {0, 256, X86::VECRRegBank}, // :7 {0, 512, X86::VECRRegBank}, // :8 }; +#endif // GET_TARGET_REGBANK_INFO_IMPL +#ifdef GET_TARGET_REGBANK_INFO_CLASS enum PartialMappingIdx { PMI_None = -1, PMI_GPR8, @@ -44,7 +46,9 @@ enum PartialMappingIdx { PMI_VEC256, PMI_VEC512 }; +#endif // GET_TARGET_REGBANK_INFO_CLASS +#ifdef GET_TARGET_REGBANK_INFO_IMPL #define INSTR_3OP(INFO) INFO, INFO, INFO, #define BREAKDOWN(INDEX, NUM) \ { &X86GenRegisterBankInfo::PartMappings[INDEX], NUM } @@ -65,7 +69,9 @@ RegisterBankInfo::ValueMapping X86GenRegisterBankInfo::ValMappings[]{ }; #undef INSTR_3OP #undef BREAKDOWN +#endif // GET_TARGET_REGBANK_INFO_IMPL +#ifdef GET_TARGET_REGBANK_INFO_CLASS enum ValueMappingIdx { VMI_None = -1, VMI_3OpsGpr8Idx = PMI_GPR8 * 3, @@ -78,5 +84,21 @@ enum ValueMappingIdx { VMI_3OpsVec256Idx = PMI_VEC256 * 3, VMI_3OpsVec512Idx = PMI_VEC512 * 3, }; +#undef GET_TARGET_REGBANK_INFO_CLASS +#endif // GET_TARGET_REGBANK_INFO_CLASS + +#ifdef GET_TARGET_REGBANK_INFO_IMPL +#undef GET_TARGET_REGBANK_INFO_IMPL +const RegisterBankInfo::ValueMapping * +X86GenRegisterBankInfo::getValueMapping(PartialMappingIdx Idx, + unsigned NumOperands) { + + // We can use VMI_3Ops Mapping for all the cases. + if (NumOperands <= 3 && (Idx >= PMI_GPR8 && Idx <= PMI_VEC512)) + return &ValMappings[(unsigned)Idx * 3]; + + llvm_unreachable("Unsupported PartialMappingIdx."); +} + +#endif // GET_TARGET_REGBANK_INFO_IMPL -} // End llvm namespace. diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp index f572538fa3c..e45d12268fb 100644 --- a/llvm/lib/Target/X86/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "X86InstructionSelector.h" +#include "X86InstrBuilder.h" #include "X86InstrInfo.h" #include "X86RegisterBankInfo.h" #include "X86RegisterInfo.h" @@ -154,7 +155,9 @@ bool X86InstructionSelector::select(MachineInstr &I) const { // TODO: This should be implemented by tblgen, pattern with predicate not // supported yet. - if (selectBinaryOp(I, MRI)) + if (selectBinaryOp(I, MRI, MF)) + return true; + if (selectLoadStoreOp(I, MRI, MF)) return true; return selectImpl(I); @@ -269,15 +272,16 @@ unsigned X86InstructionSelector::getSubOp(LLT &Ty, } bool X86InstructionSelector::selectBinaryOp(MachineInstr &I, - MachineRegisterInfo &MRI) const { + MachineRegisterInfo &MRI, + MachineFunction &MF) const { - LLT Ty = MRI.getType(I.getOperand(0).getReg()); const unsigned DefReg = I.getOperand(0).getReg(); + LLT Ty = MRI.getType(DefReg); const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); unsigned NewOpc = I.getOpcode(); - switch (I.getOpcode()) { + switch (NewOpc) { case TargetOpcode::G_FADD: NewOpc = getFAddOp(Ty, RB); break; @@ -301,3 +305,87 @@ bool X86InstructionSelector::selectBinaryOp(MachineInstr &I, return constrainSelectedInstRegOperands(I, TII, TRI, RBI); } + +unsigned X86InstructionSelector::getLoadStoreOp(LLT &Ty, const RegisterBank &RB, + unsigned Opc, + uint64_t Alignment) const { + bool Isload = (Opc == TargetOpcode::G_LOAD); + bool HasAVX = STI.hasAVX(); + bool HasAVX512 = STI.hasAVX512(); + bool HasVLX = STI.hasVLX(); + + if (Ty == LLT::scalar(8)) { + if (X86::GPRRegBankID == RB.getID()) + return Isload ? X86::MOV8rm : X86::MOV8mr; + } else if (Ty == LLT::scalar(16)) { + if (X86::GPRRegBankID == RB.getID()) + return Isload ? X86::MOV16rm : X86::MOV16mr; + } else if (Ty == LLT::scalar(32)) { + if (X86::GPRRegBankID == RB.getID()) + return Isload ? X86::MOV32rm : X86::MOV32mr; + if (X86::VECRRegBankID == RB.getID()) + return Isload ? (HasAVX512 ? X86::VMOVSSZrm + : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm) + : (HasAVX512 ? X86::VMOVSSZmr + : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr); + } else if (Ty == LLT::scalar(64)) { + if (X86::GPRRegBankID == RB.getID()) + return Isload ? X86::MOV64rm : X86::MOV64mr; + if (X86::VECRRegBankID == RB.getID()) + return Isload ? (HasAVX512 ? X86::VMOVSDZrm + : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm) + : (HasAVX512 ? X86::VMOVSDZmr + : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr); + } else if (Ty.isVector() && Ty.getSizeInBits() == 128) { + if (Alignment >= 16) + return Isload ? (HasVLX ? X86::VMOVAPSZ128rm + : HasAVX512 + ? X86::VMOVAPSZ128rm_NOVLX + : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm) + : (HasVLX ? X86::VMOVAPSZ128mr + : HasAVX512 + ? X86::VMOVAPSZ128mr_NOVLX + : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr); + else + return Isload ? (HasVLX ? X86::VMOVUPSZ128rm + : HasAVX512 + ? X86::VMOVUPSZ128rm_NOVLX + : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm) + : (HasVLX ? X86::VMOVUPSZ128mr + : HasAVX512 + ? X86::VMOVUPSZ128mr_NOVLX + : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr); + } + return Opc; +} + +bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I, + MachineRegisterInfo &MRI, + MachineFunction &MF) const { + + unsigned Opc = I.getOpcode(); + + if (Opc != TargetOpcode::G_STORE && Opc != TargetOpcode::G_LOAD) + return false; + + const unsigned DefReg = I.getOperand(0).getReg(); + LLT Ty = MRI.getType(DefReg); + const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); + + auto &MemOp = **I.memoperands_begin(); + unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment()); + if (NewOpc == Opc) + return false; + + I.setDesc(TII.get(NewOpc)); + MachineInstrBuilder MIB(MF, I); + if (Opc == TargetOpcode::G_LOAD) + addOffset(MIB, 0); + else { + // G_STORE (VAL, Addr), X86Store instruction (Addr, VAL) + I.RemoveOperand(0); + addOffset(MIB, 0).addUse(DefReg); + } + return constrainSelectedInstRegOperands(I, TII, TRI, RBI); +} + diff --git a/llvm/lib/Target/X86/X86InstructionSelector.h b/llvm/lib/Target/X86/X86InstructionSelector.h index 2482734fa7d..a8eb4ca6cea 100644 --- a/llvm/lib/Target/X86/X86InstructionSelector.h +++ b/llvm/lib/Target/X86/X86InstructionSelector.h @@ -27,6 +27,7 @@ class X86TargetMachine; class LLT; class RegisterBank; class MachineRegisterInfo; +class MachineFunction; class X86InstructionSelector : public InstructionSelector { public: @@ -45,7 +46,13 @@ private: unsigned getFSubOp(LLT &Ty, const RegisterBank &RB) const; unsigned getAddOp(LLT &Ty, const RegisterBank &RB) const; unsigned getSubOp(LLT &Ty, const RegisterBank &RB) const; - bool selectBinaryOp(MachineInstr &I, MachineRegisterInfo &MRI) const; + unsigned getLoadStoreOp(LLT &Ty, const RegisterBank &RB, unsigned Opc, + uint64_t Alignment) const; + + bool selectBinaryOp(MachineInstr &I, MachineRegisterInfo &MRI, + MachineFunction &MF) const; + bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI, + MachineFunction &MF) const; const X86Subtarget &STI; const X86InstrInfo &TII; diff --git a/llvm/lib/Target/X86/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/X86LegalizerInfo.cpp index 4e94e45af64..bda657946f7 100644 --- a/llvm/lib/Target/X86/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/X86LegalizerInfo.cpp @@ -37,13 +37,24 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI) : Subtarget(STI) { void X86LegalizerInfo::setLegalizerInfo32bit() { + if (Subtarget.is64Bit()) + return; + + const LLT p0 = LLT::pointer(0, 32); const LLT s8 = LLT::scalar(8); const LLT s16 = LLT::scalar(16); const LLT s32 = LLT::scalar(32); - for (auto Ty : {s8, s16, s32}) { - setAction({G_ADD, Ty}, Legal); - setAction({G_SUB, Ty}, Legal); + for (unsigned BinOp : {G_ADD, G_SUB}) + for (auto Ty : {s8, s16, s32}) + setAction({BinOp, Ty}, Legal); + + for (unsigned MemOp : {G_LOAD, G_STORE}) { + for (auto Ty : {s8, s16, s32, p0}) + setAction({MemOp, Ty}, Legal); + + // And everything's fine in addrspace 0. + setAction({MemOp, 1, p0}, Legal); } } @@ -52,10 +63,23 @@ void X86LegalizerInfo::setLegalizerInfo64bit() { if (!Subtarget.is64Bit()) return; + const LLT p0 = LLT::pointer(0, 64); + const LLT s8 = LLT::scalar(8); + const LLT s16 = LLT::scalar(16); + const LLT s32 = LLT::scalar(32); const LLT s64 = LLT::scalar(64); - setAction({G_ADD, s64}, Legal); - setAction({G_SUB, s64}, Legal); + for (unsigned BinOp : {G_ADD, G_SUB}) + for (auto Ty : {s8, s16, s32, s64}) + setAction({BinOp, Ty}, Legal); + + for (unsigned MemOp : {G_LOAD, G_STORE}) { + for (auto Ty : {s8, s16, s32, s64, p0}) + setAction({MemOp, Ty}, Legal); + + // And everything's fine in addrspace 0. + setAction({MemOp, 1, p0}, Legal); + } } void X86LegalizerInfo::setLegalizerInfoSSE1() { @@ -64,10 +88,15 @@ void X86LegalizerInfo::setLegalizerInfoSSE1() { const LLT s32 = LLT::scalar(32); const LLT v4s32 = LLT::vector(4, 32); + const LLT v2s64 = LLT::vector(2, 64); for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV}) for (auto Ty : {s32, v4s32}) setAction({BinOp, Ty}, Legal); + + for (unsigned MemOp : {G_LOAD, G_STORE}) + for (auto Ty : {v4s32, v2s64}) + setAction({MemOp, Ty}, Legal); } void X86LegalizerInfo::setLegalizerInfoSSE2() { diff --git a/llvm/lib/Target/X86/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/X86RegisterBankInfo.cpp index c06e4baa3b7..ad9e5f6bef9 100644 --- a/llvm/lib/Target/X86/X86RegisterBankInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterBankInfo.cpp @@ -21,11 +21,11 @@ #define GET_TARGET_REGBANK_IMPL #include "X86GenRegisterBank.inc" +using namespace llvm; // This file will be TableGen'ed at some point. +#define GET_TARGET_REGBANK_INFO_IMPL #include "X86GenRegisterBankInfo.def" -using namespace llvm; - #ifndef LLVM_BUILD_GLOBAL_ISEL #error "You shouldn't build this" #endif @@ -64,72 +64,67 @@ const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass( llvm_unreachable("Unsupported register kind yet."); } -RegisterBankInfo::InstructionMapping -X86RegisterBankInfo::getOperandsMapping(const MachineInstr &MI, bool isFP) { - const MachineFunction &MF = *MI.getParent()->getParent(); - const MachineRegisterInfo &MRI = MF.getRegInfo(); - - unsigned NumOperands = MI.getNumOperands(); - LLT Ty = MRI.getType(MI.getOperand(0).getReg()); - - if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) || - (Ty != MRI.getType(MI.getOperand(2).getReg()))) - llvm_unreachable("Unsupported operand maping yet."); - - ValueMappingIdx ValMapIdx = VMI_None; - - if (Ty.isScalar()) { - if (!isFP) { - switch (Ty.getSizeInBits()) { - case 8: - ValMapIdx = VMI_3OpsGpr8Idx; - break; - case 16: - ValMapIdx = VMI_3OpsGpr16Idx; - break; - case 32: - ValMapIdx = VMI_3OpsGpr32Idx; - break; - case 64: - ValMapIdx = VMI_3OpsGpr64Idx; - break; - default: - llvm_unreachable("Unsupported register size."); - } - } else { - switch (Ty.getSizeInBits()) { - case 32: - ValMapIdx = VMI_3OpsFp32Idx; - break; - case 64: - ValMapIdx = VMI_3OpsFp64Idx; - break; - default: - llvm_unreachable("Unsupported register size."); - } +X86GenRegisterBankInfo::PartialMappingIdx +X86GenRegisterBankInfo::getPartialMappingIdx(const LLT &Ty, bool isFP) { + if ((Ty.isScalar() && !isFP) || Ty.isPointer()) { + switch (Ty.getSizeInBits()) { + case 8: + return PMI_GPR8; + case 16: + return PMI_GPR16; + case 32: + return PMI_GPR32; + case 64: + return PMI_GPR64; + break; + default: + llvm_unreachable("Unsupported register size."); + } + } else if (Ty.isScalar()) { + switch (Ty.getSizeInBits()) { + case 32: + return PMI_FP32; + case 64: + return PMI_FP64; + default: + llvm_unreachable("Unsupported register size."); } } else { switch (Ty.getSizeInBits()) { case 128: - ValMapIdx = VMI_3OpsVec128Idx; - break; + return PMI_VEC128; case 256: - ValMapIdx = VMI_3OpsVec256Idx; - break; + return PMI_VEC256; case 512: - ValMapIdx = VMI_3OpsVec512Idx; - break; + return PMI_VEC512; default: llvm_unreachable("Unsupported register size."); } } - return InstructionMapping{DefaultMappingID, 1, &ValMappings[ValMapIdx], - NumOperands}; + return PMI_None; +} + +RegisterBankInfo::InstructionMapping +X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, bool isFP) { + const MachineFunction &MF = *MI.getParent()->getParent(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); + + unsigned NumOperands = MI.getNumOperands(); + LLT Ty = MRI.getType(MI.getOperand(0).getReg()); + + if (NumOperands != 3 || (Ty != MRI.getType(MI.getOperand(1).getReg())) || + (Ty != MRI.getType(MI.getOperand(2).getReg()))) + llvm_unreachable("Unsupported operand mapping yet."); + + auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3); + return InstructionMapping{DefaultMappingID, 1, Mapping, NumOperands}; } RegisterBankInfo::InstructionMapping X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { + const MachineFunction &MF = *MI.getParent()->getParent(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); auto Opc = MI.getOpcode(); // Try the default logic for non-generic instructions that are either copies @@ -143,17 +138,46 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { switch (Opc) { case TargetOpcode::G_ADD: case TargetOpcode::G_SUB: - return getOperandsMapping(MI, false); + return getSameOperandsMapping(MI, false); break; case TargetOpcode::G_FADD: case TargetOpcode::G_FSUB: case TargetOpcode::G_FMUL: case TargetOpcode::G_FDIV: - return getOperandsMapping(MI, true); + return getSameOperandsMapping(MI, true); break; default: - return InstructionMapping{}; + break; + } + + unsigned NumOperands = MI.getNumOperands(); + unsigned Cost = 1; // set dafault cost + + // Track the bank of each register. + SmallVector<PartialMappingIdx, 4> OpRegBankIdx(NumOperands); + for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { + auto &MO = MI.getOperand(Idx); + if (!MO.isReg()) + continue; + + // As a top-level guess, use NotFP mapping (all scalars in GPRs) + OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), false); + } + + // Finally construct the computed mapping. + RegisterBankInfo::InstructionMapping Mapping = + InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands}; + SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands); + for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { + if (MI.getOperand(Idx).isReg()) { + auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1); + if (!Mapping->isValid()) + return InstructionMapping(); + + OpdsMapping[Idx] = Mapping; + } } - return InstructionMapping{}; + Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping)); + return Mapping; } diff --git a/llvm/lib/Target/X86/X86RegisterBankInfo.h b/llvm/lib/Target/X86/X86RegisterBankInfo.h index a46355102c7..5fcce87a71e 100644 --- a/llvm/lib/Target/X86/X86RegisterBankInfo.h +++ b/llvm/lib/Target/X86/X86RegisterBankInfo.h @@ -21,13 +21,21 @@ namespace llvm { +class LLT; + class X86GenRegisterBankInfo : public RegisterBankInfo { protected: +#define GET_TARGET_REGBANK_CLASS +#include "X86GenRegisterBank.inc" +#define GET_TARGET_REGBANK_INFO_CLASS +#include "X86GenRegisterBankInfo.def" + static RegisterBankInfo::PartialMapping PartMappings[]; static RegisterBankInfo::ValueMapping ValMappings[]; -#define GET_TARGET_REGBANK_CLASS -#include "X86GenRegisterBank.inc" + static PartialMappingIdx getPartialMappingIdx(const LLT &Ty, bool isFP); + static const RegisterBankInfo::ValueMapping * + getValueMapping(PartialMappingIdx Idx, unsigned NumOperands); }; class TargetRegisterInfo; @@ -38,8 +46,8 @@ private: /// Get an instruction mapping. /// \return An InstructionMappings with a statically allocated /// OperandsMapping. - static InstructionMapping getOperandsMapping(const MachineInstr &MI, - bool isFP); + static InstructionMapping getSameOperandsMapping(const MachineInstr &MI, + bool isFP); public: X86RegisterBankInfo(const TargetRegisterInfo &TRI); |