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
484e5cf5
Commit
484e5cf5
authored
Jun 17, 2004
by
Götz Lindenmaier
Browse files
irscc: bugfix, can now deal with loops not reachable from start
cgana: bugfix, skip_Tuple rta: improved [r3133]
parent
4e530c4a
Changes
3
Show whitespace changes
Inline
Side-by-side
ir/ana/cgana.c
View file @
484e5cf5
...
@@ -49,9 +49,9 @@ static void * MARK = &MARK;
...
@@ -49,9 +49,9 @@ static void * MARK = &MARK;
static
eset
*
entities
=
NULL
;
static
eset
*
entities
=
NULL
;
/* Bestimmt die eindeutige Methode, die die Methode fr den
/*
*
Bestimmt die eindeutige Methode, die die Methode fr den
* bergebenen
e
(dynamischen) Typ berschreibt. */
* bergebenen (dynamischen) Typ berschreibt. */
entity
*
get_implementation
(
type
*
class
,
entity
*
method
)
{
static
entity
*
get_implementation
(
type
*
class
,
entity
*
method
)
{
int
i
;
int
i
;
if
(
get_entity_peculiarity
(
method
)
!=
peculiarity_description
&&
if
(
get_entity_peculiarity
(
method
)
!=
peculiarity_description
&&
get_entity_owner
(
method
)
==
class
)
{
get_entity_owner
(
method
)
==
class
)
{
...
@@ -73,9 +73,9 @@ entity * get_implementation(type * class, entity * method) {
...
@@ -73,9 +73,9 @@ entity * get_implementation(type * class, entity * method) {
return
NULL
;
return
NULL
;
}
}
/* Returns the entity that contains the implementation of the inherited
/*
*
Returns the entity that contains the implementation of the inherited
entity if available, else returns the entity passed. */
entity if available, else returns the entity passed. */
entity
*
get_inherited_methods_implementation
(
entity
*
inh_meth
)
{
static
entity
*
get_inherited_methods_implementation
(
entity
*
inh_meth
)
{
entity
*
impl_meth
=
NULL
;
entity
*
impl_meth
=
NULL
;
ir_node
*
addr
=
get_atomic_ent_value
(
inh_meth
);
ir_node
*
addr
=
get_atomic_ent_value
(
inh_meth
);
assert
(
addr
&&
"constant entity without value"
);
assert
(
addr
&&
"constant entity without value"
);
...
@@ -112,6 +112,7 @@ entity *get_inherited_methods_implementation(entity *inh_meth) {
...
@@ -112,6 +112,7 @@ entity *get_inherited_methods_implementation(entity *inh_meth) {
*/
*/
static
void
collect_impls
(
entity
*
method
,
eset
*
set
,
int
*
size
,
bool
*
open
)
{
static
void
collect_impls
(
entity
*
method
,
eset
*
set
,
int
*
size
,
bool
*
open
)
{
int
i
;
int
i
;
if
(
get_entity_peculiarity
(
method
)
==
peculiarity_existent
)
{
if
(
get_entity_peculiarity
(
method
)
==
peculiarity_existent
)
{
if
(
get_entity_visibility
(
method
)
==
visibility_external_allocated
)
{
if
(
get_entity_visibility
(
method
)
==
visibility_external_allocated
)
{
assert
(
get_entity_irg
(
method
)
==
NULL
);
assert
(
get_entity_irg
(
method
)
==
NULL
);
...
@@ -124,6 +125,7 @@ static void collect_impls(entity *method, eset *set, int *size, bool *open) {
...
@@ -124,6 +125,7 @@ static void collect_impls(entity *method, eset *set, int *size, bool *open) {
}
}
}
}
}
}
if
(
get_entity_peculiarity
(
method
)
==
peculiarity_inherited
)
{
if
(
get_entity_peculiarity
(
method
)
==
peculiarity_inherited
)
{
entity
*
impl_ent
=
get_inherited_methods_implementation
(
method
);
entity
*
impl_ent
=
get_inherited_methods_implementation
(
method
);
assert
(
impl_ent
&&
"no implementation for inherited entity"
);
assert
(
impl_ent
&&
"no implementation for inherited entity"
);
...
@@ -200,15 +202,29 @@ static entity ** get_impl_methods(entity * method) {
...
@@ -200,15 +202,29 @@ static entity ** get_impl_methods(entity * method) {
__dbg_info_merge_pair(new_node, node, dbg_rem_poly_call)
__dbg_info_merge_pair(new_node, node, dbg_rem_poly_call)
/** Analyse address computations.
*
* - If the node is a SymConst replace it by Const(ent) if possible.
* - If the node is a Sel:
* * If the pointer to the Sel comes directly from an Alloc node
* replace the Sel by a Const(ent).
*
*
* @param node The node to analyze
* @param ldname_map A map that mapps names of entities to the entities.
*/
static
void
sel_methods_walker
(
ir_node
*
node
,
pmap
*
ldname_map
)
{
static
void
sel_methods_walker
(
ir_node
*
node
,
pmap
*
ldname_map
)
{
if
(
get_irn_op
(
node
)
==
op_SymConst
)
{
if
(
get_irn_op
(
node
)
==
op_SymConst
)
{
/* Wenn mglich SymConst-Operation durch Const-Operation
/* Wenn mglich SymConst-Operation durch Const-Operation
* ersetzen. */
* ersetzen. */
if
(
get_SymConst_kind
(
node
)
==
linkage_ptr_info
)
{
if
(
get_SymConst_kind
(
node
)
==
linkage_ptr_info
)
{
pmap_entry
*
entry
=
pmap_find
(
ldname_map
,
(
void
*
)
get_SymConst_ptrinfo
(
node
));
pmap_entry
*
entry
=
pmap_find
(
ldname_map
,
(
void
*
)
get_SymConst_ptrinfo
(
node
));
if
(
entry
!=
NULL
)
{
/* Method is declared in the compiled code */
if
(
entry
!=
NULL
)
{
/* Method is declared in the compiled code */
entity
*
ent
=
entry
->
value
;
entity
*
ent
=
entry
->
value
;
if
(
get_opt_normalize
()
&&
(
get_entity_visibility
(
ent
)
!=
visibility_external_allocated
))
{
/* Meth. is defined */
if
(
get_opt_normalize
()
&&
(
get_entity_visibility
(
ent
)
!=
visibility_external_allocated
))
{
/* Meth. is defined */
ir_node
*
new_node
;
ir_node
*
new_node
;
assert
(
get_entity_irg
(
ent
));
assert
(
get_entity_irg
(
ent
));
set_irg_current_block
(
current_ir_graph
,
get_nodes_Block
(
node
));
set_irg_current_block
(
current_ir_graph
,
get_nodes_Block
(
node
));
...
@@ -300,12 +316,12 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
...
@@ -300,12 +316,12 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
}
}
/* Datenstruktur initialisieren. Zustzlich werden alle
/*
*
Datenstruktur initialisieren. Zustzlich werden alle
* SymConst-Operationen, die auf interne Methoden verweisen, durch
* SymConst-Operationen, die auf interne Methoden verweisen, durch
* Const-Operationen ersetzt. */
* Const-Operationen ersetzt. */
static
void
sel_methods_init
(
void
)
{
static
void
sel_methods_init
(
void
)
{
int
i
;
int
i
;
pmap
*
ldname_map
=
pmap_create
();
pmap
*
ldname_map
=
pmap_create
();
/* Map entitiy names to entities: to replace SymConst by Const(ent). */
assert
(
entities
==
NULL
);
assert
(
entities
==
NULL
);
entities
=
eset_create
();
entities
=
eset_create
();
for
(
i
=
get_irp_n_irgs
()
-
1
;
i
>=
0
;
--
i
)
{
for
(
i
=
get_irp_n_irgs
()
-
1
;
i
>=
0
;
--
i
)
{
...
...
ir/ana/irscc.c
View file @
484e5cf5
...
@@ -103,7 +103,7 @@ set_irn_uplink (ir_node *n, int uplink) {
...
@@ -103,7 +103,7 @@ set_irn_uplink (ir_node *n, int uplink) {
((
scc_info
*
)
n
->
link
)
->
uplink
=
uplink
;
((
scc_info
*
)
n
->
link
)
->
uplink
=
uplink
;
}
}
static
INLINE
int
INLINE
int
get_irn_uplink
(
ir_node
*
n
)
{
get_irn_uplink
(
ir_node
*
n
)
{
assert
(
get_irn_link
(
n
));
assert
(
get_irn_link
(
n
));
/* from fast to slow */
/* from fast to slow */
...
@@ -119,7 +119,7 @@ set_irn_dfn (ir_node *n, int dfn) {
...
@@ -119,7 +119,7 @@ set_irn_dfn (ir_node *n, int dfn) {
((
scc_info
*
)
n
->
link
)
->
dfn
=
dfn
;
((
scc_info
*
)
n
->
link
)
->
dfn
=
dfn
;
}
}
static
INLINE
int
INLINE
int
get_irn_dfn
(
ir_node
*
n
)
{
get_irn_dfn
(
ir_node
*
n
)
{
assert
(
get_irn_link
(
n
));
assert
(
get_irn_link
(
n
));
/* to slow */
/* to slow */
...
@@ -247,6 +247,9 @@ pop_scc_to_loop (ir_node *n)
...
@@ -247,6 +247,9 @@ pop_scc_to_loop (ir_node *n)
do
do
{
{
m
=
pop
();
m
=
pop
();
//printf(" dfn: %d, upl %d upl-new %d ", get_irn_dfn(m), get_irn_uplink(m), loop_node_cnt+1); DDMN(m);
loop_node_cnt
++
;
loop_node_cnt
++
;
set_irn_dfn
(
m
,
loop_node_cnt
);
set_irn_dfn
(
m
,
loop_node_cnt
);
add_loop_node
(
current_loop
,
m
);
add_loop_node
(
current_loop
,
m
);
...
@@ -635,72 +638,6 @@ get_start_index(ir_node *n) {
...
@@ -635,72 +638,6 @@ get_start_index(ir_node *n) {
}
}
#if 0
/* Returns current_ir_graph and set it to the irg of predecessor index
of node n. */
static INLINE ir_graph *
switch_irg (ir_node *n, int index) {
ir_graph *old_current = current_ir_graph;
if (interprocedural_view) {
/* Only Filter and Block nodes can have predecessors in other graphs. */
if (get_irn_op(n) == op_Filter)
n = get_nodes_Block(n);
if (get_irn_op(n) == op_Block) {
ir_node *cfop = skip_Proj(get_Block_cfgpred(n, index));
if (is_ip_cfop(cfop)) {
current_ir_graph = get_irn_irg(cfop);
set_irg_visited(current_ir_graph, get_max_irg_visited());
}
}
}
return old_current;
}
/* Walks up the stack passing n and then finding the node
where we walked into the irg n is contained in.
Here we switch the irg. */
static ir_graph *
find_irg_on_stack (ir_node *n) {
ir_node *m;
ir_graph *old_current = current_ir_graph;
int i;
if (interprocedural_view) {
for (i = tos; i >= 0; i--) {
if (stack[i] == n) break;
}
if (i < 0) i = tos;
assert (i >= 0);
for (; i >= 0; i--) {
m = stack[i];
/*printf(" Visiting %d ", i); DDMN(m);*/
if (is_ip_cfop(m)) {
current_ir_graph = get_irn_irg(m);
break;
}
if (get_irn_op(m) == op_Filter) {
/* Find the corresponding ip_cfop */
ir_node *pred = stack[i+1];
int j;
for (j = 0; j < get_Filter_n_cg_preds(m); j++)
if (get_Filter_cg_pred(m, j) == pred) break;
if (j >= get_Filter_n_cg_preds(m))
/* It is a filter we didn't pass as the predecessors are marked. */
continue;
assert(get_Filter_cg_pred(m, j) == pred);
switch_irg(m, j);
break;
}
}
}
return old_current;
}
#endif
#if 0
#if 0
static void test(ir_node *pred, ir_node *root, ir_node *this) {
static void test(ir_node *pred, ir_node *root, ir_node *this) {
int i;
int i;
...
@@ -751,11 +688,10 @@ is_head (ir_node *n, ir_node *root)
...
@@ -751,11 +688,10 @@ is_head (ir_node *n, ir_node *root)
if
(
!
irn_is_in_stack
(
pred
))
{
if
(
!
irn_is_in_stack
(
pred
))
{
some_outof_loop
=
1
;
some_outof_loop
=
1
;
}
else
{
}
else
{
if
(
get_irn_uplink
(
pred
)
<
get_irn_uplink
(
root
))
if
(
get_irn_uplink
(
pred
)
<
get_irn_uplink
(
root
))
{
{
DDMN
(
n
);
DDMN
(
pred
);
DDMN
(
root
);
DDMN
(
pred
);
DDMN
(
root
);
}
assert
(
get_irn_uplink
(
pred
)
>=
get_irn_uplink
(
root
));
assert
(
get_irn_uplink
(
pred
)
>=
get_irn_uplink
(
root
));
}
some_in_loop
=
1
;
some_in_loop
=
1
;
}
}
}
}
...
@@ -763,6 +699,40 @@ is_head (ir_node *n, ir_node *root)
...
@@ -763,6 +699,40 @@ is_head (ir_node *n, ir_node *root)
return
some_outof_loop
&&
some_in_loop
;
return
some_outof_loop
&&
some_in_loop
;
}
}
/* Returns true 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
is_endless_head
(
ir_node
*
n
,
ir_node
*
root
)
{
int
i
,
arity
;
int
some_outof_loop
=
0
,
some_in_loop
=
0
;
/* Test for legal loop header: Block, Phi, ... */
if
(
!
is_possible_loop_head
(
n
))
return
false
;
if
(
!
is_outermost_Start
(
n
))
{
arity
=
get_irn_arity
(
n
);
for
(
i
=
get_start_index
(
n
);
i
<
arity
;
i
++
)
{
ir_node
*
pred
=
get_irn_n
(
n
,
i
);
assert
(
pred
);
if
(
is_backedge
(
n
,
i
))
{
continue
;
}
if
(
!
irn_is_in_stack
(
pred
))
{
some_outof_loop
=
1
;
//printf(" some out of loop ");
}
else
{
if
(
get_irn_uplink
(
pred
)
<
get_irn_uplink
(
root
))
{
DDMN
(
pred
);
DDMN
(
root
);
assert
(
get_irn_uplink
(
pred
)
>=
get_irn_uplink
(
root
));
}
some_in_loop
=
1
;
}
}
}
return
!
some_outof_loop
&&
some_in_loop
;
}
/* Returns index of the predecessor with the smallest dfn number
/* Returns index of the predecessor with the smallest dfn number
greater-equal than limit. */
greater-equal than limit. */
static
int
static
int
...
@@ -805,11 +775,14 @@ largest_dfn_pred (ir_node *n)
...
@@ -805,11 +775,14 @@ largest_dfn_pred (ir_node *n)
return
index
;
return
index
;
}
}
/* Searches the stack for possible loop heads. Tests these for backedges.
/*
*
Searches the stack for possible loop heads. Tests these for backedges.
If it finds a head with an unmarked backedge it marks this edge and
If it finds a head with an unmarked backedge it marks this edge and
returns the tail of the loop.
returns the tail of the loop.
If it finds no backedge returns NULL.
If it finds no backedge returns NULL.
("disable_backedge" in fiasco) */
("disable_backedge" in fiasco)
*
* @param n A node where uplink == dfn.
**/
static
ir_node
*
static
ir_node
*
find_tail
(
ir_node
*
n
)
{
find_tail
(
ir_node
*
n
)
{
...
@@ -819,7 +792,6 @@ find_tail (ir_node *n) {
...
@@ -819,7 +792,6 @@ find_tail (ir_node *n) {
/*
/*
if (!icfg && rm_cyclic_phis && remove_cyclic_phis (n)) return NULL;
if (!icfg && rm_cyclic_phis && remove_cyclic_phis (n)) return NULL;
*/
*/
m
=
stack
[
tos
-
1
];
/* tos = top of stack */
m
=
stack
[
tos
-
1
];
/* tos = top of stack */
if
(
is_head
(
m
,
n
))
{
if
(
is_head
(
m
,
n
))
{
res_index
=
smallest_dfn_pred
(
m
,
0
);
res_index
=
smallest_dfn_pred
(
m
,
0
);
...
@@ -827,16 +799,45 @@ find_tail (ir_node *n) {
...
@@ -827,16 +799,45 @@ find_tail (ir_node *n) {
(
n
==
m
))
(
n
==
m
))
return
NULL
;
return
NULL
;
}
else
{
}
else
{
if
(
m
==
n
)
return
NULL
;
if
(
m
==
n
)
return
NULL
;
// Is this to catch Phi - self loops?
for
(
i
=
tos
-
2
;
;
--
i
)
{
for
(
i
=
tos
-
2
;
i
>=
0
;
--
i
)
{
m
=
stack
[
i
];
m
=
stack
[
i
];
if
(
is_head
(
m
,
n
))
{
if
(
is_head
(
m
,
n
))
{
res_index
=
smallest_dfn_pred
(
m
,
get_irn_dfn
(
m
)
+
1
);
if
(
res_index
==
-
2
)
/* no smallest dfn pred found. */
res_index
=
largest_dfn_pred
(
m
);
if
((
m
==
n
)
&&
(
res_index
==
-
2
))
{
i
=
-
1
;
}
break
;
}
/* We should not walk past our selves on the stack: The upcoming nodes
are not in this loop. We assume a loop not reachable from Start. */
if
(
m
==
n
)
{
i
=
-
1
;
break
;
}
}
if
(
i
<
0
)
{
/* A dead loop not reachable from Start. */
for
(
i
=
tos
-
2
;
i
>=
0
;
--
i
)
{
m
=
stack
[
i
];
if
(
is_endless_head
(
m
,
n
))
{
res_index
=
smallest_dfn_pred
(
m
,
get_irn_dfn
(
m
)
+
1
);
res_index
=
smallest_dfn_pred
(
m
,
get_irn_dfn
(
m
)
+
1
);
if
(
res_index
==
-
2
)
/* no smallest dfn pred found. */
if
(
res_index
==
-
2
)
/* no smallest dfn pred found. */
res_index
=
largest_dfn_pred
(
m
);
res_index
=
largest_dfn_pred
(
m
);
break
;
break
;
}
}
if
(
m
==
n
)
{
break
;
}
/* It's not an unreachable loop, either. */
}
}
//assert(0 && "no head found on stack");
}
}
}
assert
(
res_index
>
-
2
);
assert
(
res_index
>
-
2
);
...
@@ -986,7 +987,6 @@ static void scc (ir_node *n) {
...
@@ -986,7 +987,6 @@ static void scc (ir_node *n) {
for
(
i
=
get_start_index
(
n
);
i
<
arity
;
i
++
)
{
for
(
i
=
get_start_index
(
n
);
i
<
arity
;
i
++
)
{
ir_node
*
m
;
ir_node
*
m
;
if
(
is_backedge
(
n
,
i
))
continue
;
if
(
is_backedge
(
n
,
i
))
continue
;
/* printf("i: %d\n", i); */
m
=
get_irn_n
(
n
,
i
);
/* get_irn_ip_pred(n, i); */
m
=
get_irn_n
(
n
,
i
);
/* get_irn_ip_pred(n, i); */
/* if ((!m) || (get_irn_op(m) == op_Unknown)) continue; */
/* if ((!m) || (get_irn_op(m) == op_Unknown)) continue; */
scc
(
m
);
scc
(
m
);
...
...
ir/ana/rta.c
View file @
484e5cf5
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
*/
*/
/**
/**
* Intraprozedurale Analyse zur Abschtzung der Aufrufrelation. Es
nn
* Intraprozedurale Analyse zur Abschtzung der Aufrufrelation. Es
* die Menge der instantiierten Klassen bestimmt, und daraus existierende Methoden
* die Menge der instantiierten Klassen bestimmt, und daraus existierende Methoden
* bestimmt.
* bestimmt.
*/
*/
...
@@ -87,7 +87,10 @@ static void rta_act (ir_node *node, void *env)
...
@@ -87,7 +87,10 @@ static void rta_act (ir_node *node, void *env)
ent
=
get_tarval_entity
(
get_Const_tarval
(
ptr
));
ent
=
get_tarval_entity
(
get_Const_tarval
(
ptr
));
}
else
if
(
iro_SymConst
==
get_irn_opcode
(
ptr
))
{
/* CALL SYMCONST */
}
else
if
(
iro_SymConst
==
get_irn_opcode
(
ptr
))
{
/* CALL SYMCONST */
assert
(
ent
&&
"couldn't determine entity of call to symConst"
);
/* If this SymConst refers to a method the method is external_visible
and therefore must be considered executed anyways. */
//dump_ir_block_graph(get_irn_irg(ptr));
//assert (ent && "couldn't determine entity of call to symConst");
}
}
if
(
ent
)
{
if
(
ent
)
{
...
@@ -285,7 +288,13 @@ static int has_live_call (entity *method, ir_graph *graph)
...
@@ -285,7 +288,13 @@ static int has_live_call (entity *method, ir_graph *graph)
int
i
,
n_over
;
int
i
,
n_over
;
/* stop searching if a overwriting method comes with a new graph */
/* stop searching if a overwriting method comes with a new graph */
if
(
get_irg_ent
(
graph
)
!=
method
)
{
/* shouldn't we compare GRAPHS here????? */
/* if (get_irg_ent (graph) != method) *
{ /* shouldn't we compare GRAPHS here????? *
return (FALSE);
}
*/
if
(
graph
!=
get_entity_irg
(
method
))
{
return
(
FALSE
);
return
(
FALSE
);
}
}
...
@@ -442,6 +451,8 @@ static void remove_irg (ir_graph *graph)
...
@@ -442,6 +451,8 @@ static void remove_irg (ir_graph *graph)
{
{
entity
*
ent
=
get_irg_entity
(
graph
);
entity
*
ent
=
get_irg_entity
(
graph
);
//DDMEO(get_irg_ent(graph));
/* delete the ir_graph data */
/* delete the ir_graph data */
remove_irp_irg
(
graph
);
remove_irp_irg
(
graph
);
/* remove reference to the graph */
/* remove reference to the graph */
...
@@ -534,7 +545,14 @@ void rta_delete_dead_graphs ()
...
@@ -534,7 +545,14 @@ void rta_delete_dead_graphs ()
eset_insert
(
dead_graphs
,
graph
);
eset_insert
(
dead_graphs
,
graph
);
}
}
}
}
/*
for (i = 0; i < get_irp_n_types(); ++i) {
type *tp = get_irp_type(i);
if (is_class_type(tp) && !rta_is_alive_class(tp)) {
printf(" never allocated: "); DDMT(tp);
}
}
*/
/* now delete the graphs. */
/* now delete the graphs. */
for
(
graph
=
eset_first
(
dead_graphs
);
for
(
graph
=
eset_first
(
dead_graphs
);
graph
;
graph
;
...
@@ -620,6 +638,11 @@ int rta_is_alive_field (entity *field)
...
@@ -620,6 +638,11 @@ int rta_is_alive_field (entity *field)
/*
/*
* $Log$
* $Log$
* Revision 1.10 2004/06/17 10:31:41 goetz
* irscc: bugfix, can now deal with loops not reachable from start
* cgana: bugfix, skip_Tuple
* rta: improved
*
* Revision 1.9 2004/06/17 08:56:03 liekweg
* Revision 1.9 2004/06/17 08:56:03 liekweg
* Fixed typos in comments
* Fixed typos in comments
*
*
...
...
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