On 9/23/2011 6:03 PM, Sriraman Tallam wrote:
This patch adds a new linker plugin to re-order functions.
This is great stuff. We were experimenting with using the coverage
files to generate an ordering for --section-ordering-file, but this
might be even better, will have to experiment with it.
A couple of comments on the code itself:
Index: function_reordering_plugin/callgraph.h
+inline static Edge_list *
+make_edge_list (Edge *e)
+{
+ Edge_list *list = (Edge_list *)malloc (sizeof (Edge_list));
If you are going to use libiberty via hashtab.h, you might as well make
use of the *ALLOC family of macros to make this and other allocations a
little neater.
+/*Represents an edge in the call graph. */
+struct __edge__
I think the usual convention is to call this edge_d or something
similar, avoiding the profusion of underscores.
+void
+map_section_name_to_index (char *section_name, void *handle, int shndx)
+{
+ void **slot;
+ char *function_name;
+
+ if (is_prefix_of (".text.hot.", section_name))
+ function_name = section_name + 10 /* strlen (".text.hot.") */;
+ else if (is_prefix_of (".text.unlikely.", section_name))
+ function_name = section_name + 15 /* strlen (".text.unlikely.") */;
+ else if (is_prefix_of (".text.cold.", section_name))
+ function_name = section_name + 11 /* strlen (".text.cold.") */;
+ else if (is_prefix_of (".text.startup.", section_name))
+ function_name = section_name + 14 /* strlen (".text.startup.") */;
+ else
+ function_name = section_name + 6 /*strlen (".text.") */;
You don't handle plain .text; this is assuming -ffunction-sections,
right? Can this limitation be easily removed?
I think it is customary to put the comment after the semicolon.
Might just be easier to say something like:
const char *sections[] = { ".text.hot", ... }
char *function_name = NULL;
for (i = 0; i < ARRAY_SIZE (sections); i++)
if (is_prefix_of (sections[i], section_name))
{
function_name = section_name + strlen (sections[i]);
break;
}
if (!function_name)
function_name = section_name + 6; /* strlen (".text.") */
I guess that's not much shorter.
+void
+cleanup ()
+{
+ Node *node;
+ Edge *edge;
+
+ /* Free all nodes and edge_lists. */
+ for (node = node_chain; node != NULL; )
+ {
+ Node *next_node = node->next;
+ Edge_list *it;
+ for (it = node->edge_list; it != NULL; )
+ {
+ Edge_list *next_it = it->next;
+ free (it);
+ it = next_it;
+ }
Write a free_edge_list function, since you do this once here and twice
below.
-Nathan