On 01/09/12 20:05, Iain Buclaw wrote:
> On 9 January 2012 18:15, Artur Skawina <[email protected]> wrote:
>>
>> [1] I guess omitting the frame pointer manipulation for (at least) just 
>> nonthrowing leaf functions that don't use any stack slots wouldn't be easy? 
>> (the vector extensions will probably make this even more important...)
> 
> I think the tweaks I've made for extern(D) - frame pointer turned on
> unless naked - trumps all other checks for whether it is ok to omit
> frame pointer. For extern(C) at least for x86, the frame pointer is
> omitted by default as is the default for that particular backend.

Didn't realize extern(C) would influence this, other than changing name
mangling and calling convention - will have to try it. I'm afraid it
could cause symbol collisions with the "real" C code (for wrappers). [1]

The cases i'm worried about are things like virtual methods - imagine eg
a gui toolkit where every widget has certain properties (x,width,hidden etc)
which are implemented using getters, which in many cases should be just
"mov IMM, eax; ret" or "mov OFF(eax), eax; ret" -- this is what the C
compiler will emit; setting up the frame pointer just adds overhead and
inlining cannot help here.
SIMD code can have similar properties - only access data passed via
pointers, never calling other functions nor spilling.

> Will need to fix the inline asm in phobos and druntime to be C calling
> convention friendly, then can drop all relevant attempts at matching
> the DMD calling convention.

Do I understand correctly that you want to ignore the "official" D abi,
and go with an incompatible one, as a long term goal? That has downsides,
but as i think the "D ABI" will end up being changed and gdc is currently
not compatible anyway - maybe it's a reasonable option.
But gdc's D abi won't be fully compatible with the C one, right? Then,
avoiding some of C's mistakes would be a good idea (name mangling, 
default to regparm etc)


I have porting the runtime/phobos asms to gcc asm on my to-do list, will
try to get to that within two weeks. What would be the preferred way - 
version() guards? if yes - what version? Or would you prefer replacing
the asms, if the changes are not going to be merged upstream anyway?

artur

[1] Maybe extern(C) would work for the following case, but i think i'll
wait with trying it until LTO fails to build this, so far it's working. :)


A D main module with this:

---------------------------------------------
[...]
  const char* guname = glib.get_user_name();
 805139f:       e8 5c 02 00 00          call   8051600 <char* 
GLib2.get_user_name()>
[...]
---------------------------------------------

built with a "glib" module containing:

---------------------------------------------
[...]
extern (C) char* g_get_user_name();
char* get_user_name() {
   return g_get_user_name();
}
[...]
---------------------------------------------

results in the above call going through this "function":

---------------------------------------------
08051600 <char* GLib2.get_user_name()>:
 8051600:       55                      push   %ebp
 8051601:       89 e5                   mov    %esp,%ebp
 8051603:       5d                      pop    %ebp
 8051604:       e9 c7 f1 ff ff          jmp    80507d0 <g_get_user_name@plt>
---------------------------------------------

So clearly the compiler gets confused, it does a good job of optimizing
the tail call (this also works when the called functions takes args, btw),
but then fails to kill the ebp-related code.

If i use a D alias, instead of a wrapper, i get a direct call via PLT;
compiling with LTO also results in code that does not use this stub
 - at least until GDC's LTO will decide it's missing some symbols and
fail to link. :)

Reply via email to