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