This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
SPU stack analysis and function splitting
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Thu, 28 Feb 2008 20:00:01 +1030
- Subject: SPU stack analysis and function splitting
Currently the SPU stack analysis code assumes that there are at most
two code sections per function (hot/cold function partitioning). That
may be true at the moment, but won't be when spu-gcc starts splitting
functions into multiple sections.
* elf32-spu.c (mark_functions_via_relocs): Don't assume that
the "->start" pointer reaches to function origin, so that we
can handle functions split over more than two sections.
(build_call_tree): Likewise.
(pasted_function): Don't attempt to set fun->start back to the
function origin, just go back one section.
Index: bfd/elf32-spu.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-spu.c,v
retrieving revision 1.29
diff -u -p -r1.29 elf32-spu.c
--- bfd/elf32-spu.c 7 Feb 2008 01:26:56 -0000 1.29
+++ bfd/elf32-spu.c 27 Feb 2008 22:21:43 -0000
@@ -1997,14 +1997,29 @@ mark_functions_via_relocs (asection *sec
destination has been called by some other function then
it is a separate function. We also assume that functions
are not split across input files. */
- if (callee->fun->start != NULL
- || sec->owner != sym_sec->owner)
+ if (sec->owner != sym_sec->owner)
{
callee->fun->start = NULL;
callee->fun->is_func = TRUE;
}
- else
+ else if (callee->fun->start == NULL)
callee->fun->start = caller;
+ else
+ {
+ struct function_info *callee_start;
+ struct function_info *caller_start;
+ callee_start = callee->fun;
+ while (callee_start->start)
+ callee_start = callee_start->start;
+ caller_start = caller;
+ while (caller_start->start)
+ caller_start = caller_start->start;
+ if (caller_start != callee_start)
+ {
+ callee->fun->start = NULL;
+ callee->fun->is_func = TRUE;
+ }
+ }
}
}
@@ -2041,11 +2056,7 @@ pasted_function (asection *sec, struct b
if (l->u.indirect.section == sec)
{
if (fun_start != NULL)
- {
- if (fun_start->start)
- fun_start = fun_start->start;
- fun->start = fun_start;
- }
+ fun->start = fun_start;
return TRUE;
}
if (l->type == bfd_indirect_link_order
@@ -2382,14 +2393,19 @@ build_call_tree (bfd *output_bfd, struct
int i;
for (i = 0; i < sinfo->num_fun; ++i)
{
- if (sinfo->fun[i].start != NULL)
+ struct function_info *start = sinfo->fun[i].start;
+
+ if (start != NULL)
{
- struct call_info *call = sinfo->fun[i].call_list;
+ struct call_info *call;
+ while (start->start != NULL)
+ start = start->start;
+ call = sinfo->fun[i].call_list;
while (call != NULL)
{
struct call_info *call_next = call->next;
- if (!insert_callee (sinfo->fun[i].start, call))
+ if (!insert_callee (start, call))
free (call);
call = call_next;
}
--
Alan Modra
Australia Development Lab, IBM