------- 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