Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit eb1c51f

Browse files
committed
[FastISel] Let the target decide first if it wants to materialize a constant.
This changes the order in which FastISel tries to materialize a constant. Originally it would try to use a simple target-independent approach, which can lead to the generation of inefficient code. On X86 this would result in the use of movabsq to materialize any 64bit integer constant - even for simple and small values such as 0 and 1. Also some very funny floating-point materialization could be observed too. On AArch64 it would materialize the constant 0 in a register even the architecture has an actual "zero" register. On ARM it would generate unnecessary mov instructions or not use mvn. This change simply changes the order and always asks the target first if it likes to materialize the constant. This doesn't fix all the issues mentioned above, but it enables the targets to implement such optimizations. Related to <rdar://problem/17420988>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215588 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 2205044 commit eb1c51f

File tree

10 files changed

+56
-87
lines changed

10 files changed

+56
-87
lines changed

include/llvm/CodeGen/FastISel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,10 @@ class FastISel {
575575
/// correspond to a different MBB than the end.
576576
bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
577577

578+
/// \brief Helper for materializeRegForValue to materialize a constant in a
579+
/// target-independent way.
580+
unsigned MaterializeConstant(const Value *V, MVT VT);
581+
578582
/// Helper for getRegForVale. This function is called when the value isn't
579583
/// already available in a register and must be materialized with new
580584
/// instructions.

lib/CodeGen/SelectionDAG/FastISel.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -198,29 +198,24 @@ unsigned FastISel::getRegForValue(const Value *V) {
198198
return Reg;
199199
}
200200

201-
/// materializeRegForValue - Helper for getRegForValue. This function is
202-
/// called when the value isn't already available in a register and must
203-
/// be materialized with new instructions.
204-
unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) {
201+
unsigned FastISel::MaterializeConstant(const Value *V, MVT VT) {
205202
unsigned Reg = 0;
206-
207203
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
208204
if (CI->getValue().getActiveBits() <= 64)
209205
Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
210-
} else if (isa<AllocaInst>(V)) {
206+
} else if (isa<AllocaInst>(V))
211207
Reg = TargetMaterializeAlloca(cast<AllocaInst>(V));
212-
} else if (isa<ConstantPointerNull>(V)) {
208+
else if (isa<ConstantPointerNull>(V))
213209
// Translate this as an integer zero so that it can be
214210
// local-CSE'd with actual integer zeros.
215211
Reg =
216212
getRegForValue(Constant::getNullValue(DL.getIntPtrType(V->getContext())));
217-
} else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
218-
if (CF->isNullValue()) {
213+
else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
214+
if (CF->isNullValue())
219215
Reg = TargetMaterializeFloatZero(CF);
220-
} else {
216+
else
221217
// Try to emit the constant directly.
222218
Reg = FastEmit_f(VT, VT, ISD::ConstantFP, CF);
223-
}
224219

225220
if (!Reg) {
226221
// Try to emit the constant by using an integer constant with a cast.
@@ -253,15 +248,26 @@ unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) {
253248
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
254249
TII.get(TargetOpcode::IMPLICIT_DEF), Reg);
255250
}
251+
return Reg;
252+
}
256253

