[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-02-05 Thread via cfe-commits

https://github.com/weiguozhi closed 
https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-31 Thread David Li via cfe-commits


@@ -0,0 +1,131 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 4
+; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=corei7 < %s | FileCheck %s
+
+; This test checks various function call behaviors between preserve_none and
+; normal calling conventions.
+
+declare preserve_nonecc void @callee(ptr)
+
+; Normal caller calls preserve_none callee. Will not generated tail call 
because
+; of incompatible calling convention. Callee saved registers are saved/restored
+; around the call.
+define void @caller1(ptr %a) {
+; CHECK-LABEL: caller1:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:pushq %r15
+; CHECK-NEXT:.cfi_def_cfa_offset 16
+; CHECK-NEXT:pushq %r14
+; CHECK-NEXT:.cfi_def_cfa_offset 24
+; CHECK-NEXT:pushq %r13
+; CHECK-NEXT:.cfi_def_cfa_offset 32
+; CHECK-NEXT:pushq %r12
+; CHECK-NEXT:.cfi_def_cfa_offset 40
+; CHECK-NEXT:pushq %rbx
+; CHECK-NEXT:.cfi_def_cfa_offset 48
+; CHECK-NEXT:.cfi_offset %rbx, -48
+; CHECK-NEXT:.cfi_offset %r12, -40
+; CHECK-NEXT:.cfi_offset %r13, -32
+; CHECK-NEXT:.cfi_offset %r14, -24
+; CHECK-NEXT:.cfi_offset %r15, -16
+; CHECK-NEXT:callq callee@PLT
+; CHECK-NEXT:popq %rbx
+; CHECK-NEXT:.cfi_def_cfa_offset 40
+; CHECK-NEXT:popq %r12
+; CHECK-NEXT:.cfi_def_cfa_offset 32
+; CHECK-NEXT:popq %r13
+; CHECK-NEXT:.cfi_def_cfa_offset 24
+; CHECK-NEXT:popq %r14
+; CHECK-NEXT:.cfi_def_cfa_offset 16
+; CHECK-NEXT:popq %r15
+; CHECK-NEXT:.cfi_def_cfa_offset 8
+; CHECK-NEXT:retq
+  tail call preserve_nonecc void @callee(ptr %a)
+  ret void
+}
+
+; Preserve_none caller calls preserve_none callee. Same function body.
+; The tail call is preserved. No registers are saved/restored around the call.
+; Actually a simple jmp instruction is generated.
+define preserve_nonecc void @caller2(ptr %a) {
+; CHECK-LABEL: caller2:
+; CHECK:   # %bb.0:
+; CHECK-NEXT:jmp callee@PLT # TAILCALL
+  tail call preserve_nonecc void @callee(ptr %a)
+  ret void
+}
+
+; Preserve_none function can use more registers to pass parameters.
+define preserve_nonecc i64 @callee_with_many_param(i64 %a1, i64 %a2, i64 %a3, 
i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 
%a12) {

david-xl wrote:

or better yet, pass the arguments in order to (tail)call to another 
preserve_none callee.

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-31 Thread via cfe-commits

https://github.com/weiguozhi updated 
https://github.com/llvm/llvm-project/pull/76868

>From 90e14918a0eb13e2187f8548416ac72491d966c1 Mon Sep 17 00:00:00 2001
From: Guozhi Wei 
Date: Thu, 21 Dec 2023 19:04:44 +
Subject: [PATCH 1/6] New calling convention preserve_none

The new calling convention preserve_none is the opposite side of
existing preserve_all. It tries to preserve as few general registers as
possible. So all general registers are caller saved registers. It can
also uses more general registers to pass arguments. This attribute
doesn't impact floating-point registers. Floating-point registers still
follow the c calling convention.

Currently preserve_none is supported on X86-64 only.
---
 clang/include/clang-c/Index.h |  1 +
 clang/include/clang/Basic/Attr.td |  5 ++
 clang/include/clang/Basic/AttrDocs.td | 17 
 clang/include/clang/Basic/Specifiers.h|  1 +
 clang/lib/AST/ItaniumMangle.cpp   |  1 +
 clang/lib/AST/Type.cpp|  2 +
 clang/lib/AST/TypePrinter.cpp |  6 ++
 clang/lib/Basic/Targets/X86.h |  2 +
 clang/lib/CodeGen/CGCall.cpp  |  4 +
 clang/lib/CodeGen/CGDebugInfo.cpp |  2 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  7 ++
 clang/lib/Sema/SemaType.cpp   |  5 +-
 clang/test/CodeGen/debug-info-cc.c|  7 ++
 clang/test/CodeGen/preserve-call-conv.c   |  8 +-
 clang/test/Sema/no_callconv.cpp   |  2 +
 clang/test/Sema/preserve-none-call-conv.c | 19 
 clang/tools/libclang/CXType.cpp   |  1 +
 llvm/docs/LangRef.rst |  6 ++
 llvm/include/llvm/AsmParser/LLToken.h |  1 +
 llvm/include/llvm/BinaryFormat/Dwarf.def  |  1 +
 llvm/include/llvm/IR/CallingConv.h|  3 +
 llvm/lib/AsmParser/LLLexer.cpp|  1 +
 llvm/lib/AsmParser/LLParser.cpp   |  2 +
 llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp |  3 +
 llvm/lib/IR/AsmWriter.cpp |  1 +
 llvm/lib/Target/X86/X86CallingConv.td | 18 
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp   |  1 +
 llvm/lib/Target/X86/X86RegisterInfo.cpp   |  4 +
 llvm/test/Bitcode/compatibility.ll|  2 +
 .../X86/dynamic-regmask-preserve-none.ll  | 88 +++
 llvm/test/CodeGen/X86/ipra-reg-usage.ll   |  9 +-
 llvm/test/CodeGen/X86/ipra-transform.ll   | 19 
 .../X86/preserve_nonecc64-ret-double.ll   | 85 ++
 llvm/test/CodeGen/X86/preserve_nonecc64.ll| 86 ++
 34 files changed, 417 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Sema/preserve-none-call-conv.c
 create mode 100644 llvm/test/CodeGen/X86/dynamic-regmask-preserve-none.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64-ret-double.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64.ll

diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 64ab3378957c7..c241a8ccc7dfa 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2981,6 +2981,7 @@ enum CXCallingConv {
   CXCallingConv_SwiftAsync = 17,
   CXCallingConv_AArch64SVEPCS = 18,
   CXCallingConv_M68kRTD = 19,
+  CXCallingConv_PreserveNone = 20,
 
   CXCallingConv_Invalid = 100,
   CXCallingConv_Unexposed = 200
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index db17211747b17..87e2ce91a0afb 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2868,6 +2868,11 @@ def M68kRTD: DeclOrTypeAttr {
   let Documentation = [M68kRTDDocs];
 }
 
+def PreserveNone : DeclOrTypeAttr {
+  let Spellings = [Clang<"preserve_none">];
+  let Documentation = [PreserveNoneDocs];
+}
+
 def Target : InheritableAttr {
   let Spellings = [GCC<"target">];
   let Args = [StringArgument<"featuresStr">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 98a7ecc7fd7df..a43e00c07e141 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5494,6 +5494,23 @@ experimental at this time.
   }];
 }
 
+def PreserveNoneDocs : Documentation {
+  let Category = DocCatCallingConvs;
+  let Content = [{
+On X86-64 target, this attribute changes the calling convention of a function.
+The ``preserve_none`` calling convention tries to preserve as few general
+registers as possible. So all general registers are caller saved registers. It
+also uses more general registers to pass arguments. This attribute doesn't
+impact floating-point registers (XMMs/YMMs). Floating-point registers still
+follow the c calling convention.
+
+- Only RSP and RBP are preserved by callee.
+
+- Register RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can
+  be used to pass function arguments.
+  }];
+}
+
 def DeprecatedDocs : Documentation {
   let Category = DocCatDecl;
   let Content 

[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-31 Thread via cfe-commits

https://github.com/weiguozhi updated 
https://github.com/llvm/llvm-project/pull/76868

>From 90e14918a0eb13e2187f8548416ac72491d966c1 Mon Sep 17 00:00:00 2001
From: Guozhi Wei 
Date: Thu, 21 Dec 2023 19:04:44 +
Subject: [PATCH 1/5] New calling convention preserve_none

The new calling convention preserve_none is the opposite side of
existing preserve_all. It tries to preserve as few general registers as
possible. So all general registers are caller saved registers. It can
also uses more general registers to pass arguments. This attribute
doesn't impact floating-point registers. Floating-point registers still
follow the c calling convention.

Currently preserve_none is supported on X86-64 only.
---
 clang/include/clang-c/Index.h |  1 +
 clang/include/clang/Basic/Attr.td |  5 ++
 clang/include/clang/Basic/AttrDocs.td | 17 
 clang/include/clang/Basic/Specifiers.h|  1 +
 clang/lib/AST/ItaniumMangle.cpp   |  1 +
 clang/lib/AST/Type.cpp|  2 +
 clang/lib/AST/TypePrinter.cpp |  6 ++
 clang/lib/Basic/Targets/X86.h |  2 +
 clang/lib/CodeGen/CGCall.cpp  |  4 +
 clang/lib/CodeGen/CGDebugInfo.cpp |  2 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  7 ++
 clang/lib/Sema/SemaType.cpp   |  5 +-
 clang/test/CodeGen/debug-info-cc.c|  7 ++
 clang/test/CodeGen/preserve-call-conv.c   |  8 +-
 clang/test/Sema/no_callconv.cpp   |  2 +
 clang/test/Sema/preserve-none-call-conv.c | 19 
 clang/tools/libclang/CXType.cpp   |  1 +
 llvm/docs/LangRef.rst |  6 ++
 llvm/include/llvm/AsmParser/LLToken.h |  1 +
 llvm/include/llvm/BinaryFormat/Dwarf.def  |  1 +
 llvm/include/llvm/IR/CallingConv.h|  3 +
 llvm/lib/AsmParser/LLLexer.cpp|  1 +
 llvm/lib/AsmParser/LLParser.cpp   |  2 +
 llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp |  3 +
 llvm/lib/IR/AsmWriter.cpp |  1 +
 llvm/lib/Target/X86/X86CallingConv.td | 18 
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp   |  1 +
 llvm/lib/Target/X86/X86RegisterInfo.cpp   |  4 +
 llvm/test/Bitcode/compatibility.ll|  2 +
 .../X86/dynamic-regmask-preserve-none.ll  | 88 +++
 llvm/test/CodeGen/X86/ipra-reg-usage.ll   |  9 +-
 llvm/test/CodeGen/X86/ipra-transform.ll   | 19 
 .../X86/preserve_nonecc64-ret-double.ll   | 85 ++
 llvm/test/CodeGen/X86/preserve_nonecc64.ll| 86 ++
 34 files changed, 417 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Sema/preserve-none-call-conv.c
 create mode 100644 llvm/test/CodeGen/X86/dynamic-regmask-preserve-none.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64-ret-double.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64.ll

diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 64ab3378957c7..c241a8ccc7dfa 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2981,6 +2981,7 @@ enum CXCallingConv {
   CXCallingConv_SwiftAsync = 17,
   CXCallingConv_AArch64SVEPCS = 18,
   CXCallingConv_M68kRTD = 19,
+  CXCallingConv_PreserveNone = 20,
 
   CXCallingConv_Invalid = 100,
   CXCallingConv_Unexposed = 200
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index db17211747b17..87e2ce91a0afb 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2868,6 +2868,11 @@ def M68kRTD: DeclOrTypeAttr {
   let Documentation = [M68kRTDDocs];
 }
 
+def PreserveNone : DeclOrTypeAttr {
+  let Spellings = [Clang<"preserve_none">];
+  let Documentation = [PreserveNoneDocs];
+}
+
 def Target : InheritableAttr {
   let Spellings = [GCC<"target">];
   let Args = [StringArgument<"featuresStr">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 98a7ecc7fd7df..a43e00c07e141 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5494,6 +5494,23 @@ experimental at this time.
   }];
 }
 
+def PreserveNoneDocs : Documentation {
+  let Category = DocCatCallingConvs;
+  let Content = [{
+On X86-64 target, this attribute changes the calling convention of a function.
+The ``preserve_none`` calling convention tries to preserve as few general
+registers as possible. So all general registers are caller saved registers. It
+also uses more general registers to pass arguments. This attribute doesn't
+impact floating-point registers (XMMs/YMMs). Floating-point registers still
+follow the c calling convention.
+
+- Only RSP and RBP are preserved by callee.
+
+- Register RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can
+  be used to pass function arguments.
+  }];
+}
+
 def DeprecatedDocs : Documentation {
   let Category = DocCatDecl;
   let Content 

[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-30 Thread David Li via cfe-commits

https://github.com/david-xl commented:

Can you increase the test coverage:

1) preserve_none caller TAIL-calls preserve_none callee -- the tail call is 
preserved
2) regular function TAIL-calls preserve_none callee -- the tail call should be 
disabled and all CSRs should be saved/restored around the call.
3) preserve-none caller calls preserve_none callee -- no registers are 
saved/restored around the call
4) preserve_none caller calls preserve_none callee with long argument list -- 
CSRs used for arg passing.

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-30 Thread David Li via cfe-commits

https://github.com/david-xl edited 
https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-25 Thread via cfe-commits


@@ -1056,6 +1056,23 @@ def CC_Intel_OCL_BI : CallingConv<[
   CCDelegateTo
 ]>;
 
+def CC_X86_64_Preserve_None : CallingConv<[
+  // We don't preserve general registers, so all of them can be used to pass
+  // arguments except
+  //   - RBPframe pointer
+  //   - R10'nest' parameter
+  //   - RBXbase pointer
+  //   - R16 - R31  these are not available everywhere
+  CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D,
+R11D, R12D, R13D, R14D, R15D, EAX]>>,
+
+  CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8, R9,
+ R11, R12, R13, R14, R15, RAX]>>,
+
+  // Otherwise it's the same as the regular C calling convention.
+  CCDelegateTo

weiguozhi wrote:

@jyknight could you help to review the code that checks the combination of 
swift attributes and preserve_none in 
https://github.com/llvm/llvm-project/pull/76868/commits/dc1bc55634045adb5b0ab465b16dcf73f1e77144

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-11 Thread via cfe-commits


@@ -2868,6 +2868,11 @@ def M68kRTD: DeclOrTypeAttr {
   let Documentation = [M68kRTDDocs];
 }
 
+def PreserveNone : DeclOrTypeAttr {
+  let Spellings = [Clang<"preserve_none">];

weiguozhi wrote:

FunctionLike works for me. Thanks!

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-10 Thread Shengchen Kan via cfe-commits


@@ -1056,6 +1056,23 @@ def CC_Intel_OCL_BI : CallingConv<[
   CCDelegateTo
 ]>;
 
+def CC_X86_64_Preserve_None : CallingConv<[
+  // We don't preserve general registers, so all of them can be used to pass
+  // arguments except
+  //   - RBPframe pointer
+  //   - R10'nest' parameter
+  //   - RBXbase pointer
+  //   - R16 - R31  these are not available everywhere

KanRobert wrote:

I won't expect this from the name `preserve_none`. R16-R31 should be used to 
pas arguments when they're available. 

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-10 Thread James Y Knight via cfe-commits


@@ -1056,6 +1056,23 @@ def CC_Intel_OCL_BI : CallingConv<[
   CCDelegateTo
 ]>;
 
+def CC_X86_64_Preserve_None : CallingConv<[
+  // We don't preserve general registers, so all of them can be used to pass
+  // arguments except
+  //   - RBPframe pointer
+  //   - R10'nest' parameter
+  //   - RBXbase pointer
+  //   - R16 - R31  these are not available everywhere
+  CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D,
+R11D, R12D, R13D, R14D, R15D, EAX]>>,
+
+  CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8, R9,
+ R11, R12, R13, R14, R15, RAX]>>,
+
+  // Otherwise it's the same as the regular C calling convention.
+  CCDelegateTo

jyknight wrote:

This delegation seems questionable -- what about the interaction with the swift 
attributes which use dedicated registers in CC_X86_64_C, which you're now also 
using for normal parameters?

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-10 Thread via cfe-commits


@@ -2868,6 +2868,11 @@ def M68kRTD: DeclOrTypeAttr {
   let Documentation = [M68kRTDDocs];
 }
 
+def PreserveNone : DeclOrTypeAttr {
+  let Spellings = [Clang<"preserve_none">];

weiguozhi wrote:

I tried to add
```
  let Subjects = SubjectList<[Function]>;
```
But it doesn't work for the code
```
  void __attribute__((preserve_none)) boo(void *ptr) {
  }

  void (__attribute__((preserve_none)) *pboo1)(void *) = boo;
```
I got the error message
```
'preserve_none' attribute only applies to functions
```


https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-08 Thread Erich Keane via cfe-commits

https://github.com/erichkeane edited 
https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-08 Thread via cfe-commits


@@ -1056,6 +1056,22 @@ def CC_Intel_OCL_BI : CallingConv<[
   CCDelegateTo
 ]>;
 
+def CC_X86_64_Preserve_None : CallingConv<[
+  // We don't preserve general registers, so all of them can be used to pass
+  // arguments except
+  //   - RBP  frame pointer

weiguozhi wrote:

Added a comment to mention that R16-R31 are not used to pass arguments because 
they are not universally available.

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-08 Thread via cfe-commits

https://github.com/weiguozhi updated 
https://github.com/llvm/llvm-project/pull/76868

>From 90e14918a0eb13e2187f8548416ac72491d966c1 Mon Sep 17 00:00:00 2001
From: Guozhi Wei 
Date: Thu, 21 Dec 2023 19:04:44 +
Subject: [PATCH 1/2] New calling convention preserve_none

The new calling convention preserve_none is the opposite side of
existing preserve_all. It tries to preserve as few general registers as
possible. So all general registers are caller saved registers. It can
also uses more general registers to pass arguments. This attribute
doesn't impact floating-point registers. Floating-point registers still
follow the c calling convention.

Currently preserve_none is supported on X86-64 only.
---
 clang/include/clang-c/Index.h |  1 +
 clang/include/clang/Basic/Attr.td |  5 ++
 clang/include/clang/Basic/AttrDocs.td | 17 
 clang/include/clang/Basic/Specifiers.h|  1 +
 clang/lib/AST/ItaniumMangle.cpp   |  1 +
 clang/lib/AST/Type.cpp|  2 +
 clang/lib/AST/TypePrinter.cpp |  6 ++
 clang/lib/Basic/Targets/X86.h |  2 +
 clang/lib/CodeGen/CGCall.cpp  |  4 +
 clang/lib/CodeGen/CGDebugInfo.cpp |  2 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  7 ++
 clang/lib/Sema/SemaType.cpp   |  5 +-
 clang/test/CodeGen/debug-info-cc.c|  7 ++
 clang/test/CodeGen/preserve-call-conv.c   |  8 +-
 clang/test/Sema/no_callconv.cpp   |  2 +
 clang/test/Sema/preserve-none-call-conv.c | 19 
 clang/tools/libclang/CXType.cpp   |  1 +
 llvm/docs/LangRef.rst |  6 ++
 llvm/include/llvm/AsmParser/LLToken.h |  1 +
 llvm/include/llvm/BinaryFormat/Dwarf.def  |  1 +
 llvm/include/llvm/IR/CallingConv.h|  3 +
 llvm/lib/AsmParser/LLLexer.cpp|  1 +
 llvm/lib/AsmParser/LLParser.cpp   |  2 +
 llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp |  3 +
 llvm/lib/IR/AsmWriter.cpp |  1 +
 llvm/lib/Target/X86/X86CallingConv.td | 18 
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp   |  1 +
 llvm/lib/Target/X86/X86RegisterInfo.cpp   |  4 +
 llvm/test/Bitcode/compatibility.ll|  2 +
 .../X86/dynamic-regmask-preserve-none.ll  | 88 +++
 llvm/test/CodeGen/X86/ipra-reg-usage.ll   |  9 +-
 llvm/test/CodeGen/X86/ipra-transform.ll   | 19 
 .../X86/preserve_nonecc64-ret-double.ll   | 85 ++
 llvm/test/CodeGen/X86/preserve_nonecc64.ll| 86 ++
 34 files changed, 417 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Sema/preserve-none-call-conv.c
 create mode 100644 llvm/test/CodeGen/X86/dynamic-regmask-preserve-none.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64-ret-double.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64.ll

diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 64ab3378957c70..c241a8ccc7dfac 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2981,6 +2981,7 @@ enum CXCallingConv {
   CXCallingConv_SwiftAsync = 17,
   CXCallingConv_AArch64SVEPCS = 18,
   CXCallingConv_M68kRTD = 19,
+  CXCallingConv_PreserveNone = 20,
 
   CXCallingConv_Invalid = 100,
   CXCallingConv_Unexposed = 200
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index db17211747b17d..87e2ce91a0afb7 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2868,6 +2868,11 @@ def M68kRTD: DeclOrTypeAttr {
   let Documentation = [M68kRTDDocs];
 }
 
+def PreserveNone : DeclOrTypeAttr {
+  let Spellings = [Clang<"preserve_none">];
+  let Documentation = [PreserveNoneDocs];
+}
+
 def Target : InheritableAttr {
   let Spellings = [GCC<"target">];
   let Args = [StringArgument<"featuresStr">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 98a7ecc7fd7df3..a43e00c07e141d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5494,6 +5494,23 @@ experimental at this time.
   }];
 }
 
+def PreserveNoneDocs : Documentation {
+  let Category = DocCatCallingConvs;
+  let Content = [{
+On X86-64 target, this attribute changes the calling convention of a function.
+The ``preserve_none`` calling convention tries to preserve as few general
+registers as possible. So all general registers are caller saved registers. It
+also uses more general registers to pass arguments. This attribute doesn't
+impact floating-point registers (XMMs/YMMs). Floating-point registers still
+follow the c calling convention.
+
+- Only RSP and RBP are preserved by callee.
+
+- Register RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15 and RAX now can
+  be used to pass function arguments.
+  }];
+}
+
 def DeprecatedDocs : Documentation {
   let Category = DocCatDecl;
   let 

[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-04 Thread via cfe-commits


@@ -416,6 +416,12 @@ added in the future:
 This calling convention, like the `PreserveMost` calling convention, will 
be
 used by a future version of the ObjectiveC runtime and should be considered
 experimental at this time.
+"``preserve_nonecc``" - The `PreserveNone` calling convention
+This calling convention doesn't preserve any general registers. So all
+general registers are caller saved registers. It also uses all general
+registers to pass arguments. This attribute doesn't impact floating-point

weiguozhi wrote:

> I suspect this should say any `non-general purpose registers (e.g. floating 
> point registers, on x86 XMMs/YMMs)`. Rather than `floating-point registers`. 

Thanks for the correction! Will change it.

> Also isn't this just a hack to increase the number of registers used to pass 
> arguments? If so there has to be a better way of doing this. Maybe a 
> non-exposed attribute which is used only for non-exposed functions? e.g. on 
> x86 (not 64bit), regparm could be used internally there.

It's not a hack, it's a natural extension. Because we don't preserve general 
registers, we can use all of them to pass arguments without the extra cost to 
save/restore those registers, they are clobbered by the function call anyway.

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-03 Thread Shengchen Kan via cfe-commits


@@ -1056,6 +1056,22 @@ def CC_Intel_OCL_BI : CallingConv<[
   CCDelegateTo
 ]>;
 
+def CC_X86_64_Preserve_None : CallingConv<[
+  // We don't preserve general registers, so all of them can be used to pass
+  // arguments except
+  //   - RBP  frame pointer

KanRobert wrote:

It does not mention R16-R31

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-03 Thread Andrew Pinski via cfe-commits


@@ -416,6 +416,12 @@ added in the future:
 This calling convention, like the `PreserveMost` calling convention, will 
be
 used by a future version of the ObjectiveC runtime and should be considered
 experimental at this time.
+"``preserve_nonecc``" - The `PreserveNone` calling convention
+This calling convention doesn't preserve any general registers. So all
+general registers are caller saved registers. It also uses all general
+registers to pass arguments. This attribute doesn't impact floating-point

pinskia wrote:

I suspect this should say any `non-general purpose registers (e.g. floating 
point registers, on x86 XMMs/YMMs)`. Rather than `floating-point registers`.
Also isn't this just a hack to increase the number of registers used to pass 
arguments? If so there has to be a better way of doing this.  Maybe a 
non-exposed attribute which is used only for non-exposed functions?
e.g. on x86 (not 64bit), regparm could be used internally there. 

https://github.com/llvm/llvm-project/pull/76868
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-03 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-clang

Author: None (weiguozhi)


Changes

The new experimental calling convention preserve_none is the opposite side of 
existing preserve_all. It tries to preserve as few general registers as 
possible. So all general registers are caller saved registers. It can also uses 
more general registers to pass arguments. This attribute doesn't impact 
floating-point registers. Floating-point registers still follow the c calling 
convention.

Currently preserve_none is supported on X86-64 only. It changes the c calling 
convention in following fields:
  
  * RSP and RBP are the only preserved general registers, all other general 
registers are caller saved registers.
  * We can use [RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15, RAX] to 
pass arguments.

It can improve the performance of hot tailcall chain, because many callee saved 
registers' save/restore instructions can be removed if the tail functions are 
using preserve_none. In my experiment in protocol buffer, the parsing functions 
are improved by 3% to 10%.


---

Patch is 39.57 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/76868.diff


34 Files Affected:

- (modified) clang/include/clang-c/Index.h (+1) 
- (modified) clang/include/clang/Basic/Attr.td (+5) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+17) 
- (modified) clang/include/clang/Basic/Specifiers.h (+1) 
- (modified) clang/lib/AST/ItaniumMangle.cpp (+1) 
- (modified) clang/lib/AST/Type.cpp (+2) 
- (modified) clang/lib/AST/TypePrinter.cpp (+6) 
- (modified) clang/lib/Basic/Targets/X86.h (+2) 
- (modified) clang/lib/CodeGen/CGCall.cpp (+4) 
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+2) 
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+7) 
- (modified) clang/lib/Sema/SemaType.cpp (+4-1) 
- (modified) clang/test/CodeGen/debug-info-cc.c (+7) 
- (modified) clang/test/CodeGen/preserve-call-conv.c (+7-1) 
- (modified) clang/test/Sema/no_callconv.cpp (+2) 
- (added) clang/test/Sema/preserve-none-call-conv.c (+19) 
- (modified) clang/tools/libclang/CXType.cpp (+1) 
- (modified) llvm/docs/LangRef.rst (+6) 
- (modified) llvm/include/llvm/AsmParser/LLToken.h (+1) 
- (modified) llvm/include/llvm/BinaryFormat/Dwarf.def (+1) 
- (modified) llvm/include/llvm/IR/CallingConv.h (+3) 
- (modified) llvm/lib/AsmParser/LLLexer.cpp (+1) 
- (modified) llvm/lib/AsmParser/LLParser.cpp (+2) 
- (modified) llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp (+3) 
- (modified) llvm/lib/IR/AsmWriter.cpp (+1) 
- (modified) llvm/lib/Target/X86/X86CallingConv.td (+18) 
- (modified) llvm/lib/Target/X86/X86ISelLoweringCall.cpp (+1) 
- (modified) llvm/lib/Target/X86/X86RegisterInfo.cpp (+4) 
- (modified) llvm/test/Bitcode/compatibility.ll (+2) 
- (added) llvm/test/CodeGen/X86/dynamic-regmask-preserve-none.ll (+88) 
- (modified) llvm/test/CodeGen/X86/ipra-reg-usage.ll (+8-1) 
- (modified) llvm/test/CodeGen/X86/ipra-transform.ll (+19) 
- (added) llvm/test/CodeGen/X86/preserve_nonecc64-ret-double.ll (+85) 
- (added) llvm/test/CodeGen/X86/preserve_nonecc64.ll (+86) 


``diff
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 64ab3378957c70..c241a8ccc7dfac 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2981,6 +2981,7 @@ enum CXCallingConv {
   CXCallingConv_SwiftAsync = 17,
   CXCallingConv_AArch64SVEPCS = 18,
   CXCallingConv_M68kRTD = 19,
+  CXCallingConv_PreserveNone = 20,
 
   CXCallingConv_Invalid = 100,
   CXCallingConv_Unexposed = 200
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index db17211747b17d..87e2ce91a0afb7 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2868,6 +2868,11 @@ def M68kRTD: DeclOrTypeAttr {
   let Documentation = [M68kRTDDocs];
 }
 
+def PreserveNone : DeclOrTypeAttr {
+  let Spellings = [Clang<"preserve_none">];
+  let Documentation = [PreserveNoneDocs];
+}
+
 def Target : InheritableAttr {
   let Spellings = [GCC<"target">];
   let Args = [StringArgument<"featuresStr">];
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 98a7ecc7fd7df3..a43e00c07e141d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5494,6 +5494,23 @@ experimental at this time.
   }];
 }
 
+def PreserveNoneDocs : Documentation {
+  let Category = DocCatCallingConvs;
+  let Content = [{
+On X86-64 target, this attribute changes the calling convention of a function.
+The ``preserve_none`` calling convention tries to preserve as few general
+registers as possible. So all general registers are caller saved registers. It
+also uses more general registers to pass arguments. This attribute doesn't
+impact floating-point registers (XMMs/YMMs). Floating-point registers still
+follow the c calling convention.
+
+- Only RSP and RBP are preserved by callee.
+
+- Register RDI, 

[llvm] [clang] New calling convention preserve_none (PR #76868)

2024-01-03 Thread via cfe-commits

https://github.com/weiguozhi created 
https://github.com/llvm/llvm-project/pull/76868

The new experimental calling convention preserve_none is the opposite side of 
existing preserve_all. It tries to preserve as few general registers as 
possible. So all general registers are caller saved registers. It can also uses 
more general registers to pass arguments. This attribute doesn't impact 
floating-point registers. Floating-point registers still follow the c calling 
convention.

Currently preserve_none is supported on X86-64 only. It changes the c calling 
convention in following fields:
  
  * RSP and RBP are the only preserved general registers, all other general 
registers are caller saved registers.
  * We can use [RDI, RSI, RDX, RCX, R8, R9, R11, R12, R13, R14, R15, RAX] to 
pass arguments.

It can improve the performance of hot tailcall chain, because many callee saved 
registers' save/restore instructions can be removed if the tail functions are 
using preserve_none. In my experiment in protocol buffer, the parsing functions 
are improved by 3% to 10%.


>From 90e14918a0eb13e2187f8548416ac72491d966c1 Mon Sep 17 00:00:00 2001
From: Guozhi Wei 
Date: Thu, 21 Dec 2023 19:04:44 +
Subject: [PATCH] New calling convention preserve_none

The new calling convention preserve_none is the opposite side of
existing preserve_all. It tries to preserve as few general registers as
possible. So all general registers are caller saved registers. It can
also uses more general registers to pass arguments. This attribute
doesn't impact floating-point registers. Floating-point registers still
follow the c calling convention.

Currently preserve_none is supported on X86-64 only.
---
 clang/include/clang-c/Index.h |  1 +
 clang/include/clang/Basic/Attr.td |  5 ++
 clang/include/clang/Basic/AttrDocs.td | 17 
 clang/include/clang/Basic/Specifiers.h|  1 +
 clang/lib/AST/ItaniumMangle.cpp   |  1 +
 clang/lib/AST/Type.cpp|  2 +
 clang/lib/AST/TypePrinter.cpp |  6 ++
 clang/lib/Basic/Targets/X86.h |  2 +
 clang/lib/CodeGen/CGCall.cpp  |  4 +
 clang/lib/CodeGen/CGDebugInfo.cpp |  2 +
 clang/lib/Sema/SemaDeclAttr.cpp   |  7 ++
 clang/lib/Sema/SemaType.cpp   |  5 +-
 clang/test/CodeGen/debug-info-cc.c|  7 ++
 clang/test/CodeGen/preserve-call-conv.c   |  8 +-
 clang/test/Sema/no_callconv.cpp   |  2 +
 clang/test/Sema/preserve-none-call-conv.c | 19 
 clang/tools/libclang/CXType.cpp   |  1 +
 llvm/docs/LangRef.rst |  6 ++
 llvm/include/llvm/AsmParser/LLToken.h |  1 +
 llvm/include/llvm/BinaryFormat/Dwarf.def  |  1 +
 llvm/include/llvm/IR/CallingConv.h|  3 +
 llvm/lib/AsmParser/LLLexer.cpp|  1 +
 llvm/lib/AsmParser/LLParser.cpp   |  2 +
 llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp |  3 +
 llvm/lib/IR/AsmWriter.cpp |  1 +
 llvm/lib/Target/X86/X86CallingConv.td | 18 
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp   |  1 +
 llvm/lib/Target/X86/X86RegisterInfo.cpp   |  4 +
 llvm/test/Bitcode/compatibility.ll|  2 +
 .../X86/dynamic-regmask-preserve-none.ll  | 88 +++
 llvm/test/CodeGen/X86/ipra-reg-usage.ll   |  9 +-
 llvm/test/CodeGen/X86/ipra-transform.ll   | 19 
 .../X86/preserve_nonecc64-ret-double.ll   | 85 ++
 llvm/test/CodeGen/X86/preserve_nonecc64.ll| 86 ++
 34 files changed, 417 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Sema/preserve-none-call-conv.c
 create mode 100644 llvm/test/CodeGen/X86/dynamic-regmask-preserve-none.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64-ret-double.ll
 create mode 100644 llvm/test/CodeGen/X86/preserve_nonecc64.ll

diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 64ab3378957c70..c241a8ccc7dfac 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2981,6 +2981,7 @@ enum CXCallingConv {
   CXCallingConv_SwiftAsync = 17,
   CXCallingConv_AArch64SVEPCS = 18,
   CXCallingConv_M68kRTD = 19,
+  CXCallingConv_PreserveNone = 20,
 
   CXCallingConv_Invalid = 100,
   CXCallingConv_Unexposed = 200
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index db17211747b17d..87e2ce91a0afb7 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2868,6 +2868,11 @@ def M68kRTD: DeclOrTypeAttr {
   let Documentation = [M68kRTDDocs];
 }
 
+def PreserveNone : DeclOrTypeAttr {
+  let Spellings = [Clang<"preserve_none">];
+  let Documentation = [PreserveNoneDocs];
+}
+
 def Target : InheritableAttr {
   let Spellings = [GCC<"target">];
   let Args = [StringArgument<"featuresStr">];
diff --git a/clang/include/clang/Basic/AttrDocs.td