Commit c85be8ca authored by Florian Liekweg's avatar Florian Liekweg
Browse files

Optionally do whole-program assumption; obey stickiness (OBEY)

[r3440]
parent d09e8a63
......@@ -84,7 +84,7 @@ static entity *get_inherited_methods_implementation(entity *inh_meth) {
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!");
......@@ -144,7 +144,7 @@ static void collect_impls(entity *method, eset *set, int *size, bool *open) {
}
}
}
/** 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);
}
......@@ -226,17 +226,17 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
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 &&
......@@ -460,10 +460,10 @@ static void callee_ana_node(ir_node * node, eset * methods) {
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);
......@@ -478,8 +478,8 @@ static void callee_ana_node(ir_node * node, eset * methods) {
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 {
......@@ -718,7 +718,7 @@ static void free_ana_walker(ir_node * node, eset * set) {
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;
......@@ -743,23 +743,37 @@ static void free_ana_walker(ir_node * node, eset * set) {
* SymConst-Operationen mssen 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()) {
......@@ -774,12 +788,12 @@ static entity ** get_free_methods(void) {
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();
......
Markdown is supported
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