* Copyright: (c) 2004 Universität Karlsruhe
* Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
-
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <stdlib.h>
+
#include "callgraph.h"
#include "irloop_t.h"
/* --------------------- Compute the callgraph ------------------------ */
+/* Hash an address */
+#define HASH_ADDRESS(adr) (((unsigned)(adr)) >> 3)
+/**
+ * Walker called by compute_callgraph()
+ */
static void ana_Call(ir_node *n, void *env) {
int i, n_callees;
ir_graph *irg;
n_callees = get_Call_n_callees(n);
for (i = 0; i < n_callees; ++i) {
entity *callee_e = get_Call_callee(n, i);
- if (callee_e) { /* Null for unknown caller */
- ir_graph *callee = get_entity_irg(callee_e);
+ ir_graph *callee = get_entity_irg(callee_e);
+ if (callee) { /* For unknown caller */
pset_insert((pset *)callee->callers, irg, (unsigned)irg >> 3);
-
ana_entry buf = { callee, NULL, 0};
- ana_entry *found = pset_find((pset *)irg->callees, &buf, (unsigned)callee >> 3);
+ ana_entry *found = pset_find((pset *)irg->callees, &buf, HASH_ADDRESS(callee));
if (found) { /* add Call node to list, compute new nesting. */
} else { /* New node, add Call node and init nesting. */
found = (ana_entry *) obstack_alloc (irg->obst, sizeof (ana_entry));
found->irg = callee;
found->call_list = NULL;
found->max_depth = 0;
- pset_insert((pset *)irg->callees, found, (unsigned)callee >> 3);
+ pset_insert((pset *)irg->callees, found, HASH_ADDRESS(callee));
}
int depth = get_loop_depth(get_irn_loop(get_nodes_block(n)));
found->max_depth = (depth > found->max_depth) ? depth : found->max_depth;
}
}
-/* compare two ir graphs */
+/** compare two ir graphs in a ana_entry */
static int ana_entry_cmp(const void *elt, const void *key) {
- ana_entry *e1 = (ana_entry *)elt;
- ana_entry *e2 = (ana_entry *)key;
+ const ana_entry *e1 = elt;
+ const ana_entry *e2 = key;
return e1->irg != e2->irg;
}
-/* compare two ir graphs */
+/** compare two ir graphs */
static int graph_cmp(const void *elt, const void *key) {
return elt != key;
}
void compute_callgraph(void) {
int i, n_irgs = get_irp_n_irgs();
- assert(interprocedural_view == 0); /* Else walking will not reach the Call nodes. */
+ assert(! get_interprocedural_view()); /* Else walking will not reach the Call nodes. */
/* initialize */
free_callgraph();
ir_graph *irg = get_irp_irg(i);
if (irg->callees) DEL_ARR_F(irg->callees);
if (irg->callers) DEL_ARR_F(irg->callers);
- if (irg->callee_isbe) DEL_ARR_F(irg->callee_isbe);
- if (irg->caller_isbe) DEL_ARR_F(irg->caller_isbe);
+ if (irg->callee_isbe) free(irg->callee_isbe);
+ if (irg->caller_isbe) free(irg->caller_isbe);
irg->callees = NULL;
irg->callers = NULL;
irg->callee_isbe = NULL;
static bool
is_ip_head (ir_graph *n, ir_graph *pred)
{
- int iv_rem = interprocedural_view;
- interprocedural_view = 1;
+ int iv_rem = get_interprocedural_view();
+ set_interprocedural_view(true);
ir_node *sblock = get_irg_start_block(n);
int i, arity = get_Block_n_cfgpreds(sblock);
int is_be = 0;
}
}
- interprocedural_view = iv_rem;
+ set_interprocedural_view(iv_rem);
return is_be;
}