257-
// If target-independent code couldn't handle the value, give target-specific
258-
// code a try.
259-
if (!Reg && isa<Constant>(V))
254+
/// materializeRegForValue - Helper for getRegForValue. This function is
255+
/// called when the value isn't already available in a register and must
256+
/// be materialized with new instructions.
257+
unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) {
258+
unsigned Reg = 0;
259+
// Give the target-specific code a try first.
260+
if (isa<Constant>(V))
260261
Reg = TargetMaterializeConstant(cast<Constant>(V));
261262

263+
// If target-specific code couldn't or didn't want to handle the value, then
264+
// give target-independent code a try.
265+
if (!Reg)
266+
Reg = MaterializeConstant(V, VT);
267+
262268
// Don't cache constant materializations in the general ValueMap.
263269
// To do so would require tracking what uses they dominate.
264-
if (Reg != 0) {
270+
if (Reg) {
265271
LocalValueMap[V] = Reg;
266272
LastLocalValue = MRI.getVRegDef(Reg);
267273
}

test/CodeGen/ARM/fast-isel-call.ll

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,11 @@ entry:
117117
; ARM-LONG: blx [[R]]
118118
; THUMB: @t10
119119
; THUMB: movs [[R0:l?r[0-9]*]], #0
120-
; THUMB: movt [[R0]], #0
121120
; THUMB: movs [[R1:l?r[0-9]*]], #248
122-
; THUMB: movt [[R1]], #0
123121
; THUMB: movs [[R2:l?r[0-9]*]], #187
124-
; THUMB: movt [[R2]], #0
125122
; THUMB: movs [[R3:l?r[0-9]*]], #28
126-
; THUMB: movt [[R3]], #0
127123
; THUMB: movw [[R4:l?r[0-9]*]], #40
128-
; THUMB: movt [[R4]], #0
129124
; THUMB: movw [[R5:l?r[0-9]*]], #186
130-
; THUMB: movt [[R5]], #0
131125
; THUMB: and [[R0]], [[R0]], #255
132126
; THUMB: and [[R1]], [[R1]], #255
133127
; THUMB: and [[R2]], [[R2]], #255

test/CodeGen/ARM/fast-isel-deadcode.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ entry:
1414
; THUMB-NOT: ldr
1515
; THUMB-NOT: sxtb
1616
; THUMB: movs r0, #0
17-
; THUMB: movt r0, #0
1817
; THUMB: pop
1918
ret i32 0
2019
}

test/CodeGen/ARM/fast-isel-intrinsic.ll

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ define void @t1() nounwind ssp {
3131
; THUMB: {{(movt r0, :upper16:_?message1)|(ldr r0, \[r0\])}}
3232
; THUMB: adds r0, #5
3333
; THUMB: movs r1, #64
34-
; THUMB: movt r1, #0
3534
; THUMB: movs r2, #10
36-
; THUMB: movt r2, #0
3735
; THUMB: and r1, r1, #255
3836
; THUMB: bl {{_?}}memset
3937
; THUMB-LONG-LABEL: t1:
@@ -71,7 +69,6 @@ define void @t2() nounwind ssp {
7169
; THUMB: adds r1, r0, #4
7270
; THUMB: adds r0, #16
7371
; THUMB: movs r2, #17
74-
; THUMB: movt r2, #0
7572
; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill
7673
; THUMB: mov r0, r1
7774
; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload
@@ -109,7 +106,6 @@ define void @t3() nounwind ssp {
109106
; THUMB: adds r1, r0, #4
110107
; THUMB: adds r0, #16
111108
; THUMB: movs r2, #10
112-
; THUMB: movt r2, #0
113109
; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill
114110
; THUMB: mov r0, r1
115111
; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload

test/CodeGen/ARM/fast-isel-mvn.ll

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=armv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
22
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=armv7-linux-gnueabi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
3-
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB
3+
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=thumbv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
4+
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=true -mtriple=thumbv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB
45
; rdar://10412592
56

6-
; Note: The Thumb code is being generated by the target-independent selector.
7-
87
define void @t1() nounwind {
98
entry:
10-
; ARM: t1
11-
; THUMB: t1
12-
; ARM: mvn r0, #0
13-
; THUMB: movw r0, #65535
14-
; THUMB: movt r0, #65535
9+
; CHECK-LABEL: t1
10+
; CHECK: mvn r0, #0
1511
call void @foo(i32 -1)
1612
ret void
1713
}
@@ -20,89 +16,68 @@ declare void @foo(i32)
2016

2117
define void @t2() nounwind {
2218
entry:
23-
; ARM: t2
24-
; THUMB: t2
25-
; ARM: mvn r0, #233
26-
; THUMB: movw r0, #65302
27-
; THUMB: movt r0, #65535
19+
; CHECK-LABEL: t2
20+
; CHECK: mvn r0, #233
2821
call void @foo(i32 -234)
2922
ret void
3023
}
3124

3225
define void @t3() nounwind {
3326
entry:
34-
; ARM: t3
35-
; THUMB: t3
36-
; ARM: mvn r0, #256
37-
; THUMB: movw r0, #65279
38-
; THUMB: movt r0, #65535
27+
; CHECK-LABEL: t3
28+
; CHECK: mvn r0, #256
3929
call void @foo(i32 -257)
4030
ret void
4131
}
4232

4333
; Load from constant pool
4434
define void @t4() nounwind {
4535
entry:
46-
; ARM: t4
47-
; THUMB: t4
48-
; ARM: ldr r0
49-
; THUMB: movw r0, #65278
50-
; THUMB: movt r0, #65535
36+
; ARM-LABEL: t4
37+
; ARM: ldr r0
38+
; THUMB-LABEL: t4
39+
; THUMB: movw r0, #65278
40+
; THUMB: movt r0, #65535
5141
call void @foo(i32 -258)
5242
ret void
5343
}
5444

5545
define void @t5() nounwind {
5646
entry:
57-
; ARM: t5
58-
; THUMB: t5
59-
; ARM: mvn r0, #65280
60-
; THUMB: movs r0, #255
61-
; THUMB: movt r0, #65535
47+
; CHECK-LABEL: t5
48+
; CHECK: mvn r0, #65280
6249
call void @foo(i32 -65281)
6350
ret void
6451
}
6552

6653
define void @t6() nounwind {
6754
entry:
68-
; ARM: t6
69-
; THUMB: t6
70-
; ARM: mvn r0, #978944
71-
; THUMB: movw r0, #4095
72-
; THUMB: movt r0, #65521
55+
; CHECK-LABEL: t6
56+
; CHECK: mvn r0, #978944
7357
call void @foo(i32 -978945)
7458
ret void
7559
}
7660

7761
define void @t7() nounwind {
7862
entry:
79-
; ARM: t7
80-
; THUMB: t7
81-
; ARM: mvn r0, #267386880
82-
; THUMB: movw r0, #65535
83-
; THUMB: movt r0, #61455
63+
; CHECK-LABEL: t7
64+
; CHECK: mvn r0, #267386880
8465
call void @foo(i32 -267386881)
8566
ret void
8667
}
8768

8869
define void @t8() nounwind {
8970
entry:
90-
; ARM: t8
91-
; THUMB: t8
92-
; ARM: mvn r0, #65280
93-
; THUMB: movs r0, #255
94-
; THUMB: movt r0, #65535
71+
; CHECK-LABEL: t8
72+
; CHECK: mvn r0, #65280
9573
call void @foo(i32 -65281)
9674
ret void
9775
}
9876

9977
define void @t9() nounwind {
10078
entry:
101-
; ARM: t9
102-
; THUMB: t9
103-
; ARM: mvn r0, #2130706432
104-
; THUMB: movw r0, #65535
105-
; THUMB: movt r0, #33023
79+
; CHECK-LABEL: t9
80+
; CHECK: mvn r0, #2130706432
10681
call void @foo(i32 -2130706433)
10782
ret void
10883
}

test/CodeGen/ARM/fast-isel-select.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ entry:
1212
; ARM: mov r0, r{{[1-9]}}
1313
; THUMB: t1
1414
; THUMB: movs r{{[1-9]}}, #10
15-
; THUMB: movt r{{[1-9]}}, #0
1615
; THUMB: cmp r0, #0
1716
; THUMB: it eq
1817
; THUMB: moveq r{{[1-9]}}, #20
@@ -59,13 +58,12 @@ entry:
5958
; ARM: cmp r0, #0
6059
; ARM: mvneq r{{[1-9]}}, #0
6160
; ARM: mov r0, r{{[1-9]}}
62-
; THUMB: t4
63-
; THUMB: movw r{{[1-9]}}, #65526
64-
; THUMB: movt r{{[1-9]}}, #65535
61+
; THUMB-LABEL: t4
62+
; THUMB: mvn [[REG:r[1-9]+]], #9
6563
; THUMB: cmp r0, #0
6664
; THUMB: it eq
67-
; THUMB: mvneq r{{[1-9]}}, #0
68-
; THUMB: mov r0, r{{[1-9]}}
65+
; THUMB: mvneq [[REG]], #0
66+
; THUMB: mov r0, [[REG]]
6967
%0 = select i1 %c, i32 -10, i32 -1
7068
ret i32 %0
7169
}

test/CodeGen/ARM/fast-isel-vararg.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ entry:
2929
; ARM: bl {{_?CallVariadic}}
3030
; THUMB: sub sp, #32
3131
; THUMB: movs r0, #5
32-
; THUMB: movt r0, #0
3332
; THUMB: ldr r1, [sp, #28]
3433
; THUMB: ldr r2, [sp, #24]
3534
; THUMB: ldr r3, [sp, #20]

test/CodeGen/PowerPC/fast-isel-call.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ entry:
5757
; ELF64: t10
5858
%call = call i32 @bar(i8 zeroext 0, i8 zeroext -8, i8 zeroext -69, i8 zeroext 28, i8 zeroext 40, i8 zeroext -70)
5959
; ELF64: li 3, 0
60-
; ELF64: li 4, 248
61-
; ELF64: li 5, 187
60+
; ELF64: li 4, -8
61+
; ELF64: li 5, -69
6262
; ELF64: li 6, 28
6363
; ELF64: li 7, 40
64-
; ELF64: li 8, 186
64+
; ELF64: li 8, -70
6565
; ELF64: rldicl 3, 3, 0, 56
6666
; ELF64: rldicl 4, 4, 0, 56
6767
; ELF64: rldicl 5, 5, 0, 56

test/CodeGen/X86/fast-isel-x86-64.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,10 @@ define void @test16() nounwind {
194194
br label %block2
195195

196196
block2:
197-
; CHECK: movabsq $1
198-
; CHECK: cvtsi2sdq {{.*}} %xmm0
197+
; CHECK: movsd LCP{{.*}}_{{.*}}(%rip), %xmm0
199198
; CHECK: movb $1, %al
200199
; CHECK: callq _test16callee
201200

202-
; AVX: movabsq $1
203201
; AVX: vmovsd LCP{{.*}}_{{.*}}(%rip), %xmm0
204202
; AVX: movb $1, %al
205203
; AVX: callq _test16callee

0 commit comments

Comments
 (0)