Bug 29963 - could speed up variable access with different object layout
Summary: could speed up variable access with different object layout
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks: 29842
  Show dependency tree / graph
 
Reported: 2006-11-23 20:35 UTC by Jorn Wolfgang Rennecke
Modified: 2012-11-13 00:53 UTC (History)
1 user (show)

See Also:
Host:
Target: sh-*-*
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jorn Wolfgang Rennecke 2006-11-23 20:35:43 UTC
Currently, variables are generally placed in the data or bss segment;
they cannot be addressed directly, hence their address needs to be
loaded into a register first.  Moreover, this address load is
done with a pc-relative load, which incurs extra latency.

If the variable was in the text segment within pc-relative load range,
integer loads could be done with pc-relative loads, while stores
and floating point loads could obtain their address using the mova
instruction.
Using a pc-relative load saves the extra latency of the address load
and/or the register that is used to hold the address.
Using mova saves the address load latency, and by making the address
cheper to obtain, makes it more feasible to recompute it in a loop
so that harder to reload values can be kept in a register.

For static variables, the compiler can determine if it is possible
to place the variable within reach when the translation unit is compiled.
(There are some issues with asms using directives like .rept or .org
 throwing off the instruction length calculations, but these are also
 a problem with other compiler activities requiring length calculation,
 i.e. branch shortening and constant pool layout, and programmers are
 well-advised to write their assembler templates in a way that their size
 will not underestimated, e.g. by passing with extra lines.)
For variables with global / namespace linkage, the best placement can
only be determined at link time.  This could either be done using the
-mrelax mechanism ( but that would need fixing first, see binutils/3298
http://sourceware.org/bugzilla/show_bug.cgi?id=3298 ), or by integrating
this optimization in the LTO framework.
Comment 1 Oleg Endo 2012-11-01 21:26:56 UTC
I'm not sure how the proposed optimization could be done in a generic way.  It would not work for code (i.e. text section) that resides in read-only memory, such as ROM or MMU read-only pages.
Comment 2 Jorn Wolfgang Rennecke 2012-11-01 21:42:12 UTC
(In reply to comment #1)
> I'm not sure how the proposed optimization could be done in a generic way.  It
> would not work for code (i.e. text section) that resides in read-only memory,
> such as ROM or MMU read-only pages.

In that case, you could indeed only do this optimization for constant
variables / arrays.

But it is not uncommon to load the program into RAM before executing,
e.g. because the ROM it's stored in is too slow.  In this case, placing
the program code in a writable segment is merely a matter of policy;
the user would be expected have control if this optimization is enabled,
taking into account if there are any overriding security concerns.
Comment 3 Oleg Endo 2012-11-13 00:53:45 UTC
(In reply to comment #2)

> But it is not uncommon to load the program into RAM before executing,
> e.g. because the ROM it's stored in is too slow.

Newer SH2A devices with on-chip flash have some facilities to fix that ;)

> 
> In that case, you could indeed only do this optimization for constant
> variables / arrays.
> 

True.  For example in such cases as:

const char* test (void)
{
  return "test";
}

        .file	"sh_tmp.cpp"
        .text
        .little
        .section .rodata.str1.4,"aMS",@progbits,1
        .align 2
.LC0:
        .string "test"
        .text
        .align 1
        .global __Z4testv
        .type   __Z4testv, @function
__Z4testv:
        mov.l   .L2,r0
        rts	
        nop
.L3:
        .align 2
.L2:
        .long	.LC0
        .size	__Z4testv, .-__Z4testv
        .ident	"GCC: (GNU) 4.8.0 20121112 (experimental)"


The string constant could be placed in .text instead of .rodata, even without link time relaxation:

__Z4testv:
        mova   .L2,r0
        rts	
        nop
.L3:
        .align 2
.L2:
        .string "test"

However, it might have negative effects on the overall constant pool usage.  I guess there should be a limit on the size (and the number of) elements that are moved from .rodata to .text.