X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Frta.c;h=7964fa8feb4b26154cc23ee67ada627ba8178c24;hb=0fbcef83aa6060534172bb13e71cdadb04428806;hp=5d22d385c7cd90c0724d6efd2f7e6873e4b7ac61;hpb=e9132fa5fc7e5a60fb4de60ddd224394fdc8c345;p=libfirm diff --git a/ir/ana/rta.c b/ir/ana/rta.c index 5d22d385c..7964fa8fe 100644 --- a/ir/ana/rta.c +++ b/ir/ana/rta.c @@ -1,21 +1,30 @@ -/* -*- c -*- */ - /* - * Project: libFIRM - * File name: ir/ana/rta.c - * Purpose: Interprocedural analysis to improve the call graph estimate. - * Author: Florian - * Modified by: - * Created: 09.06.2002 - * CVS-ID: $Id$ - * Copyright: (c) 1999-2004 Universität Karlsruhe - * Licence: This file is protected by GPL - GNU GENERAL PUBLIC LICENSE. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +/** + * @file + * @brief Interprocedural analysis to improve the call graph estimate. + * @author Florian + * @version 09.06.2002 + * @version $Id$ + */ +#include "config.h" #include "rta.h" @@ -28,9 +37,8 @@ #include "eset.h" #include "irgwalk.h" #include "irgmod.h" -#include "typewalk.h" #include "irvrfy.h" -#include "trvrfy.h" +#include "irprintf.h" # ifndef TRUE # define TRUE 1 @@ -50,19 +58,19 @@ static eset *_live_graphs = NULL; /** Given a method, find the firm graph that implements that method. */ -static ir_graph *get_implementing_graph (entity *method) +static ir_graph *get_implementing_graph (ir_entity *method) { #if 0 - ir_graph *graph = get_entity_irg ((entity*) method); + ir_graph *graph = get_entity_irg ((ir_entity*) method); /* Search upwards in the overwrites graph. */ /* GL: this will not work for multiple inheritance */ if (NULL == graph) { int i; - int n_over = get_entity_n_overwrites ((entity*) method); + int n_over = get_entity_n_overwrites ((ir_entity*) method); for (i = 0; (NULL == graph) && (i < n_over); i ++) { - entity *over = get_entity_overwrites ((entity*) method, i); + ir_entity *over = get_entity_overwrites ((ir_entity*) method, i); graph = get_implementing_graph (over); } } @@ -86,12 +94,18 @@ static ir_graph *get_implementing_graph (entity *method) #endif } +/** + * Add a graph to the set of live graphs. + * + * @param graph the graph to add + * @return non-zero if the graph was added, zero + * if it was already in the live set + */ static int add_graph (ir_graph *graph) { if (!eset_contains (_live_graphs, graph)) { if (verbose > 1) { - fprintf(stdout, "RTA: new graph of "); - DDMEO(get_irg_entity (graph)); + ir_fprintf(stdout, "RTA: new graph of %+F\n", graph); } eset_insert (_live_graphs, graph); @@ -101,12 +115,18 @@ static int add_graph (ir_graph *graph) return (FALSE); } -static int add_class (type *clazz) +/** + * Add a class to the set of live classes. + * + * @param clazz the class to add + * @return non-zero if the graph was added, zero + * if it was already in the live set + */ +static int add_class (ir_type *clazz) { if (!eset_contains (_live_classes, clazz)) { if (verbose > 1) { - fprintf(stdout, "RTA: new class: "); - DDMT(clazz); + ir_fprintf(stdout, "RTA: new class: %+F\n", clazz); } eset_insert (_live_classes, clazz); @@ -121,7 +141,7 @@ static int add_class (type *clazz) * * Iff additions occurred, return TRUE, else FALSE. */ -static int add_implementing_graphs (entity *method) +static int add_implementing_graphs (ir_entity *method) { int i; int n_over = get_entity_n_overwrittenby (method); @@ -133,8 +153,7 @@ static int add_implementing_graphs (entity *method) } if (verbose > 1) { - fprintf(stdout, "RTA: new call to "); - DDMEO(method); + ir_fprintf(stdout, "RTA: new call to %+F\n", method); } if (rta_is_alive_class (get_entity_owner (method))) { @@ -144,7 +163,7 @@ static int add_implementing_graphs (entity *method) } for (i = 0; i < n_over; i ++) { - entity *over = get_entity_overwrittenby (method, i); + ir_entity *over = get_entity_overwrittenby (method, i); change |= add_implementing_graphs (over); } @@ -159,11 +178,10 @@ static int add_implementing_graphs (entity *method) static void rta_act (ir_node *node, void *env) { int *change = (int*) env; - - opcode op = get_irn_opcode (node); + ir_opcode op = get_irn_opcode (node); if (iro_Call == op) { /* CALL */ - entity *ent = NULL; + ir_entity *ent = NULL; ir_node *ptr = get_Call_ptr (node); @@ -196,12 +214,11 @@ static void rta_act (ir_node *node, void *env) /* STRANGE */ } else { - DDMN(ptr); assert(0 && "Unexpected address expression: can not analyse, therefore can not do correct rta!"); } } else if (iro_Alloc == op) { /* ALLOC */ - type *type = get_Alloc_type (node); + ir_type *type = get_Alloc_type (node); *change |= add_class (type); } @@ -214,12 +231,8 @@ static void rta_act (ir_node *node, void *env) static int rta_fill_graph (ir_graph* graph) { int change = FALSE; - - current_ir_graph = graph; - irg_walk_graph (graph, rta_act, NULL, &change); - - return (change); + return change; } /** Traverse all graphs to collect method accesses and object allocations. @@ -229,9 +242,11 @@ static int rta_fill_incremental (void) int i; int n_runs = 0; int rerun = TRUE; +#ifdef INTERPROCEDURAL_VIEW int old_ip_view = get_interprocedural_view(); set_interprocedural_view(0); /* save this for later */ +#endif /* init_tables has added main_irg to _live_graphs */ @@ -240,7 +255,7 @@ static int rta_fill_incremental (void) for (i = 0; i < get_irp_n_irgs(); i++) { ir_graph *graph = get_irp_irg (i); - entity *ent = get_irg_entity (graph); + ir_entity *ent = get_irg_entity (graph); if ((visibility_external_visible == get_entity_visibility (ent)) || (stickyness_sticky == get_entity_stickyness (ent))) { @@ -269,8 +284,8 @@ static int rta_fill_incremental (void) graph = eset_next (live_graphs)) { if (verbose > 1) { - fprintf(stdout, "RTA: RUN %i: considering graph of ", n_runs); - DDMEO(get_irg_entity (graph)); + ir_fprintf(stdout, "RTA: RUN %i: considering graph of %+F\n", n_runs, + graph); } rerun |= rta_fill_graph (graph); @@ -281,7 +296,9 @@ static int rta_fill_incremental (void) n_runs ++; } +#ifdef INTERPROCEDURAL_VIEW set_interprocedural_view(old_ip_view); /* cover up our traces */ +#endif return (n_runs); } @@ -313,18 +330,18 @@ static int stats (void) entity that used to inherit this entity's graph is now abstract. */ /* Since we *know* that this entity will not be called, this is OK. */ -static void force_description (entity *ent, entity *addr) +static void force_description (ir_entity *ent, ir_entity *addr) { int i, n_over = get_entity_n_overwrittenby (ent); set_entity_peculiarity (ent, peculiarity_description); for (i = 0; i < n_over; i ++) { - entity *over = get_entity_overwrittenby (ent, i); + ir_entity *over = get_entity_overwrittenby (ent, i); if (peculiarity_inherited == get_entity_peculiarity (over)) { /* We rely on the fact that cse is performed on the const_code_irg. */ - entity *my_addr = get_SymConst_entity(get_atomic_ent_value(over)); + ir_entity *my_addr = get_SymConst_entity(get_atomic_ent_value(over)); if (addr == my_addr) { force_description (over, addr); @@ -332,9 +349,9 @@ static void force_description (entity *ent, entity *addr) } else if (peculiarity_existent == get_entity_peculiarity (over)) { /* check whether 'over' forces 'inheritance' of *our* graph: */ ir_node *f_addr = get_atomic_ent_value (over); - entity *impl_ent = get_SymConst_entity (f_addr); + ir_entity *impl_ent = get_SymConst_entity (f_addr); - assert ((get_irn_op(f_addr) == op_SymConst) && "can't do complex addrs"); + assert(is_SymConst(f_addr) && "can't do complex addrs"); if (impl_ent == addr) { assert (0 && "gibt's denn sowas"); force_description (over, addr); @@ -348,7 +365,8 @@ static void force_description (entity *ent, entity *addr) */ static void init_tables (void) { - int i, n_globs = get_class_n_members(get_glob_type()); + ir_type *tp; + int i, n; _live_classes = eset_create (); _live_graphs = eset_create (); @@ -358,8 +376,18 @@ static void init_tables (void) } /* Find static allocated classes */ - for (i = 0; i < n_globs; ++i) { - type *member_type = get_entity_type(get_class_member(get_glob_type(), i)); + tp = get_glob_type(); + n = get_class_n_members(tp); + for (i = 0; i < n; ++i) { + ir_type *member_type = get_entity_type(get_class_member(tp, i)); + if (is_Class_type(member_type)) + eset_insert(_live_classes, member_type); + } + + tp = get_tls_type(); + n = get_struct_n_members(tp); + for (i = 0; i < n; ++i) { + ir_type *member_type = get_entity_type(get_struct_member(tp, i)); if (is_Class_type(member_type)) eset_insert(_live_classes, member_type); } @@ -371,16 +399,20 @@ static void init_tables (void) */ void rta_init (int do_verbose) { - int i, n_runs = 0; + int n_runs = 0; int rem_vpi = get_visit_pseudo_irgs(); set_visit_pseudo_irgs(1); # ifdef DEBUG_libfirm - for (i = 0; i < get_irp_n_irgs(); i++) { - irg_vrfy (get_irp_irg(i)); + { + int i, n; + n = get_irp_n_irgs(); + for (i = 0; i < n; i++) { + irg_vrfy (get_irp_irg(i)); + } + tr_vrfy (); } - tr_vrfy (); # endif /* defined DEBUG_libfirm */ verbose = do_verbose; @@ -398,10 +430,14 @@ void rta_init (int do_verbose) } # ifdef DEBUG_libfirm - for (i = 0; i < get_irp_n_irgs(); i++) { - irg_vrfy (get_irp_irg(i)); + { + int i, n; + n = get_irp_n_irgs(); + for (i = 0; i < n; i++) { + irg_vrfy (get_irp_irg(i)); + } + tr_vrfy (); } - tr_vrfy (); # endif /* defined DEBUG_libfirm */ set_visit_pseudo_irgs(rem_vpi); @@ -413,9 +449,10 @@ void rta_init (int do_verbose) * Changes the peculiarity of entities that represents * dead graphs to peculiarity_description. */ -static void make_entity_to_description(type_or_ent *tore, void *env) { - if (get_kind(tore) == k_entity) { - entity *ent = (entity *)tore; +static void make_entity_to_description(type_or_ent tore, void *env) { + (void) env; + if (is_entity(tore.ent)) { + ir_entity *ent = tore.ent; if ((is_Method_type(get_entity_type(ent))) && (get_entity_peculiarity(ent) != peculiarity_description) && @@ -443,9 +480,7 @@ void rta_delete_dead_graphs (void) int rem_vpi = get_visit_pseudo_irgs(); set_visit_pseudo_irgs(1); - if (!get_optimize() || !get_opt_dead_method_elimination()) return; - - dead_graphs = xmalloc(sizeof(*dead_graphs) * get_irp_n_irgs()); + dead_graphs = XMALLOCN(ir_graph*, get_irp_n_irgs()); for (i = 0; i < n_graphs; i++) { graph = get_irp_irg(i); @@ -453,10 +488,10 @@ void rta_delete_dead_graphs (void) if (rta_is_alive_graph (graph)) { /* do nothing (except some debugging fprintf`s :-) */ } else { -# ifdef DEBUG_libfirm - entity *ent = get_irg_entity (graph); +#ifndef NDEBUG + ir_entity *ent = get_irg_entity (graph); assert (visibility_external_visible != get_entity_visibility (ent)); -# endif /* defined DEBUG_libfirm */ +#endif dead_graphs[n_dead_graphs] = graph; n_dead_graphs ++; @@ -500,7 +535,7 @@ void rta_cleanup (void) } /* Say whether this class might be instantiated at any point in the program: */ -int rta_is_alive_class (type *clazz) +int rta_is_alive_class (ir_type *clazz) { return (eset_contains (_live_classes, clazz)); } @@ -517,125 +552,15 @@ void rta_report (void) int i; for (i = 0; i < get_irp_n_types(); ++i) { - type *tp = get_irp_type(i); + ir_type *tp = get_irp_type(i); if (is_Class_type(tp) && rta_is_alive_class(tp)) { - fprintf(stdout, "RTA: considered allocated: "); DDMT(tp); + ir_fprintf(stdout, "RTA: considered allocated: %+F\n", tp); } } for (i = 0; i < get_irp_n_irgs(); i++) { if (rta_is_alive_graph (get_irp_irg(i))) { - fprintf(stdout, "RTA: considered called: graph of "); - DDMEO(get_irg_entity (get_irp_irg(i))); + ir_fprintf(stdout, "RTA: considered called: graph of %+F\n", get_irp_irg(i)); } } } - - -/* - * $Log$ - * Revision 1.34 2006/01/02 15:01:16 beck - * missing include added - * - * Revision 1.33 2005/11/17 17:26:57 beck - * removed bool type and depency from stdbool.h (not C89) - * - * Revision 1.32 2005/01/05 14:24:52 beck - * renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG frontend - * - * Revision 1.31 2004/12/21 13:45:14 beck - * removed C99 constructs - * - * Revision 1.30 2004/12/02 16:16:11 beck - * fixed config.h include - * used xmalloc instead of malloc - * - * Revision 1.29 2004/11/11 13:28:08 goetz - * made pseudo irg aware - * - * Revision 1.28 2004/11/03 14:47:18 beck - * removed gloval intraprocedural_view variable and replaced by get_*() set_*() functions - * - * Revision 1.27 2004/10/21 07:23:34 goetz - * comments - * - * Revision 1.26 2004/10/20 14:59:27 liekweg - * Removed ecg - * - * Revision 1.25 2004/10/18 12:47:08 liekweg - * avoid warning - * - * Revision 1.24 2004/09/24 13:59:04 beck - * fixed doxygen comments, removed initialization for description entities - * - * Revision 1.23 2004/08/19 16:51:02 goetz - * fixed some errors, pushed closer to inteded firm semantics - * - * Revision 1.22 2004/08/13 08:57:15 beyhan - * normalized names of functions, enums ... - * added suffix as argument to dumpers, removed global variable - * removed support for tarval/Const - * - * Revision 1.21 2004/07/08 15:50:56 goetz - * firmstat added - * - * Revision 1.20 2004/07/08 11:17:40 goetz - * *** empty log message *** - * - * Revision 1.19 2004/07/06 12:30:37 beyhan - * new SymConst semantics - * - * Revision 1.18 2004/06/27 21:17:41 liekweg - * Added comment - * - * Revision 1.17 2004/06/25 13:45:13 liekweg - * observe stickyness; minor refactoring - * - * Revision 1.16 2004/06/24 06:42:14 goetz - * test of firm flags - * - * Revision 1.15 2004/06/18 15:47:19 liekweg - * minor bug fix (go forward, not backward) --flo - * - * Revision 1.14 2004/06/18 13:12:43 liekweg - * final bug fix (calls via consts) - * - * Revision 1.13 2004/06/17 16:34:33 liekweg - * removed DD*s - * - * Revision 1.12 2004/06/17 16:33:33 liekweg - * minor bug fix - * - * Revision 1.11 2004/06/17 14:21:13 liekweg - * major bugfix - * - * Revision 1.10 2004/06/17 10:31:41 goetz - * irscc: bugfix, can now deal with loops not reachable from start - * cgana: bugfix, skip_Tuple - * rta: improved - * - * Revision 1.9 2004/06/17 08:56:03 liekweg - * Fixed typos in comments - * - * Revision 1.8 2004/06/17 08:33:01 liekweg - * Added comments; added remove_irg - * - * Revision 1.6 2004/06/14 13:02:03 goetz - * bugfixesbug - * - * Revision 1.5 2004/06/13 15:03:45 liekweg - * RTA auf Iterative RTA aufgebohrt --flo - * - * 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 - * - * Revision 1.2 2004/06/11 18:25:39 liekweg - * Added todo - * - * Revision 1.1 2004/06/11 18:24:18 liekweg - * Added RTA --flo - * - */