Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
efa44a3c
Commit
efa44a3c
authored
Sep 22, 2011
by
Matthias Braun
Browse files
remove old+unused execution_frequency/field_temperature
parent
5c6f5d46
Changes
12
Hide whitespace changes
Inline
Side-by-side
include/libfirm/callgraph.h
View file @
efa44a3c
...
...
@@ -135,23 +135,6 @@ FIRM_API void callgraph_walk(callgraph_walk_func *pre,
*/
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 two numbers for each irg: the depth it is called in 'normal'
...
...
include/libfirm/execution_frequency.h
deleted
100644 → 0
View file @
5c6f5d46
/*
* 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
include/libfirm/field_temperature.h
deleted
100644 → 0
View file @
5c6f5d46
/*
* 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
include/libfirm/firm.h
View file @
efa44a3c
...
...
@@ -66,8 +66,6 @@
#include
"cgana.h"
#include
"dbginfo.h"
#include
"execfreq.h"
#include
"execution_frequency.h"
#include
"field_temperature.h"
#include
"firm_common.h"
#include
"firmstat.h"
#include
"firm_types.h"
...
...
ir/ana/callgraph.c
View file @
efa44a3c
...
...
@@ -37,7 +37,6 @@
#include
"irnode_t.h"
#include
"cgana.h"
#include
"execution_frequency.h"
#include
"array.h"
#include
"pmap.h"
...
...
@@ -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
;
}
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 ------------------------ */
...
...
@@ -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. */
/* ----------------------------------------------------------------------------------- */
...
...
@@ -1201,80 +960,6 @@ void find_callgraph_recursions(void)
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
this irg. */
size_t
get_irg_loop_depth
(
const
ir_graph
*
irg
)
...
...
@@ -1309,8 +994,6 @@ void analyse_loop_nesting_depth(void)
find_callgraph_recursions
();
compute_performance_estimates
();
set_irp_loop_nesting_depth_state
(
loop_nesting_depth_consistent
);
}
...
...
ir/ana/execution_frequency.c
deleted
100644 → 0
View file @
5c6f5d46
/*
* 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.
*/