This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: TREE_UNCHANGING?
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 8 May 2002 22:46:37 -0400 (EDT)
- Subject: Re: TREE_UNCHANGING?
On Thu, 9 May 2002, Jason Merrill wrote:
> >>>>> "Jason" == Jason Merrill <jason@redhat.com> writes:
>
> > I would like to be able to tell the backend that the vtable for a class
> > object will never change, regardless of anything else we might or might not
> > know about that object, so we can hoist vtable lookups out of loops.
>
> Tangent:
>
> While setting TREE_CONSTANT does the trick for normal virtual function
> calls, it isn't enough for calls through a pointer-to-member function.
> This turns out to be because the loop optimizer isn't clever enough to
> hoist the complicated code for resolving a pmf, which involves a test and
> jump.
>
> I've whipped up a C analog below; this testcase takes 50% longer to run
> with -O2 than with -O2 -fno-inline, because of the const function
> optimization. If we inline, we lose that information; there ought to be a
> way to express the same thing for inlined/open-coded routines.
>
> I thought about using a libcall block, but that seems to be specific to
> calls. Any reason not to use it for an arbitrary block of code with
> defined inputs and output? <hack, hack> Nope, doesn't work. loop still
> looks at the individual insns, and doesn't think it can move some of the
> internal sets.
>
> Does the AST optimizer branch support anything like this?
It'll simplify it so that it might be able to hoist it.
That is, it *would*, except expand_call_inline produces invalid statement
expressions.
The c-tree docs say "The @code{STMT_EXPR_STMT} gives the statement
contained in the expression; this is always a @code{COMPOUND_STMT}."
It forgets the compound statement.
So we never notice it returns a value in simplification, and end up
aborting eventually because something tries to use the return value, when
it's now a null tree (since we never stored it anywhere, thinking it
wasn't used).
The stmt_expr inlining generates:
<stmt_expr 0x40191c78
type <pointer_type 0x40190570 pfn_type
type <function_type 0x4017ebc8 type <void_type 0x40178828 void>
DI
size <integer_cst 0x40177020 constant 64>
unit size <integer_cst 0x40177240 constant 8>
align 64 symtab 0 alias set -1
pointer_to_this <pointer_type 0x4017eef4>>
unsigned SI
size <integer_cst 0x401772a0 constant 32>
unit size <integer_cst 0x40177300 constant 4>
align 32 symtab 0 alias set -1
pointer_to_this <pointer_type 0x40190b54>>
side-effects tree_0
arg 0 <scope_stmt 0x40191cc0 tree_0 tree_3
arg 0 <block 0x4018ee80 used vars <var_decl 0x40192658 ap>
abstract_origin <function_decl 0x40190ef4 extract_pfn>>
chain <decl_stmt 0x40191c90 arg 0 <var_decl 0x40192658 ap>
chain <decl_stmt 0x40191ca8 arg 0 <var_decl 0x401926cc pmf>
chain <decl_stmt 0x40191cf0 arg 0 <var_decl 0x401927b4>
chain <compound_stmt 0x40191d08 tree_2
arg 0 <scope_stmt 0x40191d20 tree_0 arg 0 <block
0x4018eec0> chain <if_stmt 0x40193160>>
chain <scope_stmt 0x40191f18 tree_3 arg 0 <block
0x4018ee80> chain <label_stmt 0x40191f30>>>>>>>>
In fact, I took most of the code to find the value from c-common.c's
c_expand_expr, which expects that things that return a value do start with
a compound_stmt.
>
>