X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fcgana.c;h=b4b051201de2ac564f72601639c2212ac9b234b6;hb=f64411a2a8a4e28e70a281ac67736a1bdf996b72;hp=a4313025013d2568d95158d66c57ef24b3805c19;hpb=4c5416bd31274ba09361160480f53c6d6d3f54be;p=libfirm diff --git a/ir/ana/cgana.c b/ir/ana/cgana.c index a43130250..b4b051201 100644 --- a/ir/ana/cgana.c +++ b/ir/ana/cgana.c @@ -54,8 +54,7 @@ -/* Eindeutige Adresse zur Markierung von besuchten Knoten und zur - * Darstellung der unbekannten Methode. */ +/* unambiguous address used as a mark. */ static void *MARK = &MARK; static eset *entities = NULL; @@ -82,7 +81,7 @@ static entity *get_inherited_methods_implementation(entity *inh_meth) { } /** Collect the entity representing the implementation of this - * entity (not the same if inherited) and all entities for overwriting + * method (not the same if inherited) and all entities for overwriting * implementations in "set". * If the implementation of the method is not included in the * compilation unit "open" is set to true. @@ -94,7 +93,7 @@ static entity *get_inherited_methods_implementation(entity *inh_meth) { * @param size Number of entities in set. * @param open */ -static void collect_impls(entity *method, eset *set, int *size, bool *open) { +static void collect_impls(entity *method, eset *set, int *size, int *open) { int i; entity *impl; @@ -128,7 +127,7 @@ static entity ** get_impl_methods(entity * method) { eset * set = eset_create(); int size = 0; entity ** arr; - bool open = false; + int open = 0; /* Collect all method entities that can be called here */ collect_impls(method, set, &size, &open); @@ -180,7 +179,8 @@ static void sel_methods_walker(ir_node * node, void *env) { /* Call standard optimizations */ if (get_irn_op(node) == op_Sel) { ir_node *new_node = optimize_in_place(node); - if (node != new_node) exchange(node, new_node); + if (node != new_node) + exchange(node, new_node); } /* replace SymConst(name)-operations by SymConst(ent) */ @@ -229,7 +229,7 @@ static void sel_methods_walker(ir_node * node, void *env) { set_irg_current_block(current_ir_graph, get_nodes_block(node)); assert(get_entity_peculiarity(get_SymConst_entity(get_atomic_ent_value(arr[0]))) == peculiarity_existent); - new_node = copy_const_value(get_atomic_ent_value(arr[0])); + new_node = copy_const_value(get_irn_dbg_info(node), get_atomic_ent_value(arr[0])); DBG_OPT_POLY(node, new_node); exchange(node, new_node); } @@ -471,6 +471,14 @@ static void free_ana_walker(ir_node *node, void *env) { /** * Add all method addresses in global initializers to the set. + * + * @note + * We do NOT check the type here, just it it's an entity address. + * The reason for this is code like: + * + * void *p = function; + * + * which is sometimes used to anchor functions. */ static void add_method_address(entity *ent, eset *set) { @@ -485,10 +493,8 @@ static void add_method_address(entity *ent, eset *set) if (is_atomic_entity(ent)) { tp = get_entity_type(ent); - /* only function pointers are interesting */ - if (! is_Pointer_type(tp)) - return; - if (! is_Method_type(get_pointer_points_to_type(tp))) + /* ignore methods: these of course reference it's address */ + if (is_Method_type(tp)) return; /* let's check if it's the address of a function */ @@ -497,7 +503,8 @@ static void add_method_address(entity *ent, eset *set) if (get_SymConst_kind(n) == symconst_addr_ent) { ent = get_SymConst_entity(n); - eset_insert(set, ent); + if (is_Method_type(get_entity_type(ent))) + eset_insert(set, ent); } } } @@ -510,7 +517,8 @@ static void add_method_address(entity *ent, eset *set) if (get_SymConst_kind(n) == symconst_addr_ent) { entity *ent = get_SymConst_entity(n); - eset_insert(set, ent); + if (is_Method_type(get_entity_type(ent))) + eset_insert(set, ent); } } }