} else {
assert(get_entity_irg(method) != NULL);
if (!eset_contains(set, method)) {
- eset_insert(set, method);
- ++(*size);
+ eset_insert(set, method);
+ ++(*size);
}
}
}
} else {
assert(get_entity_irg(impl_ent) != NULL);
if (!eset_contains(set, impl_ent)) {
- eset_insert(set, impl_ent);
- ++(*size);
+ eset_insert(set, impl_ent);
+ ++(*size);
}
}
}
if (get_SymConst_kind(node) == linkage_ptr_info) {
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 */
- ir_node *new_node;
- assert(get_entity_irg(ent));
- set_irg_current_block(current_ir_graph, get_nodes_Block(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;
- exchange(node, new_node);
- }
+ 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));
+ new_node = new_d_Const(get_irn_dbg_info(node),
+ mode_P_mach, new_tarval_from_entity(ent, mode_P_mach)); DBG_OPT_NORMALIZE;
+ exchange(node, new_node);
+ }
}
}
} 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);
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;
entity *called_ent;
/* We know which method will be called, no dispatch necessary. */
assert(get_entity_peculiarity(ent) != peculiarity_description);
set_irg_current_block(current_ir_graph, get_nodes_Block(node));
/* @@@ 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 */
new_node = copy_const_value(get_atomic_ent_value(ent)); DBG_OPT_POLY_ALLOC;
#else
} else {
assert(get_entity_peculiarity(ent) != peculiarity_inherited);
if (!eset_contains(entities, ent)) {
- /* Entity noch nicht behandelt. Alle (intern oder extern)
- * implementierten Methoden suchen, die diese Entity
- * überschreiben. Die Menge an entity.link speichern. */
- set_entity_link(ent, get_impl_methods(ent));
- eset_insert(entities, ent);
+ /* Entity noch nicht behandelt. Alle (intern oder extern)
+ * implementierten Methoden suchen, die diese Entity
+ * überschreiben. Die Menge an entity.link speichern. */
+ set_entity_link(ent, get_impl_methods(ent));
+ eset_insert(entities, ent);
}
if (get_entity_link(ent) == NULL) {
- /* Die Sel-Operation kann nie einen Zeiger auf eine aufrufbare
- * Methode zurückgeben. Damit ist sie insbesondere nicht
- * ausführbar und nicht erreichbar. */
- /* Gib eine Warnung aus wenn die Entitaet eine Beschreibung ist
- fuer die es keine Implementierung gibt. */
- if (get_entity_peculiarity(ent) == peculiarity_description) {
- /* @@@ GL Methode um Fehler anzuzeigen aufrufen! */
- printf("WARNING: Calling method description %s\n in method %s\n of class %s\n which has "
- "no implementation!\n", get_entity_name(ent),
- get_entity_name(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., "
- "no class implementing the interface is ever used.\n");
- } else {
- exchange(node, new_Bad());
- }
+ /* Die Sel-Operation kann nie einen Zeiger auf eine aufrufbare
+ * Methode zurückgeben. Damit ist sie insbesondere nicht
+ * ausführbar und nicht erreichbar. */
+ /* Gib eine Warnung aus wenn die Entitaet eine Beschreibung ist
+ fuer die es keine Implementierung gibt. */
+ if (get_entity_peculiarity(ent) == peculiarity_description) {
+ /* @@@ GL Methode um Fehler anzuzeigen aufrufen! */
+ printf("WARNING: Calling method description %s\n in method %s\n of class %s\n which has "
+ "no implementation!\n", get_entity_name(ent),
+ get_entity_name(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., "
+ "no class implementing the interface is ever used.\n");
+ } else {
+ exchange(node, new_Bad());
+ }
} else {
- entity ** arr = get_entity_link(ent);
+ entity ** arr = get_entity_link(ent);
#if 0
- int i;
- printf("\nCall site "); DDMN(node);
- printf(" in "); DDME(get_irg_ent(current_ir_graph));
- printf(" can call:\n");
- for (i = 0; i < ARR_LEN(arr); i++) {
- printf(" - "); DDME(arr[i]);
- printf(" with owner "); DDMT(get_entity_owner(arr[i]));
- }
- printf("\n");
+ int i;
+ printf("\nCall site "); DDMN(node);
+ printf(" in "); DDME(get_irg_ent(current_ir_graph));
+ printf(" can call:\n");
+ for (i = 0; i < ARR_LEN(arr); i++) {
+ printf(" - "); DDME(arr[i]);
+ printf(" with owner "); DDMT(get_entity_owner(arr[i]));
+ }
+ printf("\n");
#endif
- if (get_opt_optimize() && get_opt_dyn_meth_dispatch() &&
- (ARR_LEN(arr) == 1 && arr[0] != NULL)) {
- ir_node *new_node;
- /* Die Sel-Operation kann immer nur einen Wert auf eine
- * interne Methode zurückgeben. Wir können daher die
- * Sel-Operation durch eine Const- bzw. SymConst-Operation
- * ersetzen. */
- 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;
- exchange (node, new_node);
- }
+ if (get_opt_optimize() && get_opt_dyn_meth_dispatch() &&
+ (ARR_LEN(arr) == 1 && arr[0] != NULL)) {
+ ir_node *new_node;
+ /* Die Sel-Operation kann immer nur einen Wert auf eine
+ * interne Methode zurückgeben. Wir können daher die
+ * Sel-Operation durch eine Const- bzw. SymConst-Operation
+ * ersetzen. */
+ 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;
+ exchange (node, new_node);
+ }
}
}
}
for (i = get_Sel_n_methods(node) - 1; i >= 0; --i) {
entity * ent = get_Sel_method(node, i);
if (ent) {
- eset_insert(methods, ent);
+ eset_insert(methods, ent);
} else {
- eset_insert(methods, MARK);
+ eset_insert(methods, MARK);
}
}
break;
/* 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)
{
opcode op = get_irn_opcode (node);
entity *ent = NULL;
ir_node *ptr = get_Call_ptr (node);
- // TODO: test: ptr.op == Const
if (iro_Sel == get_irn_opcode (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) {
eset_insert (_called_methods, ent);
}
}
} else if (iro_Alloc == op) {
type *type = get_Alloc_type (node);
+
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)
{
if (NULL != graph) {
}
}
+/**
+Traverse all graphs to collect method and field accesses and object allocations.
+*/
static void rta_fill_all ()
{
int i;
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 i;
/* The method could be the target of a polymorphic call if it is
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);
}
- 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 ++) {
- entity *over = get_entity_overwrittenby (method, i);
+ entity *over = get_entity_overwrittenby ((entity*) method, i);
is_target |= is_call_target (over);
}
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) {
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 ++) {
- entity *over = get_entity_overwrites (method, i);
+ entity *over = get_entity_overwrites ((entity*) method, i);
graph = get_implementing_graph (over);
}
}
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)
{
int has_call = FALSE;
int i, n_over;
+ /* stop searching if a overwriting method comes with a new graph */
if (get_irg_ent (graph) != method) {
return (FALSE);
}
+ /* maybe we're called (possibly through polymorphy)? */
if (is_call_target (method)) {
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 ++) {
- entity *over = get_entity_overwrittenby(method, i);
+ entity *over = get_entity_overwrittenby((entity*) method, i);
has_call |= has_live_call (over, graph);
}
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)
{
int has_the_graph = FALSE;
} /* all methods */
} /* _live_classes.contains (clazz) */
+ /* our subclasses might be using that graph, no? */
n_sub = get_class_n_subtypes (clazz);
for (i = 0; !has_the_graph && (i < n_sub); i ++) {
type *sub = get_class_subtype (clazz, i);
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)
{
int has_class = FALSE;
int n_over;
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) {
return (FALSE);
}
clazz = get_entity_owner (method);
- if (has_graph (clazz, graph)) {
+
+ if (has_graph (clazz, graph)) { /* this also checks whether clazz is live*/
return (TRUE);
}
eset_insert (_live_graphs, get_irp_main_irg ());
}
+ if (get_glob_type ()) {
+ eset_insert (_live_classes, get_glob_type ());
+ }
+
rta_fill_all ();
}
ir_graph *graph = get_irp_irg(i);
if (rta_check (graph)) {
- char *name = NULL;
+ const char *name = get_entity_name (get_irg_ent (graph));;
n_live_graphs ++;
- name = get_entity_name (get_irg_ent (graph));
fprintf (stdout, "LIVE %s\n", name);
}
/*
* $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
* RTA works, outedges breaks. "Yay." --flo
*