Skip to content

Commit ef658eb

Browse files
committed
MIR Statepoint refactoring. Part 1: Basic MI level changes.
Basic support for variadic-def MIR Statepoint: - Change TableGen STATEPOINT description to variadic out list (For self-documentation purpose; by itself it does not affect code generation in any way). - Update StatepointOpers helper class to handle variadic defs. - Update MachineVerifier to properly handle them, too. With this change, new Statepoint instruction can be passed through backend (excluding ISEL) without errors. Full change set is available at D81603. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D81645
1 parent d909764 commit ef658eb

File tree

4 files changed

+171
-9
lines changed

4 files changed

+171
-9
lines changed

llvm/include/llvm/CodeGen/StackMaps.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,21 +166,23 @@ class StatepointOpers {
166166
enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
167167

168168
public:
169-
explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
169+
explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {
170+
NumDefs = MI->getNumDefs();
171+
}
170172

171173
/// Get index of statepoint ID operand.
172-
unsigned getIDPos() const { return IDPos; }
174+
unsigned getIDPos() const { return NumDefs + IDPos; }
173175

174176
/// Get index of Num Patch Bytes operand.
175-
unsigned getNBytesPos() const { return NBytesPos; }
177+
unsigned getNBytesPos() const { return NumDefs + NBytesPos; }
176178

177179
/// Get index of Num Call Arguments operand.
178-
unsigned getNCallArgsPos() const { return NCallArgsPos; }
180+
unsigned getNCallArgsPos() const { return NumDefs + NCallArgsPos; }
179181

180182
/// Get starting index of non call related arguments
181183
/// (calling convention, statepoint flags, vm state and gc state).
182184
unsigned getVarIdx() const {
183-
return MI->getOperand(NCallArgsPos).getImm() + MetaEnd;
185+
return MI->getOperand(NumDefs + NCallArgsPos).getImm() + MetaEnd + NumDefs;
184186
}
185187

186188
/// Get index of Calling Convention operand.
@@ -195,16 +197,16 @@ class StatepointOpers {
195197
}
196198

197199
/// Return the ID for the given statepoint.
198-
uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
200+
uint64_t getID() const { return MI->getOperand(NumDefs + IDPos).getImm(); }
199201

200202
/// Return the number of patchable bytes the given statepoint should emit.
201203
uint32_t getNumPatchBytes() const {
202-
return MI->getOperand(NBytesPos).getImm();
204+
return MI->getOperand(NumDefs + NBytesPos).getImm();
203205
}
204206

205207
/// Return the target of the underlying call.
206208
const MachineOperand &getCallTarget() const {
207-
return MI->getOperand(CallTargetPos);
209+
return MI->getOperand(NumDefs + CallTargetPos);
208210
}
209211

210212
/// Return the calling convention.
@@ -217,6 +219,7 @@ class StatepointOpers {
217219

218220
private:
219221
const MachineInstr *MI;
222+
unsigned NumDefs;
220223
};
221224

222225
class StackMaps {

llvm/include/llvm/Target/Target.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,7 +1157,7 @@ def PATCHPOINT : StandardPseudoInstruction {
11571157
let usesCustomInserter = 1;
11581158
}
11591159
def STATEPOINT : StandardPseudoInstruction {
1160-
let OutOperandList = (outs);
1160+
let OutOperandList = (outs variable_ops);
11611161
let InOperandList = (ins variable_ops);
11621162
let usesCustomInserter = 1;
11631163
let mayLoad = 1;

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,6 +1565,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
15651565
if (MCID.getOpcode() == TargetOpcode::PATCHPOINT)
15661566
NumDefs = (MONum == 0 && MO->isReg()) ? NumDefs : 0;
15671567

1568+
if (MCID.getOpcode() == TargetOpcode::STATEPOINT)
1569+
NumDefs = MI->getNumDefs();
1570+
15681571
// The first MCID.NumDefs operands must be explicit register defines
15691572
if (MONum < NumDefs) {
15701573
const MCOperandInfo &MCOI = MCID.OpInfo[MONum];
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
# RUN: llc -o - %s -start-after=finalize-isel | FileCheck %s
3+
4+
--- |
5+
; ModuleID = 'test/CodeGen/X86/statepoint-vreg.ll'
6+
source_filename = "test/CodeGen/X86/statepoint-vreg.ll"
7+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
8+
target triple = "x86_64-pc-linux-gnu"
9+
10+
declare void @bar()
11+
12+
define i32 @test_basic(i32 addrspace(1)* %obj1, i32 addrspace(1)* %obj2) gc "statepoint-example" {
13+
; CHECK-LABEL: test_basic:
14+
; CHECK: # %bb.0:
15+
; CHECK-NEXT: pushq %r14
16+
; CHECK-NEXT: .cfi_def_cfa_offset 16
17+
; CHECK-NEXT: pushq %rbx
18+
; CHECK-NEXT: .cfi_def_cfa_offset 24
19+
; CHECK-NEXT: pushq %rax
20+
; CHECK-NEXT: .cfi_def_cfa_offset 32
21+
; CHECK-NEXT: .cfi_offset %rbx, -24
22+
; CHECK-NEXT: .cfi_offset %r14, -16
23+
; CHECK-NEXT: movq %rsi, %r14
24+
; CHECK-NEXT: movq %rdi, %rbx
25+
; CHECK-NEXT: callq bar
26+
; CHECK-NEXT: .Ltmp0:
27+
; CHECK-NEXT: movl (%rbx), %eax
28+
; CHECK-NEXT: addl (%r14), %eax
29+
; CHECK-NEXT: addq $8, %rsp
30+
; CHECK-NEXT: .cfi_def_cfa_offset 24
31+
; CHECK-NEXT: popq %rbx
32+
; CHECK-NEXT: .cfi_def_cfa_offset 16
33+
; CHECK-NEXT: popq %r14
34+
; CHECK-NEXT: .cfi_def_cfa_offset 8
35+
; CHECK-NEXT: retq
36+
%token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(i32 addrspace(1)* %obj1, i32 addrspace(1)* %obj2) ]
37+
%rel1 = call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token, i32 0, i32 0) ; (%obj1, %obj1)
38+
%rel2 = call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %token, i32 1, i32 1) ; (%obj2, %obj2)
39+
%a = load i32, i32 addrspace(1)* %rel1, align 4
40+
%b = load i32, i32 addrspace(1)* %rel2, align 4
41+
%c = add i32 %a, %b
42+
ret i32 %c
43+
}
44+
45+
; CHECK-LABEL: __LLVM_StackMaps:
46+
; CHECK-NEXT: .byte 3
47+
; CHECK-NEXT: .byte 0
48+
; CHECK-NEXT: .short 0
49+
; CHECK-NEXT: .long 1
50+
; CHECK-NEXT: .long 0
51+
; CHECK-NEXT: .long 1
52+
; CHECK-NEXT: .quad test_basic
53+
; CHECK-NEXT: .quad 24
54+
; CHECK-NEXT: .quad 1
55+
; CHECK-NEXT: .quad 2882400000
56+
; CHECK-NEXT: .long .Ltmp0-test_basic
57+
; CHECK-NEXT: .short 0
58+
; CHECK-NEXT: .short 8
59+
; CHECK-NEXT: .byte 4
60+
; CHECK-NEXT: .byte 0
61+
; CHECK-NEXT: .short 8
62+
; CHECK-NEXT: .short 0
63+
; CHECK-NEXT: .short 0
64+
; CHECK-NEXT: .long 0
65+
; CHECK-NEXT: .byte 4
66+
; CHECK-NEXT: .byte 0
67+
; CHECK-NEXT: .short 8
68+
; CHECK-NEXT: .short 0
69+
; CHECK-NEXT: .short 0
70+
; CHECK-NEXT: .long 0
71+
; CHECK-NEXT: .byte 4
72+
; CHECK-NEXT: .byte 0
73+
; CHECK-NEXT: .short 8
74+
; CHECK-NEXT: .short 0
75+
; CHECK-NEXT: .short 0
76+
; CHECK-NEXT: .long 1
77+
; CHECK-NEXT: .byte 4
78+
; CHECK-NEXT: .byte 0
79+
; CHECK-NEXT: .short 8
80+
; CHECK-NEXT: .short 0
81+
; CHECK-NEXT: .short 0
82+
; CHECK-NEXT: .long 0
83+
; CHECK-NEXT: .byte 1
84+
; CHECK-NEXT: .byte 0
85+
; CHECK-NEXT: .short 8
86+
; CHECK-NEXT: .short 14
87+
; CHECK-NEXT: .short 0
88+
; CHECK-NEXT: .long 0
89+
; CHECK-NEXT: .byte 1
90+
; CHECK-NEXT: .byte 0
91+
; CHECK-NEXT: .short 8
92+
; CHECK-NEXT: .short 14
93+
; CHECK-NEXT: .short 0
94+
; CHECK-NEXT: .long 0
95+
; CHECK-NEXT: .byte 1
96+
; CHECK-NEXT: .byte 0
97+
; CHECK-NEXT: .short 8
98+
; CHECK-NEXT: .short 3
99+
; CHECK-NEXT: .short 0
100+
; CHECK-NEXT: .long 0
101+
; CHECK-NEXT: .byte 1
102+
; CHECK-NEXT: .byte 0
103+
; CHECK-NEXT: .short 8
104+
; CHECK-NEXT: .short 3
105+
; CHECK-NEXT: .short 0
106+
; CHECK-NEXT: .long 0
107+
; CHECK-NEXT: .p2align 3
108+
; CHECK-NEXT: .short 0
109+
; CHECK-NEXT: .short 0
110+
; CHECK-NEXT: .p2align 3
111+
112+
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 immarg, i32 immarg, void ()*, i32 immarg, i32 immarg, ...)
113+
114+
; Function Attrs: nounwind readonly
115+
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32 immarg, i32 immarg) #0
116+
117+
attributes #0 = { nounwind readonly }
118+
attributes #1 = { nounwind }
119+
120+
...
121+
---
122+
name: test_basic
123+
alignment: 16
124+
selected: false
125+
failedISel: false
126+
tracksRegLiveness: true
127+
registers:
128+
- { id: 0, class: gr64, preferred-register: '' }
129+
- { id: 1, class: gr64, preferred-register: '' }
130+
- { id: 2, class: gr64, preferred-register: '' }
131+
- { id: 3, class: gr64, preferred-register: '' }
132+
- { id: 4, class: gr32, preferred-register: '' }
133+
- { id: 5, class: gr32, preferred-register: '' }
134+
liveins:
135+
- { reg: '$rdi', virtual-reg: '%0' }
136+
- { reg: '$rsi', virtual-reg: '%1' }
137+
fixedStack: []
138+
stack: []
139+
callSites: []
140+
constants: []
141+
machineFunctionInfo: {}
142+
body: |
143+
bb.0 (%ir-block.0):
144+
liveins: $rdi, $rsi
145+
146+
%1:gr64 = COPY $rsi
147+
%0:gr64 = COPY $rdi
148+
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
149+
%2:gr64, %3:gr64 = STATEPOINT 2882400000, 0, 0, @bar, 2, 0, 2, 0, 2, 1, 2, 0, %1, %1(tied-def 0), %0, %0(tied-def 1), csr_64, implicit-def $rsp, implicit-def $ssp
150+
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
151+
%4:gr32 = MOV32rm killed %3, 1, $noreg, 0, $noreg :: (load 4 from %ir.rel1, addrspace 1)
152+
%5:gr32 = ADD32rm %4, killed %2, 1, $noreg, 0, $noreg, implicit-def dead $eflags :: (load 4 from %ir.rel2, addrspace 1)
153+
$eax = COPY %5
154+
RET 0, $eax
155+
156+
...

0 commit comments

Comments
 (0)