diff options
author | Igor Breger <igor.breger@intel.com> | 2017-02-22 12:25:09 +0000 |
---|---|---|
committer | Igor Breger <igor.breger@intel.com> | 2017-02-22 12:25:09 +0000 |
commit | f7359d893af318deca46b85f2d6c0f0f533783c7 (patch) | |
tree | 08b92e8cbc965238c1b4465f9e74c722f0b3860e /llvm/lib/Target | |
parent | a2fc1e0cc886df429cde9e6ac59ce3fad4419461 (diff) | |
download | bcm5719-llvm-f7359d893af318deca46b85f2d6c0f0f533783c7.tar.gz bcm5719-llvm-f7359d893af318deca46b85f2d6c0f0f533783c7.zip |
[X86][GlobalISel] Initial implementation , select G_ADD gpr, gpr
Summary: Initial implementation for X86InstructionSelector. Handle selection COPY and G_ADD/G_SUB gpr, gpr .
Reviewers: qcolombet, rovka, zvi, ab
Reviewed By: rovka
Subscribers: mgorny, dberris, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D29816
llvm-svn: 295824
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstructionSelector.cpp | 133 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstructionSelector.h | 47 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86LegalizerInfo.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86RegisterBankInfo.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86TargetMachine.cpp | 9 |
6 files changed, 194 insertions, 6 deletions
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt index 56130023563..055b0f047c1 100644 --- a/llvm/lib/Target/X86/CMakeLists.txt +++ b/llvm/lib/Target/X86/CMakeLists.txt @@ -12,6 +12,7 @@ tablegen(LLVM X86GenCallingConv.inc -gen-callingconv) tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget) if(LLVM_BUILD_GLOBAL_ISEL) tablegen(LLVM X86GenRegisterBank.inc -gen-register-bank) + tablegen(LLVM X86GenGlobalISel.inc -gen-global-isel) endif() add_public_tablegen_target(X86CommonTableGen) @@ -21,6 +22,7 @@ set(GLOBAL_ISEL_FILES X86CallLowering.cpp X86LegalizerInfo.cpp X86RegisterBankInfo.cpp + X86InstructionSelector.cpp ) if(LLVM_BUILD_GLOBAL_ISEL) diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp new file mode 100644 index 00000000000..9b21ce41e05 --- /dev/null +++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp @@ -0,0 +1,133 @@ +//===- X86InstructionSelector.cpp ----------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements the targeting of the InstructionSelector class for +/// X86. +/// \todo This should be generated by TableGen. +//===----------------------------------------------------------------------===// + +#include "X86InstructionSelector.h" +#include "X86InstrInfo.h" +#include "X86RegisterBankInfo.h" +#include "X86RegisterInfo.h" +#include "X86Subtarget.h" +#include "X86TargetMachine.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "X86-isel" + +using namespace llvm; + +#ifndef LLVM_BUILD_GLOBAL_ISEL +#error "You shouldn't build this" +#endif + +#include "X86GenGlobalISel.inc" + +X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM, + const X86Subtarget &STI, + const X86RegisterBankInfo &RBI) + : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), + TRI(*STI.getRegisterInfo()), RBI(RBI) {} + +// FIXME: This should be target-independent, inferred from the types declared +// for each class in the bank. +static const TargetRegisterClass * +getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB) { + if (RB.getID() == X86::GPRRegBankID) { + if (Ty.getSizeInBits() <= 32) + return &X86::GR32RegClass; + if (Ty.getSizeInBits() == 64) + return &X86::GR64RegClass; + } + + llvm_unreachable("Unknown RegBank!"); +} + +// Set X86 Opcode and constrain DestReg. +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)) { + assert(I.isCopy() && "Generic operators do not allow physical registers"); + return true; + } + + const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); + const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); + unsigned SrcReg = I.getOperand(1).getReg(); + const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); + (void)SrcSize; + assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) && + "No phys reg on generic operators"); + assert((DstSize == SrcSize || + // Copies are a mean to setup initial types, the number of + // bits may not exactly match. + (TargetRegisterInfo::isPhysicalRegister(SrcReg) && + DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI))) && + "Copy with different width?!"); + + const TargetRegisterClass *RC = nullptr; + + switch (RegBank.getID()) { + case X86::GPRRegBankID: + assert((DstSize <= 64) && "GPRs cannot get more than 64-bit width values."); + RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank); + break; + default: + llvm_unreachable("Unknown RegBank!"); + } + + // No need to constrain SrcReg. It will get constrained when + // we hit another of its use 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"); + return false; + } + I.setDesc(TII.get(X86::COPY)); + return true; +} + +bool X86InstructionSelector::select(MachineInstr &I) const { + assert(I.getParent() && "Instruction should be in a basic block!"); + assert(I.getParent()->getParent() && "Instruction should be in a function!"); + + MachineBasicBlock &MBB = *I.getParent(); + MachineFunction &MF = *MBB.getParent(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + + unsigned Opcode = I.getOpcode(); + if (!isPreISelGenericOpcode(Opcode)) { + // Certain non-generic instructions also need some special handling. + + if (I.isCopy()) + return selectCopy(I, TII, MRI, TRI, RBI); + + // TODO: handle more cases - LOAD_STACK_GUARD, PHI + return true; + } + + if (I.getNumOperands() != I.getNumExplicitOperands()) { + assert("Generic instruction has unexpected implicit operands\n"); + return false; + } + + return selectImpl(I); +} diff --git a/llvm/lib/Target/X86/X86InstructionSelector.h b/llvm/lib/Target/X86/X86InstructionSelector.h new file mode 100644 index 00000000000..0a8ea3d5304 --- /dev/null +++ b/llvm/lib/Target/X86/X86InstructionSelector.h @@ -0,0 +1,47 @@ +//===- X86InstructionSelector --------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares the targeting of the InstructionSelector class for X86. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_X86_X86INSTRUCTIONSELECTOR_H +#define LLVM_LIB_TARGET_X86_X86INSTRUCTIONSELECTOR_H + +#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" + +namespace llvm { + +class X86InstrInfo; +class X86RegisterBankInfo; +class X86RegisterInfo; +class X86Subtarget; +class X86TargetMachine; + +class X86InstructionSelector : public InstructionSelector { +public: + X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI, + const X86RegisterBankInfo &RBI); + + bool select(MachineInstr &I) const override; + +private: + /// tblgen-erated 'select' implementation, used as the initial selector for + /// the patterns that don't require complex C++. + bool selectImpl(MachineInstr &I) const; + + const X86TargetMachine &TM; + const X86Subtarget &STI; + const X86InstrInfo &TII; + const X86RegisterInfo &TRI; + const X86RegisterBankInfo &RBI; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_X86_X86INSTRUCTIONSELECTOR_H diff --git a/llvm/lib/Target/X86/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/X86LegalizerInfo.cpp index 24000aad1df..5f63f8d4e98 100644 --- a/llvm/lib/Target/X86/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/X86LegalizerInfo.cpp @@ -38,12 +38,13 @@ void X86LegalizerInfo::setLegalizerInfo32bit() { const LLT s16 = LLT::scalar(16); const LLT s32 = LLT::scalar(32); - for (auto Ty : {s8, s16, s32}) + for (auto Ty : {s8, s16, s32}) { setAction({TargetOpcode::G_ADD, Ty}, Legal); + setAction({TargetOpcode::G_SUB, Ty}, Legal); + } } -void -X86LegalizerInfo::setLegalizerInfo64bit() { +void X86LegalizerInfo::setLegalizerInfo64bit() { if (!Subtarget.is64Bit()) return; @@ -51,4 +52,5 @@ X86LegalizerInfo::setLegalizerInfo64bit() { const LLT s64 = LLT::scalar(64); setAction({TargetOpcode::G_ADD, s64}, Legal); + setAction({TargetOpcode::G_SUB, s64}, Legal); } diff --git a/llvm/lib/Target/X86/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/X86RegisterBankInfo.cpp index e94c5caedac..626e7ef4bed 100644 --- a/llvm/lib/Target/X86/X86RegisterBankInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterBankInfo.cpp @@ -111,6 +111,7 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { switch (Opc) { case TargetOpcode::G_ADD: + case TargetOpcode::G_SUB: return getOperandsMapping(MI, false); break; default: diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index 1894d61ad2b..3f61cd8ccee 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -15,6 +15,7 @@ #include "X86.h" #include "X86CallLowering.h" #include "X86LegalizerInfo.h" +#include "X86InstructionSelector.h" #ifdef LLVM_BUILD_GLOBAL_ISEL #include "X86RegisterBankInfo.h" #endif @@ -34,6 +35,7 @@ #include "llvm/CodeGen/GlobalISel/IRTranslator.h" #include "llvm/CodeGen/GlobalISel/Legalizer.h" #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/CodeGen/MachineScheduler.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetPassConfig.h" @@ -211,14 +213,14 @@ struct X86GISelActualAccessor : public GISelAccessor { std::unique_ptr<CallLowering> CallLoweringInfo; std::unique_ptr<LegalizerInfo> Legalizer; std::unique_ptr<RegisterBankInfo> RegBankInfo; + std::unique_ptr<InstructionSelector> InstSelector; const CallLowering *getCallLowering() const override { return CallLoweringInfo.get(); } const InstructionSelector *getInstructionSelector() const override { - //TODO: Implement - return nullptr; + return InstSelector.get(); } const LegalizerInfo *getLegalizerInfo() const override { @@ -282,6 +284,7 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const { auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo()); GISel->RegBankInfo.reset(RBI); + GISel->InstSelector.reset(new X86InstructionSelector(*this, *I, *RBI)); #endif I->setGISelAccessor(*GISel); @@ -391,7 +394,7 @@ bool X86PassConfig::addRegBankSelect() { } bool X86PassConfig::addGlobalInstructionSelect() { - //TODO: Implement + addPass(new InstructionSelect()); return false; } #endif |