Commit 99c702d3 authored by Florian Liekweg's avatar Florian Liekweg
Browse files

Kommentare eingef"ugt --flo

[r3065]
parent e7eac363
...@@ -110,8 +110,8 @@ void collect_impls(entity *method, eset *set, int *size, bool *open) { ...@@ -110,8 +110,8 @@ void collect_impls(entity *method, eset *set, int *size, bool *open) {
} else { } else {
assert(get_entity_irg(method) != NULL); assert(get_entity_irg(method) != NULL);
if (!eset_contains(set, method)) { if (!eset_contains(set, method)) {
eset_insert(set, method); eset_insert(set, method);
++(*size); ++(*size);
} }
} }
} }
...@@ -124,8 +124,8 @@ void collect_impls(entity *method, eset *set, int *size, bool *open) { ...@@ -124,8 +124,8 @@ void collect_impls(entity *method, eset *set, int *size, bool *open) {
} else { } else {
assert(get_entity_irg(impl_ent) != NULL); assert(get_entity_irg(impl_ent) != NULL);
if (!eset_contains(set, impl_ent)) { if (!eset_contains(set, impl_ent)) {
eset_insert(set, impl_ent); eset_insert(set, impl_ent);
++(*size); ++(*size);
} }
} }
} }
...@@ -196,22 +196,22 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) { ...@@ -196,22 +196,22 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
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));
new_node = new_d_Const(get_irn_dbg_info(node), new_node = new_d_Const(get_irn_dbg_info(node),
mode_P_mach, new_tarval_from_entity(ent, mode_P_mach)); DBG_OPT_NORMALIZE; mode_P_mach, new_tarval_from_entity(ent, mode_P_mach)); DBG_OPT_NORMALIZE;
exchange(node, new_node); exchange(node, new_node);
} }
} }
} }
} else if (intern_get_irn_op(node) == op_Sel && } else if (intern_get_irn_op(node) == op_Sel &&
is_method_type(get_entity_type(get_Sel_entity(node)))) { is_method_type(get_entity_type(get_Sel_entity(node)))) {
entity * ent = get_Sel_entity(node); entity * ent = get_Sel_entity(node);
if (get_opt_optimize() && get_opt_dyn_meth_dispatch() && if (get_opt_optimize() && get_opt_dyn_meth_dispatch() &&
(intern_get_irn_op(skip_Proj(get_Sel_ptr(node))) == op_Alloc)) { (intern_get_irn_op(skip_Proj(get_Sel_ptr(node))) == op_Alloc)) {
ir_node *new_node; ir_node *new_node;
entity *called_ent; entity *called_ent;
/* We know which method will be called, no dispatch necessary. */ /* We know which method will be called, no dispatch necessary. */
...@@ -219,7 +219,7 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) { ...@@ -219,7 +219,7 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
assert(get_entity_peculiarity(ent) != peculiarity_description); assert(get_entity_peculiarity(ent) != peculiarity_description);
set_irg_current_block(current_ir_graph, get_nodes_Block(node)); set_irg_current_block(current_ir_graph, get_nodes_Block(node));
/* @@@ Is this correct?? Alloc could reference a subtype of the owner /* @@@ Is this correct?? Alloc could reference a subtype of the owner
of Sel that overwrites the method referenced in Sel. */ of Sel that overwrites the method referenced in Sel. */
/* @@@ Yes, this is wrong. GL, 10.3.04 */ /* @@@ Yes, this is wrong. GL, 10.3.04 */
new_node = copy_const_value(get_atomic_ent_value(ent)); DBG_OPT_POLY_ALLOC; new_node = copy_const_value(get_atomic_ent_value(ent)); DBG_OPT_POLY_ALLOC;
#else #else
...@@ -233,55 +233,55 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) { ...@@ -233,55 +233,55 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
} else { } else {
assert(get_entity_peculiarity(ent) != peculiarity_inherited); assert(get_entity_peculiarity(ent) != peculiarity_inherited);
if (!eset_contains(entities, ent)) { if (!eset_contains(entities, ent)) {
/* Entity noch nicht behandelt. Alle (intern oder extern) /* Entity noch nicht behandelt. Alle (intern oder extern)
* implementierten Methoden suchen, die diese Entity * implementierten Methoden suchen, die diese Entity
* berschreiben. Die Menge an entity.link speichern. */ * berschreiben. Die Menge an entity.link speichern. */
set_entity_link(ent, get_impl_methods(ent)); set_entity_link(ent, get_impl_methods(ent));
eset_insert(entities, ent); eset_insert(entities, ent);
} }
if (get_entity_link(ent) == NULL) { if (get_entity_link(ent) == NULL) {
/* Die Sel-Operation kann nie einen Zeiger auf eine aufrufbare /* Die Sel-Operation kann nie einen Zeiger auf eine aufrufbare
* Methode zurckgeben. Damit ist sie insbesondere nicht * Methode zurckgeben. Damit ist sie insbesondere nicht
* ausfhrbar und nicht erreichbar. */ * ausfhrbar und nicht erreichbar. */
/* Gib eine Warnung aus wenn die Entitaet eine Beschreibung ist /* Gib eine Warnung aus wenn die Entitaet eine Beschreibung ist
fuer die es keine Implementierung gibt. */ fuer die es keine Implementierung gibt. */
if (get_entity_peculiarity(ent) == peculiarity_description) { if (get_entity_peculiarity(ent) == peculiarity_description) {
/* @@@ GL Methode um Fehler anzuzeigen aufrufen! */ /* @@@ GL Methode um Fehler anzuzeigen aufrufen! */
printf("WARNING: Calling method description %s\n in method %s\n of class %s\n which has " printf("WARNING: Calling method description %s\n in method %s\n of class %s\n which has "
"no implementation!\n", get_entity_name(ent), "no implementation!\n", get_entity_name(ent),
get_entity_name(get_irg_ent(current_ir_graph)), get_entity_name(get_irg_ent(current_ir_graph)),
get_type_name(get_entity_owner(get_irg_ent(current_ir_graph)))); get_type_name(get_entity_owner(get_irg_ent(current_ir_graph))));
printf("This happens when compiling a Java Interface that's never really used, i.e., " printf("This happens when compiling a Java Interface that's never really used, i.e., "
"no class implementing the interface is ever used.\n"); "no class implementing the interface is ever used.\n");
} else { } else {
exchange(node, new_Bad()); exchange(node, new_Bad());
} }
} else { } else {
entity ** arr = get_entity_link(ent); entity ** arr = get_entity_link(ent);
#if 0 #if 0
int i; int i;
printf("\nCall site "); DDMN(node); printf("\nCall site "); DDMN(node);
printf(" in "); DDME(get_irg_ent(current_ir_graph)); printf(" in "); DDME(get_irg_ent(current_ir_graph));
printf(" can call:\n"); printf(" can call:\n");
for (i = 0; i < ARR_LEN(arr); i++) { for (i = 0; i < ARR_LEN(arr); i++) {
printf(" - "); DDME(arr[i]); printf(" - "); DDME(arr[i]);
printf(" with owner "); DDMT(get_entity_owner(arr[i])); printf(" with owner "); DDMT(get_entity_owner(arr[i]));
} }
printf("\n"); printf("\n");
#endif #endif
if (get_opt_optimize() && get_opt_dyn_meth_dispatch() && if (get_opt_optimize() && get_opt_dyn_meth_dispatch() &&
(ARR_LEN(arr) == 1 && arr[0] != NULL)) { (ARR_LEN(arr) == 1 && arr[0] != NULL)) {
ir_node *new_node; ir_node *new_node;
/* Die Sel-Operation kann immer nur einen Wert auf eine /* Die Sel-Operation kann immer nur einen Wert auf eine
* interne Methode zurckgeben. Wir knnen daher die * interne Methode zurckgeben. Wir knnen daher die
* Sel-Operation durch eine Const- bzw. SymConst-Operation * Sel-Operation durch eine Const- bzw. SymConst-Operation
* ersetzen. */ * ersetzen. */
set_irg_current_block(current_ir_graph, get_nodes_Block(node)); set_irg_current_block(current_ir_graph, get_nodes_Block(node));
new_node = copy_const_value(get_atomic_ent_value(arr[0])); DBG_OPT_POLY; new_node = copy_const_value(get_atomic_ent_value(arr[0])); DBG_OPT_POLY;
exchange (node, new_node); exchange (node, new_node);
} }
} }
} }
} }
...@@ -445,9 +445,9 @@ static void callee_ana_node(ir_node * node, eset * methods) { ...@@ -445,9 +445,9 @@ static void callee_ana_node(ir_node * node, eset * methods) {
for (i = get_Sel_n_methods(node) - 1; i >= 0; --i) { for (i = get_Sel_n_methods(node) - 1; i >= 0; --i) {
entity * ent = get_Sel_method(node, i); entity * ent = get_Sel_method(node, i);
if (ent) { if (ent) {
eset_insert(methods, ent); eset_insert(methods, ent);
} else { } else {
eset_insert(methods, MARK); eset_insert(methods, MARK);
} }
} }
break; break;
......
...@@ -54,6 +54,9 @@ static eset *_dead_graphs = NULL; ...@@ -54,6 +54,9 @@ static eset *_dead_graphs = NULL;
/* now the meat */ /* now the meat */
/**
Enter all method and field accesses and all class allocations into our tables.
*/
static void rta_act (ir_node *node, void *env) static void rta_act (ir_node *node, void *env)
{ {
opcode op = get_irn_opcode (node); opcode op = get_irn_opcode (node);
...@@ -62,12 +65,15 @@ static void rta_act (ir_node *node, void *env) ...@@ -62,12 +65,15 @@ static void rta_act (ir_node *node, void *env)
entity *ent = NULL; entity *ent = NULL;
ir_node *ptr = get_Call_ptr (node); ir_node *ptr = get_Call_ptr (node);
// TODO: test: ptr.op == Const
if (iro_Sel == get_irn_opcode (ptr)) { if (iro_Sel == get_irn_opcode (ptr)) {
ent = get_Sel_entity (ptr); ent = get_Sel_entity (ptr);
} else if (iro_Const == get_irn_opcode (ptr)) {
ent = get_tarval_entity (get_Const_tarval (ptr));
} }
assert (ent);
if (ent) { if (ent) {
eset_insert (_called_methods, ent); eset_insert (_called_methods, ent);
} }
...@@ -93,10 +99,14 @@ static void rta_act (ir_node *node, void *env) ...@@ -93,10 +99,14 @@ static void rta_act (ir_node *node, void *env)
} }
} else if (iro_Alloc == op) { } else if (iro_Alloc == op) {
type *type = get_Alloc_type (node); type *type = get_Alloc_type (node);
eset_insert (_live_classes, type); eset_insert (_live_classes, type);
} }
} }
/**
Traverse the given graph to collect method and field accesses and object allocations.
*/
static void rta_fill_graph (ir_graph* graph) static void rta_fill_graph (ir_graph* graph)
{ {
if (NULL != graph) { if (NULL != graph) {
...@@ -106,6 +116,9 @@ static void rta_fill_graph (ir_graph* graph) ...@@ -106,6 +116,9 @@ static void rta_fill_graph (ir_graph* graph)
} }
} }
/**
Traverse all graphs to collect method and field accesses and object allocations.
*/
static void rta_fill_all () static void rta_fill_all ()
{ {
int i; int i;
...@@ -118,7 +131,11 @@ static void rta_fill_all () ...@@ -118,7 +131,11 @@ static void rta_fill_all ()
interprocedural_view = old_ip_view; interprocedural_view = old_ip_view;
} }
static int is_call_target (entity *method) /**
Find out whether the given method could be the target of a
polymorphic call.
*/
static int is_call_target (const entity *method)
{ {
int is_target = FALSE; int is_target = FALSE;
int i; int i;
...@@ -127,30 +144,33 @@ static int is_call_target (entity *method) ...@@ -127,30 +144,33 @@ static int is_call_target (entity *method)
/* The method could be the target of a polymorphic call if it is /* The method could be the target of a polymorphic call if it is
called or if it overrides a method that is called. */ called or if it overrides a method that is called. */
if (eset_contains (_called_methods, method)) { if (eset_contains (_called_methods, (entity*) method)) {
return (TRUE); return (TRUE);
} }
n_over = get_entity_n_overwrittenby (method); /* not called? check methods in superclass(es) */
n_over = get_entity_n_overwrittenby ((entity*) method);
for (i = 0; !is_target && (i < n_over); i ++) { for (i = 0; !is_target && (i < n_over); i ++) {
entity *over = get_entity_overwrittenby (method, i); entity *over = get_entity_overwrittenby ((entity*) method, i);
is_target |= is_call_target (over); is_target |= is_call_target (over);
} }
return (is_target); return (is_target);
} }
/**
static ir_graph *get_implementing_graph (entity *method) Given a method, find the firm graph that implements that method.
*/
static ir_graph *get_implementing_graph (const entity *method)
{ {
ir_graph *graph = get_entity_irg (method); ir_graph *graph = get_entity_irg ((entity*) method);
if (NULL == graph) { if (NULL == graph) {
int i; int i;
int n_over = get_entity_n_overwrites (method); int n_over = get_entity_n_overwrites ((entity*) method);
for (i = 0; (NULL == graph) && (i < n_over); i ++) { for (i = 0; (NULL == graph) && (i < n_over); i ++) {
entity *over = get_entity_overwrites (method, i); entity *over = get_entity_overwrites ((entity*) method, i);
graph = get_implementing_graph (over); graph = get_implementing_graph (over);
} }
} }
...@@ -160,28 +180,39 @@ static ir_graph *get_implementing_graph (entity *method) ...@@ -160,28 +180,39 @@ static ir_graph *get_implementing_graph (entity *method)
return (graph); return (graph);
} }
/**
Determine whether the give method or one of its overwriter have
been used in a call to the given graph.
*/
static int has_live_call (entity *method, ir_graph *graph) static int has_live_call (entity *method, ir_graph *graph)
{ {
int has_call = FALSE; int has_call = FALSE;
int i, n_over; int i, n_over;
/* stop searching if a overwriting method comes with a new graph */
if (get_irg_ent (graph) != method) { if (get_irg_ent (graph) != method) {
return (FALSE); return (FALSE);
} }
/* maybe we're called (possibly through polymorphy)? */
if (is_call_target (method)) { if (is_call_target (method)) {
return (TRUE); return (TRUE);
} }
n_over = get_entity_n_overwrittenby (method); /* maybe we're overwritten by a method that is called? */
n_over = get_entity_n_overwrittenby ((entity*) method);
for (i = 0; !has_call && (i < n_over); i ++) { for (i = 0; !has_call && (i < n_over); i ++) {
entity *over = get_entity_overwrittenby(method, i); entity *over = get_entity_overwrittenby((entity*) method, i);
has_call |= has_live_call (over, graph); has_call |= has_live_call (over, graph);
} }
return (has_call); return (has_call);
} }
/**
Determine whether the given class is live *and* uses the given
graph at some point.
*/
static int has_graph (type *clazz, ir_graph *graph) static int has_graph (type *clazz, ir_graph *graph)
{ {
int has_the_graph = FALSE; int has_the_graph = FALSE;
...@@ -203,6 +234,7 @@ static int has_graph (type *clazz, ir_graph *graph) ...@@ -203,6 +234,7 @@ static int has_graph (type *clazz, ir_graph *graph)
} /* all methods */ } /* all methods */
} /* _live_classes.contains (clazz) */ } /* _live_classes.contains (clazz) */
/* our subclasses might be using that graph, no? */
n_sub = get_class_n_subtypes (clazz); n_sub = get_class_n_subtypes (clazz);
for (i = 0; !has_the_graph && (i < n_sub); i ++) { for (i = 0; !has_the_graph && (i < n_sub); i ++) {
type *sub = get_class_subtype (clazz, i); type *sub = get_class_subtype (clazz, i);
...@@ -213,6 +245,10 @@ static int has_graph (type *clazz, ir_graph *graph) ...@@ -213,6 +245,10 @@ static int has_graph (type *clazz, ir_graph *graph)
return (has_the_graph); return (has_the_graph);
} }
/**
Determine wether the given method could be used in a call to the
given graph on a live class.
*/
static int has_live_class (entity *method, ir_graph *graph) static int has_live_class (entity *method, ir_graph *graph)
{ {
int has_class = FALSE; int has_class = FALSE;
...@@ -220,12 +256,16 @@ static int has_live_class (entity *method, ir_graph *graph) ...@@ -220,12 +256,16 @@ static int has_live_class (entity *method, ir_graph *graph)
int n_over; int n_over;
type *clazz; type *clazz;
/* const char *name = get_entity_name (method); */
/* stop searching when an overwriting method provides a new graph */
if (get_implementing_graph (method) != graph) { if (get_implementing_graph (method) != graph) {
return (FALSE); return (FALSE);
} }
clazz = get_entity_owner (method); clazz = get_entity_owner (method);
if (has_graph (clazz, graph)) {
if (has_graph (clazz, graph)) { /* this also checks whether clazz is live*/
return (TRUE); return (TRUE);
} }
...@@ -261,6 +301,10 @@ void rta_init () ...@@ -261,6 +301,10 @@ void rta_init ()
eset_insert (_live_graphs, get_irp_main_irg ()); eset_insert (_live_graphs, get_irp_main_irg ());
} }
if (get_glob_type ()) {
eset_insert (_live_classes, get_glob_type ());
}
rta_fill_all (); rta_fill_all ();
} }
...@@ -274,10 +318,9 @@ void rta_cleanup () ...@@ -274,10 +318,9 @@ void rta_cleanup ()
ir_graph *graph = get_irp_irg(i); ir_graph *graph = get_irp_irg(i);
if (rta_check (graph)) { if (rta_check (graph)) {
char *name = NULL; const char *name = get_entity_name (get_irg_ent (graph));;
n_live_graphs ++; n_live_graphs ++;
name = get_entity_name (get_irg_ent (graph));
fprintf (stdout, "LIVE %s\n", name); fprintf (stdout, "LIVE %s\n", name);
} }
...@@ -348,6 +391,9 @@ int rta_is_alive_field (entity *field) ...@@ -348,6 +391,9 @@ int rta_is_alive_field (entity *field)
/* /*
* $Log$ * $Log$
* Revision 1.4 2004/06/12 19:35:04 liekweg
* Kommentare eingef"ugt --flo
*
* Revision 1.3 2004/06/12 17:09:46 liekweg * Revision 1.3 2004/06/12 17:09:46 liekweg
* RTA works, outedges breaks. "Yay." --flo * RTA works, outedges breaks. "Yay." --flo
* *
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment