llvm.org GIT mirror llvm / 7a3b1c2
[GlobalISel][X86] support G_FRAME_INDEX instruction selection. Summary: G_LOAD/G_STORE, add alternative RegisterBank mapping. For G_LOAD, Fast and Greedy mode choose the same RegisterBank mapping (GprRegBank ) for the G_GLOAD + G_FADD , can't get rid of cross register bank copy GprRegBank->VecRegBank. Reviewers: zvi, rovka, qcolombet, ab Reviewed By: zvi Subscribers: llvm-commits, dberris, kristof.beyls, eladcohen, guyblank Differential Revision: https://reviews.llvm.org/D30979 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298907 91177308-0d34-0410-b5e6-96231b3b80d8 Igor Breger 3 years ago
5 changed file(s) with 207 addition(s) and 77 deletion(s). Raw diff Collapse all Expand all
104104 return PMI_None;
105105 }
106106
107 void X86RegisterBankInfo::getInstrPartialMappingIdxs(
108 const MachineInstr &MI, const MachineRegisterInfo &MRI, const bool isFP,
109 SmallVectorImpl &OpRegBankIdx) {
110
111 unsigned NumOperands = MI.getNumOperands();
112 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
113 auto &MO = MI.getOperand(Idx);
114 if (!MO.isReg())
115 OpRegBankIdx[Idx] = PMI_None;
116 else
117 OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP);
118 }
119 }
120
121 bool X86RegisterBankInfo::getInstrValueMapping(
122 const MachineInstr &MI,
123 const SmallVectorImpl &OpRegBankIdx,
124 SmallVectorImpl &OpdsMapping) {
125
126 unsigned NumOperands = MI.getNumOperands();
127 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
128 if (!MI.getOperand(Idx).isReg())
129 continue;
130
131 auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
132 if (!Mapping->isValid())
133 return false;
134
135 OpdsMapping[Idx] = Mapping;
136 }
137 return true;
138 }
139
107140 RegisterBankInfo::InstructionMapping
108141 X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, bool isFP) {
109142 const MachineFunction &MF = *MI.getParent()->getParent();
150183 }
151184
152185 unsigned NumOperands = MI.getNumOperands();
153 unsigned Cost = 1; // set dafault cost
154
155 // Track the bank of each register.
186
187 // Track the bank of each register, use NotFP mapping (all scalars in GPRs)
156188 SmallVector OpRegBankIdx(NumOperands);
157 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
158 auto &MO = MI.getOperand(Idx);
159 if (!MO.isReg())
160 continue;
161
162 // As a top-level guess, use NotFP mapping (all scalars in GPRs)
163 OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), false);
164 }
189 getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx);
165190
166191 // Finally construct the computed mapping.
167 RegisterBankInfo::InstructionMapping Mapping =
168 InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands};
169192 SmallVector OpdsMapping(NumOperands);
170 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
171 if (MI.getOperand(Idx).isReg()) {
172 auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1);
173 if (!Mapping->isValid())
174 return InstructionMapping();
175
176 OpdsMapping[Idx] = Mapping;
177 }
178 }
179
180 Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
181 return Mapping;
182 }
193 if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
194 return InstructionMapping();
195
196 return InstructionMapping{DefaultMappingID, /* Cost */ 1,
197 getOperandsMapping(OpdsMapping), NumOperands};
198 }
199
200 void X86RegisterBankInfo::applyMappingImpl(
201 const OperandsMapper &OpdMapper) const {
202 return applyDefaultMapping(OpdMapper);
203 }
204
205 RegisterBankInfo::InstructionMappings
206 X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
207
208 const MachineFunction &MF = *MI.getParent()->getParent();
209 const TargetSubtargetInfo &STI = MF.getSubtarget();
210 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
211 const MachineRegisterInfo &MRI = MF.getRegInfo();
212
213 switch (MI.getOpcode()) {
214 case TargetOpcode::G_LOAD:
215 case TargetOpcode::G_STORE: {
216 // we going to try to map 32/64 bit to PMI_FP32/PMI_FP64
217 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
218 if (Size != 32 && Size != 64)
219 break;
220
221 unsigned NumOperands = MI.getNumOperands();
222
223 // Track the bank of each register, use FP mapping (all scalars in VEC)
224 SmallVector OpRegBankIdx(NumOperands);
225 getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx);
226
227 // Finally construct the computed mapping.
228 SmallVector OpdsMapping(NumOperands);
229 if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
230 break;
231
232 RegisterBankInfo::InstructionMapping Mapping = InstructionMapping{
233 /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands};
234 InstructionMappings AltMappings;
235 AltMappings.emplace_back(std::move(Mapping));
236 return AltMappings;
237 }
238 default:
239 break;
240 }
241 return RegisterBankInfo::getInstrAlternativeMappings(MI);
242 }
4848 static InstructionMapping getSameOperandsMapping(const MachineInstr &MI,
4949 bool isFP);
5050
51 /// Track the bank of each instruction operand(register)
52 /// \return An instruction PartialMappingIdxs.
53 static void
54 getInstrPartialMappingIdxs(const MachineInstr &MI,
55 const MachineRegisterInfo &MRI, const bool isFP,
56 SmallVectorImpl &OpRegBankIdx);
57
58 /// Construct the instruction ValueMapping from PartialMappingIdxs
59 /// \return true if mapping succeeded.
60 static bool
61 getInstrValueMapping(const MachineInstr &MI,
62 const SmallVectorImpl &OpRegBankIdx,
63 SmallVectorImpl &OpdsMapping);
64
5165 public:
5266 X86RegisterBankInfo(const TargetRegisterInfo &TRI);
5367
5468 const RegisterBank &
5569 getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
5670
71 InstructionMappings
72 getInstrAlternativeMappings(const MachineInstr &MI) const override;
73
74 /// See RegisterBankInfo::applyMapping.
75 void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
76
5777 InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
5878 };
5979
None # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=regbankselect %s -o - | FileCheck %s
0 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
1 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -regbankselect-greedy -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
12
23 --- |
34 ; ModuleID = 'tmp.ll'
3536 ret double %ret
3637 }
3738
38 define <4 x i32> @test_add_v4i32(<4 x i32> %arg1, <4 x i32> %arg2) {
39 %ret = add <4 x i32> %arg1, %arg2
40 ret <4 x i32> %ret
41 }
42
43 define <4 x float> @test_add_v4f32(<4 x float> %arg1, <4 x float> %arg2) {
44 %ret = fadd <4 x float> %arg1, %arg2
45 ret <4 x float> %ret
39 define <4 x i32> @test_add_v4i32(<4 x i32> %arg1, <4 x i32> %arg2) {
40 %ret = add <4 x i32> %arg1, %arg2
41 ret <4 x i32> %ret
42 }
43
44 define <4 x float> @test_add_v4f32(<4 x float> %arg1, <4 x float> %arg2) {
45 %ret = fadd <4 x float> %arg1, %arg2
46 ret <4 x float> %ret
4647 }
4748
4849 define i8 @test_load_i8(i8* %p1) {
535536 selected: false
536537 # CHECK-LABEL: name: test_store_float
537538 # CHECK: registers:
538 # CHECK: - { id: 0, class: vecr }
539 # CHECK: - { id: 1, class: gpr }
540 # CHECK: - { id: 2, class: gpr }
539
540 # FAST-NEXT: - { id: 0, class: vecr }
541 # FAST-NEXT: - { id: 1, class: gpr }
542 # FAST-NEXT: - { id: 2, class: gpr }
543
544 # GREEDY-NEXT: - { id: 0, class: vecr }
545 # GREEDY-NEXT: - { id: 1, class: gpr }
541546
542547 registers:
543548 - { id: 0, class: _ }
548553
549554 %0(s32) = COPY %xmm0
550555 %1(p0) = COPY %rdi
551 ; CHECK: %2(s32) = COPY %0(s32)
552 ; CHECK: G_STORE %2(s32), %1(p0) :: (store 4 into %ir.p1)
556 ; CHECK: %1(p0) = COPY %rdi
557
558 ; FAST-NEXT: %2(s32) = COPY %0(s32)
559 ; FAST-NEXT: G_STORE %2(s32), %1(p0) :: (store 4 into %ir.p1)
560
561 ; GREEDY-NEXT: G_STORE %0(s32), %1(p0) :: (store 4 into %ir.p1)
562
553563 G_STORE %0(s32), %1(p0) :: (store 4 into %ir.p1)
554564 %rax = COPY %1(p0)
555565 RET 0, implicit %rax
563573 selected: false
564574 # CHECK-LABEL: name: test_store_double
565575 # CHECK: registers:
566 # CHECK: - { id: 0, class: vecr }
567 # CHECK: - { id: 1, class: gpr }
568 # CHECK: - { id: 2, class: gpr }
576
577 # FAST-NEXT: - { id: 0, class: vecr }
578 # FAST-NEXT: - { id: 1, class: gpr }
579 # FAST-NEXT: - { id: 2, class: gpr }
580
581 # GREEDY-NEXT: - { id: 0, class: vecr }
582 # GREEDY-NEXT: - { id: 1, class: gpr }
569583
570584 registers:
571585 - { id: 0, class: _ }
576590
577591 %0(s64) = COPY %xmm0
578592 %1(p0) = COPY %rdi
579 ; CHECK: %2(s64) = COPY %0(s64)
580 ; CHECK: G_STORE %2(s64), %1(p0) :: (store 8 into %ir.p1)
593
594 ; CHECK: %1(p0) = COPY %rdi
595
596 ; FAST-NEXT: %2(s64) = COPY %0(s64)
597 ; FAST-NEXT: G_STORE %2(s64), %1(p0) :: (store 8 into %ir.p1)
598
599 ; GREEDY-NEXT: G_STORE %0(s64), %1(p0) :: (store 8 into %ir.p1)
600
581601 G_STORE %0(s64), %1(p0) :: (store 8 into %ir.p1)
582602 %rax = COPY %1(p0)
583603 RET 0, implicit %rax
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=ALL --check-prefix=SSE
2 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX
3 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX512F
4 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX512VL
1 ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=SSE
2 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX
3 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX512F
4 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -mattr=+avx512vl -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX512VL
55
66 define i64 @test_add_i64(i64 %arg1, i64 %arg2) {
77 ; ALL-LABEL: test_add_i64:
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=ALL --check-prefix=SSE
2 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX
3 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX512F
4 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=AVX512VL
1 ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE_FAST
2 ; RUN: llc -mtriple=x86_64-linux-gnu -regbankselect-greedy -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE_GREEDY
3 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=ALL_AVX_FAST --check-prefix=AVX_FAST
4 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx -regbankselect-greedy -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=ALL_AVX_GREEDY --check-prefix=AVX_GREEDY
5 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=ALL_AVX_FAST --check-prefix=AVX512F_FAST
6 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -regbankselect-greedy -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=ALL_AVX_GREEDY --check-prefix=AVX512F_GREEDY
7 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -mattr=+avx512vl -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=ALL_AVX_FAST --check-prefix=AVX512VL_FAST
8 ; RUN: llc -mtriple=x86_64-linux-gnu -mattr=+avx512f -mattr=+avx512vl -regbankselect-greedy -global-isel < %s -o - | FileCheck %s --check-prefix=ALL --check-prefix=ALL_AVX --check-prefix=ALL_AVX_GREEDY --check-prefix=AVX512VL_GREEDY
59
610
711 define i8 @test_load_i8(i8 * %p1) {
121125 }
122126
123127 define float * @test_store_float(float %val, float * %p1) {
124 ; SSE-LABEL: test_store_float:
125 ; SSE: # BB#0:
126 ; SSE-NEXT: movd %xmm0, %eax
127 ; SSE-NEXT: movl %eax, (%rdi)
128 ; SSE-NEXT: movq %rdi, %rax
129 ; SSE-NEXT: retq
130128 ;
131 ; ALL_AVX-LABEL: test_store_float:
132 ; ALL_AVX: # BB#0:
133 ; ALL_AVX-NEXT: vmovd %xmm0, %eax
134 ; ALL_AVX-NEXT: movl %eax, (%rdi)
135 ; ALL_AVX-NEXT: movq %rdi, %rax
136 ; ALL_AVX-NEXT: retq
129 ; SSE_FAST-LABEL: test_store_float:
130 ; SSE_FAST: # BB#0:
131 ; SSE_FAST-NEXT: movd %xmm0, %eax
132 ; SSE_FAST-NEXT: movl %eax, (%rdi)
133 ; SSE_FAST-NEXT: movq %rdi, %rax
134 ; SSE_FAST-NEXT: retq
135 ;
136 ; SSE_GREEDY-LABEL: test_store_float:
137 ; SSE_GREEDY: # BB#0:
138 ; SSE_GREEDY-NEXT: movss %xmm0, (%rdi)
139 ; SSE_GREEDY-NEXT: movq %rdi, %rax
140 ; SSE_GREEDY-NEXT: retq
141 ;
142 ; ALL_AVX_FAST-LABEL: test_store_float:
143 ; ALL_AVX_FAST: # BB#0:
144 ; ALL_AVX_FAST-NEXT: vmovd %xmm0, %eax
145 ; ALL_AVX_FAST-NEXT: movl %eax, (%rdi)
146 ; ALL_AVX_FAST-NEXT: movq %rdi, %rax
147 ; ALL_AVX_FAST-NEXT: retq
148 ;
149 ; ALL_AVX_GREEDY-LABEL: test_store_float:
150 ; ALL_AVX_GREEDY: # BB#0:
151 ; ALL_AVX_GREEDY-NEXT: vmovss %xmm0, (%rdi)
152 ; ALL_AVX_GREEDY-NEXT: movq %rdi, %rax
153 ; ALL_AVX_GREEDY-NEXT: retq
137154 store float %val, float* %p1
138155 ret float * %p1;
139156 }
140157
141158 define double * @test_store_double(double %val, double * %p1) {
142 ; SSE-LABEL: test_store_double:
143 ; SSE: # BB#0:
144 ; SSE-NEXT: movd %xmm0, %rax
145 ; SSE-NEXT: movq %rax, (%rdi)
146 ; SSE-NEXT: movq %rdi, %rax
147 ; SSE-NEXT: retq
148159 ;
149 ; ALL_AVX-LABEL: test_store_double:
150 ; ALL_AVX: # BB#0:
151 ; ALL_AVX-NEXT: vmovq %xmm0, %rax
152 ; ALL_AVX-NEXT: movq %rax, (%rdi)
153 ; ALL_AVX-NEXT: movq %rdi, %rax
154 ; ALL_AVX-NEXT: retq
160 ; SSE_FAST-LABEL: test_store_double:
161 ; SSE_FAST: # BB#0:
162 ; SSE_FAST-NEXT: movd %xmm0, %rax
163 ; SSE_FAST-NEXT: movq %rax, (%rdi)
164 ; SSE_FAST-NEXT: movq %rdi, %rax
165 ; SSE_FAST-NEXT: retq
166 ;
167 ; SSE_GREEDY-LABEL: test_store_double:
168 ; SSE_GREEDY: # BB#0:
169 ; SSE_GREEDY-NEXT: movsd %xmm0, (%rdi)
170 ; SSE_GREEDY-NEXT: movq %rdi, %rax
171 ; SSE_GREEDY-NEXT: retq
172 ;
173 ; ALL_AVX_FAST-LABEL: test_store_double:
174 ; ALL_AVX_FAST: # BB#0:
175 ; ALL_AVX_FAST-NEXT: vmovq %xmm0, %rax
176 ; ALL_AVX_FAST-NEXT: movq %rax, (%rdi)
177 ; ALL_AVX_FAST-NEXT: movq %rdi, %rax
178 ; ALL_AVX_FAST-NEXT: retq
179 ;
180 ; ALL_AVX_GREEDY-LABEL: test_store_double:
181 ; ALL_AVX_GREEDY: # BB#0:
182 ; ALL_AVX_GREEDY-NEXT: vmovsd %xmm0, (%rdi)
183 ; ALL_AVX_GREEDY-NEXT: movq %rdi, %rax
184 ; ALL_AVX_GREEDY-NEXT: retq
155185 store double %val, double* %p1
156186 ret double * %p1;
157187 }