llvm.org GIT mirror llvm / 7733e74
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298800 91177308-0d34-0410-b5e6-96231b3b80d8 Igor Breger 3 years ago
7 changed file(s) with 110 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
157157 if (selectBinaryOp(I, MRI, MF))
158158 return true;
159159 if (selectLoadStoreOp(I, MRI, MF))
160 return true;
161 if (selectFrameIndex(I, MRI, MF))
160162 return true;
161163
162164 return selectImpl(I);
388390 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
389391 }
390392
393 bool X86InstructionSelector::selectFrameIndex(MachineInstr &I,
394 MachineRegisterInfo &MRI,
395 MachineFunction &MF) const {
396 if (I.getOpcode() != TargetOpcode::G_FRAME_INDEX)
397 return false;
398
399 const unsigned DefReg = I.getOperand(0).getReg();
400 LLT Ty = MRI.getType(DefReg);
401
402 // Use LEA to calculate frame index.
403 unsigned NewOpc;
404 if (Ty == LLT::pointer(0, 64))
405 NewOpc = X86::LEA64r;
406 else if (Ty == LLT::pointer(0, 32))
407 NewOpc = STI.isTarget64BitILP32() ? X86::LEA64_32r : X86::LEA32r;
408 else
409 llvm_unreachable("Can't select G_FRAME_INDEX, unsupported type.");
410
411 I.setDesc(TII.get(NewOpc));
412 MachineInstrBuilder MIB(MF, I);
413 addOffset(MIB, 0);
414
415 return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
416 }
5252 MachineFunction &MF) const;
5353 bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
5454 MachineFunction &MF) const;
55 bool selectFrameIndex(MachineInstr &I, MachineRegisterInfo &MRI,
56 MachineFunction &MF) const;
5557
5658 const X86Subtarget &STI;
5759 const X86InstrInfo &TII;
1212
1313 #include "X86LegalizerInfo.h"
1414 #include "X86Subtarget.h"
15 #include "X86TargetMachine.h"
1516 #include "llvm/CodeGen/ValueTypes.h"
1617 #include "llvm/IR/DerivedTypes.h"
1718 #include "llvm/IR/Type.h"
2425 #error "You shouldn't build this"
2526 #endif
2627
27 X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI) : Subtarget(STI) {
28 X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
29 const X86TargetMachine &TM)
30 : Subtarget(STI), TM(TM) {
2831
2932 setLegalizerInfo32bit();
3033 setLegalizerInfo64bit();
5558 // And everything's fine in addrspace 0.
5659 setAction({MemOp, 1, p0}, Legal);
5760 }
61
62 // Pointer-handling
63 setAction({G_FRAME_INDEX, p0}, Legal);
5864 }
5965
6066 void X86LegalizerInfo::setLegalizerInfo64bit() {
6268 if (!Subtarget.is64Bit())
6369 return;
6470
65 const LLT p0 = LLT::pointer(0, 64);
71 const LLT p0 = LLT::pointer(0, TM.getPointerSize() * 8);
6672 const LLT s8 = LLT::scalar(8);
6773 const LLT s16 = LLT::scalar(16);
6874 const LLT s32 = LLT::scalar(32);
7985 // And everything's fine in addrspace 0.
8086 setAction({MemOp, 1, p0}, Legal);
8187 }
88
89 // Pointer-handling
90 setAction({G_FRAME_INDEX, p0}, Legal);
8291 }
8392
8493 void X86LegalizerInfo::setLegalizerInfoSSE1() {
1919 namespace llvm {
2020
2121 class X86Subtarget;
22 class X86TargetMachine;
2223
2324 /// This class provides the information for the target register banks.
2425 class X86LegalizerInfo : public LegalizerInfo {
2627 /// Keep a reference to the X86Subtarget around so that we can
2728 /// make the right decision when generating code for different targets.
2829 const X86Subtarget &Subtarget;
30 const X86TargetMachine &TM;
2931
3032 public:
31 X86LegalizerInfo(const X86Subtarget &STI);
33 X86LegalizerInfo(const X86Subtarget &STI, const X86TargetMachine &TM);
3234
3335 private:
3436 void setLegalizerInfo32bit();
3638 void setLegalizerInfoSSE1();
3739 void setLegalizerInfoSSE2();
3840 };
39 } // End llvm namespace.
41 } // namespace llvm
4042 #endif
282282 X86GISelActualAccessor *GISel = new X86GISelActualAccessor();
283283
284284 GISel->CallLoweringInfo.reset(new X86CallLowering(*I->getTargetLowering()));
285 GISel->Legalizer.reset(new X86LegalizerInfo(*I));
285 GISel->Legalizer.reset(new X86LegalizerInfo(*I, *this));
286286
287287 auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
288288 GISel->RegBankInfo.reset(RBI);
0 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X64
1 # RUN: llc -mtriple=i386-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32
2 # RUN: llc -mtriple=x86_64-linux-gnux32 -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=X32ABI
3
4 --- |
5 define i32* @allocai32() {
6 %ptr1 = alloca i32
7 ret i32* %ptr1
8 }
9
10 ...
11 ---
12 name: allocai32
13 legalized: true
14 regBankSelected: true
15 selected: false
16 # CHECK-LABEL: name: allocai32
17 # CHECK: registers:
18 # CHECK-X32: - { id: 0, class: gr32 }
19 # CHECK-X32ABI: - { id: 0, class: gr32 }
20 # CHECK-X64: - { id: 0, class: gr64 }
21 registers:
22 - { id: 0, class: gpr }
23 stack:
24 - { id: 0, name: ptr1, offset: 0, size: 4, alignment: 4 }
25
26 # CHECK-X32: %0 = LEA32r %stack.0.ptr1, 1, _, 0, _
27 # CHECK-X32ABI: %0 = LEA64_32r %stack.0.ptr1, 1, _, 0, _
28 # CHECK-X64: %0 = LEA64r %stack.0.ptr1, 1, _, 0, _
29 body: |
30 bb.1 (%ir-block.0):
31 %0(p0) = G_FRAME_INDEX %stack.0.ptr1
32 %eax = COPY %0(p0)
33 RET 0, implicit %eax
34
35 ...
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X64
2 ; RUN: llc -mtriple=x86_64-linux-gnu < %s -o - | FileCheck %s --check-prefix=X64
3 ; RUN: llc -mtriple=i386-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=X32
4 ; RUN: llc -mtriple=i386-linux-gnu < %s -o - | FileCheck %s --check-prefix=X32
5 ; RUN: llc -mtriple=x86_64-linux-gnux32 -global-isel < %s -o - | FileCheck %s --check-prefix=X32ABI
6 ; RUN: llc -mtriple=x86_64-linux-gnux32 < %s -o - | FileCheck %s --check-prefix=X32ABI
7
8 define i32* @allocai32() {
9 ; X64-LABEL: allocai32:
10 ; X64: # BB#0:
11 ; X64-NEXT: leaq -4(%rsp), %rax
12 ; X64-NEXT: retq
13 ;
14 ; X32-LABEL: allocai32:
15 ; X32: # BB#0:
16 ; X32-NEXT: pushl %eax
17 ; X32-NEXT: .Lcfi0:
18 ; X32-NEXT: .cfi_def_cfa_offset 8
19 ; X32-NEXT: movl %esp, %eax
20 ; X32-NEXT: popl %ecx
21 ; X32-NEXT: retl
22 ;
23 ; X32ABI-LABEL: allocai32:
24 ; X32ABI: # BB#0:
25 ; X32ABI-NEXT: leal -4(%rsp), %eax
26 ; X32ABI-NEXT: retq
27 %ptr1 = alloca i32
28 ret i32* %ptr1
29 }