------- Comment #5 from ebotcazou at gcc dot gnu dot org  2005-10-11 10:42 
-------
Really interesting: it's a combination of TARGET_PTRMEMFUNC_VBIT_LOCATION,
inlining, efficient stack slot allocation and delay slot scheduling!

SPARC doesn't define TARGET_PTRMEMFUNC_VBIT_LOCATION so the compiler selects
ptrmemfunc_vbit_in_pfn.  This means typechk.c:get_member_function_from_ptrfunc
will be building an expression of the form:

  __pfn & 1 ? *(*(p + __delta) + __pfn - 1) : __pfn (p + __delta)

Now for the minimal class "Class" in the testcase, the function is not virtual
and the alignment of p is 1.  Thanks to inlining, the above expression boils
down to:

   func & 1 ? *(*p + func - 1) : func (p)

Of course func is a multiple of 4 so the first branch will not be executed,
although it is compiled.  Then delay slot scheduling kicks in: it hoists

  *p

in the delay slot of the ? branch because register liveness analysis allows it
to do so (the register set in the insn is dead in the second branch):

        sethi   %hi(_ZNK5Class4vf0cEv), %l5
        or      %l5, %lo(_ZNK5Class4vf0cEv), %l0
        andcc   %l0, 1, %l3
        bne     .LL6
         ld     [%fp-17], %g1
        mov     %l0, %g1

and the game is over.


The only approach to fixing this I can think of is to modify the selection
logic of TARGET_PTRMEMFUNC_VBIT_LOCATION: if the target has strict alignment
and delay slots, the macro should be set to ptrmemfunc_vbit_in_delta.

What do you think, Mark?  Thanks in advance.


-- 

ebotcazou at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mark at codesourcery dot com
          Component|middle-end                  |target


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23585

Reply via email to