This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[commit, spu] Handle non-branch relocs when building call graph
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: binutils at sourceware dot org
- Date: Tue, 3 Nov 2009 15:01:23 +0100 (CET)
- Subject: [commit, spu] Handle non-branch relocs when building call graph
Hello,
when using a software i-cache compiler on the SPU that splits functions up into
multiple sections, the linker currently may not always recognize all part of that
function. The unrecognized sections will then be treated as "pasted" sections
(like .init) that must join the preceding section. This can cause suboptimal
placement decisions or even cache line overflows.
The reason why sections may not be recognized as part of a function is that
mark_functions_via_relocs currently does not handle relocations on anything
but branch instructions. This means that parts of function code that are
reachable only via a code label reference from anything but a branch (e.g.
jump table entries or other references to load a code label as data) will
be ignored.
The following patch fixes this problem by handling such references as well.
Note that while they must contribute to the call graph, they do not require
stubs to be generated in the software i-cache case; this is reflected by
setting the call_info.count field to zero for these cases.
Tested with no regressions on spu-elf on mainline and the 2_20 branch.
Approved off-line by Alan Modra; committed to mainline and branch.
Bye,
Ulrich
2009-11-03 Alan Modra <amodra@bigpond.net.au>
Ulrich Weigand <uweigand@de.ibm.com>
* elf32-spu.c (mark_functions_via_relocs): Handle non-branch relocs
(jump tables or other references to code labels) as well.
diff -urNp src.orig/bfd/elf32-spu.c src/bfd/elf32-spu.c
--- src.orig/bfd/elf32-spu.c 2009-11-02 16:26:03.000000000 +0100
+++ src/bfd/elf32-spu.c 2009-11-02 16:33:56.000000000 +0100
@@ -2670,19 +2670,12 @@ mark_functions_via_relocs (asection *sec
Elf_Internal_Sym *sym;
struct elf_link_hash_entry *h;
bfd_vma val;
- bfd_boolean reject, is_call;
+ bfd_boolean nonbranch, is_call;
struct function_info *caller;
struct call_info *callee;
- reject = FALSE;
r_type = ELF32_R_TYPE (irela->r_info);
- if (r_type != R_SPU_REL16
- && r_type != R_SPU_ADDR16)
- {
- reject = TRUE;
- if (!(call_tree && spu_hash_table (info)->params->auto_overlay))
- continue;
- }
+ nonbranch = r_type != R_SPU_REL16 && r_type != R_SPU_ADDR16;
r_indx = ELF32_R_SYM (irela->r_info);
if (!get_sym_h (&h, &sym, &sym_sec, psyms, r_indx, sec->owner))
@@ -2693,7 +2686,7 @@ mark_functions_via_relocs (asection *sec
continue;
is_call = FALSE;
- if (!reject)
+ if (!nonbranch)
{
unsigned char insn[4];
@@ -2724,14 +2717,13 @@ mark_functions_via_relocs (asection *sec
}
else
{
- reject = TRUE;
- if (!(call_tree && spu_hash_table (info)->params->auto_overlay)
- || is_hint (insn))
+ nonbranch = TRUE;
+ if (is_hint (insn))
continue;
}
}
- if (reject)
+ if (nonbranch)
{
/* For --auto-overlay, count possible stubs we need for
function pointer references. */
@@ -2741,8 +2733,20 @@ mark_functions_via_relocs (asection *sec
else
sym_type = ELF_ST_TYPE (sym->st_info);
if (sym_type == STT_FUNC)
- spu_hash_table (info)->non_ovly_stub += 1;
- continue;
+ {
+ if (call_tree && spu_hash_table (info)->params->auto_overlay)
+ spu_hash_table (info)->non_ovly_stub += 1;
+ /* If the symbol type is STT_FUNC then this must be a
+ function pointer initialisation. */
+ continue;
+ }
+ /* Ignore data references. */
+ if ((sym_sec->flags & (SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ != (SEC_ALLOC | SEC_LOAD | SEC_CODE))
+ continue;
+ /* Otherwise we probably have a jump table reloc for
+ a switch statement or some other reference to a
+ code label. */
}
if (h)
@@ -2791,7 +2795,7 @@ mark_functions_via_relocs (asection *sec
callee->is_pasted = FALSE;
callee->broken_cycle = FALSE;
callee->priority = priority;
- callee->count = 1;
+ callee->count = nonbranch? 0 : 1;
if (callee->fun->last_caller != sec)
{
callee->fun->last_caller = sec;
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com