[PATCH] Fix constant array ARRAY_REF[constant index] optimization (PR middle-end/28755)

Richard Sandiford richard@codesourcery.com
Tue Aug 22 18:09:00 GMT 2006


Jakub Jelinek <jakub@redhat.com> writes:
> On Tue, Aug 22, 2006 at 03:29:10PM +0100, Richard Sandiford wrote:
>> Jakub Jelinek <jakub@redhat.com> writes:
>> > As shown by the attached testcase, the constant array ARRAY_REF
>> > with constant index optimization is in some cases really big pessimization.
>> > If expand_expr decides to put a CONSTRUCTOR into memory, then we just waste
>> > rodata memory, while we in that case really should just use the original
>> > array entry.
>> > The following patches (attached 4.1 and 4.2 versions) check for this and
>> > if it determines it is not a win, it falls back to using the actual
>> > original array reference.  On 4.1 that works without a problem,
>> > unfortunately in 4.2 it seems -fsection-anchors kills the garbage collection
>> > of unused deferred constants.
>> 
>> Can you give more details?
>
> static rtx
> expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
> {
>   rtx mem;
>
>   mem = output_constant_def (exp, defer);
>   if (modifier != EXPAND_INITIALIZER)
>     mem = use_anchored_address (mem);
>   return mem;
> }
>
> Several places in expr.c call this routine with defer = 1, which means that
> the constant shouldn't be output right away, only the symbol created and
> it will be output if needed (i.e. if referenced at the end of RTL
> optimizations).  At least that's how it used to work.
> See also maybe_output_constant_def_contents and
> output_constant_pool/mark_constant_pool.

Ah!  Sorry, I'd got the wrong end of the stick.  I thought you were
talking about garbage-collecting gcc's memory during compilation,
not garbage-collecting constants in the output.

> But, with -fsection-anchors, use_anchored_address will "use" the constant
> right away, immediately allocates space for it in the anchor data block
> and returns the anchor symbol plus computed offset.  For defer == 0
> that's fine, but for defer != 0 that's a bad idea.  Either we shouldn't
> call use_anchored_address if defer != 0, or we should, but return from
> it some new RTL expression which would mean anchor data block offset
> of SYMBOL_REF xyz and let that RTL live at least through the first
> half of RTL optimizations, so that it can be optimized away if not needed
> and only if still needed be expanded into some actual CONST_INT.

Unfortunately, I don't think the latter suggestion is practical.
The whole point of placing these things when we do is that we need a
CONST_INT straight away.  Otherwise, we can't enforce the settings of
{MIN,MAX}_ANCHOR_OFFSET.  (On targets like PowerPC where these settings
are greater than the load/store offsets, we also need to know the offset
up-front in order to determine whether a high-part addition is needed.)

I'm happier with the idea of not using anchors if defer == 1.
It will obviously pessimise some cases that -fsection-anchors
would otherwise handle better, but I think the trade-off is the
right one.  Any pessimisation we get by ignoring the defer parameter
will be a regression from earlier releases; any curtailment of the
-fsection-anchors functionality will not.  Of course, if there are
cases where we can safely use anchors even with defer == 1,
so much the better.

I also think a patch to expand_expr_constant would be much better
than the save_section_anchors one.  We can remove the defer == 1
check later if we ever get to the stage where the decision about
whether a constant is needed is made before RTL expansion, and
where we have no on the fly expansion decisions like the one
you're changing.

Richard



More information about the Gcc-patches mailing list