[PATCH] Add frontend support for __vectorcall

Aaron Ballman aaron at aaronballman.com
Wed Oct 22 12:41:06 PDT 2014


On Wed, Oct 22, 2014 at 3:29 PM, Reid Kleckner <rnk at google.com> wrote:
> On Thu, Oct 16, 2014 at 5:35 AM, Aaron Ballman <aaron at aaronballman.com> wrote:
>> > Index: include/clang-c/Index.h
>> > ===================================================================
>> > --- include/clang-c/Index.h
>> > +++ include/clang-c/Index.h
>> > @@ -2853,6 +2853,7 @@
>> >    CXCallingConv_IntelOclBicc = 9,
>> >    CXCallingConv_X86_64Win64 = 10,
>> >    CXCallingConv_X86_64SysV = 11,
>> > +  CXCallingConv_X86VectorCall = 12,
>>
>> Isn't this an x86_64 attribute?
>
> Nope, it's both x86 and x64. x86 is like __fastcall except it uses xmm
> registers.

Ah, good to know.

>
>> >
>> >    CXCallingConv_Invalid = 100,
>> >    CXCallingConv_Unexposed = 200
>> > Index: include/clang/AST/Type.h
>> > ===================================================================
>> > --- include/clang/AST/Type.h
>> > +++ include/clang/AST/Type.h
>> > @@ -3432,6 +3432,7 @@
>> >      attr_stdcall,
>> >      attr_thiscall,
>> >      attr_pascal,
>> > +    attr_vectorcall,
>> >      attr_pnaclcall,
>> >      attr_inteloclbicc,
>> >      attr_ms_abi,
>> > Index: include/clang/Basic/Attr.td
>> > ===================================================================
>> > --- include/clang/Basic/Attr.td
>> > +++ include/clang/Basic/Attr.td
>> > @@ -1167,6 +1167,13 @@
>> >    let Documentation = [Undocumented];
>> >  }
>> >
>> > +def VectorCall : InheritableAttr {
>> > +  let Spellings = [GCC<"vectorcall">, Keyword<"__vectorcall">,
>> > +                   Keyword<"_vectorcall">];
>>
>> I can find no documentation that suggests GCC supports vectorcall. Are
>> we sure we want those spellings?
>
> I think Clang should support a way of getting at this convention
> without using -fms-extensions, and using the __attribute__ syntax
> seems like a reasonable way to do that.

Please use GNU<"vectorcall"> for that, then. GCC will add
[[gnu::vectorcall]] in addition to __attribute__((vectorcall)), which
is not a namespace we should be adding into (until such time as GCC
adds this attribute, at least).

>
>> > +//  let Subjects = [Function, ObjCMethod];
>> > +  let Documentation = [Undocumented];
>>
>> Please, no new undocumented attributes. (I know this is the first
>> calling convention one which will be documented; natch.)
>
> =P
>
>> > +}
>> > +
>> >  def Pascal : InheritableAttr {
>> >    let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
>> >  //  let Subjects = [Function, ObjCMethod];
>> > Index: include/clang/Basic/DiagnosticSemaKinds.td
>> > ===================================================================
>> > --- include/clang/Basic/DiagnosticSemaKinds.td
>> > +++ include/clang/Basic/DiagnosticSemaKinds.td
>> > @@ -2255,9 +2255,9 @@
>> >  def warn_cconv_ignored : Warning<
>> >    "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>;
>> >  def err_cconv_knr : Error<
>> > -  "function with no prototype cannot use the callee-cleanup %0 calling convention">;
>> > +  "function with no prototype cannot use the %0 calling convention">;
>> >  def warn_cconv_knr : Warning<
>> > -  "function with no prototype cannot use the callee-cleanup %0 calling convention">,
>> > +  "function with no prototype cannot use the %0 calling convention">,
>>
>> Could this be defined using err_cconv_knr.Text please?
>
> I didn't know you could do that...
>
>> >    InGroup<DiagGroup<"missing-prototype-for-cc">>;
>> >  def err_cconv_varargs : Error<
>> >    "variadic function cannot use %0 calling convention">;
>> > Index: include/clang/Basic/Specifiers.h
>> > ===================================================================
>> > --- include/clang/Basic/Specifiers.h
>> > +++ include/clang/Basic/Specifiers.h
>> > @@ -203,6 +203,7 @@
>> >      CC_X86StdCall,  // __attribute__((stdcall))
>> >      CC_X86FastCall, // __attribute__((fastcall))
>> >      CC_X86ThisCall, // __attribute__((thiscall))
>> > +    CC_X86VectorCall, // __attribute__((vectorcall))
>>
>> Same comment about x86_64 here as elsewhere.
>>
>> >      CC_X86Pascal,   // __attribute__((pascal))
>> >      CC_X86_64Win64, // __attribute__((ms_abi))
>> >      CC_X86_64SysV,  // __attribute__((sysv_abi))
>> > @@ -212,16 +213,18 @@
>> >      CC_IntelOclBicc // __attribute__((intel_ocl_bicc))
>> >    };
>> >
>> > -  /// \brief Checks whether the given calling convention is callee-cleanup.
>> > -  inline bool isCalleeCleanup(CallingConv CC) {
>> > +  /// \brief Checks whether the given calling convention supports variadic
>> > +  /// calls. Unprototyped calls also use the variadic call rules.
>> > +  inline bool supportsVariadicCall(CallingConv CC) {
>>
>> Can we make this function const while we're at it?
>
> Do you mean constexpr? It's not a method, so 'this' cannot be marked const.

inline bool supportsVariadicCall(CallingConv CC) const;

Not certain what you mean about it not being a method; that
declaration should be legal, no?

>
>> >      switch (CC) {
>> >      case CC_X86StdCall:
>> >      case CC_X86FastCall:
>> >      case CC_X86ThisCall:
>> >      case CC_X86Pascal:
>> > -      return true;
>> > -    default:
>> > +    case CC_X86VectorCall:
>> >        return false;
>> > +    default:
>> > +      return true;
>> >      }
>> >    }
>> >
>> > Index: include/clang/Basic/TokenKinds.def
>> > ===================================================================
>> > --- include/clang/Basic/TokenKinds.def
>> > +++ include/clang/Basic/TokenKinds.def
>> > @@ -457,6 +457,7 @@
>> >  KEYWORD(__stdcall                   , KEYALL)
>> >  KEYWORD(__fastcall                  , KEYALL)
>> >  KEYWORD(__thiscall                  , KEYALL)
>> > +KEYWORD(__vectorcall                , KEYALL)
>> >  KEYWORD(__forceinline               , KEYMS)
>> >  KEYWORD(__unaligned                 , KEYMS)
>> >  KEYWORD(__super                     , KEYMS)
>> > @@ -560,6 +561,7 @@
>> >  ALIAS("_fastcall"        , __fastcall , KEYMS | KEYBORLAND)
>> >  ALIAS("_stdcall"         , __stdcall  , KEYMS | KEYBORLAND)
>> >  ALIAS("_thiscall"        , __thiscall , KEYMS)
>> > +ALIAS("_vectorcall"      , __vectorcall, KEYMS)
>> >  ALIAS("_uuidof"          , __uuidof   , KEYMS | KEYBORLAND)
>> >  ALIAS("_inline"          , inline     , KEYMS)
>> >  ALIAS("_declspec"        , __declspec , KEYMS)
>> > Index: lib/AST/Expr.cpp
>> > ===================================================================
>> > --- lib/AST/Expr.cpp
>> > +++ lib/AST/Expr.cpp
>> > @@ -557,6 +557,7 @@
>> >        case CC_X86StdCall: POut << "__stdcall "; break;
>> >        case CC_X86FastCall: POut << "__fastcall "; break;
>> >        case CC_X86ThisCall: POut << "__thiscall "; break;
>> > +      case CC_X86VectorCall: POut << "__vectorcall "; break;
>> >        // Only bother printing the conventions that MSVC knows about.
>> >        default: break;
>> >        }
>> > Index: lib/AST/MicrosoftMangle.cpp
>> > ===================================================================
>> > --- lib/AST/MicrosoftMangle.cpp
>> > +++ lib/AST/MicrosoftMangle.cpp
>> > @@ -1687,6 +1687,7 @@
>> >    //                      ::= H # __export __stdcall
>> >    //                      ::= I # __fastcall
>> >    //                      ::= J # __export __fastcall
>> > +  //                      ::= Q # __vectorcall
>> >    // The 'export' calling conventions are from a bygone era
>> >    // (*cough*Win16*cough*) when functions were declared for export with
>> >    // that keyword. (It didn't actually export them, it just made them so
>> > @@ -1703,6 +1704,7 @@
>> >      case CC_X86ThisCall: Out << 'E'; break;
>> >      case CC_X86StdCall: Out << 'G'; break;
>> >      case CC_X86FastCall: Out << 'I'; break;
>> > +    case CC_X86VectorCall: Out << 'Q'; break;
>>
>> Doesn't this also mangle in C, using @@? Or does that magic happen elsewhere?
>
> That magic happens on the LLVM side.

Ah, good to know. Thanks!

~Aaron
>
>> >    }
>> >  }



More information about the cfe-commits mailing list