forked from OSchip/llvm-project
[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
This commit is contained in:
parent
fa7367428a
commit
531a203a06
|
@ -159,6 +159,8 @@ bool X86InstructionSelector::select(MachineInstr &I) const {
|
||||||
return true;
|
return true;
|
||||||
if (selectLoadStoreOp(I, MRI, MF))
|
if (selectLoadStoreOp(I, MRI, MF))
|
||||||
return true;
|
return true;
|
||||||
|
if (selectFrameIndex(I, MRI, MF))
|
||||||
|
return true;
|
||||||
|
|
||||||
return selectImpl(I);
|
return selectImpl(I);
|
||||||
}
|
}
|
||||||
|
@ -389,3 +391,27 @@ bool X86InstructionSelector::selectLoadStoreOp(MachineInstr &I,
|
||||||
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ private:
|
||||||
MachineFunction &MF) const;
|
MachineFunction &MF) const;
|
||||||
bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
|
bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
|
||||||
MachineFunction &MF) const;
|
MachineFunction &MF) const;
|
||||||
|
bool selectFrameIndex(MachineInstr &I, MachineRegisterInfo &MRI,
|
||||||
|
MachineFunction &MF) const;
|
||||||
|
|
||||||
const X86Subtarget &STI;
|
const X86Subtarget &STI;
|
||||||
const X86InstrInfo &TII;
|
const X86InstrInfo &TII;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "X86LegalizerInfo.h"
|
#include "X86LegalizerInfo.h"
|
||||||
#include "X86Subtarget.h"
|
#include "X86Subtarget.h"
|
||||||
|
#include "X86TargetMachine.h"
|
||||||
#include "llvm/CodeGen/ValueTypes.h"
|
#include "llvm/CodeGen/ValueTypes.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
#include "llvm/IR/Type.h"
|
#include "llvm/IR/Type.h"
|
||||||
|
@ -25,7 +26,9 @@ using namespace TargetOpcode;
|
||||||
#error "You shouldn't build this"
|
#error "You shouldn't build this"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI) : Subtarget(STI) {
|
X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
|
||||||
|
const X86TargetMachine &TM)
|
||||||
|
: Subtarget(STI), TM(TM) {
|
||||||
|
|
||||||
setLegalizerInfo32bit();
|
setLegalizerInfo32bit();
|
||||||
setLegalizerInfo64bit();
|
setLegalizerInfo64bit();
|
||||||
|
@ -56,6 +59,9 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
|
||||||
// And everything's fine in addrspace 0.
|
// And everything's fine in addrspace 0.
|
||||||
setAction({MemOp, 1, p0}, Legal);
|
setAction({MemOp, 1, p0}, Legal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pointer-handling
|
||||||
|
setAction({G_FRAME_INDEX, p0}, Legal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86LegalizerInfo::setLegalizerInfo64bit() {
|
void X86LegalizerInfo::setLegalizerInfo64bit() {
|
||||||
|
@ -63,7 +69,7 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
|
||||||
if (!Subtarget.is64Bit())
|
if (!Subtarget.is64Bit())
|
||||||
return;
|
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 s8 = LLT::scalar(8);
|
||||||
const LLT s16 = LLT::scalar(16);
|
const LLT s16 = LLT::scalar(16);
|
||||||
const LLT s32 = LLT::scalar(32);
|
const LLT s32 = LLT::scalar(32);
|
||||||
|
@ -80,6 +86,9 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
|
||||||
// And everything's fine in addrspace 0.
|
// And everything's fine in addrspace 0.
|
||||||
setAction({MemOp, 1, p0}, Legal);
|
setAction({MemOp, 1, p0}, Legal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pointer-handling
|
||||||
|
setAction({G_FRAME_INDEX, p0}, Legal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void X86LegalizerInfo::setLegalizerInfoSSE1() {
|
void X86LegalizerInfo::setLegalizerInfoSSE1() {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class X86Subtarget;
|
class X86Subtarget;
|
||||||
|
class X86TargetMachine;
|
||||||
|
|
||||||
/// This class provides the information for the target register banks.
|
/// This class provides the information for the target register banks.
|
||||||
class X86LegalizerInfo : public LegalizerInfo {
|
class X86LegalizerInfo : public LegalizerInfo {
|
||||||
|
@ -27,9 +28,10 @@ private:
|
||||||
/// Keep a reference to the X86Subtarget around so that we can
|
/// Keep a reference to the X86Subtarget around so that we can
|
||||||
/// make the right decision when generating code for different targets.
|
/// make the right decision when generating code for different targets.
|
||||||
const X86Subtarget &Subtarget;
|
const X86Subtarget &Subtarget;
|
||||||
|
const X86TargetMachine &TM;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
X86LegalizerInfo(const X86Subtarget &STI);
|
X86LegalizerInfo(const X86Subtarget &STI, const X86TargetMachine &TM);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setLegalizerInfo32bit();
|
void setLegalizerInfo32bit();
|
||||||
|
@ -37,5 +39,5 @@ private:
|
||||||
void setLegalizerInfoSSE1();
|
void setLegalizerInfoSSE1();
|
||||||
void setLegalizerInfoSSE2();
|
void setLegalizerInfoSSE2();
|
||||||
};
|
};
|
||||||
} // End llvm namespace.
|
} // namespace llvm
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -283,7 +283,7 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const {
|
||||||
X86GISelActualAccessor *GISel = new X86GISelActualAccessor();
|
X86GISelActualAccessor *GISel = new X86GISelActualAccessor();
|
||||||
|
|
||||||
GISel->CallLoweringInfo.reset(new X86CallLowering(*I->getTargetLowering()));
|
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());
|
auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
|
||||||
GISel->RegBankInfo.reset(RBI);
|
GISel->RegBankInfo.reset(RBI);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
...
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue