[cfe-dev] Accessibility of name mangling utilities

Anton Lokhmotov Anton.Lokhmotov at arm.com
Wed May 12 08:57:15 PDT 2010


> -----Original Message-----
> From: Douglas Gregor [mailto:dgregor at apple.com]
> Sent: 12 May 2010 16:39
> To: Anton Lokhmotov
> Cc: cfe-dev at cs.uiuc.edu
> Subject: Re: [cfe-dev] Accessibility of name mangling utilities

> It would be a shame if you were forced to rewrite all of name mangling
> because of some limitations in the current implementation. 
The real limitation was exactly that the functionality was hidden inside
CodeGen.

> Could you explain why you had to re-implement name mangling for your task?
I was working on a prototype and just wanted to have something working in
under a day (hence, I wasn't forced to rewrite all of name mangling).  I
hope that when it comes to proper software engineering, the functionality
will be accessible.

BTW, perhaps it's time to bring up a limitation of the name mangling scheme
I found.  Namely, name mangling for vector functions doesn't take into
account the vector length.  For example, given declarations:

__attribute__((overloadable))  float8 select(float8,  float8,  int8);
__attribute__((overloadable)) float16 select(float16, float16, int16);

Clang produces only one LLVM declaration depending on whether in source code
a call to the 8-element version comes first or a call to the 16-element
version comes first.  If a call to the 8-element version comes first, the
declaration is:

declare <8 x float>
	@_Z6selectU8__vectorfS_U8__vectori(<8 x float>, <8 x float>, <8 x
i32>)

If, however, a call to the 16-element version comes first, the declaration
is:

declare <16 x float> 
	@_Z6selectU8__vectorfS_U8__vectori(<16 x float>, <16 x float>, <16 x
i32>)


In the former case, the calls look like:

; call for 8-element operands
%call8 = call <8 x float> @_Z6selectU8__vectorfS_U8__vectori(<8 x float>
%Vf8_0, <8 x float> %Vf8_1, <8 x i32> %Vi8) nounwind
...
; call for 16-element operands
%call16 = call <16 x float> bitcast (<8 x float> (<8 x float>, <8 x float>,
<8 x i32>)* @_Z6selectU8__vectorfS_U8__vectori to <16 x float> (<16 x
float>, <16 x float>, <16 x i32>)*)(<16 x float> %Vf16_0, <16 x float>
%Vf16_1, <16 x i32> %Vi16) nounwind


In the latter case, the calls look like:

; call for 16-element operands
%call16 = call <16 x float> @_Z6selectU8__vectorfS_U8__vectori(<16 x float>
%Vf16_1, <16 x float> %Vf16_2, <16 x i32> %Vi16)
...
; call for 8-element operands
%call8 = call <8 x float> bitcast (<16 x float> (<16 x float>, <16 x float>,
<16 x i32>)* @_Z6selectU8__vectorfS_U8__vectori to <8 x float> (<8 x float>,
<8 x float>, <8 x i32>)*)(<8 x float> %Vf8_0, <8 x float> %Vf8_1, <8 x i32>
%Vi8) nounwind


In either case, a call to the version that has no declaration involves
bitcast of the function pointer with unclear semantics.  Is this really as
bad as it seems?

Anton L.





More information about the cfe-dev mailing list