This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[commit] SPU i-cache: Correct calculation of number of required stubs (2/2)
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: binutils at sourceware dot org
- Date: Thu, 28 May 2009 12:57:08 +0200 (CEST)
- Subject: [commit] SPU i-cache: Correct calculation of number of required stubs (2/2)
Hello,
after the previous patch, I was still seeing off-by-one errors in the number
of required call stubs. It turned out that this was caused by remove_cycles
eliminating some of the call_info edges. While it is true that you need to
remove those edges when recursively traversing the call graph, you actually
need to consider all of the edges when counting stubs.
The following patch changes remove_cycles to not actually eliminate the edges,
but instead simply mark them with an broken_cycle flag. This allows some users
to ignore them and others to take them into account ...
Note that this problem was latent not only with software i-cache, but also
with traditional automatic overlay generation.
Tested on spu-elf with no regressions.
Approved off-line by Alan Modra; committed to mainline.
Bye,
Ulrich
ChangeLog:
* elf32-spu.c (struct call_info): New member broken_cycle.
(remove_cycle): Instead of physically removing call_info structures
to break call graph cycles, mark them using the broken_cycle flag.
(mark_overlay_section): Respect broken_cycle flag.
(unmark_overlay_section): Likewise.
(collect_lib_sections): Likewise.
(collect_overlays): Likewise.
(sum_stack): Likewise.
--- src/bfd/elf32-spu.c.orig 2009-05-26 21:26:39.000000000 +0200
+++ src/bfd/elf32-spu.c 2009-05-26 21:24:41.000000000 +0200
@@ -367,6 +367,7 @@ struct call_info
unsigned int max_depth;
unsigned int is_tail : 1;
unsigned int is_pasted : 1;
+ unsigned int broken_cycle : 1;
unsigned int priority : 13;
};
@@ -3267,9 +3268,8 @@ remove_cycles (struct function_info *fun
"from %s to %s\n"),
f1, f2);
}
- *callp = call->next;
- free (call);
- continue;
+
+ call->broken_cycle = TRUE;
}
callp = &call->next;
}
@@ -3512,7 +3512,8 @@ mark_overlay_section (struct function_in
BFD_ASSERT (!fun->sec->segment_mark);
fun->sec->segment_mark = 1;
}
- if (!mark_overlay_section (call->fun, info, param))
+ if (!call->broken_cycle
+ && !mark_overlay_section (call->fun, info, param))
return FALSE;
}
@@ -3572,7 +3573,8 @@ unmark_overlay_section (struct function_
}
for (call = fun->call_list; call != NULL; call = call->next)
- if (!unmark_overlay_section (call->fun, info, param))
+ if (!call->broken_cycle
+ && !unmark_overlay_section (call->fun, info, param))
return FALSE;
if (RECURSE_UNMARK)
@@ -3623,7 +3625,8 @@ collect_lib_sections (struct function_in
}
for (call = fun->call_list; call != NULL; call = call->next)
- collect_lib_sections (call->fun, info, param);
+ if (!call->broken_cycle)
+ collect_lib_sections (call->fun, info, param);
return TRUE;
}
@@ -3817,7 +3820,7 @@ collect_overlays (struct function_info *
fun->visit7 = TRUE;
for (call = fun->call_list; call != NULL; call = call->next)
- if (!call->is_pasted)
+ if (!call->is_pasted && !call->broken_cycle)
{
if (!collect_overlays (call->fun, info, ovly_sections))
return FALSE;
@@ -3863,7 +3866,8 @@ collect_overlays (struct function_info *
}
for (call = fun->call_list; call != NULL; call = call->next)
- if (!collect_overlays (call->fun, info, ovly_sections))
+ if (!call->broken_cycle
+ && !collect_overlays (call->fun, info, ovly_sections))
return FALSE;
if (added_fun)
@@ -3914,6 +3918,8 @@ sum_stack (struct function_info *fun,
max = NULL;
for (call = fun->call_list; call; call = call->next)
{
+ if (call->broken_cycle)
+ continue;
if (!call->is_pasted)
has_call = TRUE;
if (!sum_stack (call->fun, info, sum_stack_param))
@@ -3957,7 +3963,7 @@ sum_stack (struct function_info *fun,
{
info->callbacks->minfo (_(" calls:\n"));
for (call = fun->call_list; call; call = call->next)
- if (!call->is_pasted)
+ if (!call->is_pasted && !call->broken_cycle)
{
const char *f2 = func_name (call->fun);
const char *ann1 = call->fun == max ? "*" : " ";
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com