jhc vs ghc and the surprising result involving ghc generatedassembly.

Florian Weimer fw at deneb.enyo.de
Wed Nov 2 08:59:10 EST 2005


* Simon Marlow:

>>> gcc started generating this rubbish around version 3.4, if I recall
>>> correctly.  I've tried disabling various optimisations, but can't
>>> seem to convince gcc not to generate the extra jump.  You don't get
>>> this from the native code generator, BTW.
>> 
>> But the comparison is present in the C code.  What do you want GCC to
>> do?
>
> I didn't mean to sound overly critical of gcc.

It didn't come across that way.  I just want to construct a test case,
so it can be fixed on the GCC side, and see if I can suggest
alternatives.

> Actually if I add -O2, then I get better code, so perhaps this isn't a
> real problem.  Although gcc still generates this:

> 	movl	$Fac_zdwfac_info, %eax
> 	jmp	*%rax
>
> and fails to combine the movs with the jmp instruction (we do this
> simplification ourselves when post-processing the assembly code).  

I agree, GCC should optimize this case.  A minimal test case is:

extern void bar();

void foo()
{
  void *p = bar;
  goto *p;
}

None of the GCC versions I have tried optimizes away the indirect
call.

> I'll compile up gcc 4 and see what happens with that.

The jump target is not propagated, either.  Same with 4.1.

However, beginning with GCC 3.4, you can use:

extern void bar();

void foo()
{
  void (*p)(void) = bar;
  p();
}

And the indirect call is turned into a direct jump.  Tail recursive
calls and really indirect tail calls are also optimzed.  Together with
-fomit-frame-pointer, this could give you what you need, without
post-processing the generated assembler code (which is desirable
because the asm volatile statements inhibit further optimization).

Is it correct that you use indirect gotos across functions?  Such
gotos aren't supported by GCC and work only by accident.


More information about the Glasgow-haskell-users mailing list