if (get_irn_op(addr) == op_Const) {
impl_meth = tarval_to_entity(get_Const_tarval(addr));
} else if ((get_irn_op(addr) == op_SymConst) &&
- (get_SymConst_kind(addr) == symconst_addr_ent)) {
+ (get_SymConst_kind(addr) == symconst_addr_ent)) {
impl_meth = get_SymConst_entity(addr);
} else {
assert(0 && "Complex constant values not supported -- address of method should be straight constant!");
}
}
}
- /** recursive descend **/
+ /** recursive descent **/
for (i = get_entity_n_overwrittenby(method) - 1; i >= 0; --i)
collect_impls(get_entity_overwrittenby(method, i), set, size, open);
}
if (get_SymConst_kind(node) == symconst_addr_name) {
pmap_entry * entry = pmap_find(ldname_map, (void *) get_SymConst_name(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;
- symconst_symbol sym;
- assert(get_entity_irg(ent));
- sym.entity_p = ent;
- set_irg_current_block(current_ir_graph, get_nodes_Block(node));
- new_node = new_d_SymConst(get_irn_dbg_info(node), sym, symconst_addr_ent); DBG_OPT_NORMALIZE;
- DDMN(new_node);
- 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;
+ symconst_symbol sym;
+ assert(get_entity_irg(ent));
+ sym.entity_p = ent;
+ set_irg_current_block(current_ir_graph, get_nodes_Block(node));
+ new_node = new_d_SymConst(get_irn_dbg_info(node), sym, symconst_addr_ent); DBG_OPT_NORMALIZE;
+ DDMN(new_node);
+ exchange(node, new_node);
+ }
}
}
} else if (get_irn_op(node) == op_Sel &&
entity * ent = get_SymConst_entity(node);
assert(ent && is_method_type(get_entity_type(ent)));
if (get_entity_visibility(ent) != visibility_external_allocated) {
- assert(get_entity_irg(ent));
- eset_insert(methods, ent);
+ assert(get_entity_irg(ent));
+ eset_insert(methods, ent);
} else {
- eset_insert(methods, MARK); /* free method -> unknown */
+ eset_insert(methods, MARK); /* free method -> unknown */
}
} else {
assert(get_SymConst_kind(node) == symconst_addr_name);
assert(ent && is_method_type(get_entity_type(ent)));
if (get_entity_visibility(ent) != visibility_external_allocated) {
if (!get_entity_irg(ent)) {
- dump_entity(ent);
- assert(get_entity_irg(ent));
+ dump_entity(ent);
+ assert(get_entity_irg(ent));
}
eset_insert(methods, ent);
} else {
for (i = get_Call_arity(node) - 1; i >= 0; --i) {
ir_node * pred = get_Call_param(node, i);
if (mode_is_reference(get_irn_mode(pred))) {
- free_mark(pred, set);
+ free_mark(pred, set);
}
}
break;
* SymConst-Operationen müssen in passende Const-Operationen
* umgewandelt worden sein, d.h. SymConst-Operationen verweisen immer
* auf eine echt externe Methode. */
-static entity ** get_free_methods(void) {
+static entity ** get_free_methods(int whole)
+{
eset * set = eset_create();
int i;
entity ** arr = NEW_ARR_F(entity *, 0);
entity * ent;
+ if (! whole) {
+ for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
+ ir_graph * irg = get_irp_irg(i);
+ entity * ent = get_irg_ent(irg);
+ /* insert "external visible" methods. */
+ if (get_entity_visibility(ent) != visibility_local) {
+ eset_insert(set, ent);
+ }
+ /* Finde alle Methoden die in dieser Methode extern sichtbar werden,
+ z.B. da die Adresse einer Methode abgespeichert wird. */
+ irg_walk_graph(irg, NULL, (irg_walk_func *) free_ana_walker, set);
+ }
+ }
+
+ /* insert sticky methods, too */
for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
ir_graph * irg = get_irp_irg(i);
entity * ent = get_irg_ent(irg);
/* insert "external visible" methods. */
- if (get_entity_visibility(ent) != visibility_local) {
+ if (get_entity_stickyness (ent) == stickyness_sticky) {
eset_insert(set, ent);
}
- /* Finde alle Methoden die in dieser Methode extern sichtbar werden,
- z.B. da die Adresse einer Methode abgespeichert wird. */
- irg_walk_graph(irg, NULL, (irg_walk_func *) free_ana_walker, set);
}
+
/* Hauptprogramm ist auch dann frei, wenn es nicht "external
* visible" ist. */
if (get_irp_main_irg()) {
return arr;
}
-void cgana(int *length, entity ***free_methods) {
+void cgana(int *length, entity ***free_methods, int whole) {
entity ** free_meths;
int i;
sel_methods_init();
- free_meths = get_free_methods();
+ free_meths = get_free_methods(whole);
callee_ana();
sel_methods_dispose();