* Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+# include "config.h"
#endif
#ifdef HAVE_STRING_H
-#include <string.h>
+# include <string.h>
#endif
-
+# ifdef HAVE_STDLIB_H
#include <stdlib.h>
+#endif
#include "callgraph.h"
#include "array.h"
#include "pmap.h"
+#include "hashptr.h"
#include "irgwalk.h"
-double get_irg_callee_execution_freqency(ir_graph *irg, int pos) {
+double get_irg_callee_execution_frequency(ir_graph *irg, int pos) {
ir_node **arr = ((ana_entry *)irg->callees[pos])->call_list;
int i, n_Calls = ARR_LEN(arr);
double freq = 0;
return freq;
}
-double get_irg_callee_method_execution_freqency(ir_graph *irg, int pos) {
- double call_freq = get_irg_callee_execution_freqency(irg, pos);
+double get_irg_callee_method_execution_frequency(ir_graph *irg, int pos) {
+ double call_freq = get_irg_callee_execution_frequency(irg, pos);
double meth_freq = get_irg_method_execution_frequency(irg);
return call_freq * meth_freq;
}
-double get_irg_caller_method_execution_freqency(ir_graph *irg, int pos) {
+double get_irg_caller_method_execution_frequency(ir_graph *irg, int pos) {
ir_graph *caller = get_irg_caller(irg, pos);
int pos_callee = reverse_pos(irg, pos);
- return get_irg_callee_method_execution_freqency(caller, pos_callee);
+ return get_irg_callee_method_execution_frequency(caller, pos_callee);
}
/* --------------------- Compute the callgraph ------------------------ */
-/* Hash an address */
-#define HASH_ADDRESS(adr) (((unsigned)(adr)) >> 3)
-
/**
* Walker called by compute_callgraph()
*/
int i, n_callees;
ir_graph *irg;
- if (get_irn_op(n) != op_Call) return;
+ if (! is_Call(n)) return;
irg = get_irn_irg(n);
n_callees = get_Call_n_callees(n);
ir_graph *callee = get_entity_irg(callee_e);
if (callee) {
- ana_entry buf = { callee, NULL, 0};
+ ana_entry buf = { NULL, NULL, 0};
ana_entry *found;
int depth;
- pset_insert((pset *)callee->callers, irg, (unsigned)irg >> 3);
- found = pset_find((pset *)irg->callees, &buf, HASH_ADDRESS(callee));
+ buf.irg = callee;
+
+ pset_insert((pset *)callee->callers, irg, HASH_PTR(irg));
+ found = pset_find((pset *)irg->callees, &buf, HASH_PTR(callee));
if (found) { /* add Call node to list, compute new nesting. */
ir_node **arr = found->call_list;
ARR_APP1(ir_node *, arr, n);
found->call_list = NEW_ARR_F(ir_node *, 1);
found->call_list[0] = n;
found->max_depth = 0;
- pset_insert((pset *)irg->callees, found, HASH_ADDRESS(callee));
+ pset_insert((pset *)irg->callees, found, HASH_PTR(callee));
}
depth = get_loop_depth(get_irn_loop(get_nodes_block(n)));
found->max_depth = (depth > found->max_depth) ? depth : found->max_depth;
/**********************************************************************/
typedef struct scc_info {
- bool in_stack; /**< Marks whether node is on the stack. */
+ int in_stack; /**< Marks whether node is on the stack. */
int dfn; /**< Depth first search number. */
int uplink; /**< dfn number of ancestor. */
int visited;
mark_irg_in_stack (ir_graph *n) {
scc_info *info = get_irg_link(n);
assert(info);
- info->in_stack = true;
+ info->in_stack = 1;
}
static INLINE void
mark_irg_not_in_stack (ir_graph *n) {
scc_info *info = get_irg_link(n);
assert(info);
- info->in_stack = false;
+ info->in_stack = 0;
}
-static INLINE bool
+static INLINE int
irg_is_in_stack (ir_graph *n) {
scc_info *info = get_irg_link(n);
assert(info);
}
}
-/** Returns true if n is a loop header, i.e., it is a Block node
+/** Returns non-zero if n is a loop header, i.e., it is a Block node
* and has predecessors within the cfloop and out of the cfloop.
*
* @param root: only needed for assertion.
*/
-static bool
+static int
is_head (ir_graph *n, ir_graph *root)
{
int i, arity;
}
/**
- * Returns true if n is possible loop head of an endless loop.
+ * Returns non-zero if n is possible loop head of an endless loop.
* I.e., it is a Block, Phi or Filter node and has only predecessors
* within the loop.
* @arg root: only needed for assertion.
*/
-static bool
+static int
is_endless_head (ir_graph *n, ir_graph *root)
{
int i, arity;
* Check whether there is a parallel edge in the ip control flow.
* Only
*/
-static bool
+static int
is_ip_head (ir_graph *n, ir_graph *pred)
{
int is_be = 0;
int iv_rem = get_interprocedural_view();
- set_interprocedural_view(true);
+ set_interprocedural_view(1);
{
ir_node *sblock = get_irg_start_block(n);
int i, arity = get_Block_n_cfgpreds(sblock);
//printf(" "); DDMG(ip_pred);
if ((ip_pred == pred) && is_backedge(sblock, i)) {
//printf(" found\n");
- is_be = 1;
+ is_be = 1;
}
}
}
/* ----------------------------------------------------------------------------------- */
-/* Another algorithm to compute recursion nesting depth */
-/* Walk the callgraph. Ignore backedges. Use sum of execution freqencies of Call */
+/* Another algorithm to compute the execution frequency of methods ignoring recursions. */
+/* Walk the callgraph. Ignore backedges. Use sum of execution frequencies of Call */
/* nodes to evaluate a callgraph edge. */
/* ----------------------------------------------------------------------------------- */
void set_irg_method_execution_frequency (ir_graph *irg, double freq) {
irg->method_execution_frequency = freq;
+
+ if (irp->max_method_execution_frequency < freq)
+ irp->max_method_execution_frequency = freq;
}
static void compute_method_execution_frequency (ir_graph *irg, void *env) {
}
mark_cg_irg_visited(irg);
- /* Compute the new freqency. */
+ /* Compute the new frequency. */
freq = 0;
found_edge = 0;
for (i = 0; i < n_callers; i++) {
if (! is_irg_caller_backedge(irg, i)) {
- double edge_freq = get_irg_caller_method_execution_freqency(irg, i);
+ double edge_freq = get_irg_caller_method_execution_frequency(irg, i);
assert(edge_freq >= 0);
freq += edge_freq;
found_edge = 1;
DEL_ARR_F(e.loop_stack);
- //dump_callgraph("-with_nesting");
- //dump_callgraph_loop_tree(current_loop, "-after_cons");
-
-
/* -- compute the execution frequency -- */
irp->max_method_execution_frequency = 0;
master_cg_visited += 2;
find_callgraph_recursions();
compute_performance_estimates();
+
+ set_irp_loop_nesting_depth_state(loop_nesting_depth_consistent);
+}
+
+
+loop_nesting_depth_state get_irp_loop_nesting_depth_state(void) {
+ return irp->lnd_state;
+}
+void set_irp_loop_nesting_depth_state(loop_nesting_depth_state s) {
+ irp->lnd_state = s;
+}
+void set_irp_loop_nesting_depth_state_inconsistent(void) {
+ if (irp->lnd_state == loop_nesting_depth_consistent)
+ irp->lnd_state = loop_nesting_depth_inconsistent;
}