From d07b7388a477ce7ce7ceb5fcf427b8db040ff55e Mon Sep 17 00:00:00 2001 From: Florian Liekweg Date: Wed, 24 Nov 2004 14:53:56 +0000 Subject: [PATCH] Bugfixes [r4462] --- ir/ana2/ecg.c | 9 +- ir/ana2/pto.c | 1092 ------------------------------------------- ir/ana2/pto.h | 10 +- ir/ana2/pto_comp.c | 166 +++---- ir/ana2/pto_comp.h | 15 +- ir/ana2/pto_ctx.c | 5 +- ir/ana2/pto_debug.c | 5 +- ir/ana2/pto_debug.h | 5 +- ir/ana2/pto_init.c | 162 ++++++- ir/ana2/pto_init.h | 12 + ir/ana2/pto_name.c | 253 +++++++++- ir/ana2/pto_name.h | 79 +++- ir/ana2/pto_util.c | 52 +++ ir/ana2/pto_util.h | 8 + ir/ana2/qset.c | 72 ++- ir/ana2/qset.h | 14 +- 16 files changed, 687 insertions(+), 1272 deletions(-) delete mode 100644 ir/ana2/pto.c diff --git a/ir/ana2/ecg.c b/ir/ana2/ecg.c index fc64464ab..ac926db90 100644 --- a/ir/ana2/ecg.c +++ b/ir/ana2/ecg.c @@ -573,7 +573,11 @@ void ecg_iterate_graphs (graph_hnd_t *hnd, void *env) graph_info_t *ginfo = graph_infos_list; while (NULL != ginfo) { - hnd (ginfo, env); + /* do not visit graphs that have 0 == ginfo->n_ctxs, since they + are not called */ + if (0 != ginfo->n_ctxs) { + hnd (ginfo, env); + } ginfo = ginfo->prev; } @@ -1109,6 +1113,9 @@ void ecg_ecg () /* $Log$ + Revision 1.6 2004/11/24 14:53:55 liekweg + Bugfixes + Revision 1.5 2004/11/20 21:20:29 liekweg Added iterator functions diff --git a/ir/ana2/pto.c b/ir/ana2/pto.c deleted file mode 100644 index 65c0d1c77..000000000 --- a/ir/ana2/pto.c +++ /dev/null @@ -1,1092 +0,0 @@ -/* -*- c -*- */ - -/* - * Project: libFIRM - * File name: ir/ana2/pto.c - * Purpose: Pto - * Author: Florian - * Modified by: - * Created: Mon 18 Oct 2004 - * CVS-ID: $Id$ - * Copyright: (c) 1999-2004 Universität Karlsruhe - * Licence: This file is protected by GPL - GNU GENERAL PUBLIC LICENSE. - */ - - -# ifdef HAVE_CONFIG_H -# include -# endif - -# include "pto.h" -# include "pto_util.h" -# include "pto_init.h" - -# include "entity.h" - -# include "irnode.h" -# include "irprog.h" - -/* # include "eset.h" */ -# include "irgraph.h" -# include "irgwalk.h" -# include "irgmod.h" -# include "irvrfy.h" -# include "trvrfy.h" -# include "xmalloc.h" - -# include "typewalk.h" -# include "irmemwalk.h" - -# define DBGPRINT(lvl, msg) if (get_pto_verbose () > lvl) { fprintf msg; } -# define DBGEXE(lvl, cmd) if (get_pto_verbose () > lvl) { cmd; } - -/* - Local Protos -*/ -static void pto_node (ir_node*, void*); -static void pto_node_pre (ir_node*, void*); -static void pto_node_post (ir_node*, void*); - -/* - Get the pto infos of a node -*/ -static pto_t *get_pto (ir_node *node) -{ - - - return ((pto_t*) get_irn_link (node)); -} - -/* - Propagate pto values up to the given node, and return the propagated - value. This recursion has to stop at important nodes, such as - loads and allocs, where pto is computed differently (albeit this may - involve more calls to this function for a different ptr value). -*/ -static pto_t *compute_pto (ir_node *node, void *env) -{ - pto_t *node_pto = get_pto (node); - - if ((NULL != node_pto) && (pto_is_dummy (node_pto))) { - /* weed out initialisation data as good as possible */ - - DBGPRINT (0, (stdout, "%s: dummy pto for (%s[%li])\n", - __FUNCTION__, - get_op_name (get_irn_op (node)), - get_irn_node_nr (node))); - - pto_delete (node_pto); - node_pto = NULL; - } - - if (NULL == node_pto) { - DBGPRINT (1, (stdout, "%s: must compute pto for %s[%li]\n", - __FUNCTION__, - get_op_name (get_irn_op (node)), - get_irn_node_nr (node))); - - pto_node (node, env); - - node_pto = get_pto (node); - } - - assert (node_pto); - - return (node_pto); -} - -/* - Transfer the actual arguments to the given call's formal arguments -*/ -static void set_call_args (ir_node *call, ir_graph *graph, void *env) -{ - ir_node **args = find_irg_args (graph); - int i; - - const int n_call_args = get_irn_arity (call); - - /* call: M x meth_ptr x Arg x Arg x ... x Arg */ - /* projT(start): Arg x Arg x ... x Arg */ - /* projM(start): M */ - - for (i = 2; i < n_call_args; i ++) { - if (NULL != args [i-2]) { - if (mode_P == get_irn_mode (args [i-2])) { - pto_t *arg_pto = compute_pto (get_irn_n (call, i), env); - /* off-by-two because of ProjT bd */ - set_pto (args [i-2], arg_pto); - } else { - /* not a pointer value */ - } - } - } - free (args); -} - -/* - Transfer the return value of a call to the callR node -*/ -static void get_call_ret (ir_node *call, ir_graph *graph, void *env) -{ - entity *ent = get_irg_ent (graph); - type *ent_tp = get_entity_type (ent); - - if (NULL != get_pto (call)) { - pto_t *old = get_pto (call); - - if (pto_is_dummy (old)) { - DBGPRINT (2, (stdout, "%s: dummy pto (0x%08x) from call[%li]\n", - __FUNCTION__, (int) old, get_irn_node_nr (call))); - } - - pto_delete (old); - } - - if (0 != get_method_n_ress (ent_tp)) { - type *ent_ret_tp = get_method_res_type (ent_tp, 0); - - if (mode_P == get_type_mode (ent_ret_tp)) { - pto_t *res_pto = get_pto (get_irg_end_block (graph)); - - set_pto (call, res_pto); - } - } -} - - -/* - Take care of a single proj node. Basically a multiplex/dispatch for the - different node types that a proj can have as a predecessor. -*/ -static void pto_node_proj (ir_node *proj, void *env) -{ - /* - pto for proj({proj(start),load,call,alloc,raise?,...}) node - */ - ir_node *in = get_Proj_pred (proj); - const opcode in_op = get_irn_opcode (in); - const long proj_proj = get_Proj_proj (proj); - - DBGPRINT (3, (stdout, "%s: --> Proj[%li] (%s)\n", - __FUNCTION__, - get_irn_node_nr (proj), - get_op_name (get_irn_op (in)))); - - switch (in_op) { - case (iro_Start): { - /* nothing (handled by proj(proj)) */ - } break; - - case (iro_Load): { - /* copy from load */ - if (pn_Load_res == proj_proj) { - set_pto (proj, compute_pto (in, env)); - } else { - /* ProjM(load) or ProjX(load) - do nothing */ - } - } break; - - case (iro_Store): { - /* ProjM (store) or ProjX (store) - nothing */ - } break; - - case (iro_Alloc): { - /* copy from alloc */ - if (pn_Alloc_res == proj_proj) { - set_pto (proj, compute_pto (in, env)); - } else { - /* ProjM(alloc) or ProjX (alloc) -- nothing */ - } - } break; - - case (iro_Raise): { - /* ProjX (raise), ProjM (raise) -- nothing */ - } break; - - case (iro_Call): { - if (pn_Call_M_regular == proj_proj) { - /* ProjM(call) -- nothing */ - } else if (pn_Call_T_result == proj_proj) { - /* copy return value of call */ - pto_t *call_pto = get_pto (in); /* get result from call */ - assert (call_pto); - set_pto (proj, call_pto); - } else if (pn_Call_P_value_res_base == proj_proj) { - /* wtf? */ - assert (0 && "what's with pn_Call_P_value_res_base?"); - } else { - /* ProjX (call) or ProjM_exc (call) -- nothing */ - } - - } break; - - case (iro_Proj): { - const ir_node *in_in = get_Proj_pred (in); - const opcode in_in_op = get_irn_opcode (in_in); - - switch (in_in_op) { - case (iro_Call): { - /* projP (projT (call)) */ - /* copy from projT to projP */ - pto_t *in_pto = compute_pto (in, env); - set_pto (proj, in_pto); - } break; - case (iro_Start): { - /* proj(proj(start)) - make sure the arguments are initialised */ - assert (get_pto (proj)); - } break; - default: { - DBGPRINT (1, (stdout, "%s:%i: proj(proj(%s)) not handled\n", - __FILE__, __LINE__, get_op_name (get_irn_op (in_in)))); - assert (0); - } - } - } break; - - case (iro_Cast): { - /* make sure the input has been analysed */ - pto_t *cast_pto = compute_pto (in, env); - set_pto (proj, cast_pto); - - } break; - - default: { - fprintf (stderr, "%s: opcode %s of Node %ld not handled\n", - __FUNCTION__, - get_op_name (get_irn_op (in)), - get_irn_node_nr (in)); - - assert (0 && "something not handled"); - } - } - - DBGPRINT (2, (stdout, "%s: Proj (%s)\n", - __FUNCTION__, - get_op_name (get_irn_op (in)))); -} - -static void pto_node_obj_load (ir_node *load, ir_node *ptr, - entity *ent, void *env) -{ - /* - pto for obj load node - - so far: - load.ptr analysed - todo: - look up - */ - const char *ent_name = (char*) get_entity_name (ent); - const char *own_name = (char*) get_type_name (get_entity_owner (ent)); - - DBGPRINT (1, (stdout, "%s for (%s[%li])\n", - __FUNCTION__, - get_op_name (get_irn_op (ptr)), - get_irn_node_nr (ptr))); - - if (! is_pointer_type (get_entity_type (ent))) { - return; - } - - if (NULL != get_pto (load)) { - pto_t *old = get_pto (load); - - if (pto_is_dummy (old)) { - DBGPRINT (1, (stdout, "%s: dummy pto (0x%08x) from load[%li]\n", - __FUNCTION__, (int) old, get_irn_node_nr (load))); - } - - pto_delete (old); - } - - DBGPRINT (1, (stdout, "%s: obj load from ent (0x%08x) \"%s.%s\"\n", - __FUNCTION__, - (int) ent, - own_name, - ent_name)); - - pto_t *ptr_objs = compute_pto (ptr, env); - qset_t *objs = ptr_objs->objs; - pto_t *res = pto_new_empty (load); - obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs); - - DBGPRINT (1, (stdout, "%s: ptr_pto = ", __FUNCTION__)); - DBGEXE (1, qset_print (objs, stdout)); - - while (NULL != obj_desc) { - qset_t *cnts = pto_lookup (obj_desc, ent); - - DBGPRINT (1, (stdout, "%s: cnts = ", __FUNCTION__)); - DBGEXE (1, qset_print (cnts, stdout)); - - pto_add_all_names (res, cnts); - - obj_desc = (obj_desc_t*) qset_next (objs); - } - - set_pto (load, res); - - DBGPRINT (1, (stdout, "%s\n", __FUNCTION__)); -} - -static void pto_node_arr_load (ir_node *load, ir_node *ptr, - entity *ent, void *env) -{ - /* - pto for array load node - - so far: - load.ptr analysed or can be computed on-the-fly - todo: - look up - */ - const char *ent_name = (char*) get_entity_name (ent); - const char *own_name = (char*) get_type_name (get_entity_owner (ent)); - - /* load from array */ - DBGPRINT (1, (stdout, "%s for (%s[%li])\n", - __FUNCTION__, - get_op_name (get_irn_op (ptr)), - get_irn_node_nr (ptr))); - - if (! is_pointer_type (get_entity_type (ent))) { - return; - } - - DBGPRINT (1, (stdout, "%s: array load from ent (0x%08x) \"%s.%s\"\n", - __FUNCTION__, - (int) ent, - own_name, - ent_name)); - - pto_t *ptr_objs = compute_pto (ptr, env); - qset_t *objs = ptr_objs->objs; - pto_t *res = pto_new_empty (load); - - obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs); - - while (NULL != obj_desc) { - qset_t *cnts = pto_lookup (obj_desc, NULL); - - pto_add_all_names (res, cnts); - - obj_desc = (obj_desc_t*) qset_next (objs); - } - - set_pto (load, res); -} - -static void pto_node_load (ir_node *load, void *env) -{ - /* - pto for load node - - so far: - load.ptr analysed or can be computed on-the-fly - todo: - look up - */ - ir_node *ptr = get_Load_ptr (load); - const opcode op = get_irn_opcode (ptr); - entity *ent = NULL; - - /* check the funny cases */ - if (iro_Proj == op) { - /* then it's an unused Load(this) (or whatever) and we don't need to look at it */ - DBGPRINT (1, (stderr, "%s: %s[%li] ignored\n", - __FUNCTION__, - get_op_name (get_irn_op (ptr)), - get_irn_node_nr (ptr))); - return; - } else if (iro_Cast == op) { - /* then it's (whatever) and we don't know where to look at */ - DBGPRINT (1, (stderr, "%s: %s[%li] ignored\n", - __FUNCTION__, - get_op_name (get_irn_op (ptr)), - get_irn_node_nr (ptr))); - return; - } - - ent = get_ptr_ent (ptr); - - assert (ent); - - /* array load or obj load? */ - if ((iro_Sel == op) && (3 == get_irn_arity (ptr))) { - pto_node_arr_load (load, ptr, ent, env); - } else { - pto_node_obj_load (load, ptr, ent, env); - } - -} - -static void pto_node_obj_store (ir_node *store, - ir_node *ptr, - entity *ent, - ir_node *val, - void *env) -{ - /* - pto for obj store node - - so far: ptr analysed or can be computed on-the-fly - todo: - update - */ - - - const char *ent_name = (char*) get_entity_name (ent); - const char *own_name = (char*) get_type_name (get_entity_owner (ent)); - - DBGPRINT (1, (stdout, "%s: obj store to ent (0x%08x) \"%s.%s\"\n", - __FUNCTION__, - (int) ent, own_name, ent_name)); - - pto_t *ptr_pto = compute_pto (ptr, env); - pto_t *val_pto = compute_pto (val, env); - qset_t *objs = ptr_pto->objs; - qset_t *vals = val_pto->objs; - - obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs); - - DBGPRINT (1, (stdout, "%s: ptr_pto = ", __FUNCTION__)); - DBGEXE (1, qset_print (objs, stdout)); - - DBGPRINT (1, (stdout, "%s: ptr_val = ", __FUNCTION__)); - DBGEXE (1, qset_print (vals, stdout)); - - while (NULL != obj_desc) { - qset_t *cnts = pto_lookup (obj_desc, ent); - - qset_insert_all (cnts, vals); - - DBGPRINT (1, (stdout, "%s: cnts = ", __FUNCTION__)); - DBGEXE (1, qset_print (cnts, stdout)); - - obj_desc = (obj_desc_t*) qset_next (objs); - } - - DBGPRINT (1, (stdout, "%s\n", __FUNCTION__)); -} - -static void pto_node_arr_store (ir_node *store, - ir_node *ptr, - entity *ent, - ir_node *val, - void *env) -{ - /* - pto for array store node - - so far: ptr analysed or can be computed on-the-fly - todo: - update - */ - - const char *ent_name = (char*) get_entity_name (ent); - const char *own_name = (char*) get_type_name (get_entity_owner (ent)); - - DBGPRINT (1, (stdout, "%s: array store to ent (0x%08x) \"%s.%s\"\n", - __FUNCTION__, - (int) ent, own_name, ent_name)); - - pto_t *ptr_pto = compute_pto (ptr, env); - pto_t *val_pto = compute_pto (val, env); - qset_t *objs = ptr_pto->objs; - qset_t *vals = val_pto->objs; - - obj_desc_t *obj_desc = (obj_desc_t*) qset_start (objs); - - while (NULL != obj_desc) { - qset_t *cnts = pto_lookup (obj_desc, NULL); - - qset_insert_all (cnts, vals); - - obj_desc = (obj_desc_t*) qset_next (objs); - } -} - -static void pto_node_store (ir_node *store, void *env) -{ - /* - pto for store node - - so far: ptr analysed or can be computed on-the-fly - todo: - update - */ - - ir_node *ptr = get_Store_ptr (store); - ir_node *val = get_Store_value (store); - const opcode op = get_irn_opcode (ptr); - entity *ent = get_ptr_ent (ptr); - - if (mode_P != get_irn_mode (val)) { - return; - } - - /* array load or obj load? */ - if ((iro_Sel == op) && (3 == get_irn_arity (ptr))) { - pto_node_arr_store (store, ptr, ent, val, env); - } else { - pto_node_obj_store (store, ptr, ent, val, env); - } - -} - -static void pto_node_alloc (ir_node *alloc, void *env) -{ - /* - pto for alloc node - - so far: nothing to do - todo: - invent new name - */ - - if (NULL == get_pto (alloc)) { - type *tp = get_Alloc_type (alloc); - - pto_t *alloc_pto = pto_new_name (alloc, tp); - set_pto (alloc, alloc_pto); - DBGPRINT (0, (stdout, "%s (%s[%li]): new pto\n", - __FUNCTION__, - get_op_name (get_irn_op (alloc)), - get_irn_node_nr (alloc))); - } else { - DBGPRINT (0, (stdout, "%s (%s[%li]): reusing pto\n", - __FUNCTION__, - get_op_name (get_irn_op (alloc)), - get_irn_node_nr (alloc))); - } - -} - -static void pto_node_free (ir_node *free, void *env) -{ - /* - pto for free node - - so far: ptr analysed or can be computed on-the-fly - todo: - nothing, actually - */ - /* still, copy somthing */ - ir_node *ptr = get_Free_ptr (free); - - pto_t *ptr_pto = compute_pto (ptr, env); - set_pto (free, ptr_pto); -} - -static void pto_node_raise (ir_node *raise, void *env) -{ - /* - pto for raise node - - so far: ptr analysed or can be computed on-the-fly - todo: - - */ - - /* right now, just copy something */ - ir_node *ptr = get_Raise_exo_ptr (raise); - - pto_t *ptr_pto = compute_pto (ptr, env); - - set_pto (raise, ptr_pto); -} - -static void pto_node_sel (ir_node *sel, void *env) -{ - /* - pto for sel node - - so far: input selected or can be computed on-the-fly - todo: - just copy (the selected entity is used in the load/store) - */ - - ir_node *sel_in = get_Sel_ptr (sel); - pto_t *sel_pto = compute_pto (sel_in, env); - - if (NULL == sel_pto) { - fprintf (stdout, "%s:%i: sel.in = %s[%li]\n", - __FUNCTION__, __LINE__, - get_op_name (get_irn_op (sel_in)), - get_irn_node_nr (sel_in)); - } - assert (sel_pto); - - set_pto (sel, sel_pto); -} - -static void pto_node_call (ir_node *call, void *env) -{ - ir_graph *graph = NULL; - ir_node *ptr = get_Call_ptr (call); - entity *ent = get_ptr_ent (ptr); - - DBGPRINT (1, (stdout, "%s (%s[%li])\n", - __FUNCTION__, - get_op_name (get_irn_op (call)), - get_irn_node_nr (call))); - - - const char *ent_name = (char*) get_entity_name (ent); - const char *own_name = (char*) get_type_name (get_entity_owner (ent)); - - /* Todo: Iterate over all graphs in 'get_implementing_graphs' */ - graph = get_entity_irg (ent); - if (NULL != graph) { - if (! get_irg_is_mem_visited (graph)) { - DBGPRINT (1, (stdout, " -> visit graph (0x%08x) of \"%s.%s\"\n", - (int) graph, own_name, ent_name)); - - /* compute call arguments */ - set_call_args (call, graph, env); - /* traverse callEd */ - irg_walk_mem (graph, pto_node_pre, pto_node_post, NULL); - /* maybe get result from called graph */ - get_call_ret (call, graph, env); - } - } else { - DBGPRINT (0, (stdout, "%s:%i: Warning: no graph for ent \"%s.%s\" in call[%li]\n", - __FILE__, __LINE__, own_name, ent_name, get_irn_node_nr (call))); - } -} - -static void pto_node_ret (ir_node *ret, void *env) -{ - /* - pto for return node - - so far: - input should be availlable - todo: - just copy - */ - - if ((0 != get_Return_n_ress (ret)) && - (mode_P == get_irn_mode (get_Return_res (ret, 0)))) { - ir_node *ret_in = get_Return_res (ret, 0); - - pto_t *ret_pto = compute_pto (ret_in, env); - - DBGPRINT (4, (stdout, "--> Return Node (%ld) (%s)\n", - get_irn_node_nr (ret), - get_op_name (get_irn_op (ret)))); - - set_pto (ret, ret_pto); - } else { - /* nothing to do! */ - } -} - -static void pto_node_phi (ir_node *phi, void *env) -{ - /* - pto for phi node - - so far: - all ins present or can be computed on-the-fly - todo: - collect ins - */ - - int i; - int n_ins = get_irn_arity (phi); - ir_node *in = NULL; - - if (mode_P != get_irn_mode (phi)) { - return; - } - - assert (0 && "test phi"); - - pto_t *phi_pto = get_pto (phi); - - if (NULL == phi_pto) { - phi_pto = pto_new_empty (phi); - set_pto (phi, phi_pto); - } - - for (i = 0; i < n_ins; i ++) { - in = get_irn_n (phi, i); - - pto_t *in_pto = compute_pto (in, env); - - DBGPRINT (0, (stdout, "%s: IN PHI Node (%ld) (%s) (pto = 0x%08x)\n", - __FUNCTION__, - get_irn_node_nr (in), - get_op_name (get_irn_op (in)), - (int) in_pto)); - - qset_insert_all (phi_pto->objs, in_pto->objs); - } -} - -static void pto_node_cnst (ir_node *cnst, void *env) -{ - /* - pto for const node - - so far: nothing - todo: - if this represents something nameable, name it - */ - type *tp = get_Const_type (cnst); - pto_t *cnst_pto = pto_new_name (cnst, tp); /* WRONG */ - - - set_pto (cnst, cnst_pto); -} - -static void pto_node_sym_cnst (ir_node *sym_cnst, void *env) -{ - /* - pto for const node - - so far: nothing - todo: - if this represents something nameable, name it - */ - entity *ent = get_SymConst_entity (sym_cnst); - type *tp = get_entity_type (ent); - - if (is_pointer_type (tp)) { - tp = get_pointer_points_to_type (tp); - pto_t *sym_cnst_pto = (pto_t*) get_entity_link (ent); - - DBGPRINT (2, (stdout, "%s: SymConst (%ld) (%s)\n", - __FUNCTION__, - get_irn_node_nr (sym_cnst), - get_op_name (get_irn_op (sym_cnst)))); - - - if (NULL == sym_cnst_pto) { - sym_cnst_pto = pto_new_name (sym_cnst, tp); - - DBGPRINT (1, (stdout, "%s: SymConst (%ld) (%s): NEW PTO\n", - __FUNCTION__, - get_irn_node_nr (sym_cnst), - get_op_name (get_irn_op (sym_cnst)))); - - set_entity_link (ent, sym_cnst_pto); - } else { - DBGPRINT (1, (stdout, "%s: SymConst (%ld) (%s): reusing pto\n", - __FUNCTION__, - get_irn_node_nr (sym_cnst), - get_op_name (get_irn_op (sym_cnst)))); - } - - set_pto (sym_cnst, sym_cnst_pto); - } else { - /* nothing to do */ - } -} - -static void pto_node_end_block (ir_node *end, void *env) -{ - /* - pto for const node - - so far: all returns are set or can be computed on-the-fly - todo: - collect results, set to node. - */ - entity *ent = get_irg_entity (get_irn_irg (end)); - type *tp = get_entity_type (ent); - - DBGPRINT (2, (stdout, "%s: End Block (%ld) (%s)\n", - __FUNCTION__, - get_irn_node_nr (end), - get_op_name (get_irn_op (end)))); - - if (0 != get_method_n_ress (tp)) { - tp = get_method_res_type (tp, 0); - - if (mode_P == get_type_mode (tp)) { - int i; - int n_ins = get_irn_arity (end); - pto_t *end_pto = pto_new_empty (end); - - for (i = 0; i < n_ins; i ++) { - ir_node *ret = get_irn_n (end, i); - - if (iro_Return == get_irn_opcode (ret)) { - pto_t *ret_pto = get_pto (ret); - assert (ret_pto); - - pto_add_all_names (end_pto, ret_pto->objs); - } - } - - set_pto (end, end_pto); - } - } -} - -/* - Take care of a single node. Basically a multiplex/dispatch for the - different node types. -*/ -static void pto_node (ir_node *node, void *env) -{ - const opcode op = get_irn_opcode (node); - - DBGPRINT (1, (stdout, "%s (%s[%li])\n", - __FUNCTION__, - get_op_name (get_irn_op (node)), - get_irn_node_nr (node))); - - switch (op) { - case (iro_Start): { - /* pto_node_start (node, env); */ - /* nothing to do */ - - } break; - case (iro_Load): { - pto_node_load (node, env); - - } break; - case (iro_Store): { - pto_node_store (node, env); - - } break; - case (iro_Alloc): { - pto_node_alloc (node, env); - - } break; - case (iro_Free): { - pto_node_free (node, env); - - } break; - case (iro_Raise): { - pto_node_raise (node, env); - - } break; - case (iro_Sel): { - pto_node_sel (node, env); - - } break; - case (iro_Call): { - /* assert (0 && "calls must be handled in main loop"); */ - pto_node_call (node, env); - } break; - case (iro_Return): { - if (0 < get_Return_n_ress (node)) { - pto_node_ret (node, env); - } - } break; - case (iro_Proj): { - pto_node_proj (node, env); - } break; - case (iro_Phi): { - pto_node_phi (node, env); - } break; - case (iro_Const): { - pto_node_cnst (node, env); - } break; - case (iro_SymConst): { - pto_node_sym_cnst (node, env); - } break; - case (iro_Cast): { - pto_t *cast_pto = compute_pto (get_Cast_op (node), env); - set_pto (node, cast_pto); - } break; - case (iro_Block): { - /* End Block ONLY */ - pto_node_end_block (node, env); - } break; - /* all the uninteresting stuff */ - case (iro_Div): - case (iro_Quot): - case (iro_Mod): - case (iro_DivMod): - set_pto (node, NULL); - break; - default: { - /* stopgap measure */ - DBGPRINT (0, (stdout, "%s: not handled: node[%li].op = %s\n", - __FUNCTION__, - get_irn_node_nr (node), - get_op_name (get_irn_op (node)))); - assert (0 && "something not handled"); - } - } -} -static void pto_node_pre (ir_node *node, void *env) -{ - DBGPRINT (1, (stdout, "%s (%s[%li])\n", - __FUNCTION__, - get_op_name (get_irn_op (node)), - get_irn_node_nr (node))); - - pto_init_node (node); -} - -static void pto_node_post (ir_node *node, void *env) -{ - DBGPRINT (1, (stdout, "%s (%s[%li])\n", - __FUNCTION__, - get_op_name (get_irn_op (node)), - get_irn_node_nr (node))); - - pto_node (node, env); -} - -static int pto_verbose = 0; - -/* - Helper to pto_init --- clear the link fields of class types -*/ -static void clear_type_link (type_or_ent *thing, void *__unused) -{ - if (is_type (thing)) { - type *tp = (type*) thing; - - if (is_class_type (tp)) { - DBGPRINT (1, (stdout, "%s (\"%s\")\n", - __FUNCTION__, get_type_name (tp))); - - set_type_link (tp, NULL); - } - } else if (is_entity (thing)) { - entity *ent = (entity*) thing; - - DBGPRINT (1, (stdout, "%s (\"%s\")\n", - __FUNCTION__, get_entity_name (ent))); - - set_entity_link (ent, NULL); - } -} - -/* - Helper to pto_cleanup --- deallocate the field closure lists and clear the link fields of class types -*/ -static void free_field_list (type_or_ent *thing, void *__unused) -{ - if (is_type) { - type *tp = (type*) thing; - - if (is_class_type (tp)) { - if (NULL != get_type_link (tp)) { - entity **fields = (entity**) get_type_link (tp); - - free (fields); - } - - set_type_link (tp, NULL); - } - } -} - - -void set_pto (ir_node *node, pto_t *pto) -{ - check_pto (pto); - - set_irn_link (node, (void*) pto); -} - -int get_pto_verbose () -{ - return (pto_verbose); -} - -void set_pto_verbose (int verbose) -{ - pto_verbose = verbose; -} - -/* - Initialise Pto -*/ -void pto_init () -{ - type_walk (clear_type_link, NULL, NULL); -} - - -/* - Run Pto -*/ -void pto_run (int do_verbose) -{ - /* int i; */ - set_pto_verbose (do_verbose); - set_pto_verbose (2); - - DBGPRINT (0, (stdout, "START PTO\n")); - - ir_graph *graph = get_irp_main_irg (); - - DBGPRINT (0, (stdout, "START GRAPH (0x%08x) of \"%s.%s\"\n", - (int) graph, - get_type_name (get_entity_owner (get_irg_entity (graph))), - get_entity_name (get_irg_entity (graph)))); - - /* Set args for main graph */ - { - type *meth_tp = get_entity_type (get_irg_entity (graph)); - type *param_tp = get_method_param_type (meth_tp, 1); - param_tp = get_pointer_points_to_type (param_tp); - - const long n_args = /* wtf? */ - get_method_n_params (meth_tp); - ir_node **args = find_irg_args (graph); - pto_t *main_pto = pto_new_name (args [1], param_tp); - int i; - - for (i = 0; i < n_args; i ++) { - DBGPRINT (2, (stdout, "arg [%i] = %s[%ld]\n", - i, - args [i] ? get_op_name (get_irn_op (args [i])) : "none", - args [i] ? get_irn_node_nr (args [i]) : -1)); - } - set_pto (args [1], main_pto); - - free (args); - } - - irg_walk_mem (graph, pto_node_pre, pto_node_post, NULL); - - DBGPRINT (0, (stdout, "END GRAPH (0x%08x)\n", (int) graph)); - DBGPRINT (0, (stdout, "END PTO\n")); - - obj_desc_list_all (NULL); -} - -/* - Clean Up -*/ -void pto_cleanup () -{ - type_walk (free_field_list, NULL, NULL); -} - - - -/* - * $Log$ - * Revision 1.6 2004/11/09 16:47:09 liekweg - * fix SymConst handling - * - * Revision 1.5 2004/11/08 12:33:06 liekweg - * initialisation; sanitize print levels, misc fixes - * - * Revision 1.4 2004/11/04 14:58:38 liekweg - * expanded pto, added initialisation, added debugging printing - * - * Revision 1.3 2004/10/25 11:59:45 liekweg - * Copy Only works - * - * Revision 1.2 2004/10/21 11:09:37 liekweg - * Moved memwalk stuf into irmemwalk - * Moved lset stuff into lset - * Moved typalise stuff into typalise - * - * Revision 1.1 2004/10/20 14:59:42 liekweg - * Added ana2, added ecg and pto - * - */ diff --git a/ir/ana2/pto.h b/ir/ana2/pto.h index a288daeff..eee19008a 100644 --- a/ir/ana2/pto.h +++ b/ir/ana2/pto.h @@ -3,7 +3,7 @@ /* Project: libFIRM File name: ir/ana/pto.h - Purpose: Import all includes needed for PTO + Purpose: Import all includes needed for PTO/Entry to PTO Author: Florian Modified by: Created: Sat Nov 13 19:35:27 CET 2004 @@ -21,6 +21,7 @@ /* =================================================== Global Defines: =================================================== */ +# define N_INITIAL_OJBS 10 /* =================================================== Global Data Types: @@ -29,6 +30,10 @@ /* =================================================== Global Prototypes: =================================================== */ +/* Perform PTO on all visible graphs. */ +void pto_init (int); +void pto_run (void); +void pto_cleanup (void); /* =================================================== Global Variables: @@ -41,6 +46,9 @@ /* $Log$ + Revision 1.6 2004/11/24 14:53:55 liekweg + Bugfixes + Revision 1.5 2004/11/18 16:37:07 liekweg rewrite diff --git a/ir/ana2/pto_comp.c b/ir/ana2/pto_comp.c index fc0514986..ae8f0cb95 100644 --- a/ir/ana2/pto_comp.c +++ b/ir/ana2/pto_comp.c @@ -24,6 +24,7 @@ # include "pto_comp.h" # include "pto_util.h" +# include "pto_name.h" # include "pto_ctx.h" # include "irnode.h" @@ -40,7 +41,7 @@ /* Local Data Types: */ typedef struct pto_env_str { - int dummy; + int ctx_idx; } pto_env_t; @@ -50,7 +51,6 @@ typedef struct pto_env_str { char *spaces = NULL; /* Local Prototypes: */ -static void pto_graph (ir_graph*); static void pto_call (ir_graph*, ir_node*, pto_env_t*); /* =================================================== @@ -66,16 +66,20 @@ static pto_t *get_pto_proj (ir_node *proj) pto_t *in_pto = NULL; pto_t *proj_pto = get_node_pto (proj); + ir_node *proj_in_in = NULL; + switch (in_op) { case (iro_Start): /* ProjT (Start) */ assert (0 && "pto from ProjT(Start) requested"); return (NULL); case (iro_Proj): /* ProjT (Start), ProjT (Call) */ - assert ((pn_Start_T_args == proj_proj) || - (pn_Call_T_result == proj_proj)); - ir_node *proj_in_in = get_Proj_pred (proj_in); + proj_in_in = get_Proj_pred (proj_in); const opcode in_in_op = get_irn_opcode (proj_in_in); + const long proj_in_proj = get_Proj_proj (proj_in); + + assert ((pn_Start_T_args == proj_in_proj) || + (pn_Call_T_result == proj_in_proj)); switch (in_in_op) { case (iro_Start): /* ProjArg (ProjT (Start)) */ @@ -105,7 +109,7 @@ static pto_t *get_pto_proj (ir_node *proj) if (NULL != proj_pto) { return (proj_pto); } else { - in_pto = get_alloc_pto (proj_in); + in_pto = get_node_pto (proj_in); assert (in_pto); set_node_pto (proj, in_pto); @@ -126,6 +130,20 @@ static pto_t *get_pto_phi (ir_node *phi) return (NULL); } +static pto_t *get_pto_sel (ir_node *sel) +{ + pto_t *pto = get_node_pto (sel); + + if (NULL == pto) { + ir_node *in = get_Sel_ptr (sel); + + pto = get_node_pto (in); + set_node_pto (sel, pto); + } + + return (pto); +} + static pto_t *get_pto_ret (ir_node *ret) { pto_t *pto = get_node_pto (ret); @@ -150,6 +168,7 @@ static pto_t *get_pto (ir_node *node) case (iro_Cast): return (get_pto (get_Cast_op (node))); case (iro_Proj): return (get_pto_proj (node)); case (iro_Phi): return (get_pto_phi (node)); + case (iro_Sel): return (get_pto_sel (node)); case (iro_Return): return (get_pto_ret (node)); default: @@ -168,20 +187,25 @@ static pto_t *get_pto (ir_node *node) static void pto_load (ir_node *load, pto_env_t *pto_env) { /* perform load */ - DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__, OPNAME (load), OPNUM (load))); + DBGPRINT (0, (stdout, "%s (%s[%li]): pto = %p\n", __FUNCTION__, OPNAME (load), OPNUM (load), (void*) get_node_pto (load))); + + ir_node *ptr = get_Load_ptr (load); + pto_t *ptr_pto = get_pto (ptr); + + DBGPRINT (0, (stdout, "%s (%s[%li]): ptr = %p\n", __FUNCTION__, OPNAME (ptr), OPNUM (ptr), (void*) ptr_pto)); } static void pto_store (ir_node *store, pto_env_t *pto_env) { /* perform store */ - DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__, + DBGPRINT (0, (stdout, "%s (%s[%li]) (no pto)\n", __FUNCTION__, OPNAME (store), OPNUM (store))); } static void pto_method (ir_node *call, pto_env_t *pto_env) { - DBGPRINT (0, (stdout, "%s:%i (%s[%li])\n", - __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call))); + DBGPRINT (0, (stdout, "%s:%i (%s[%li]): pto = %p\n", + __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call), (void*) get_node_pto (call))); callEd_info_t *callEd_info = ecg_get_callEd_info (call); @@ -190,7 +214,11 @@ static void pto_method (ir_node *call, pto_env_t *pto_env) DBGPRINT (0, (stdout, "%s:%i (%s[%li]), graph %i\n", __FUNCTION__, __LINE__, OPNAME (call), OPNUM (call), i ++)); - pto_call (callEd_info->callEd, call, pto_env); + /* dike this out until we do procedure arguments and return + values */ + if (0) { + pto_call (callEd_info->callEd, call, pto_env); + } callEd_info = callEd_info->prev; } @@ -221,11 +249,11 @@ static void pto_call (ir_graph *graph, ir_node *call, pto_env_t *pto_env) /* Todo: Compute Arguments */ - /* Initialise Alloc Names and Node values */ - pto_reset_graph_pto (graph, ctx_idx); + /* Initialise Alloc Names and Node values (nope, done in pto_graph ()) */ + /* pto_reset_graph_pto (graph, ctx_idx); */ /* Visit/Iterate Graph */ - pto_graph (graph); + pto_graph (graph, ctx_idx); /* Restore CTX */ set_curr_ctx (old_ctx); @@ -249,15 +277,16 @@ static void pto_call (ir_graph *graph, ir_node *call, pto_env_t *pto_env) static void pto_raise (ir_node *raise, pto_env_t *pto_env) { /* perform raise */ - DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__, - OPNAME (raise), OPNUM (raise))); + DBGPRINT (0, (stdout, "%s (%s[%li]): pto = %p\n", __FUNCTION__, + OPNAME (raise), OPNUM (raise), (void*) get_node_pto (raise))); } static void pto_end_block (ir_node *end_block, pto_env_t *pto_env) { /* perform end block */ - DBGPRINT (0, (stdout, "%s (%s[%li])\n", __FUNCTION__, - OPNAME (end_block), OPNUM (end_block))); + DBGPRINT (0, (stdout, "%s (%s[%li]): pto = %p\n", __FUNCTION__, + OPNAME (end_block), OPNUM (end_block), + (void*) get_node_pto (end_block))); } /* Perform the appropriate action on the given node */ @@ -349,11 +378,23 @@ static void pto_graph_pass (ir_graph *graph, void *pto_env) } +/* =================================================== + Exported Implementation: + =================================================== */ /* Main loop: Initialise and iterate over the given graph */ -static void pto_graph (ir_graph *graph) +void pto_graph (ir_graph *graph, int ctx_idx) { pto_env_t *pto_env = xmalloc (sizeof (pto_env_t)); - HERE ("start"); + pto_env->ctx_idx = ctx_idx; + + /* HERE ("start"); */ + + DBGPRINT (0, (stdout, "%s: start for ctx %i\n", + __FUNCTION__, + ctx_idx)); + + /* todo: pto_reset_graph_pto */ + pto_reset_graph_pto (graph, ctx_idx); /* todo (here): iterate, obey 'changed' attribute */ pto_graph_pass (graph, pto_env); @@ -363,27 +404,6 @@ static void pto_graph (ir_graph *graph) HERE ("end"); } -/* "Fake" the arguments to the main method */ -static void fake_main_args (ir_graph *graph) -{ - HERE ("start"); - /* todo: fake the arguments to the main method */ - - HERE ("end"); -} - -/* Helper to pto_init */ -static void pto_init_graph_wrapper (graph_info_t *ginfo, void *__unused) -{ - ir_graph *graph = ginfo->graph; - - pto_init_graph (graph); -} - - -/* =================================================== - Exported Implementation: - =================================================== */ /* Set the PTO value for the given non-alloc node */ void set_node_pto (ir_node *node, pto_t *pto) { @@ -418,70 +438,12 @@ pto_t *get_alloc_pto (ir_node *alloc) return (alloc_pto -> curr_pto); } -/* Initialise the module (not in pto_init.c because it's the entry to pto) */ -void pto_init () -{ - HERE ("start"); - ecg_init (1); - - /* todo: initialise globals etc */ - pto_init_type_names (); - - /* todo: allocate ctx-sens names for allocs and set ... etc etc */ - pto_init_type_names (); - - ecg_iterate_graphs (pto_init_graph_wrapper, NULL); - - spaces = (char*) xmalloc (512 * sizeof (char)); - memset (spaces, ' ', 512); - spaces += 511; - *spaces = '\0'; - - /* initialise for the CTX-sensitive ecg-traversal */ - set_curr_ctx (get_main_ctx ()); - HERE ("end"); -} - -void pto_run (int dbg_lvl) -{ - HERE ("start"); - set_dbg_lvl (dbg_lvl); - - ir_graph *graph = get_irp_main_irg (); - fake_main_args (graph); - - /* todo: clear entity/type links */ - - DBGPRINT (0, (stdout, "START PTO\n")); - DBGPRINT (0, (stdout, "START GRAPH (0x%08x) of \"%s.%s\"\n", - (int) graph, - get_type_name (get_entity_owner (get_irg_entity (graph))), - get_entity_name (get_irg_entity (graph)))); - - /* do we need some kind of environment here? */ - pto_graph (graph); - - DBGPRINT (0, (stdout, "END PTO\n")); - HERE ("end"); -} - -void pto_cleanup () -{ - HERE ("start"); - /* todo: clean up our own mess */ - spaces -= 511; /* hope that all changes to spaces are - properly nested */ - memset (spaces, 0x00, 512); - free (spaces); - - /* clean up ecg infos */ - ecg_cleanup (); - HERE ("end"); -} - /* $Log$ + Revision 1.3 2004/11/24 14:53:55 liekweg + Bugfixes + Revision 1.2 2004/11/20 21:21:56 liekweg Finalise initialisation diff --git a/ir/ana2/pto_comp.h b/ir/ana2/pto_comp.h index dc7e0b6b9..aaa559321 100644 --- a/ir/ana2/pto_comp.h +++ b/ir/ana2/pto_comp.h @@ -16,7 +16,9 @@ # ifndef _PTO_COMP_ # define _PTO_COMP_ +# include "pto.h" # include "irnode.h" +# include "qset.h" /* =================================================== Global Defines: @@ -26,7 +28,7 @@ Global Data Types: =================================================== */ typedef struct pto_str { - int dummy; + qset_t *values; } pto_t; typedef struct alloc_pto_str { @@ -38,6 +40,9 @@ typedef struct alloc_pto_str { /* =================================================== Global Prototypes: =================================================== */ +/* Main loop: Initialise the graph for the given ctx_idx and iterate over it */ +void pto_graph (ir_graph*, int); + /* Set the PTO value for the given node */ void set_node_pto (ir_node*, pto_t*); /*Get the PTO value for the given non-alloc node */ @@ -50,11 +55,6 @@ void set_alloc_pto (ir_node*, alloc_pto_t*); pto_t *get_alloc_pto (ir_node*); -/* Perform PTO on all visible graphs. */ -void pto_init (void); -void pto_run (int); -void pto_cleanup (void); - /* =================================================== Global Variables: =================================================== */ @@ -66,6 +66,9 @@ void pto_cleanup (void); /* $Log$ + Revision 1.2 2004/11/24 14:53:55 liekweg + Bugfixes + Revision 1.1 2004/11/18 16:37:34 liekweg rewritten diff --git a/ir/ana2/pto_ctx.c b/ir/ana2/pto_ctx.c index 72442f3d5..868f969d2 100644 --- a/ir/ana2/pto_ctx.c +++ b/ir/ana2/pto_ctx.c @@ -26,7 +26,7 @@ # include "ecg.h" # include "irnode.h" -# include "xmalloc.h" +/* # include "xmalloc.h" */ /* Local Defines: */ @@ -85,6 +85,9 @@ ctx_info_t *set_curr_ctx (ctx_info_t *ctx) /* $Log$ + Revision 1.3 2004/11/24 14:53:55 liekweg + Bugfixes + Revision 1.2 2004/11/20 21:21:35 liekweg Add pto_ctx_allocs diff --git a/ir/ana2/pto_debug.c b/ir/ana2/pto_debug.c index d68f57567..60f0a46ee 100644 --- a/ir/ana2/pto_debug.c +++ b/ir/ana2/pto_debug.c @@ -23,7 +23,7 @@ # include "pto_debug.h" # include "irnode.h" -# include "xmalloc.h" +/* # include "xmalloc.h" */ /* Local Defines: */ @@ -56,6 +56,9 @@ void set_dbg_lvl (int lvl) /* $Log$ + Revision 1.2 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.1 2004/11/18 16:37:34 liekweg rewritten diff --git a/ir/ana2/pto_debug.h b/ir/ana2/pto_debug.h index 0a18a4c87..ccdb3e553 100644 --- a/ir/ana2/pto_debug.h +++ b/ir/ana2/pto_debug.h @@ -23,7 +23,7 @@ # define DBGEXE(lvl, cmd) if (get_dbg_lvl () > lvl) {cmd;} # define OPNAME(node) get_op_name (get_irn_op (node)) # define OPNUM(node) get_irn_node_nr (node) -# define HERE(msg) fprintf (stdout, "%s:%i: %s\n", __FUNCTION__, __LINE__, msg) +# define HERE(msg) fprintf (stdout, "%s:%i %s\n", __FUNCTION__, __LINE__, msg) # define HERE2(msg1, msg2) fprintf (stdout, "%s:%i: %s %s\n", __FUNCTION__, __LINE__, msg1, msg2) # define HERE3(msg1, msg2, msg3) fprintf (stdout, "%s:%i: %s %s %s\n", __FUNCTION__, __LINE__, msg1, msg2, msg3) @@ -47,6 +47,9 @@ void set_dbg_lvl (int); /* $Log$ + Revision 1.2 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.1 2004/11/18 16:37:34 liekweg rewritten diff --git a/ir/ana2/pto_init.c b/ir/ana2/pto_init.c index 485949aee..396d41e3c 100644 --- a/ir/ana2/pto_init.c +++ b/ir/ana2/pto_init.c @@ -20,15 +20,23 @@ pto_init: Initialisation Functions */ +# include +# include + +# include "pto.h" # include "pto_init.h" # include "pto_debug.h" # include "pto_comp.h" +# include "pto_name.h" +# include "pto_util.h" # include "typewalk.h" # include "irgwalk.h" # include "xmalloc.h" /* Local Defines: */ +# define obstack_chunk_alloc xmalloc +# define obstack_chunk_free free /* Local Data Types: */ typedef struct init_env_str @@ -42,6 +50,9 @@ typedef struct reset_env_str } reset_env_t; /* Local Variables: */ +extern struct obstack *qset_obst; /* from pto_name */ + +static struct obstack *pto_obst = NULL; /* all pto_t's go onto this one */ /* Local Prototypes: */ @@ -51,28 +62,45 @@ typedef struct reset_env_str /* Allocate a new pto */ static pto_t *new_pto (ir_node *node) { - /* dummy implementation for fake_pto */ - pto_t *pto = xmalloc (sizeof (pto_t)); + pto_t *pto = obstack_alloc (pto_obst, sizeof (pto_t)); + pto->values = qset_new (N_INITIAL_OJBS, qset_obst); return (pto); } /* Allocate a new alloc_pto */ -static alloc_pto_t *new_alloc_pto (ir_node *node, int n_ctxs) +static alloc_pto_t *new_alloc_pto (ir_node *alloc, int n_ctxs) { + assert (iro_Alloc == get_irn_opcode (alloc)); + int i; - /* dummy implementation for testing */ - alloc_pto_t *alloc_pto = xmalloc (sizeof (alloc_pto_t)); + alloc_pto_t *alloc_pto = obstack_alloc (pto_obst, sizeof (alloc_pto_t)); + type *tp = get_Alloc_type (alloc); - alloc_pto->ptos = (pto_t**) xmalloc (n_ctxs * sizeof (pto_t*)); + alloc_pto->ptos = (pto_t**) obstack_alloc (pto_obst, n_ctxs * sizeof (pto_t*)); for (i = 0; i < n_ctxs; i ++) { - alloc_pto->ptos [i] = new_pto (node); + desc_t *desc = new_name (tp, alloc); + alloc_pto->ptos [i] = new_pto (alloc); + qset_insert (alloc_pto->ptos [i]->values, desc); } return (alloc_pto); } +/* Allocate a new pto for a symconst */ +static pto_t* new_symconst_pto (ir_node *symconst) +{ + assert (iro_SymConst == get_irn_opcode (symconst)); + + pto_t *pto = new_pto (symconst); + entity *ent = get_SymConst_entity (symconst); + desc_t *desc = new_ent_name (ent); + + qset_insert (pto->values, desc); + + return (pto); +} /* Helper to pto_init --- clear the link fields of class types */ static void clear_type_link (type_or_ent *thing, void *__unused) @@ -121,13 +149,13 @@ static void reset_node_pto (ir_node *node, void *env) case (iro_Const): case (iro_Call): case (iro_Phi): { - /* todo: allocate 'empty' pto values */ + /* allocate 'empty' pto values */ pto_t *pto = new_pto (node); set_node_pto (node, pto); } break; case (iro_Alloc): { - /* todo: set alloc to 'right' current pto */ + /* set alloc to 'right' current pto */ alloc_pto_t *alloc_pto = (alloc_pto_t*) get_irn_link (node); alloc_pto->curr_pto = alloc_pto->ptos [ctx_idx]; } break; @@ -139,7 +167,7 @@ static void reset_node_pto (ir_node *node, void *env) } /* Temporary fix until we get 'real' ptos: Allocate some dummy for pto */ -static void init_alloc_pto (ir_node *node, void *env) +static void init_pto (ir_node *node, void *env) { init_env_t *init_env = (init_env_t*) env; int n_ctxs = init_env->n_ctxs; @@ -147,20 +175,43 @@ static void init_alloc_pto (ir_node *node, void *env) const opcode op = get_irn_opcode (node); switch (op) { - case (iro_Load): - case (iro_SymConst): - case (iro_Const): - case (iro_Call): - case (iro_Phi): { - /* nothing (handled by init_node_pto) */ - } break; - + case (iro_SymConst): { + const symconst_kind kind = get_SymConst_kind (node); + + if ((kind == symconst_addr_name) || (kind == symconst_addr_ent)) { + entity *ent = get_SymConst_entity (node); + + if (is_pointer_type (get_entity_type (ent))) { + DBGPRINT (0, (stdout, "%s: new name \"%s\" for symconst \"%s[%li]\"\n", + __FUNCTION__, + get_entity_name (ent), + OPNAME (node), + OPNUM (node))); + + pto_t *symconst_pto = new_symconst_pto (node); + set_node_pto (node, symconst_pto); + } + } + } break; case (iro_Alloc): { - /* todo: alloc 'right' ptos */ + type *tp = get_Alloc_type (node); /* debugging only */ alloc_pto_t *alloc_pto = new_alloc_pto (node, n_ctxs); set_alloc_pto (node, alloc_pto); - } break; + DBGPRINT (0, (stdout, "%s: %i names \"%s\" for alloc \"%s[%li]\"\n", + __FUNCTION__, + n_ctxs, + get_type_name (tp), + OPNAME (node), + OPNUM (node))); + } break; + + case (iro_Load): + case (iro_Call): + case (iro_Phi): + case (iro_Const): + /* nothing --- handled by reset_node_pto on each pass */ + break; default: { /* nothing */ } break; @@ -179,7 +230,10 @@ static void pto_init_graph_allocs (ir_graph *graph) HERE ("start"); - irg_walk_graph (graph, init_alloc_pto, NULL, init_env); + irg_walk_graph (graph, init_pto, NULL, init_env); + + memset (init_env, 0x00, sizeof (init_env_t)); + free (init_env); HERE ("end"); } @@ -187,6 +241,67 @@ static void pto_init_graph_allocs (ir_graph *graph) /* =================================================== Exported Implementation: =================================================== */ +/* "Fake" the arguments to the main method */ +void fake_main_args (ir_graph *graph) +{ + HERE ("start"); + + entity *ent = get_irg_entity (graph); + type *mtp = get_entity_type (ent); + ir_node **args = find_irg_args (graph); + type *ctp = get_method_param_type (mtp, 1); /* ctp == char[]*[]* */ + + /* 'main' has signature 'void(int, char[]*[]*)' */ + assert (NULL == args [2]); + + assert (is_pointer_type (ctp)); + + ctp = get_pointer_points_to_type (ctp); /* ctp == char[]*[] */ + + assert (is_array_type (ctp)); + + desc_t *arg_desc = new_name (ctp, args [1]); + pto_t *arg_pto = new_pto (args [1]); + /* todo: simulate 'store' to arg1[] ?!? */ + qset_insert (arg_pto->values, arg_desc); + + set_node_pto (args [1], arg_pto); + +# ifdef TEST_MAIN_TYPE + ctp = get_array_element_type (ctp); /* ctp == char[]* */ + + assert (is_pointer_type (ctp)); + + ctp = get_pointer_points_to_type (ctp); /* ctp == char[] */ + + assert (is_array_type (ctp)); + + ctp = get_array_element_type (ctp); /* ctp == char */ + + assert (is_primitive_type (ctp)); +# endif /* defined TEST_MAIN_TYPE */ + + HERE ("end"); +} + +/* Initialise the Init module */ +void pto_init_init () +{ + pto_obst = (struct obstack*) xmalloc (sizeof (struct obstack)); + + obstack_init (pto_obst); +} + +/* Cleanup the Init module */ +void pto_init_cleanup () +{ + obstack_free (pto_obst, NULL); + memset (pto_obst, 0x00, sizeof (struct obstack)); + free (pto_obst); + pto_obst = NULL; +} + + /* Initialise the Names of the Types/Entities */ void pto_init_type_names () { @@ -227,12 +342,17 @@ void pto_reset_graph_pto (ir_graph *graph, int ctx_idx) irg_walk_graph (graph, reset_node_pto, NULL, reset_env); + memset (reset_env, 0x00, sizeof (reset_env_t)); + free (reset_env); HERE ("end"); } /* $Log$ + Revision 1.5 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.4 2004/11/20 21:21:56 liekweg Finalise initialisation diff --git a/ir/ana2/pto_init.h b/ir/ana2/pto_init.h index dae2e9f4a..e972e879c 100644 --- a/ir/ana2/pto_init.h +++ b/ir/ana2/pto_init.h @@ -30,6 +30,15 @@ /* =================================================== Global Prototypes: =================================================== */ +/* "Fake" the arguments to the main method */ +void fake_main_args (ir_graph*); + +/* Initialise the Init module */ +void pto_init_init (void); + +/* Cleanup the Init module */ +void pto_init_cleanup (void); + /* Initialise the Names of the Types/Entities */ void pto_init_type_names (void); @@ -50,6 +59,9 @@ void pto_reset_graph_pto (ir_graph*, int); /* $Log$ + Revision 1.4 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.3 2004/11/20 21:21:56 liekweg Finalise initialisation diff --git a/ir/ana2/pto_name.c b/ir/ana2/pto_name.c index 9611252f1..28d879aa6 100644 --- a/ir/ana2/pto_name.c +++ b/ir/ana2/pto_name.c @@ -1,15 +1,15 @@ /* -*- c -*- */ /* - Project: libFIRM - File name: ir/ana/pto_name.c - Purpose: ... - Author: Florian - Modified by: - Created: Sat Nov 13 19:35:27 CET 2004 - CVS-ID: $Id$ - Copyright: (c) 1999-2004 Universität Karlsruhe - Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE. + Project: libFIRM + File name: ir/ana/pto_name.c + Purpose: Names for abstract objects + Author: Florian + Modified by: + Created: Sat Nov 13 19:35:27 CET 2004 + CVS-ID: $Id$ + Copyright: (c) 1999-2004 Universität Karlsruhe + Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE. */ # ifdef HAVE_CONFIG_H @@ -17,39 +17,272 @@ # endif /* - pto_name: ... + pto_name: Names for abstract objects */ +# include "pto.h" # include "pto_name.h" +# include "pto_util.h" + +# include /* for memcpy */ +# include # include "irnode.h" +# include "irprog.h" # include "xmalloc.h" # include "pto_debug.h" /* Local Defines: */ +# define obstack_chunk_alloc xmalloc +# define obstack_chunk_free free + +# define NALLOC(size) obstack_alloc (name_obst, size) /* Local Data Types: */ /* Local Variables: */ +struct obstack *qset_obst = NULL; +struct obstack *name_obst = NULL; /* Local Prototypes: */ /* =================================================== Local Implementation: =================================================== */ +/* See whether the given entity is a field. */ +static int is_field (entity *ent) +{ + type *tp = get_entity_type (ent); + + if (is_primitive_type (tp) || is_pointer_type (tp)) { + /* actually, we could get by by restricting ourselves to pointer types */ + return (TRUE); + } else { + return (FALSE); + } +} + +/* Helper to collect_fields(type*): collect all fields of the given + clazz and its super classes into the given obstack. */ +static void _collect_fields (type *clazz, struct obstack *obst) +{ + int n_members = get_class_n_members (clazz); + int n_supers = get_class_n_supertypes (clazz); + int i; + + for (i = 0; i < n_members; i ++) { + entity *ent = get_class_member (clazz, i); + + if (is_field (ent)) { + if (allocation_static != get_entity_allocation (ent)) { + obstack_ptr_grow (obst, ent); + } + } + } + + for (i = 0; i < n_supers; i ++) { + type *s_clazz = get_class_supertype (clazz, i); + + _collect_fields (s_clazz, obst); + } +} + +/* Collect the fields of the given class and its super classes into an array. + The last entry of the array is written NULL. */ +static entity **collect_fields (type *clazz) +{ + if (NULL != get_type_link (clazz)) { + DBGPRINT (3, (stdout, "%s: reusing field list for \"%s\"\n", + __FUNCTION__, get_type_name (clazz))); + + return ((entity **) get_type_link (clazz)); + } else { + DBGPRINT (2, (stdout, "%s: new field list for \"%s\"\n", + __FUNCTION__, get_type_name (clazz))); + } + + struct obstack obst; + + obstack_init (&obst); + + _collect_fields (clazz, &obst); + + /* append terminating NULL */ + int *the_null = NULL; + obstack_ptr_grow (&obst, the_null); + + int n_fields = obstack_object_size (&obst) / sizeof (void*); + + entity ** fields = (entity**) NALLOC (n_fields * sizeof (entity*)); + void *tmp = obstack_finish (&obst); + + memcpy (fields, tmp, n_fields * sizeof (entity*)); + + obstack_free (&obst, NULL); + + set_type_link (clazz, (void*) fields); + + return (fields); +} + /* =================================================== Exported Implementation: =================================================== */ +static desc_t *all_descs = NULL; + +/* get a new descriptor for the given type at the given node */ +desc_t *new_name (type *tp, ir_node *node) +{ + desc_t *desc = NULL; + + assert ((is_class_type (tp) || is_array_type (tp)) && "unsuitable type"); + + DBGPRINT (2, (stdout, "%s: new name for type \"%s\"\n", __FUNCTION__, + get_type_name (tp))); + fflush (stdout); + + if (is_class_type (tp)) { + obj_desc_t *obj_desc = (obj_desc_t*) NALLOC (sizeof (obj_desc_t)); + int i; + int n_fields; + + obj_desc->kind = object; + obj_desc->fields = collect_fields (tp); + + for (n_fields = 0; (NULL != obj_desc->fields [n_fields]); n_fields ++) { + /* nothing, just count ... */ + } + + obj_desc->n_fields = n_fields; + obj_desc->values = (qset_t**) NALLOC (n_fields * sizeof (qset_t)); + for (i = 0; i < n_fields; i ++) { + obj_desc->values [i] = qset_new (N_INITIAL_OJBS, qset_obst); + } + desc = (desc_t*) obj_desc; + } else if (is_array_type (tp)) { + arr_desc_t *arr_desc = (arr_desc_t*) NALLOC (sizeof (arr_desc_t)); + arr_desc->kind = array; + arr_desc->value = qset_new (N_INITIAL_OJBS, qset_obst); + + desc = (desc_t*) arr_desc; + } + + desc->tp = tp; + desc->node = node; + + desc->prev = all_descs; + all_descs = desc; + + return (desc); +} + +# define N_GLOB_INITIAL_FIELDS 20 +static obj_desc_t *obj_glob = NULL; +static int n_glob_fields = N_GLOB_INITIAL_FIELDS; + +/* get a new descriptor for the given (presumably static) entity */ +desc_t *new_ent_name (entity *ent) +{ + int i; + int missing = TRUE; + type *tp = get_entity_type (ent); + + assert (is_pointer_type (tp)); + tp = get_pointer_points_to_type (tp); + assert (is_class_type (tp)); + + assert (((allocation_static == get_entity_allocation (ent)) || + (allocation_automatic == get_entity_allocation (ent))) && + "not a static/automatic field"); + + if (NULL == obj_glob) { + obj_glob = (obj_desc_t*) NALLOC (sizeof (obj_desc_t)); + + obj_glob->kind = object; + obj_glob->tp = get_glob_type (); + obj_glob->node = NULL; + + obj_glob->n_fields = 0; + obj_glob->fields = (entity**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (entity*)); + obj_glob->values = (qset_t**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (qset_t*)); + + obj_glob->prev = all_descs; + all_descs = (desc_t*) obj_glob; + } + + for (i = 0; missing && (i < obj_glob->n_fields); i ++) { + if (ent == obj_glob->fields [i]) { + missing = FALSE; + } + } + + if (missing) { + if (obj_glob->n_fields == n_glob_fields) { + entity **fields = obj_glob->fields; + qset_t **values = obj_glob->values; + + n_glob_fields *= 2; + obj_glob->fields = (entity**) NALLOC (n_glob_fields * sizeof (entity*)); + obj_glob->values = (qset_t**) NALLOC (n_glob_fields * sizeof (qset_t*)); + + memcpy (obj_glob->fields, fields, obj_glob->n_fields * sizeof (entity*)); + memcpy (obj_glob->values, values, obj_glob->n_fields * sizeof (qset_t*)); + + /* free (fields); */ + /* free (values); */ + } + + obj_glob->fields [obj_glob->n_fields ] = ent; + obj_glob->values [obj_glob->n_fields ++] = qset_new (N_INITIAL_OJBS, qset_obst); + } + + return ((desc_t*) obj_glob); +} +# undef N_GLOB_INITIAL_FIELDS + +/* Initialise the name module */ +void pto_name_init () +{ + DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__)); + assert (NULL == name_obst); + assert (NULL == qset_obst); + + name_obst = xmalloc (sizeof (struct obstack)); + qset_obst = xmalloc (sizeof (struct obstack)); + + obstack_init (name_obst); + obstack_init (qset_obst); +} + +/* Cleanup the name module */ +void pto_name_cleanup () +{ + DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__)); + obstack_free (name_obst, NULL); + obstack_free (qset_obst, NULL); + + memset (name_obst, 0x00, sizeof (struct obstack)); + memset (qset_obst, 0x00, sizeof (struct obstack)); + + free (name_obst); + free (qset_obst); + + name_obst = NULL; + qset_obst = NULL; +} /* $Log$ + Revision 1.2 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.1 2004/11/18 16:37:34 liekweg rewritten diff --git a/ir/ana2/pto_name.h b/ir/ana2/pto_name.h index 8625d7ea1..3839f2c03 100644 --- a/ir/ana2/pto_name.h +++ b/ir/ana2/pto_name.h @@ -1,32 +1,86 @@ /* -*- c -*- */ /* - Project: libFIRM - File name: ir/ana/pto_name.h - Purpose: ... - Author: Florian - Modified by: - Created: Sat Nov 13 19:35:27 CET 2004 - CVS-ID: $Id$ - Copyright: (c) 1999-2004 Universität Karlsruhe - Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE. + Project: libFIRM + File name: ir/ana/pto_name.h + Purpose: Names for abstract objects + Author: Florian + Modified by: + Created: Sat Nov 13 19:35:27 CET 2004 + CVS-ID: $Id$ + Copyright: (c) 1999-2004 Universität Karlsruhe + Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE. */ # ifndef _PTO_NAME_ # define _PTO_NAME_ +# include "pto_comp.h" /* for pto_t */ +# include "irnode.h" +# include "type.h" +# include "qset.h" + /* =================================================== Global Defines: =================================================== */ /* =================================================== - Global Data Types: - =================================================== */ + Global Data Types: + =================================================== */ +typedef enum desc_kind_enum { + none, + object, + array +} desc_kind_t; + +/* abstract super class for all descriptors */ +typedef struct desc_str +{ + desc_kind_t kind; + type *tp; + ir_node *node; /* allocation node */ + struct desc_str *prev; /* linked list */ +} desc_t; + +/* object descriptor */ +typedef struct obj_desc_str +{ + desc_kind_t kind; + type *tp; + ir_node *node; /* allocation node */ + struct desc_str *prev; /* linked list */ + + int n_fields; + entity **fields; + qset_t **values; +} obj_desc_t; + +/* array descriptor */ +typedef struct arr_desc_str +{ + desc_kind_t kind; + type *tp; + ir_node *node; /* allocation node */ + struct desc_str *prev; /* linked list */ + + qset_t *value; +} arr_desc_t; /* =================================================== Global Prototypes: =================================================== */ +/* get a new descriptor for the given type at the given node */ +desc_t *new_name (type*, ir_node*); + +/* get a new descriptor for the given (presumably static) entity */ +desc_t *new_ent_name (entity*); + +/* Initialise the name module */ +void pto_name_init (void); + +/* Cleanup the name module */ +void pto_name_cleanup (void); /* =================================================== Global Variables: @@ -39,6 +93,9 @@ /* $Log$ + Revision 1.2 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.1 2004/11/18 16:37:34 liekweg rewritten diff --git a/ir/ana2/pto_util.c b/ir/ana2/pto_util.c index e39a1184b..03c4b7c16 100644 --- a/ir/ana2/pto_util.c +++ b/ir/ana2/pto_util.c @@ -23,6 +23,7 @@ # include "pto_util.h" # include "irnode.h" +# include "irgwalk.h" # include "xmalloc.h" # include "pto_debug.h" @@ -30,6 +31,12 @@ /* Local Defines: */ /* Local Data Types: */ +/* Environment for find_irg_args */ +typedef struct find_irg_args_env { + ir_node **args; + ir_node *arg; +} find_irg_args_env_t; + /* Local Variables: */ @@ -38,11 +45,53 @@ /* =================================================== Local Implementation: =================================================== */ +/* Helper for find_irg_args */ +static void find_irg_arg (ir_node *node, void *env) +{ + find_irg_args_env_t *arg_env = (find_irg_args_env_t*) env; + if (iro_Proj == get_irn_opcode (node)) { + if (arg_env->arg == get_Proj_pred (node)) { + long n = get_Proj_proj (node); + + assert (! arg_env->args [n]); + + arg_env->args [n] = node; + } + } +} /* =================================================== Exported Implementation: =================================================== */ +/* Find the arguments of a graph. For a method that has n args, the + result array has 'n+1' entries, the last of which is written NULL. */ +ir_node **find_irg_args (ir_graph *graph) +{ + type *tp = get_entity_type (get_irg_entity (graph)); + const int n_args = get_method_n_params (tp); + ir_node **args = (ir_node**) xmalloc (sizeof (ir_node*) * (n_args+1)); + ir_node *arg = get_irg_args (graph); + find_irg_args_env_t *arg_env = + (find_irg_args_env_t*) xmalloc (sizeof (find_irg_args_env_t)); + + arg_env->args = args; + arg_env->arg = arg; + + /* or use get_irg_end ?!? */ + { + ir_graph *save = get_current_ir_graph (); + set_current_ir_graph (graph); + irg_walk (get_irg_end (graph), find_irg_arg, NULL, arg_env); + set_current_ir_graph (save); + } + + free (arg_env); + + args [n_args] = NULL; + + return (args); +} /* Get the entity of a ptr */ entity *get_ptr_ent (ir_node *ptr) { @@ -74,6 +123,9 @@ entity *get_ptr_ent (ir_node *ptr) /* $Log$ + Revision 1.7 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.6 2004/11/18 16:37:07 liekweg rewrite diff --git a/ir/ana2/pto_util.h b/ir/ana2/pto_util.h index 4a76bfce3..457c54784 100644 --- a/ir/ana2/pto_util.h +++ b/ir/ana2/pto_util.h @@ -30,8 +30,13 @@ /* =================================================== Global Prototypes: =================================================== */ +/* Get the entity of a ptr */ entity *get_ptr_ent (ir_node*); +/* Find the arguments of a graph. For a method that has n args, the + result array has 'n+1' entries, the last of which is written NULL. */ +ir_node **find_irg_args (ir_graph*); + /* =================================================== Global Variables: =================================================== */ @@ -43,6 +48,9 @@ entity *get_ptr_ent (ir_node*); /* $Log$ + Revision 1.5 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.4 2004/11/18 16:37:07 liekweg rewrite diff --git a/ir/ana2/qset.c b/ir/ana2/qset.c index 0aeb7f972..8813512ae 100644 --- a/ir/ana2/qset.c +++ b/ir/ana2/qset.c @@ -1,7 +1,7 @@ /* -*- c -*- */ /* - * Time-stamp: <11.11.2004 16:42:15h liekweg> + * Time-stamp: <23.11.2004 13:26:21h liekweg> * Project: libFIRM * File name: ir/ana2/qset.c * Purpose: yet another set implementation @@ -18,6 +18,7 @@ # include # include # include +# include # include "timing.h" # include "qset.h" @@ -52,12 +53,24 @@ static __inline__ int sortable_compare (const void *pa, const void *pb) return ((a < b) ? -1 : +1); } +/* + Wrapper for mixed allocation +*/ +static void *mix_malloc (struct obstack *obst, size_t size) +{ + if (NULL != obst) { + return (obstack_alloc (obst, size)); + } else { + return (malloc (size)); + } +} + /* Allocate a list of sortables of the given length. */ -static sortable_t *alloc_list (const int len) +static sortable_t *alloc_list (const int len, struct obstack *obst) { - sortable_t *values = (sortable_t*) malloc (len * sizeof (sortable_t)); + sortable_t *values = (sortable_t*) mix_malloc (obst, len * sizeof (sortable_t)); memset (values, 0x00, len * sizeof (sortable_t)); @@ -68,10 +81,10 @@ static sortable_t *alloc_list (const int len) /* Create a list of sortables of the given length. */ -static sortable_t *gen_list (const int len) +static sortable_t *gen_list (const int len, struct obstack *obst) { int i; - sortable_t *values = alloc_list (len); + sortable_t *values = alloc_list (len, obst); for (i = 0; i < len; i ++) { values [i] = rand () >> 16; @@ -189,7 +202,7 @@ static void test_qsort (const int n_runs, const int max_elems, const int incr) int qtotal = 0; for (i = 0; i < n_runs; i ++) { - sortable_t *list = gen_list (n_elems); + sortable_t *list = gen_list (n_elems, NULL); timing_t *timing = start_timing (); q_sort (list, n_elems); @@ -201,7 +214,7 @@ static void test_qsort (const int n_runs, const int max_elems, const int incr) } for (i = 0; i < n_runs; i ++) { - sortable_t *list = gen_list (n_elems); + sortable_t *list = gen_list (n_elems, NULL); timing_t *timing = start_timing (); qsort (list, n_elems, sizeof (sortable_t), sortable_compare); @@ -229,11 +242,11 @@ static void test_qset (const int n_entries) int i; int n1, n2, n; - qset_t *q1 = qset_new (n_entries); - qset_t *q2 = qset_new (n_entries); + qset_t *q1 = qset_new (n_entries, NULL); + qset_t *q2 = qset_new (n_entries, NULL); qset_t *q = NULL; - sortable_t *values = gen_list (n_entries); + sortable_t *values = gen_list (n_entries, NULL); for (i = 0; i < n_entries; i ++) { qset_insert (q1, values [i]); @@ -327,7 +340,7 @@ static void qset_resize (qset_t *qset, const int n_slots) new_size *= 2; } - values = alloc_list (new_size); + values = alloc_list (new_size, qset->obst); memcpy (values, qset->values, qset->n_elems * sizeof (sortable_t)); memset (qset->values, 0x00, qset->n_elems * sizeof (sortable_t)); /* debug only */ @@ -407,10 +420,11 @@ static void q_sort (sortable_t *values, const int n_elems) Merge two sorted lists. Keep duplicates (if present) */ static sortable_t *q_merge (sortable_t *list1, const int n1_elems, - sortable_t *list2, const int n2_elems) + sortable_t *list2, const int n2_elems, + struct obstack *obst) { const int n_elems = n1_elems + n2_elems; - sortable_t *res = alloc_list (n_elems); + sortable_t *res = alloc_list (n_elems, obst); int i1 = 0; int i2 = 0; @@ -439,12 +453,15 @@ static sortable_t *q_merge (sortable_t *list1, const int n1_elems, /* Allocate a new qset with initial space for up to n_elems. + If a non-NULL obstack is given, it is used for all allocations of this qset + and must be initialised and deleted by the user of the qset. */ -qset_t *qset_new (const int n_elems) +qset_t *qset_new (const int n_elems, struct obstack *obst) { - qset_t *qset = (qset_t*) malloc (sizeof (qset_t)); + qset_t *qset = (qset_t*) mix_malloc (obst, sizeof (qset_t)); - qset->values = alloc_list (n_elems); + qset->obst = obst; + qset->values = alloc_list (n_elems, obst); memset (qset->values, 0x00, n_elems * sizeof (sortable_t)); qset->n_slots = n_elems; @@ -492,7 +509,8 @@ void qset_sort (qset_t *qset) */ void qset_compact (qset_t *qset) { - sortable_t *values = (sortable_t*) malloc (qset->n_elems * sizeof (sortable_t)); + sortable_t *values = (sortable_t*) mix_malloc (qset->obst, + qset->n_elems * sizeof (sortable_t)); memcpy (values, qset->values, qset->n_elems * sizeof (sortable_t)); memset (qset->values, 0x00, qset->n_elems * sizeof (sortable_t)); @@ -508,11 +526,16 @@ void qset_compact (qset_t *qset) void qset_delete (qset_t *qset) { memset (qset->values, 0x00, qset->n_elems * sizeof (sortable_t)); - free (qset->values); + + if (NULL == qset->obst) { + free (qset->values); + } memset (qset, 0x00, sizeof (qset_t)); - free (qset); + if (NULL == qset->obst) { + free (qset); + } } /* @@ -588,7 +611,8 @@ void qset_insert_all (qset_t *qset1, qset_t *qset2) qset_sort (qset2); qset1->values = q_merge (qset1->values, qset1->n_elems, - qset2->values, qset2->n_elems); + qset2->values, qset2->n_elems, + qset1->obst); qset1->n_elems = qset1->n_elems + qset2->n_elems; qset1->n_slots = qset1->n_elems; @@ -628,10 +652,10 @@ int qset_compare (qset_t *qset1, qset_t *qset2) */ qset_t *qset_union (qset_t *qset1, qset_t *qset2) { - qset_t *qset = (qset_t*) malloc (sizeof (qset_t)); + qset_t *qset = (qset_t*) mix_malloc (qset1->obst, sizeof (qset_t)); const int n_elems = qset1->n_elems + qset2->n_elems; - qset->values = alloc_list (n_elems); + qset->values = alloc_list (n_elems, qset1->obst); memcpy (qset->values, qset1->values, qset1->n_elems * sizeof (sortable_t)); @@ -639,6 +663,7 @@ qset_t *qset_union (qset_t *qset1, qset_t *qset2) memcpy (qset->values+qset1->n_elems, qset2->values, qset2->n_elems * sizeof (sortable_t)); + qset->obst = qset1->obst; qset->n_elems = n_elems; qset->n_slots = qset->n_elems; @@ -724,6 +749,9 @@ int qset_test_main (int argc, char **argv) /* $Log$ + Revision 1.5 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.4 2004/11/18 16:35:45 liekweg Added unique ids for debugging diff --git a/ir/ana2/qset.h b/ir/ana2/qset.h index c8a1f2441..7e95f5382 100644 --- a/ir/ana2/qset.h +++ b/ir/ana2/qset.h @@ -1,7 +1,7 @@ /* -*- c -*- */ /* - * Time-stamp: <11.11.2004 16:42:22h liekweg> + * Time-stamp: <23.11.2004 13:23:46h liekweg> * Project: libFIRM * File name: ir/ana2/qset.h * Purpose: yet another set implementation @@ -27,8 +27,11 @@ /* typedef unsigned int sortable_t; */ typedef void* sortable_t; +struct obstack; /* forward decl */ + typedef struct qset_str { + struct obstack *obst; sortable_t *values; int n_slots; int n_elems; @@ -40,8 +43,10 @@ typedef struct qset_str /* QSET INTERFACE */ -/* Allocate a new qset with initial space for up to n_elems. */ -qset_t *qset_new (const int); +/* Allocate a new qset with initial space for up to n_elems. + If a non-NULL obstack is given, it is used for all allocations of this qset + and must be initialised and deleted by the user of the qset. */ +qset_t *qset_new (const int, struct obstack*); /* Sort the entries of the given qset. */ void qset_sort (qset_t*); @@ -91,6 +96,9 @@ sortable_t *qset_next (qset_t*); /* $Log$ + Revision 1.4 2004/11/24 14:53:56 liekweg + Bugfixes + Revision 1.3 2004/11/18 16:35:46 liekweg Added unique ids for debugging -- 2.20.1