Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
599f2d24
Commit
599f2d24
authored
Sep 22, 2008
by
Matthias Braun
Browse files
toposort callgraph when inlining
[r22177]
parent
6df2132c
Changes
4
Show whitespace changes
Inline
Side-by-side
include/libfirm/callgraph.h
View file @
599f2d24
...
...
@@ -126,7 +126,8 @@ typedef void callgraph_walk_func(ir_graph *g, void *env);
* @param post - walker function, executed after the predecessor of a node are visited
* @param env - environment, passed to pre and post
*/
void
callgraph_walk
(
callgraph_walk_func
*
pre
,
callgraph_walk_func
*
post
,
void
*
env
);
void
callgraph_walk
(
ir_entity
**
roots
,
unsigned
n_roots
,
callgraph_walk_func
*
pre
,
callgraph_walk_func
*
post
,
void
*
env
);
/**
* Compute the backedges that represent recursions and a looptree.
...
...
ir/ana/callgraph.c
View file @
599f2d24
...
...
@@ -52,10 +52,10 @@
#include
"irgwalk.h"
static
int
master_cg_visited
=
0
;
static
unsigned
long
master_cg_visited
=
0
;
static
INLINE
int
cg_irg_visited
(
ir_graph
*
n
);
static
INLINE
void
mark_cg_irg_visited
(
ir_graph
*
n
);
static
INLINE
void
set_cg_irg_visited
(
ir_graph
*
n
,
int
i
);
static
INLINE
void
set_cg_irg_visited
(
ir_graph
*
n
,
unsigned
long
i
);
/** Returns the callgraph state of the program representation. */
irp_callgraph_state
get_irp_callgraph_state
(
void
)
{
...
...
@@ -386,11 +386,21 @@ static void do_walk(ir_graph *irg, callgraph_walk_func *pre, callgraph_walk_func
post
(
irg
,
env
);
}
void
callgraph_walk
(
callgraph_walk_func
*
pre
,
callgraph_walk_func
*
post
,
void
*
env
)
{
int
i
,
n_irgs
=
get_irp_n_irgs
();
void
callgraph_walk
(
ir_entity
**
roots
,
unsigned
n_roots
,
callgraph_walk_func
*
pre
,
callgraph_walk_func
*
post
,
void
*
env
)
{
//int i, n_irgs = get_irp_n_irgs();
unsigned
r
;
++
master_cg_visited
;
do_walk
(
get_irp_main_irg
(),
pre
,
post
,
env
);
for
(
r
=
0
;
r
<
n_roots
;
++
r
)
{
ir_graph
*
irg
=
get_entity_irg
(
roots
[
r
]);
if
(
irg
==
NULL
)
continue
;
do_walk
(
irg
,
pre
,
post
,
env
);
}
#if 0
for (i = 0; i < n_irgs; i++) {
ir_graph *irg = get_irp_irg(i);
if (!cg_irg_visited(irg) && get_irg_n_callers(irg) == 0)
...
...
@@ -401,6 +411,7 @@ void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *e
if (!cg_irg_visited(irg))
do_walk(irg, pre, post, env);
}
#endif
}
/* ----------------------------------------------------------------------------------- */
...
...
@@ -441,36 +452,28 @@ static INLINE scc_info *new_scc_info(struct obstack *obst) {
* Returns non-zero if a graph was already visited.
*/
static
INLINE
int
cg_irg_visited
(
ir_graph
*
irg
)
{
scc_info
*
info
=
get_irg_link
(
irg
);
assert
(
info
&&
"missing call to init_scc()"
);
return
info
->
visited
>=
master_cg_visited
;
return
irg
->
self_visited
>=
master_cg_visited
;
}
/**
* Marks a graph as visited.
*/
static
INLINE
void
mark_cg_irg_visited
(
ir_graph
*
irg
)
{
scc_info
*
info
=
get_irg_link
(
irg
);
assert
(
info
&&
"missing call to init_scc()"
);
info
->
visited
=
master_cg_visited
;
irg
->
self_visited
=
master_cg_visited
;
}
/**
* Set a graphs visited flag to i.
*/
static
INLINE
void
set_cg_irg_visited
(
ir_graph
*
irg
,
int
i
)
{
scc_info
*
info
=
get_irg_link
(
irg
);
assert
(
info
&&
"missing call to init_scc()"
);
info
->
visited
=
i
;
static
INLINE
void
set_cg_irg_visited
(
ir_graph
*
irg
,
unsigned
long
i
)
{
irg
->
self_visited
=
i
;
}
/**
* Returns the visited flag of a graph.
*/
static
INLINE
int
get_cg_irg_visited
(
ir_graph
*
irg
)
{
scc_info
*
info
=
get_irg_link
(
irg
);
assert
(
info
&&
"missing call to init_scc()"
);
return
info
->
visited
;
static
INLINE
unsigned
long
get_cg_irg_visited
(
ir_graph
*
irg
)
{
return
irg
->
self_visited
;
}
static
INLINE
void
mark_irg_in_stack
(
ir_graph
*
irg
)
{
...
...
@@ -1015,7 +1018,7 @@ static void reset_isbe(void) {
static
void
compute_loop_depth
(
ir_graph
*
irg
,
void
*
env
)
{
int
current_nesting
=
*
(
int
*
)
env
;
int
old_nesting
=
irg
->
callgraph_loop_depth
;
int
old_visited
=
get_cg_irg_visited
(
irg
);
unsigned
long
old_visited
=
get_cg_irg_visited
(
irg
);
int
i
,
n_callees
;
//return ;
...
...
ir/ir/irtypes.h
View file @
599f2d24
...
...
@@ -496,6 +496,8 @@ struct ir_graph {
the graph */
unsigned
long
block_visited
;
/**< same as visited, for a complete block */
unsigned
long
self_visited
;
/**< visited flag of the irg */
unsigned
estimated_node_count
;
/**< estimated number of nodes in this graph,
updated after every walk */
irg_edges_info_t
edge_info
;
/**< edge info for automatic outs */
...
...
ir/opt/opt_inline.c
View file @
599f2d24
...
...
@@ -2007,6 +2007,35 @@ static int calc_inline_benefice(ir_node *call, ir_graph *callee, unsigned *local
return
weight
;
}
static
ir_graph
**
irgs
;
static
int
last_irg
;
static
void
callgraph_walker
(
ir_graph
*
irg
,
void
*
data
)
{
(
void
)
data
;
irgs
[
last_irg
++
]
=
irg
;
}
static
ir_graph
**
create_irg_list
(
void
)
{
ir_entity
**
roots
;
int
arr_len
;
int
n_irgs
=
get_irp_n_irgs
();
cgana
(
&
arr_len
,
&
roots
);
compute_callgraph
();
last_irg
=
0
;
irgs
=
xmalloc
(
n_irgs
*
sizeof
(
*
irgs
));
memset
(
irgs
,
0
,
sizeof
(
n_irgs
*
sizeof
(
*
irgs
)));
callgraph_walk
(
roots
,
arr_len
,
NULL
,
callgraph_walker
,
NULL
);
xfree
(
roots
);
assert
(
n_irgs
==
last_irg
);
return
irgs
;
}
/**
* Heuristic inliner. Calculates a benefice value for every call and inlines
* those calls with a value higher than the threshold.
...
...
@@ -2021,23 +2050,26 @@ void inline_functions(int maxsize, int inline_threshold) {
const
call_entry
*
centry
;
pmap
*
copied_graphs
;
pmap_entry
*
pm_entry
;
ir_graph
**
irgs
;
rem
=
current_ir_graph
;
obstack_init
(
&
temp_obst
);
irgs
=
create_irg_list
();
/* a map for the copied graphs, used to inline recursive calls */
copied_graphs
=
pmap_create
();
/* extend all irgs by a temporary data structure for inlining. */
n_irgs
=
get_irp_n_irgs
();
for
(
i
=
0
;
i
<
n_irgs
;
++
i
)
set_irg_link
(
get_irp_irg
(
i
)
,
alloc_inline_irg_env
());
set_irg_link
(
irgs
[
i
]
,
alloc_inline_irg_env
());
/* Precompute information in temporary data structure. */
wenv
.
ignore_runtime
=
0
;
wenv
.
ignore_callers
=
0
;
for
(
i
=
0
;
i
<
n_irgs
;
++
i
)
{
ir_graph
*
irg
=
get_irp_irg
(
i
)
;
ir_graph
*
irg
=
irgs
[
i
]
;
assert
(
get_irg_phase_state
(
irg
)
!=
phase_building
);
free_callee_info
(
irg
);
...
...
@@ -2052,7 +2084,7 @@ void inline_functions(int maxsize, int inline_threshold) {
for
(
i
=
0
;
i
<
n_irgs
;
++
i
)
{
int
phiproj_computed
=
0
;
ir_node
*
call
;
ir_graph
*
irg
=
get_irp_irg
(
i
)
;
ir_graph
*
irg
=
irgs
[
i
]
;
current_ir_graph
=
irg
;
env
=
get_irg_link
(
irg
);
...
...
@@ -2169,7 +2201,7 @@ void inline_functions(int maxsize, int inline_threshold) {
}
for
(
i
=
0
;
i
<
n_irgs
;
++
i
)
{
ir_graph
*
irg
=
get_irp_irg
(
i
)
;
ir_graph
*
irg
=
irgs
[
i
]
;
env
=
get_irg_link
(
irg
);
if
(
env
->
got_inline
)
{
...
...
@@ -2203,6 +2235,8 @@ void inline_functions(int maxsize, int inline_threshold) {
}
pmap_destroy
(
copied_graphs
);
xfree
(
irgs
);
obstack_free
(
&
temp_obst
,
NULL
);
current_ir_graph
=
rem
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment