[GlobalISel][X86] support G_FRAME_INDEX instruction selection.
authorIgor Breger <igor.breger@intel.com>
Sun, 26 Mar 2017 08:11:12 +0000 (08:11 +0000)
committerIgor Breger <igor.breger@intel.com>
Sun, 26 Mar 2017 08:11:12 +0000 (08:11 +0000)
    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

llvm/lib/Target/X86/X86InstructionSelector.cpp
llvm/lib/Target/X86/X86InstructionSelector.h
llvm/lib/Target/X86/X86LegalizerInfo.cpp
llvm/lib/Target/X86/X86LegalizerInfo.h
llvm/lib/Target/X86/X86TargetMachine.cpp
llvm/test/CodeGen/X86/GlobalISel/frameIndex-instructionselect.mir [new file with mode: 0644]
llvm/test/CodeGen/X86/GlobalISel/frameIndex.ll [new file with mode: 0644]

index e45d122..0f01bc4 100644 (file)
@@ -159,6 +159,8 @@ bool X86InstructionSelector::select(MachineInstr &I) const {
     return true;
   if (selectLoadStoreOp(I, MRI, MF))
     return true;
+  if (selectFrameIndex(I, MRI, MF))
+    return true;
 
   return selectImpl(I);
 }
@@ -389,3 +391,27 @@ bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
   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);
+}
index a8eb4ca..fa258d4 100644 (file)
@@ -53,6 +53,8 @@ private:
                       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;
index bda6579..3ab80c4 100644 (file)
@@ -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 @@ using namespace TargetOpcode;
 #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 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
     // 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 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
   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 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
     // And everything's fine in addrspace 0.
     setAction({MemOp, 1, p0}, Legal);
   }
+
+  // Pointer-handling
+  setAction({G_FRAME_INDEX, p0}, Legal);
 }
 
 void X86LegalizerInfo::setLegalizerInfoSSE1() {
index b9cf42f..3f00898 100644 (file)
@@ -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 @@ private:
   /// 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 @@ private:
   void setLegalizerInfoSSE1();
   void setLegalizerInfoSSE2();
 };
-} // End llvm namespace.
+} // namespace llvm
 #endif
index a0d62b7..a314819 100644 (file)
@@ -283,7 +283,7 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const {
     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);
diff --git a/llvm/test/CodeGen/X86/GlobalISel/frameIndex-instructionselect.mir b/llvm/test/CodeGen/X86/GlobalISel/frameIndex-instructionselect.mir
new file mode 100644 (file)
index 0000000..2fa9ac2
--- /dev/null
@@ -0,0 +1,36 @@
+# RUN: llc -mtriple=x86_64-linux-gnu    -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X64
+# RUN: llc -mtriple=i386-linux-gnu      -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32
+# RUN: llc -mtriple=x86_64-linux-gnux32 -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32ABI
+
+--- |
+  define i32* @allocai32() {
+    %ptr1 = alloca i32
+    ret i32* %ptr1
+  }
+
+...
+---
+name:            allocai32
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK-LABEL: name:            allocai32
+# CHECK: registers:
+# CHECK-X32:     - { id: 0, class: gr32 }
+# CHECK-X32ABI:  - { id: 0, class: gr32 }
+# CHECK-X64:     - { id: 0, class: gr64 }
+registers:
+  - { id: 0, class: gpr }
+stack:
+  - { id: 0, name: ptr1, offset: 0, size: 4, alignment: 4 }
+
+# CHECK-X32:    %0 = LEA32r %stack.0.ptr1, 1, _, 0, _
+# CHECK-X32ABI: %0 = LEA64_32r %stack.0.ptr1, 1, _, 0, _
+# CHECK-X64:    %0 = LEA64r %stack.0.ptr1, 1, _, 0, _
+body:             |
+  bb.1 (%ir-block.0):
+    %0(p0) = G_FRAME_INDEX %stack.0.ptr1
+    %eax = COPY %0(p0)
+    RET 0, implicit %eax
+
+...
diff --git a/llvm/test/CodeGen/X86/GlobalISel/frameIndex.ll b/llvm/test/CodeGen/X86/GlobalISel/frameIndex.ll
new file mode 100644 (file)
index 0000000..2bb11ad
--- /dev/null
@@ -0,0 +1,30 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-linux-gnu    -global-isel < %s -o - | FileCheck %s --check-prefix=X64
+; RUN: llc -mtriple=x86_64-linux-gnu                 < %s -o - | FileCheck %s --check-prefix=X64
+; RUN: llc -mtriple=i386-linux-gnu      -global-isel < %s -o - | FileCheck %s --check-prefix=X32
+; RUN: llc -mtriple=i386-linux-gnu                   < %s -o - | FileCheck %s --check-prefix=X32
+; RUN: llc -mtriple=x86_64-linux-gnux32 -global-isel < %s -o - | FileCheck %s --check-prefix=X32ABI
+; RUN: llc -mtriple=x86_64-linux-gnux32              < %s -o - | FileCheck %s --check-prefix=X32ABI
+
+define i32* @allocai32() {
+; X64-LABEL: allocai32:
+; X64:       # BB#0:
+; X64-NEXT:    leaq -4(%rsp), %rax
+; X64-NEXT:    retq
+;
+; X32-LABEL: allocai32:
+; X32:       # BB#0:
+; X32-NEXT:    pushl %eax
+; X32-NEXT:  .Lcfi0:
+; X32-NEXT:    .cfi_def_cfa_offset 8
+; X32-NEXT:    movl %esp, %eax
+; X32-NEXT:    popl %ecx
+; X32-NEXT:    retl
+;
+; X32ABI-LABEL: allocai32:
+; X32ABI:       # BB#0:
+; X32ABI-NEXT:    leal -4(%rsp), %eax
+; X32ABI-NEXT:    retq
+  %ptr1 = alloca i32
+  ret i32* %ptr1
+}