Hello, Post-link optimizers encounter difficulties when trying to reorder data where the code was compiled with -fsection-anchors. The reordering process uses relocation information, available when linking with --emit-relocs, to update references to the relocated objects. However -fsection-anchors causes inter-object distances, between the anchor and its related objects, to be embedded in the code without associated relocation information. The following patch adds {$BLOCK_BEGIN,$BLOCK_END} symbol pair around each block of anchored objects. The symbols are local, of zero size, so they do not affect memory allocation. With these symbol pairs a post-link optimizer can turn the {begin,end} pair into a block object, and the anchored objects to size-less labels within that block. It can then reorder the blocks without the risk of violating assumptions about inter-object distances.
Bootstrapped on powerpc64-suse-linux, testing on powerpc64-suse-linux in progress. I would like to add it to 4.8. Comments? - Yaakov 2011-12-05 Yaakov Yaari <ya...@il.ibm.com> * varasm.c (output_object_block): Add a zero-size $BLOCK_BEGIN before first object in a block, and a $BLOCK_END after the last object. Index: gcc/varasm.c =================================================================== --- gcc/varasm.c (revision 181801) +++ gcc/varasm.c (working copy) @@ -7338,6 +7338,9 @@ output_object_block (struct object_block *block) HOST_WIDE_INT offset; tree decl; rtx symbol; + rtx first_symbol = 0, last_symbol; + char buffer[100]; + HOST_WIDE_INT last_size; if (block->objects == NULL) return; @@ -7376,9 +7379,27 @@ { decl = SYMBOL_REF_DECL (symbol); assemble_variable_contents (decl, XSTR (symbol, 0), false); - offset += tree_low_cst (DECL_SIZE_UNIT (decl), 1); + /* Add zero-size BLOCK_BEGIN symbol at the beginning of block. */ + if (!first_symbol) + { + first_symbol = symbol; + ASM_OUTPUT_DEF (asm_out_file, "$BLOCK_BEGIN", + XSTR (first_symbol, 0)); + ASM_OUTPUT_SIZE_DIRECTIVE (asm_out_file, "$BLOCK_BEGIN", 0); + } + last_symbol = symbol; + last_size = tree_low_cst (DECL_SIZE_UNIT (decl), 1); + offset += last_size; } } + /* Add a zero-size BLOCK_END symbol at end of block. */ + if (first_symbol) + { + sprintf (buffer, "%s +" HOST_WIDE_INT_PRINT_DEC, XSTR (last_symbol, 0), + last_size); + ASM_OUTPUT_DEF (asm_out_file, "$BLOCK_END", buffer); + ASM_OUTPUT_SIZE_DIRECTIVE (asm_out_file, "$BLOCK_END", 0); + } } /* A htab_traverse callback used to call output_object_block for