[GlobalISel][X86] support G_FRAME_INDEX instruction selection.

    Summary:
    Support G_FRAME_INDEX instruction selection.

    Reviewers: zvi, rovka, ab, qcolombet

    Reviewed By: ab

    Subscribers: llvm-commits, dberris, kristof.beyls, eladcohen, guyblank

    Differential Revision: https://reviews.llvm.org/D30980

llvm-svn: 298800
diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp
index e45d122..0f01bc4 100644
--- a/llvm/lib/Target/X86/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp
@@ -159,6 +159,8 @@
     return true;
   if (selectLoadStoreOp(I, MRI, MF))
     return true;
+  if (selectFrameIndex(I, MRI, MF))
+    return true;
 
   return selectImpl(I);
 }
@@ -389,3 +391,27 @@
   return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
 }
 
+bool X86InstructionSelector::selectFrameIndex(MachineInstr &I,
+                                              MachineRegisterInfo &MRI,
+                                              MachineFunction &MF) const {
+  if (I.getOpcode() != TargetOpcode::G_FRAME_INDEX)
+    return false;
+
+  const unsigned DefReg = I.getOperand(0).getReg();
+  LLT Ty = MRI.getType(DefReg);
+
+  // Use LEA to calculate frame index.
+  unsigned NewOpc;
+  if (Ty == LLT::pointer(0, 64))
+    NewOpc = X86::LEA64r;
+  else if (Ty == LLT::pointer(0, 32))
+    NewOpc = STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
+  else
+    llvm_unreachable("Can't select G_FRAME_INDEX, unsupported type.");
+
+  I.setDesc(TII.get(NewOpc));
+  MachineInstrBuilder MIB(MF, I);
+  addOffset(MIB, 0);
+
+  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+}
diff --git a/llvm/lib/Target/X86/X86InstructionSelector.h b/llvm/lib/Target/X86/X86InstructionSelector.h
index a8eb4ca..fa258d4 100644
--- a/llvm/lib/Target/X86/X86InstructionSelector.h
+++ b/llvm/lib/Target/X86/X86InstructionSelector.h
@@ -53,6 +53,8 @@
                       MachineFunction &MF) const;
   bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
                          MachineFunction &MF) const;
+  bool selectFrameIndex(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 bda6579..3ab80c4 100644
--- a/llvm/lib/Target/X86/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/X86LegalizerInfo.cpp
@@ -13,6 +13,7 @@
 
 #include "X86LegalizerInfo.h"
 #include "X86Subtarget.h"
+#include "X86TargetMachine.h"
 #include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Type.h"
@@ -25,7 +26,9 @@
 #error "You shouldn't build this"
 #endif
 
-X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI) : Subtarget(STI) {
+X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
+                                   const X86TargetMachine &TM)
+    : Subtarget(STI), TM(TM) {
 
   setLegalizerInfo32bit();
   setLegalizerInfo64bit();
@@ -56,6 +59,9 @@
     // And everything's fine in addrspace 0.
     setAction({MemOp, 1, p0}, Legal);
   }
+
+  // Pointer-handling
+  setAction({G_FRAME_INDEX, p0}, Legal);
 }
 
 void X86LegalizerInfo::setLegalizerInfo64bit() {
@@ -63,7 +69,7 @@
   if (!Subtarget.is64Bit())
     return;
 
-  const LLT p0 = LLT::pointer(0, 64);
+  const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8);
   const LLT s8 = LLT::scalar(8);
   const LLT s16 = LLT::scalar(16);
   const LLT s32 = LLT::scalar(32);
@@ -80,6 +86,9 @@
     // And everything's fine in addrspace 0.
     setAction({MemOp, 1, p0}, Legal);
   }
+
+  // Pointer-handling
+  setAction({G_FRAME_INDEX, p0}, Legal);
 }
 
 void X86LegalizerInfo::setLegalizerInfoSSE1() {
diff --git a/llvm/lib/Target/X86/X86LegalizerInfo.h b/llvm/lib/Target/X86/X86LegalizerInfo.h
index b9cf42f..3f00898 100644
--- a/llvm/lib/Target/X86/X86LegalizerInfo.h
+++ b/llvm/lib/Target/X86/X86LegalizerInfo.h
@@ -20,6 +20,7 @@
 namespace llvm {
 
 class X86Subtarget;
+class X86TargetMachine;
 
 /// This class provides the information for the target register banks.
 class X86LegalizerInfo : public LegalizerInfo {
@@ -27,9 +28,10 @@
   /// Keep a reference to the X86Subtarget around so that we can
   /// make the right decision when generating code for different targets.
   const X86Subtarget &Subtarget;
+  const X86TargetMachine &TM;
 
 public:
-  X86LegalizerInfo(const X86Subtarget &STI);
+  X86LegalizerInfo(const X86Subtarget &STI, const X86TargetMachine &TM);
 
 private:
   void setLegalizerInfo32bit();
@@ -37,5 +39,5 @@
   void setLegalizerInfoSSE1();
   void setLegalizerInfoSSE2();
 };
-} // End llvm namespace.
+} // namespace llvm
 #endif
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index a0d62b7..a314819 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -283,7 +283,7 @@
     X86GISelActualAccessor *GISel = new X86GISelActualAccessor();
 
     GISel->CallLoweringInfo.reset(new X86CallLowering(*I->getTargetLowering()));
-    GISel->Legalizer.reset(new X86LegalizerInfo(*I));
+    GISel->Legalizer.reset(new X86LegalizerInfo(*I, *this));
 
     auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
     GISel->RegBankInfo.reset(RBI);