Commit efa44a3c authored by Matthias Braun's avatar Matthias Braun
Browse files

remove old+unused execution_frequency/field_temperature

parent 5c6f5d46
...@@ -135,23 +135,6 @@ FIRM_API void callgraph_walk(callgraph_walk_func *pre, ...@@ -135,23 +135,6 @@ FIRM_API void callgraph_walk(callgraph_walk_func *pre,
*/ */
FIRM_API void find_callgraph_recursions(void); FIRM_API void find_callgraph_recursions(void);
/** Compute interprocedural performance estimates.
*
* Computes
* - the loop depth of the method.
* The loop depth of an edge between two methods is the
* maximal loop depth of the Call nodes that call along this edge.
* The loop depth of the method is the loop depth of the most expensive
* path from main().
* - The recursion depth. The maximal number of recursions passed
* on all paths reaching this method.
* - The execution frequency. As loop depth, but the edge weight is the sum
* of the execution frequencies of all Calls along the edge.
*
* Expects the main irg is set, see set_irp_main_irg();
**/
FIRM_API void compute_performance_estimates(void);
/** Computes the interprocedural loop nesting information. /** Computes the interprocedural loop nesting information.
* *
* Computes two numbers for each irg: the depth it is called in 'normal' * Computes two numbers for each irg: the depth it is called in 'normal'
......
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief Compute an estimate of basic block executions.
* @author Goetz Lindenmaier
* @date 5.11.2004
* @version $Id$
* @brief
* We assume the start block of a procedure is executed once. Based on this we
* compute the execution freqency of all blocks.
*
* The computation of the frequencies depends on the count of exception control
* flow computed during the interval analysis. The interval analysis again
* depends on stuff computed here.
*/
#ifndef FIRM_ANA_EXECUTION_FREQUENCY_H
#define FIRM_ANA_EXECUTION_FREQUENCY_H
#include "firm_types.h"
#include "begin.h"
/** A proj from a Cond that goes to an exception handler. */
FIRM_API int is_fragile_Proj(ir_node *n);
/** Returns the number of times the block/region is executed according to
* our estimate. Gives a number relative to the Start node of the procedure
* the block is in, which is weighted with 1. */
FIRM_API double get_irn_exec_freq(ir_node *n);
FIRM_API double get_Block_exec_freq(ir_node *b);
FIRM_API double get_region_exec_freq(void *reg);
/** Compute the execution frequency for all blocks in the given
* graph.
*
* @param irg The graph to be analyzed.
* @param default_loop_weight The default number of executions of a loop.
* @param exception_probability The probability that a fragile operation causes an exception.
*
* Uses link field.
*/
FIRM_API void compute_execution_frequency(ir_graph *irg, int default_loop_weight, double exception_probability);
/** Compute the execution frequency for all graphs.
*
* @param default_loop_weight The default number of executions of a loop.
* @param exception_probability The probability that a fragile operation causes an exception.
*
*/
FIRM_API void compute_execution_frequencies(int default_loop_weight, double exception_probability);
/** Free occupied memory, reset for all graphs. */
FIRM_API void free_execution_frequency(void);
/** State of execution frequencies for graphs and the whole program.
*
* The exec_freq_state in irp is consistent, if the state of all graphs is consistent.
* It is none, if the state of all graphs is none. Else it is inconsistent. */
typedef enum {
exec_freq_none, /**< Execution frequencies are not computed, no
memory is allocaaccess fails. */
exec_freq_consistent, /**< Execution frequency information is computed and
correct. */
exec_freq_inconsistent /**< Execution frequency is computed but the graph
has been changed since. */
} exec_freq_state;
FIRM_API exec_freq_state get_irg_exec_freq_state(ir_graph *irg);
FIRM_API void set_irg_exec_freq_state(ir_graph *irg,
exec_freq_state s);
/**
* Sets irg and irp exec freq state to inconsistent if it is set to consistent.
*/
FIRM_API void set_irg_exec_freq_state_inconsistent(ir_graph *irg);
FIRM_API exec_freq_state get_irp_exec_freq_state(void);
/**
* Sets irp and all irg exec freq states to inconsistent if it is set to
* consistent.
*/
FIRM_API void set_irp_exec_freq_state_inconsistent(void);
#include "end.h"
#endif
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief Compute an estimate of field temperature, i.e., field access heuristic.
* @author Goetz Lindenmaier
* @date 21.7.2004
* @version $Id$
* @note
* Watch it! This is highly java dependent.
*
* - All Sel nodes get an array with possibly accessed entities.
* (resolve polymorphy on base of inherited entities.)
* (the mentioned entity in first approximation.)
*
* - We compute a value for the entity based on the Sel nodes.
*/
#ifndef FIRM_ANA_FIELD_TEMPERATURE_H
#define FIRM_ANA_FIELD_TEMPERATURE_H
#include "firm_types.h"
#include "begin.h"
/** The number of array elements we assume if not both bounds are given. */
#define DEFAULT_N_ARRAY_ELEMENTS 1
FIRM_API int get_irn_loop_call_depth(ir_node *n);
/** Return loop depth of node.
*
* Returns the loop depth of n in the control flow. I.e., we
* go from the node to the block to the loop the block is in,
* and return its depth. */
FIRM_API int get_irn_cfloop_depth(ir_node *n);
FIRM_API int get_irn_recursion_depth(ir_node *n);
/**
* Get the weighted interprocedural loop depth of the node.
* The depth is estimated by a heuristic. The heuristic considers
* loop and recursion depth.
*/
FIRM_API int get_weighted_loop_depth(ir_node *n);
/** Heuristic merging recursion and loop depth. */
FIRM_API double get_irn_final_cost(ir_node *n);
/** Get accumulated(really?) execution frequencies.
* A heuristic weights the recursions. */
FIRM_API double get_type_estimated_n_instances(ir_type *clss);
FIRM_API double get_type_estimated_mem_consumption_bytes(ir_type *tp);
/** Estimates the size of an object.
*
* The heuristic mainly affects array sizes.
* Further this ignores padding for alignment, especially of small fields. */
FIRM_API int get_type_estimated_size_bytes(ir_type *tp);
/** Estimates the number of fields of a single Object.
* The heuristic mainly affects array sizes.
* @@@ Misses inherited fields! */
FIRM_API int get_type_estimated_n_fields(ir_type *tp);
FIRM_API double get_type_estimated_n_casts(ir_type *clss);
FIRM_API double get_class_estimated_n_upcasts(ir_type *clss);
FIRM_API double get_class_estimated_n_downcasts(ir_type *clss);
/**
* Returns the number of accesses to the dispatch table.
*
* This includes the initialization of the pointer field, and accesses
* to virtual fields (as instance marker in Java). Certainly this
* includes virtual method calls.
*/
FIRM_API double get_class_estimated_n_dyncalls(ir_type *clss);
/** Returns the number of writes to the dispatch pointer.
* This is the same as the number of allocations. */
FIRM_API double get_class_estimated_dispatch_writes(ir_type *clss);
/** Returns the number of reads of the dispatch pointer. */
FIRM_API double get_class_estimated_dispatch_reads (ir_type *clss);
FIRM_API double get_entity_estimated_n_loads(ir_entity *ent);
FIRM_API double get_entity_estimated_n_stores(ir_entity *ent);
FIRM_API double get_entity_estimated_n_calls(ir_entity *ent);
/**
* The number of accesses to dynamically called methods and
* to other static fields that overwrite/are overwritten.
*/
FIRM_API double get_entity_estimated_n_dyncalls(ir_entity *ent);
typedef enum {
temperature_none,
temperature_consistent,
temperature_inconsistent
} irp_temperature_state;
#include "end.h"
#endif
...@@ -66,8 +66,6 @@ ...@@ -66,8 +66,6 @@
#include "cgana.h" #include "cgana.h"
#include "dbginfo.h" #include "dbginfo.h"
#include "execfreq.h" #include "execfreq.h"
#include "execution_frequency.h"
#include "field_temperature.h"
#include "firm_common.h" #include "firm_common.h"
#include "firmstat.h" #include "firmstat.h"
#include "firm_types.h" #include "firm_types.h"
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include "irnode_t.h" #include "irnode_t.h"
#include "cgana.h" #include "cgana.h"
#include "execution_frequency.h"
#include "array.h" #include "array.h"
#include "pmap.h" #include "pmap.h"
...@@ -198,35 +197,6 @@ size_t get_irg_callee_loop_depth(const ir_graph *irg, size_t pos) ...@@ -198,35 +197,6 @@ size_t get_irg_callee_loop_depth(const ir_graph *irg, size_t pos)
return irg->callees ? irg->callees[pos]->max_depth : 0; return irg->callees ? irg->callees[pos]->max_depth : 0;
} }
static double get_irg_callee_execution_frequency(const ir_graph *irg, size_t pos)
{
ir_node **arr = irg->callees[pos]->call_list;
size_t i, n_Calls = ARR_LEN(arr);
double freq = 0.0;
for (i = 0; i < n_Calls; ++i) {
freq += get_irn_exec_freq(arr[i]);
}
return freq;
}
static double get_irg_callee_method_execution_frequency(const ir_graph *irg,
size_t 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;
}
static double get_irg_caller_method_execution_frequency(const ir_graph *irg,
size_t pos)
{
ir_graph *caller = get_irg_caller(irg, pos);
size_t pos_callee = reverse_pos(irg, pos);
return get_irg_callee_method_execution_frequency(caller, pos_callee);
}
/* --------------------- Compute the callgraph ------------------------ */ /* --------------------- Compute the callgraph ------------------------ */
...@@ -933,217 +903,6 @@ static void reset_isbe(void) ...@@ -933,217 +903,6 @@ static void reset_isbe(void)
} }
} }
/* ----------------------------------------------------------------------------------- */
/* Another algorithm to compute recursion nesting depth */
/* Walk the callgraph. For each crossed edge increase the loop depth by the edge */
/* weight. Assign graphs the maximal depth. */
/* ----------------------------------------------------------------------------------- */
static void compute_loop_depth(ir_graph *irg, void *env)
{
size_t current_nesting = *(size_t *) env;
size_t old_nesting = irg->callgraph_loop_depth;
ir_visited_t old_visited = get_cg_irg_visited(irg);
if (cg_irg_visited(irg)) return;
mark_cg_irg_visited(irg);
if (old_nesting < current_nesting)
irg->callgraph_loop_depth = current_nesting;
if (current_nesting > irp->max_callgraph_loop_depth)
irp->max_callgraph_loop_depth = current_nesting;
if ((old_visited +1 < get_cg_irg_visited(irg)) || /* not yet visited */
(old_nesting < current_nesting)) { /* propagate larger nesting */
size_t i, n_callees;
/* Don't walk the graph, but a tree that is an unfolded graph. */
n_callees = get_irg_n_callees(irg);
for (i = 0; i < n_callees; ++i) {
ir_graph *m = get_irg_callee(irg, i);
*(size_t *)env += get_irg_callee_loop_depth(irg, i);
compute_loop_depth(m, env);
*(size_t *)env -= get_irg_callee_loop_depth(irg, i);
}
}
set_cg_irg_visited(irg, master_cg_visited-1);
}
/* ------------------------------------------------------------------------------------ */
/* Another algorithm to compute recursion nesting depth */
/* Walk the callgraph. For each crossed loop increase the nesting depth by one. */
/* Assign graphs the maximal nesting depth. Don't increase if passing loops more than */
/* once. */
/* ------------------------------------------------------------------------------------ */
/* For callees, we want to remember the Call nodes, too. */
typedef struct ana_entry2 {
ir_loop **loop_stack; /**< a stack of ir_loop entries */
size_t tos; /**< the top of stack entry */
size_t recursion_nesting;
} ana_entry2;
/**
* push a loop entry on the stack
*/
static void push2(ana_entry2 *e, ir_loop *g)
{
if (ARR_LEN(e->loop_stack) == e->tos) {
ARR_APP1(ir_loop *, e->loop_stack, g);
} else {
e->loop_stack[e->tos] = g;
}
++e->tos;
}
/**
* returns the top of stack and pop it
*/
static ir_loop *pop2(ana_entry2 *e)
{
return e->loop_stack[--e->tos];
}
/**
* check if a loop g in on the stack. Did not check the TOS.
*/
static int in_stack(ana_entry2 *e, ir_loop *g)
{
size_t i;
for (i = e->tos; i != 0;) {
if (e->loop_stack[--i] == g) return 1;
}
return 0;
}
static void compute_rec_depth(ir_graph *irg, void *env)
{
ana_entry2 *e = (ana_entry2 *)env;
ir_loop *l = irg->l;
size_t depth, old_depth = irg->callgraph_recursion_depth;
int pushed = 0;
if (cg_irg_visited(irg))
return;
mark_cg_irg_visited(irg);
/* -- compute and set the new nesting value -- */
if ((l != irp->outermost_cg_loop) && !in_stack(e, l)) {
push2(e, l);
++e->recursion_nesting;
pushed = 1;
}
depth = e->recursion_nesting;
if (old_depth < depth)
irg->callgraph_recursion_depth = depth;
if (depth > irp->max_callgraph_recursion_depth)
irp->max_callgraph_recursion_depth = depth;
/* -- spread the nesting value -- */
if (depth == 0 || old_depth < depth) {
size_t i, n_callees;
/* Don't walk the graph, but a tree that is an unfolded graph.
Therefore we unset the visited flag at the end. */
n_callees = get_irg_n_callees(irg);
for (i = 0; i < n_callees; ++i) {
ir_graph *m = get_irg_callee(irg, i);
compute_rec_depth(m, env);
}
}
/* -- clean up -- */
if (pushed) {
pop2(e);
--e->recursion_nesting;
}
set_cg_irg_visited(irg, master_cg_visited-1);
}
/* ----------------------------------------------------------------------------------- */
/* 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. */
/* ----------------------------------------------------------------------------------- */
/* Returns the method execution frequency of a graph. */
double get_irg_method_execution_frequency(const ir_graph *irg)
{
return irg->method_execution_frequency;
}
/**
* Increase the method execution frequency to freq if its current value is
* smaller then this.
*/
static 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)
{
size_t i, n_callers;
double freq;
int found_edge;
size_t n_callees;
(void) env;
if (cg_irg_visited(irg))
return;
/* We need the values of all predecessors (except backedges).
So they must be marked. Else we will reach the node through
one of the unmarked ones. */
n_callers = get_irg_n_callers(irg);
for (i = 0; i < n_callers; ++i) {
ir_graph *m = get_irg_caller(irg, i);
if (is_irg_caller_backedge(irg, i))
continue;
if (!cg_irg_visited(m)) {
return;
}
}
mark_cg_irg_visited(irg);
/* 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_frequency(irg, i);
assert(edge_freq >= 0);
freq += edge_freq;
found_edge = 1;
}
}
if (!found_edge) {
/* A starting point: method only called from outside,
or only backedges as predecessors. */
freq = 1;
}
set_irg_method_execution_frequency(irg, freq);
/* recur */
n_callees = get_irg_n_callees(irg);
for (i = 0; i < n_callees; ++i) {
compute_method_execution_frequency(get_irg_callee(irg, i), NULL);
}
}
/* ----------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------------- */
/* The recursion stuff driver. */ /* The recursion stuff driver. */
/* ----------------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------------- */
...@@ -1201,80 +960,6 @@ void find_callgraph_recursions(void) ...@@ -1201,80 +960,6 @@ void find_callgraph_recursions(void)
irp->callgraph_state = irp_callgraph_and_calltree_consistent; irp->callgraph_state = irp_callgraph_and_calltree_consistent;
} }
/* Compute interprocedural performance estimates. */
void compute_performance_estimates(void)
{
size_t i, n_irgs = get_irp_n_irgs();
size_t current_nesting;
ana_entry2 e;
assert(get_irp_exec_freq_state() != exec_freq_none && "execution frequency not calculated");
/* -- compute the loop depth -- */
current_nesting = 0;
irp->max_callgraph_loop_depth = 0;
master_cg_visited += 2;
compute_loop_depth(get_irp_main_irg(), &current_nesting);
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
if ((get_cg_irg_visited(irg) < master_cg_visited-1) &&
get_irg_n_callers(irg) == 0) {
compute_loop_depth(irg, &current_nesting);
}
}
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
if (get_cg_irg_visited(irg) < master_cg_visited-1) {
compute_loop_depth(irg, &current_nesting);
}
}
/* -- compute the recursion depth -- */
e.loop_stack = NEW_ARR_F(ir_loop *, 0);
e.tos = 0;
e.recursion_nesting = 0;
irp->max_callgraph_recursion_depth = 0;
master_cg_visited += 2;
compute_rec_depth(get_irp_main_irg(), &e);
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
if ((get_cg_irg_visited(irg) < master_cg_visited-1) &&
get_irg_n_callers(irg) == 0) {
compute_rec_depth(irg, &e);
}
}
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
if (get_cg_irg_visited(irg) < master_cg_visited-1) {
compute_rec_depth(irg, &e);
}
}
DEL_ARR_F(e.loop_stack);
/* -- compute the execution frequency -- */
irp->max_method_execution_frequency = 0;
master_cg_visited += 2;
assert(get_irg_n_callers(get_irp_main_irg()) == 0);
compute_method_execution_frequency(get_irp_main_irg(), NULL);
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
if ((get_cg_irg_visited(irg) < master_cg_visited-1) &&
get_irg_n_callers(irg) == 0) {
compute_method_execution_frequency(irg, NULL);
}
}
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
if (get_cg_irg_visited(irg) < master_cg_visited-1) {
compute_method_execution_frequency(irg, NULL);
}
}
}
/* Returns the maximal loop depth of all paths from an external visible method to /* Returns the maximal loop depth of all paths from an external visible method to
this irg. */ this irg. */
size_t get_irg_loop_depth(const ir_graph *irg) size_t get_irg_loop_depth(const ir_graph *irg)
...@@ -1309,8 +994,6 @@ void analyse_loop_nesting_depth(void) ...@@ -1309,8 +994,6 @@ void analyse_loop_nesting_depth(void)
find_callgraph_recursions(); find_callgraph_recursions();
compute_performance_estimates();