* @author Hubert Schmid
* @date 09.06.2002
* @version $Id$
- * @summary
+ * @brief
* Interprocedural analysis to estimate the calling relation.
*
* This analysis computes all entities representing methods that
* methods that are 'free', i.e., their adress is handled by
* the program directly, or they are visible external.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
-#ifdef HAVE_STRING_H
# include <string.h>
-#endif
#include "cgana.h"
#include "rta.h"
#include "ircons.h"
#include "irgmod.h"
#include "iropt.h"
+#include "irtools.h"
#include "irflag_t.h"
#include "dbginfo_t.h"
#include "irdump.h"
-#include "irhooks.h"
-
-
-
/* unambiguous address used as a mark. */
static void *MARK = &MARK;
collect_impls(get_entity_overwrittenby(method, i), set, size, open);
}
-/** Alle Methoden bestimmen, die die übergebene Methode überschreiben
- * (und implementieren). In der zurückgegebenen Reihung kommt jede
- * Methode nur einmal vor. Der Wert 'NULL' steht für unbekannte
- * (externe) Methoden. Die zurückgegebene Reihung muß vom Aufrufer
- * wieder freigegeben werden (siehe "DEL_ARR_F"). Gibt es überhaupt
- * keine Methoden, die "method" überschreiben, so gibt die Methode
- * "NULL" zurück.
+/** Alle Methoden bestimmen, die die �bergebene Methode �berschreiben
+ * (und implementieren). In der zur�ckgegebenen Reihung kommt jede
+ * Methode nur einmal vor. Der Wert 'NULL' steht f�r unbekannte
+ * (externe) Methoden. Die zur�ckgegebene Reihung mu� vom Aufrufer
+ * wieder freigegeben werden (siehe "DEL_ARR_F"). Gibt es �berhaupt
+ * keine Methoden, die "method" �berschreiben, so gibt die Methode
+ * "NULL" zur�ck.
*
* @param method
*/
/* Vorgaenger einfuegen. */
if (size == 0 && !open) {
- /* keine implementierte überschriebene Methode */
+ /* keine implementierte �berschriebene Methode */
arr = NULL;
} else if (open) {
ir_entity * ent;
return arr;
} else {
/* "NULL" zeigt an, dass keine Implementierung existiert. Dies
- * kann für polymorphe (abstrakte) Methoden passieren. */
+ * kann f�r polymorphe (abstrakte) Methoden passieren. */
if (!NULL_ARRAY) {
NULL_ARRAY = NEW_ARR_F(ir_entity *, 0);
}
* op_Tuple oder ein Knoten, der in "free_ana_walker" behandelt
* wird. */
ir_node * pred = get_Proj_pred(node);
- if (get_irn_link(pred) != MARK && get_irn_op(pred) == op_Tuple) {
+ if (get_irn_link(pred) != MARK && is_Tuple(pred)) {
free_mark_proj(get_Tuple_pred(pred, get_Proj_proj(node)), n, set);
} else {
/* nothing: da in "free_ana_walker" behandelt. */
if (is_method_entity(ent)) {
eset_insert(set, ent);
}
- } else {
- assert(get_SymConst_kind(node) == symconst_addr_name);
- /* nothing: SymConst points to extern method */
}
break;
}
break;
default:
- /* other nodes: Alle anderen Knoten nehmen wir als Verräter an, bis
+ /* other nodes: Alle anderen Knoten nehmen wir als Verr�ter an, bis
* jemand das Gegenteil implementiert. */
set_irn_link(node, MARK);
for (i = get_irn_arity(node) - 1; i >= 0; --i) {
*
* which is sometimes used to anchor functions.
*/
-static void add_method_address_intitialzer(ir_initializer_t *initializer,
- eset *set)
+static void add_method_address_inititializer(ir_initializer_t *initializer,
+ eset *set)
{
+ ir_node *n;
+ size_t i;
+
switch (initializer->kind) {
- case IR_INITIALIZER_CONST: {
- ir_node *n = initializer->consti.value;
+ case IR_INITIALIZER_CONST:
+ n = initializer->consti.value;
/* let's check if it's the address of a function */
if (is_Global(n)) {
eset_insert(set, ent);
}
return;
- }
case IR_INITIALIZER_TARVAL:
case IR_INITIALIZER_NULL:
return;
- case IR_INITIALIZER_COMPOUND: {
- size_t i;
-
+ case IR_INITIALIZER_COMPOUND:
for (i = 0; i < initializer->compound.n_initializers; ++i) {
ir_initializer_t *sub_initializer
= initializer->compound.initializers[i];
- add_method_address_intitialzer(sub_initializer, set);
+ add_method_address_inititializer(sub_initializer, set);
}
return;
}
- }
panic("invalid initializer found");
}
return;
if (ent->has_initializer) {
- add_method_address_intitialzer(get_entity_initializer(ent), set);
+ add_method_address_inititializer(get_entity_initializer(ent), set);
} else if (is_atomic_entity(ent)) {
tp = get_entity_type(ent);
* returns a list of 'free' methods, i.e., the methods that can be called
* from external or via function pointers.
*
- * Die Datenstrukturen für sel-Methoden (sel_methods) muß vor dem
+ * Die Datenstrukturen f�r sel-Methoden (sel_methods) mu� vor dem
* Aufruf von "get_free_methods" aufgebaut sein. Die (internen)
- * SymConst(name)-Operationen müssen in passende SymConst(ent)-Operationen
+ * SymConst(name)-Operationen m�ssen in passende SymConst(ent)-Operationen
* umgewandelt worden sein, d.h. SymConst-Operationen verweisen immer
* auf eine echt externe Methode.
*/
for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
irg = get_irp_irg(i);
ent = get_irg_entity(irg);
- /* insert "external visible" methods. */
if (get_entity_visibility(ent) != visibility_local) {
+ /* insert non-local (external) methods. */
eset_insert(free_set, ent);
- }
- /* insert "sticky" methods. */
- if (get_entity_stickyness(ent) == stickyness_sticky) {
+ } else if (get_entity_stickyness(ent) == stickyness_sticky) {
+ /* insert "sticky" methods. */
eset_insert(free_set, ent);
}
- set_using_irn_link(irg);
- /* Find all method entities that gets "visible" trough this graphs,
+ ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
+ /* Find all method entities that gets "visible" through this graphs,
* for instance because their address is stored. */
- irg_walk_graph(irg, NULL, free_ana_walker, free_set);
- clear_using_irn_link(irg);
+ irg_walk_graph(irg, firm_clear_link, free_ana_walker, free_set);
+ ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
}
/* insert all methods that are used in global variables initializers */
/* Finally, transform the set into an array. */
*length = eset_count(free_set);
- arr = xmalloc(sizeof(ir_entity *) * (*length));
+ arr = XMALLOCN(ir_entity*, *length);
for (i = 0, ent = eset_first(free_set); ent; ent = eset_next(free_set)) {
arr[i++] = ent;
}
case iro_Proj: {
/* proj_proj: in einem "sinnvollen" Graphen kommt jetzt ein
* op_Tuple oder ein Knoten, der eine "freie Methode"
- * zurückgibt. */
+ * zur�ckgibt. */
ir_node *pred = get_Proj_pred(node);
if (get_irn_link(pred) != MARK) {
if (is_Tuple(pred)) {
callee_ana_node(get_Mux_true(node), methods);
break;
- case iro_Psi:
- for (i = get_Psi_n_conds(node) - 1; i >= 0; --i) {
- callee_ana_node(get_Psi_val(node, i), methods);
- }
- callee_ana_node(get_Psi_default(node), methods);
- break;
-
case iro_Id:
callee_ana_node(get_Id_pred(node), methods);
break;