summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorIgor Breger <igor.breger@intel.com>2017-02-22 12:25:09 +0000
committerIgor Breger <igor.breger@intel.com>2017-02-22 12:25:09 +0000
commitf7359d893af318deca46b85f2d6c0f0f533783c7 (patch)
tree08b92e8cbc965238c1b4465f9e74c722f0b3860e /llvm/lib/Target
parenta2fc1e0cc886df429cde9e6ac59ce3fad4419461 (diff)
downloadbcm5719-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.txt2
-rw-r--r--llvm/lib/Target/X86/X86InstructionSelector.cpp133
-rw-r--r--llvm/lib/Target/X86/X86InstructionSelector.h47
-rw-r--r--llvm/lib/Target/X86/X86LegalizerInfo.cpp8
-rw-r--r--llvm/lib/Target/X86/X86RegisterBankInfo.cpp1
-rw-r--r--llvm/lib/Target/X86/X86TargetMachine.cpp9
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
OpenPOWER on IntegriCloud