System programming in D (Was: The God Language)

Artur Skawina art.08.09 at gmail.com
Mon Jan 9 14:28:06 PST 2012


On 01/09/12 20:05, Iain Buclaw wrote:
> On 9 January 2012 18:15, Artur Skawina <art.08.09 at gmail.com> 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 at 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. :)


More information about the D.gnu mailing list