llvm.org GIT mirror llvm / ceaf829
Add two new calling conventions for runtime calls This patch adds two new target-independent calling conventions for runtime calls - PreserveMost and PreserveAll. The target-specific implementation for X86-64 is defined as following: - Arguments are passed as for the default C calling convention - The same applies for the return value(s) - PreserveMost preserves all GPRs - except R11 - PreserveAll preserves all GPRs and all XMMs/YMMs - except R11 Reviewed by Lang and Philip git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199508 91177308-0d34-0410-b5e6-96231b3b80d8 Juergen Ributzka 6 years ago
11 changed file(s) with 274 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
738738 * ``coldcc``: code 9
739739 * ``webkit_jscc``: code 12
740740 * ``anyregcc``: code 13
741 * ``preserve_mostcc``: code 14
742 * ``preserve_allcc``: code 15
741743 * ``x86_stdcallcc``: code 64
742744 * ``x86_fastcallcc``: code 65
743745 * ``arm_apcscc``: code 66
358358 allocated. This can currently only be used with calls to
359359 llvm.experimental.patchpoint because only this intrinsic records
360360 the location of its arguments in a side table. See :doc:`StackMaps`.
361 "``preserve_mostcc``" - The `PreserveMost` calling convention
362 This calling convention attempts to make the code in the caller as little
363 intrusive as possible. This calling convention behaves identical to the `C`
364 calling convention on how arguments and return values are passed, but it
365 uses a different set of caller/callee-saved registers. This alleviates the
366 burden of saving and recovering a large register set before and after the
367 call in the caller.
368
369 - On X86-64 the callee preserves all general purpose registers, except for
370 R11. R11 can be used as a scratch register. Floating-point registers
371 (XMMs/YMMs) are not preserved and need to be saved by the caller.
372
373 The idea behind this convention is to support calls to runtime functions
374 that have a hot path and a cold path. The hot path is usually a small piece
375 of code that doesn't many registers. The cold path might need to call out to
376 another function and therefore only needs to preserve the caller-saved
377 registers, which haven't already been saved by the caller.
378
379 This calling convention will be used by a future version of the ObjectiveC
380 runtime and should therefore still be considered experimental at this time.
381 Although this convention was created to optimize certain runtime calls to
382 the ObjectiveC runtime, it is not limited to this runtime and might be used
383 by other runtimes in the future too. The current implementation only
384 supports X86-64, but the intention is to support more architectures in the
385 future.
386 "``preserve_allcc``" - The `PreserveAll` calling convention
387 This calling convention attempts to make the code in the caller even less
388 intrusive than the `PreserveMost` calling convention. This calling
389 convention also behaves identical to the `C` calling convention on how
390 arguments and return values are passed, but it uses a different set of
391 caller/callee-saved registers. This removes the burden of saving and
392 recovering a large register set before and after the call in the caller.
393
394 - On X86-64 the callee preserves all general purpose registers, except for
395 R11. R11 can be used as a scratch register. Furthermore it also preserves
396 all floating-point registers (XMMs/YMMs).
397
398 The idea behind this convention is to support calls to runtime functions
399 that don't need to call out to any other functions.
400
401 This calling convention, like the `PreserveMost` calling convention, will be
402 used by a future version of the ObjectiveC runtime and should be considered
403 experimental at this time.
361404 "``cc ``" - Numbered convention
362405 Any calling convention may be specified by number, allowing
363406 target-specific calling conventions to be used. Target specific
5656 // AnyReg - Calling convention for dynamic register based calls (e.g.
5757 // stackmap and patchpoint intrinsics).
5858 AnyReg = 13,
59
60 // PreserveMost - Calling convention for runtime calls that preserves most
61 // registers.
62 PreserveMost = 14,
63
64 // PreserveAll - Calling convention for runtime calls that preserves
65 // (almost) all registers.
66 PreserveAll = 15,
5967
6068 // Target - This is the start of the target-specific calling conventions,
6169 // e.g. fastcall and thiscall on X86.
562562 KEYWORD(x86_64_win64cc);
563563 KEYWORD(webkit_jscc);
564564 KEYWORD(anyregcc);
565 KEYWORD(preserve_mostcc);
566 KEYWORD(preserve_allcc);
565567
566568 KEYWORD(cc);
567569 KEYWORD(c);
13681368 /// ::= 'x86_64_win64cc'
13691369 /// ::= 'webkit_jscc'
13701370 /// ::= 'anyregcc'
1371 /// ::= 'preserve_mostcc'
1372 /// ::= 'preserve_allcc'
13711373 /// ::= 'cc' UINT
13721374 ///
13731375 bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
13921394 case lltok::kw_x86_64_win64cc: CC = CallingConv::X86_64_Win64; break;
13931395 case lltok::kw_webkit_jscc: CC = CallingConv::WebKit_JS; break;
13941396 case lltok::kw_anyregcc: CC = CallingConv::AnyReg; break;
1397 case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break;
1398 case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break;
13951399 case lltok::kw_cc: {
13961400 unsigned ArbitraryCC;
13971401 Lex.Lex();
9191 kw_spir_kernel, kw_spir_func,
9292 kw_x86_64_sysvcc, kw_x86_64_win64cc,
9393 kw_webkit_jscc, kw_anyregcc,
94 kw_preserve_mostcc, kw_preserve_allcc,
9495
9596 // Attributes:
9697 kw_attributes,
7272 case CallingConv::Cold: Out << "coldcc"; break;
7373 case CallingConv::WebKit_JS: Out << "webkit_jscc"; break;
7474 case CallingConv::AnyReg: Out << "anyregcc"; break;
75 case CallingConv::PreserveMost: Out << "preserve_mostcc"; break;
76 case CallingConv::PreserveAll: Out << "preserve_allcc"; break;
7577 case CallingConv::X86_StdCall: Out << "x86_stdcallcc"; break;
7678 case CallingConv::X86_FastCall: Out << "x86_fastcallcc"; break;
7779 case CallingConv::X86_ThisCall: Out << "x86_thiscallcc"; break;
619619 def CSR_Win64 : CalleeSavedRegs<(add RBX, RBP, RDI, RSI, R12, R13, R14, R15,
620620 (sequence "XMM%u", 6, 15))>;
621621
622 // All GPRs - except r11
623 def CSR_64_RT_MostRegs : CalleeSavedRegs<(add CSR_64, RAX, RCX, RDX, RSI, RDI,
624 R8, R9, R10, RSP)>;
625
626 // All registers - except r11
627 def CSR_64_RT_AllRegs : CalleeSavedRegs<(add CSR_64_RT_MostRegs,
628 (sequence "XMM%u", 0, 15))>;
629 def CSR_64_RT_AllRegs_AVX : CalleeSavedRegs<(add CSR_64_RT_MostRegs,
630 (sequence "YMM%u", 0, 15))>;
631
622632 def CSR_64_MostRegs : CalleeSavedRegs<(add RBX, RCX, RDX, RSI, RDI, R8, R9, R10,
623633 R11, R12, R13, R14, R15, RBP,
624634 (sequence "XMM%u", 0, 15))>;
244244 if (HasAVX)
245245 return CSR_64_AllRegs_AVX_SaveList;
246246 return CSR_64_AllRegs_SaveList;
247 case CallingConv::PreserveMost:
248 return CSR_64_RT_MostRegs_SaveList;
249 case CallingConv::PreserveAll:
250 if (HasAVX)
251 return CSR_64_RT_AllRegs_AVX_SaveList;
252 return CSR_64_RT_AllRegs_SaveList;
247253 case CallingConv::Intel_OCL_BI: {
248254 if (HasAVX512 && IsWin64)
249255 return CSR_Win64_Intel_OCL_BI_AVX512_SaveList;
291297 if (HasAVX)
292298 return CSR_64_AllRegs_AVX_RegMask;
293299 return CSR_64_AllRegs_RegMask;
300 case CallingConv::PreserveMost:
301 return CSR_64_RT_MostRegs_RegMask;
302 case CallingConv::PreserveAll:
303 if (HasAVX)
304 return CSR_64_RT_AllRegs_AVX_RegMask;
305 return CSR_64_RT_AllRegs_RegMask;
294306 case CallingConv::Intel_OCL_BI: {
295307 if (IsWin64 && HasAVX512)
296308 return CSR_Win64_Intel_OCL_BI_AVX512_RegMask;
0 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck --check-prefix=SSE %s
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx | FileCheck --check-prefix=AVX %s
2
3 define preserve_allcc void @preserve_allcc1() nounwind {
4 entry:
5 ;SSE-LABEL: preserve_allcc1
6 ;SSE: pushq %r10
7 ;SSE-NEXT: pushq %r9
8 ;SSE-NEXT: pushq %r8
9 ;SSE-NEXT: pushq %rdi
10 ;SSE-NEXT: pushq %rsi
11 ;SSE-NEXT: pushq %rdx
12 ;SSE-NEXT: pushq %rcx
13 ;SSE-NEXT: pushq %rax
14 ;SSE-NEXT: pushq %rbp
15 ;SSE-NEXT: pushq %r15
16 ;SSE-NEXT: pushq %r14
17 ;SSE-NEXT: pushq %r13
18 ;SSE-NEXT: pushq %r12
19 ;SSE-NEXT: pushq %rbx
20 ;SSE: movaps %xmm15
21 ;SSE-NEXT: movaps %xmm14
22 ;SSE-NEXT: movaps %xmm13
23 ;SSE-NEXT: movaps %xmm12
24 ;SSE-NEXT: movaps %xmm11
25 ;SSE-NEXT: movaps %xmm10
26 ;SSE-NEXT: movaps %xmm9
27 ;SSE-NEXT: movaps %xmm8
28 ;SSE-NEXT: movaps %xmm7
29 ;SSE-NEXT: movaps %xmm6
30 ;SSE-NEXT: movaps %xmm5
31 ;SSE-NEXT: movaps %xmm4
32 ;SSE-NEXT: movaps %xmm3
33 ;SSE-NEXT: movaps %xmm2
34 ;SSE-NEXT: movaps %xmm1
35 ;SSE-NEXT: movaps %xmm0
36 ;AVX-LABEL: preserve_allcc1
37 ;AVX: pushq %r10
38 ;AVX-NEXT: pushq %r9
39 ;AVX-NEXT: pushq %r8
40 ;AVX-NEXT: pushq %rdi
41 ;AVX-NEXT: pushq %rsi
42 ;AVX-NEXT: pushq %rdx
43 ;AVX-NEXT: pushq %rcx
44 ;AVX-NEXT: pushq %rax
45 ;AVX-NEXT: pushq %rbp
46 ;AVX-NEXT: pushq %r15
47 ;AVX-NEXT: pushq %r14
48 ;AVX-NEXT: pushq %r13
49 ;AVX-NEXT: pushq %r12
50 ;AVX-NEXT: pushq %rbx
51 ;AVX: vmovups %ymm15
52 ;AVX-NEXT: vmovups %ymm14
53 ;AVX-NEXT: vmovups %ymm13
54 ;AVX-NEXT: vmovups %ymm12
55 ;AVX-NEXT: vmovups %ymm11
56 ;AVX-NEXT: vmovups %ymm10
57 ;AVX-NEXT: vmovups %ymm9
58 ;AVX-NEXT: vmovups %ymm8
59 ;AVX-NEXT: vmovups %ymm7
60 ;AVX-NEXT: vmovups %ymm6
61 ;AVX-NEXT: vmovups %ymm5
62 ;AVX-NEXT: vmovups %ymm4
63 ;AVX-NEXT: vmovups %ymm3
64 ;AVX-NEXT: vmovups %ymm2
65 ;AVX-NEXT: vmovups %ymm1
66 ;AVX-NEXT: vmovups %ymm0
67 call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{rbp},~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{xmm12},~{xmm13},~{xmm14},~{xmm15}"()
68 ret void
69 }
70
71 ; Make sure only R11 is saved before the call
72 declare preserve_allcc void @bar(i64, i64, double, double)
73 define void @preserve_allcc2() nounwind {
74 entry:
75 ;SSE-LABEL: preserve_allcc2
76 ;SSE: movq %r11, [[REG:%[a-z0-9]+]]
77 ;SSE-NOT: movaps %xmm
78 ;SSE: movq [[REG]], %r11
79 %a0 = call i64 asm sideeffect "", "={rax}"() nounwind
80 %a1 = call i64 asm sideeffect "", "={rcx}"() nounwind
81 %a2 = call i64 asm sideeffect "", "={rdx}"() nounwind
82 %a3 = call i64 asm sideeffect "", "={r8}"() nounwind
83 %a4 = call i64 asm sideeffect "", "={r9}"() nounwind
84 %a5 = call i64 asm sideeffect "", "={r10}"() nounwind
85 %a6 = call i64 asm sideeffect "", "={r11}"() nounwind
86 %a10 = call <2 x double> asm sideeffect "", "={xmm2}"() nounwind
87 %a11 = call <2 x double> asm sideeffect "", "={xmm3}"() nounwind
88 %a12 = call <2 x double> asm sideeffect "", "={xmm4}"() nounwind
89 %a13 = call <2 x double> asm sideeffect "", "={xmm5}"() nounwind
90 %a14 = call <2 x double> asm sideeffect "", "={xmm6}"() nounwind
91 %a15 = call <2 x double> asm sideeffect "", "={xmm7}"() nounwind
92 %a16 = call <2 x double> asm sideeffect "", "={xmm8}"() nounwind
93 %a17 = call <2 x double> asm sideeffect "", "={xmm9}"() nounwind
94 %a18 = call <2 x double> asm sideeffect "", "={xmm10}"() nounwind
95 %a19 = call <2 x double> asm sideeffect "", "={xmm11}"() nounwind
96 %a20 = call <2 x double> asm sideeffect "", "={xmm12}"() nounwind
97 %a21 = call <2 x double> asm sideeffect "", "={xmm13}"() nounwind
98 %a22 = call <2 x double> asm sideeffect "", "={xmm14}"() nounwind
99 %a23 = call <2 x double> asm sideeffect "", "={xmm15}"() nounwind
100 call preserve_allcc void @bar(i64 1, i64 2, double 3.0, double 4.0)
101 call void asm sideeffect "", "{rax},{rcx},{rdx},{r8},{r9},{r10},{r11},{xmm2},{xmm3},{xmm4},{xmm5},{xmm6},{xmm7},{xmm8},{xmm9},{xmm10},{xmm11},{xmm12},{xmm13},{xmm14},{xmm15}"(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, <2 x double> %a10, <2 x double> %a11, <2 x double> %a12, <2 x double> %a13, <2 x double> %a14, <2 x double> %a15, <2 x double> %a16, <2 x double> %a17, <2 x double> %a18, <2 x double> %a19, <2 x double> %a20, <2 x double> %a21, <2 x double> %a22, <2 x double> %a23)
102 ret void
103 }
0 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7 | FileCheck --check-prefix=SSE %s
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx | FileCheck --check-prefix=AVX %s
2
3 ; Every GPR should be saved - except r11
4 define preserve_mostcc void @preserve_mostcc1() nounwind {
5 entry:
6 ;SSE-LABEL: preserve_mostcc1
7 ;SSE: pushq %r10
8 ;SSE-NEXT: pushq %r9
9 ;SSE-NEXT: pushq %r8
10 ;SSE-NEXT: pushq %rdi
11 ;SSE-NEXT: pushq %rsi
12 ;SSE-NEXT: pushq %rdx
13 ;SSE-NEXT: pushq %rcx
14 ;SSE-NEXT: pushq %rax
15 ;SSE-NEXT: pushq %rbp
16 ;SSE-NEXT: pushq %r15
17 ;SSE-NEXT: pushq %r14
18 ;SSE-NEXT: pushq %r13
19 ;SSE-NEXT: pushq %r12
20 ;SSE-NEXT: pushq %rbx
21 ;AVX-LABEL: preserve_mostcc1
22 ;AVX: pushq %r10
23 ;AVX-NEXT: pushq %r9
24 ;AVX-NEXT: pushq %r8
25 ;AVX-NEXT: pushq %rdi
26 ;AVX-NEXT: pushq %rsi
27 ;AVX-NEXT: pushq %rdx
28 ;AVX-NEXT: pushq %rcx
29 ;AVX-NEXT: pushq %rax
30 ;AVX-NEXT: pushq %rbp
31 ;AVX-NEXT: pushq %r15
32 ;AVX-NEXT: pushq %r14
33 ;AVX-NEXT: pushq %r13
34 ;AVX-NEXT: pushq %r12
35 ;AVX-NEXT: pushq %rbx
36 call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{rbp},~{xmm0},~{xmm1},~{xmm2},~{xmm3},~{xmm4},~{xmm5},~{xmm6},~{xmm7},~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{xmm12},~{xmm13},~{xmm14},~{xmm15}"()
37 ret void
38 }
39
40 ; Make sure R11 and XMMs are saved before the call
41 declare preserve_mostcc void @foo(i64, i64, double, double)
42 define void @preserve_mostcc2() nounwind {
43 entry:
44 ;SSE-LABEL: preserve_mostcc2
45 ;SSE: movq %r11, [[REG:%[a-z0-9]+]]
46 ;SSE: movaps %xmm2
47 ;SSE: movaps %xmm3
48 ;SSE: movaps %xmm4
49 ;SSE: movaps %xmm5
50 ;SSE: movaps %xmm6
51 ;SSE: movaps %xmm7
52 ;SSE: movaps %xmm8
53 ;SSE: movaps %xmm9
54 ;SSE: movaps %xmm10
55 ;SSE: movaps %xmm11
56 ;SSE: movaps %xmm12
57 ;SSE: movaps %xmm13
58 ;SSE: movaps %xmm14
59 ;SSE: movaps %xmm15
60 ;SSE: movq [[REG]], %r11
61 %a0 = call i64 asm sideeffect "", "={rax}"() nounwind
62 %a1 = call i64 asm sideeffect "", "={rcx}"() nounwind
63 %a2 = call i64 asm sideeffect "", "={rdx}"() nounwind
64 %a3 = call i64 asm sideeffect "", "={r8}"() nounwind
65 %a4 = call i64 asm sideeffect "", "={r9}"() nounwind
66 %a5 = call i64 asm sideeffect "", "={r10}"() nounwind
67 %a6 = call i64 asm sideeffect "", "={r11}"() nounwind
68 %a10 = call <2 x double> asm sideeffect "", "={xmm2}"() nounwind
69 %a11 = call <2 x double> asm sideeffect "", "={xmm3}"() nounwind
70 %a12 = call <2 x double> asm sideeffect "", "={xmm4}"() nounwind
71 %a13 = call <2 x double> asm sideeffect "", "={xmm5}"() nounwind
72 %a14 = call <2 x double> asm sideeffect "", "={xmm6}"() nounwind
73 %a15 = call <2 x double> asm sideeffect "", "={xmm7}"() nounwind
74 %a16 = call <2 x double> asm sideeffect "", "={xmm8}"() nounwind
75 %a17 = call <2 x double> asm sideeffect "", "={xmm9}"() nounwind
76 %a18 = call <2 x double> asm sideeffect "", "={xmm10}"() nounwind
77 %a19 = call <2 x double> asm sideeffect "", "={xmm11}"() nounwind
78 %a20 = call <2 x double> asm sideeffect "", "={xmm12}"() nounwind
79 %a21 = call <2 x double> asm sideeffect "", "={xmm13}"() nounwind
80 %a22 = call <2 x double> asm sideeffect "", "={xmm14}"() nounwind
81 %a23 = call <2 x double> asm sideeffect "", "={xmm15}"() nounwind
82 call preserve_mostcc void @foo(i64 1, i64 2, double 3.0, double 4.0)
83 call void asm sideeffect "", "{rax},{rcx},{rdx},{r8},{r9},{r10},{r11},{xmm2},{xmm3},{xmm4},{xmm5},{xmm6},{xmm7},{xmm8},{xmm9},{xmm10},{xmm11},{xmm12},{xmm13},{xmm14},{xmm15}"(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, <2 x double> %a10, <2 x double> %a11, <2 x double> %a12, <2 x double> %a13, <2 x double> %a14, <2 x double> %a15, <2 x double> %a16, <2 x double> %a17, <2 x double> %a18, <2 x double> %a19, <2 x double> %a20, <2 x double> %a21, <2 x double> %a22, <2 x double> %a23)
84 ret void
85 }