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;
static
eset
*
entities
=
NULL
;
/* Bestimmt die eindeutige Methode, die die Methode fr den
* bergebenen
e
(dynamischen) Typ berschreibt. */
entity
*
get_implementation
(
type
*
class
,
entity
*
method
)
{
/*
*
Bestimmt die eindeutige Methode, die die Methode fr den
* bergebenen (dynamischen) Typ berschreibt. */
static
entity
*
get_implementation
(
type
*
class
,
entity
*
method
)
{
int
i
;
if
(
get_entity_peculiarity
(
method
)
!=
peculiarity_description
&&
get_entity_owner
(
method
)
==
class
)
{
...
...
@@ -73,9 +73,9 @@ entity * get_implementation(type * class, entity * method) {
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
*
get_inherited_methods_implementation
(
entity
*
inh_meth
)
{
static
entity
*
get_inherited_methods_implementation
(
entity
*
inh_meth
)
{
entity
*
impl_meth
=
NULL
;
ir_node
*
addr
=
get_atomic_ent_value
(
inh_meth
);
assert
(
addr
&&
"constant entity without value"
);
...
...
@@ -112,6 +112,7 @@ entity *get_inherited_methods_implementation(entity *inh_meth) {
*/
static
void
collect_impls
(
entity
*
method
,
eset
*
set
,
int
*
size
,
bool
*
open
)
{
int
i
;
if
(
get_entity_peculiarity
(
method
)
==
peculiarity_existent
)
{
if
(
get_entity_visibility
(
method
)
==
visibility_external_allocated
)
{
assert
(
get_entity_irg
(
method
)
==
NULL
);
...
...
@@ -124,6 +125,7 @@ static void collect_impls(entity *method, eset *set, int *size, bool *open) {
}
}
}
if
(
get_entity_peculiarity
(
method
)
==
peculiarity_inherited
)
{
entity
*
impl_ent
=
get_inherited_methods_implementation
(
method
);
assert
(
impl_ent
&&
"no implementation for inherited entity"
);
...
...
@@ -200,15 +202,29 @@ static entity ** get_impl_methods(entity * method) {
__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
)
{
if
(
get_irn_op
(
node
)
==
op_SymConst
)
{
/* Wenn mglich SymConst-Operation durch Const-Operation
* ersetzen. */
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 */
entity
*
ent
=
entry
->
value
;
if
(
get_opt_normalize
()
&&
(
get_entity_visibility
(
ent
)
!=
visibility_external_allocated
))
{
/* Meth. is defined */
entity
*
ent
=
entry
->
value
;
if
(
get_opt_normalize
()
&&
(
get_entity_visibility
(
ent
)
!=
visibility_external_allocated
))
{
/* Meth. is defined */
ir_node
*
new_node
;
assert
(
get_entity_irg
(
ent
));
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) {
}
/* Datenstruktur initialisieren. Zustzlich werden alle
/*
*
Datenstruktur initialisieren. Zustzlich werden alle
* SymConst-Operationen, die auf interne Methoden verweisen, durch
* Const-Operationen ersetzt. */
static
void
sel_methods_init
(
void
)
{
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
);
entities
=
eset_create
();
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) {
((
scc_info
*
)
n
->
link
)
->
uplink
=
uplink
;
}
static
INLINE
int
INLINE
int
get_irn_uplink
(
ir_node
*
n
)
{
assert
(
get_irn_link
(
n
));
/* from fast to slow */
...
...
@@ -119,7 +119,7 @@ set_irn_dfn (ir_node *n, int dfn) {
((
scc_info
*
)
n
->
link
)
->
dfn
=
dfn
;
}
static
INLINE
int
INLINE
int
get_irn_dfn
(
ir_node
*
n
)
{
assert
(
get_irn_link
(
n
));
/* to slow */
...
...
@@ -247,6 +247,9 @@ pop_scc_to_loop (ir_node *n)
do
{
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
++
;
set_irn_dfn
(
m
,
loop_node_cnt
);
add_loop_node
(
current_loop
,
m
);
...
...
@@ -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
static void test(ir_node *pred, ir_node *root, ir_node *this) {
int i;
...
...
@@ -751,11 +688,10 @@ is_head (ir_node *n, ir_node *root)
if
(
!
irn_is_in_stack
(
pred
))
{
some_outof_loop
=
1
;
}
else
{
if
(
get_irn_uplink
(
pred
)
<
get_irn_uplink
(
root
))
{
DDMN
(
pred
);
DDMN
(
root
);
}
if
(
get_irn_uplink
(
pred
)
<
get_irn_uplink
(
root
))
{
DDMN
(
n
);
DDMN
(
pred
);
DDMN
(
root
);
assert
(
get_irn_uplink
(
pred
)
>=
get_irn_uplink
(
root
));
}
some_in_loop
=
1
;
}
}
...
...
@@ -763,6 +699,40 @@ is_head (ir_node *n, ir_node *root)
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
greater-equal than limit. */
static
int
...
...
@@ -805,11 +775,14 @@ largest_dfn_pred (ir_node *n)
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
returns the tail of the loop.
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
*
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;
*/
m
=
stack
[
tos
-
1
];
/* tos = top of stack */
if
(
is_head
(
m
,
n
))
{
res_index
=
smallest_dfn_pred
(
m
,
0
);
...
...
@@ -827,16 +799,45 @@ find_tail (ir_node *n) {
(
n
==
m
))
return
NULL
;
}
else
{
if
(
m
==
n
)
return
NULL
;
for
(
i
=
tos
-
2
;
;
--
i
)
{
if
(
m
==
n
)
return
NULL
;
// Is this to catch Phi - self loops?
for
(
i
=
tos
-
2
;
i
>=
0
;
--
i
)
{
m
=
stack
[
i
];
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
);
if
(
res_index
==
-
2
)
/* no smallest dfn pred found. */
res_index
=
largest_dfn_pred
(
m
);
break
;
}
if
(
m
==
n
)
{
break
;
}
/* It's not an unreachable loop, either. */
}
//assert(0 && "no head found on stack");
}
}
assert
(
res_index
>
-
2
);
...
...
@@ -986,7 +987,6 @@ static void scc (ir_node *n) {
for
(
i
=
get_start_index
(
n
);
i
<
arity
;
i
++
)
{
ir_node
*
m
;
if
(
is_backedge
(
n
,
i
))
continue
;
/* printf("i: %d\n", i); */
m
=
get_irn_n
(
n
,
i
);
/* get_irn_ip_pred(n, i); */
/* if ((!m) || (get_irn_op(m) == op_Unknown)) continue; */
scc
(
m
);
...
...
ir/ana/rta.c
View file @
484e5cf5
...
...
@@ -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
* bestimmt.
*/
...
...
@@ -87,7 +87,10 @@ static void rta_act (ir_node *node, void *env)
ent
=
get_tarval_entity
(
get_Const_tarval
(
ptr
));
}
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
)
{
...
...
@@ -285,7 +288,13 @@ static int has_live_call (entity *method, ir_graph *graph)
int
i
,
n_over
;
/* 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
);
}
...
...
@@ -442,6 +451,8 @@ static void remove_irg (ir_graph *graph)
{
entity
*
ent
=
get_irg_entity
(
graph
);
//DDMEO(get_irg_ent(graph));
/* delete the ir_graph data */
remove_irp_irg
(
graph
);
/* remove reference to the graph */
...
...
@@ -534,7 +545,14 @@ void rta_delete_dead_graphs ()
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. */
for
(
graph
=
eset_first
(
dead_graphs
);
graph
;
...
...
@@ -620,6 +638,11 @@ int rta_is_alive_field (entity *field)
/*
* $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
* 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