added routines to free memory
authorGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Thu, 26 Feb 2004 08:54:46 +0000 (08:54 +0000)
committerGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Thu, 26 Feb 2004 08:54:46 +0000 (08:54 +0000)
[r2458]

28 files changed:
TODO
ir/ana/Makefile.in
ir/ana/cgana.h
ir/ana/irscc.c
ir/ana/irtypeinfo.c
ir/common/firm.c
ir/common/firm.h
ir/ident/ident.c
ir/ident/ident_t.h
ir/ir/irgopt.c
ir/ir/irgraph.c
ir/ir/irmode.c
ir/ir/irmode.h
ir/ir/irnode.c
ir/ir/irop.c
ir/ir/irop_t.h
ir/ir/irprog.c
ir/ir/irprog.h
ir/tr/entity.c
ir/tr/type.c
ir/tr/type.h
ir/tr/type_t.h
ir/tv/fltcalc.c
ir/tv/fltcalc.h
ir/tv/strcalc.c
ir/tv/strcalc.h
ir/tv/tv.c
ir/tv/tv.h

diff --git a/TODO b/TODO
index 102ef87..e58f508 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,7 @@
+  * 25.2.04 Goetz
+    Fix memory leak in irprog: free_ir_prog.
+    Fix memory leak in entity: free_entity_attrs
+
   * 19.12.03 Goetz
     Add state management for loops (consistent, inconsistent, invalid).
 
index beaa832..b622699 100644 (file)
@@ -20,8 +20,9 @@ INSTALL_HEADERS = irouts.h irdom.h cgana.h irloop.h irtypeinfo.h irsimpletype.h
 SOURCES = $(INSTALL_HEADERS)
 
 SOURCES += Makefile.in \
-               irouts.c irdom_t.h irdom.c  cgana.c     \
-               irloop_t.h irbackedge.c irbackedge_t.h irscc.c irtypeinfo.c irsimpletype.c
+               irouts.c irdom_t.h irdom.c cgana.c      \
+               irloop_t.h irbackedge.c irbackedge_t.h irscc.c irtypeinfo.c irsimpletype.c      \
+               confirmcons.c
 
 include $(topdir)/MakeRules
 
index 7efbe0e..6be446f 100644 (file)
@@ -23,7 +23,7 @@
 #include "entity.h"
 
 /* Methoden sind "frei", wenn ihr Funktionszeiger (potentiell)
- *"explizit" bekannt ist, d.h.:
+ * "explizit" bekannt ist, d.h.:
  *
  * - die Methode ist von aussen sichtbar (external_visible).
  *
index 2727732..dfdfa6c 100644 (file)
@@ -827,7 +827,7 @@ static void scc (ir_node *n) {
        * avoid loops without Block or Phi as first node.  This should
        * severely reduce the number of evaluations of nodes to detect
        * a fixpoint in the heap analyses.
-       * Firther it avoids loops without firm nodes that cause errors
+       * Further it avoids loops without firm nodes that cause errors
        * in the heap analyses. */
 #define NO_LOOPS_WITHOUT_HEAD 1
 #if NO_LOOPS_WITHOUT_HEAD
index ab63ada..3a34fba 100644 (file)
@@ -71,7 +71,6 @@ void init_irtypeinfo(void) {
 
   for (i = 0; i < get_irp_n_irgs(); ++i)
     set_irg_typeinfo_state(get_irp_irg(i), irg_typeinfo_none);
-
 }
 
 void free_irtypeinfo(void) {
@@ -83,7 +82,6 @@ void free_irtypeinfo(void) {
   } else
     assert(0 && "call init_type_info before freeing");
 
-
   if (type_node_map) {
     pmap_destroy(type_node_map);
     type_node_map = NULL;
index 54f3b76..4df89dc 100644 (file)
@@ -53,3 +53,24 @@ init_firm (default_initialize_local_variable_func_t *func)
   /* Constructs some idents needed. */
   init_type();
 }
+
+
+void free_firm (void) {
+  int i;
+
+  for (i = 0; i < get_irp_n_irgs(); i++)
+    free_ir_graph(get_irp_irg(i));
+
+  for (i = 0; i < get_irp_n_types(); i++) {
+    free_type_entities(get_irp_type(i));
+    free_type(get_irp_type(i));
+  }
+
+  free_type_entities(get_glob_type());
+  free_ir_prog();
+
+  finish_tarval();
+  finish_op();
+  finish_mode();
+  id_finish();
+}
index 7da17dd..eec1a4d 100644 (file)
  */
 void init_firm (default_initialize_local_variable_func_t *func);
 
+/**
+ * Frees all memory occupied by the firm library.
+ */
+void free_firm (void);
+
 # endif /* _FIRM_H_ */
index 027f02d..3f92131 100644 (file)
@@ -31,6 +31,11 @@ void id_init(int initial_n_idents)
   id_set = new_set(memcmp, initial_n_idents);
 }
 
+void id_finish (void) {
+  del_set(id_set);
+  id_set = NULL;
+}
+
 INLINE ident *id_from_str (const char *str, int len)
 {
   assert(len > 0);
index 6cdb55c..0a9df31 100644 (file)
@@ -16,6 +16,7 @@
 # include "ident.h"
 
 void id_init (int initial_n_idents);
+void id_finish (void);
 
 #define ID_HASH(str, len) \
   (((  ((unsigned char *)(str))[0] * 33 \
index 1c5c25b..4a5422d 100644 (file)
@@ -163,6 +163,11 @@ copy_node (ir_node *n, void *env) {
   ir_node *nn, *block;
   int new_arity;
 
+  /* The end node looses it's flexible in array.  This doesn't matter,
+     as dead node elimination builds End by hand, inlineing doesn't use
+     the End node. */
+  //assert(n->op == op_End ||  ((_ARR_DESCR(n->in))->cookie != ARR_F_MAGIC));
+
   if (get_irn_opcode(n) == iro_Block) {
     block = NULL;
     new_arity = compute_new_arity(n);
@@ -670,8 +675,9 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
   /* -- archive keepalives -- */
   for (i = 0; i < get_irn_arity(end); i++)
     add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
-  /* The new end node will die, but the in array is not on the obstack ... */
-  free_End(end);
+
+  /* The new end node will die.  We need not free as the in array is on the obstack:
+     copy_node only generated 'D' arrays. */
 
 /* --
       Return nodes by Jump nodes. -- */
index c38ec22..d7bd8a1 100644 (file)
@@ -23,6 +23,7 @@
 # include "array.h"
 # include "irgmod.h"
 # include "mangle.h"
+# include "irouts.h"
 
 ir_graph *current_ir_graph;
 INLINE ir_graph *get_current_ir_graph(void) {
@@ -207,6 +208,9 @@ ir_graph *new_const_code_irg(void) {
   return res;
 }
 
+/* Defined in iropt.c */
+void  del_identities (pset *value_table);
+
 /* Frees the passed irgraph.
    Deallocates all nodes in this graph and the ir_graph structure.
    Sets the field irgraph in the corresponding entity to NULL.
@@ -215,12 +219,16 @@ ir_graph *new_const_code_irg(void) {
    Does not free types, entities or modes that are used only by this
    graph, nor the entity standing for this graph. */
 void free_ir_graph (ir_graph *irg) {
-  set_entity_irg(irg->ent, NULL);
-  irg->kind = k_BAD;
+  if (irg->ent) set_entity_irg(irg->ent, NULL);  /* not set in const code irg */
+  free_End(irg->end);
+  if (irg->frame_type)  free_type(irg->frame_type);
+  if (irg->value_table) del_identities(irg->value_table);
+  if (irg->outs_state != no_outs) free_outs(irg);
   free(irg->obst);
 #if USE_EXPLICIT_PHI_IN_STACK
   free_Phi_in_stack(irg->Phi_in_stack);
 #endif
+  irg->kind = k_BAD;
   free(irg);
 }
 
index 232c688..d926e90 100644 (file)
@@ -984,3 +984,35 @@ init_mode (void)
   /* set the machine specific modes to the predifined ones */
   mode_P_mach = mode_P;
 }
+
+
+void finish_mode(void) {
+  obstack_free(&modes, 0);
+
+  mode_T = NULL;
+  mode_X = NULL;
+  mode_M = NULL;
+  mode_BB = NULL;
+  mode_ANY = NULL;
+  mode_BAD = NULL;
+
+  mode_F = NULL;
+  mode_D = NULL;
+  mode_E = NULL;
+
+  mode_Bs = NULL;
+  mode_Bu = NULL;
+  mode_Hs = NULL;
+  mode_Hu = NULL;
+  mode_Is = NULL;
+  mode_Iu = NULL;
+  mode_Ls = NULL;
+  mode_Lu = NULL;
+
+  mode_C = NULL;
+  mode_U = NULL;
+  mode_b = NULL;
+  mode_P = NULL;
+
+  mode_P_mach = NULL;
+}
index e66dbb5..0a24a05 100644 (file)
@@ -420,4 +420,7 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm);
 /** mode module initialization, call once before use of any other function **/
 void init_mode (void);
 
+/** mode module finalization. frees all memory.  */
+void finish_mode(void);
+
 #endif /* _IRMODE_H_ */
index 94cbf54..3ac55bb 100644 (file)
@@ -750,7 +750,7 @@ INLINE void
 free_End (ir_node *end) {
   assert (end->op == op_End);
   end->kind = k_BAD;
-  /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
+  DEL_ARR_F(end->in);  /* GL @@@ tut nicht ! */
   end->in = NULL;   /* @@@ make sure we get an error if we use the
                       in array afterwards ... */
 }
index b42ec10..16909cc 100644 (file)
@@ -99,6 +99,9 @@ new_ir_op (opcode code, const char *name, op_pinned p, int labeled, size_t attr_
   return res;
 }
 
+void free_ir_op (ir_op *code) {
+  free(code);
+}
 
 void
 init_op(void)
@@ -164,6 +167,68 @@ init_op(void)
   op_FuncCall  = new_ir_op (iro_FuncCall,  "FuncCall",  floats, 1, sizeof (call_attr));
 }
 
+
+/* free memory used by irop module. */
+void finish_op() {
+  free_ir_op (op_Block); op_Block     = NULL;
+
+  free_ir_op (op_Start    ); op_Start     = NULL;
+  free_ir_op (op_End      ); op_End       = NULL;
+  free_ir_op (op_Jmp      ); op_Jmp       = NULL;
+  free_ir_op (op_Cond     ); op_Cond      = NULL;
+  free_ir_op (op_Return   ); op_Return    = NULL;
+  free_ir_op (op_Raise    ); op_Raise     = NULL;
+
+  free_ir_op (op_Const    ); op_Const     = NULL;
+  free_ir_op (op_SymConst ); op_SymConst  = NULL;
+
+  free_ir_op (op_Sel      ); op_Sel       = NULL;
+  free_ir_op (op_InstOf   ); op_InstOf    = NULL;
+
+  free_ir_op (op_Call     ); op_Call      = NULL;
+  free_ir_op (op_Add      ); op_Add       = NULL;
+  free_ir_op (op_Minus    ); op_Minus     = NULL;
+  free_ir_op (op_Sub      ); op_Sub       = NULL;
+  free_ir_op (op_Mul      ); op_Mul       = NULL;
+  free_ir_op (op_Quot     ); op_Quot      = NULL;
+  free_ir_op (op_DivMod   ); op_DivMod    = NULL;
+  free_ir_op (op_Div      ); op_Div       = NULL;
+  free_ir_op (op_Mod      ); op_Mod       = NULL;
+  free_ir_op (op_Abs      ); op_Abs       = NULL;
+  free_ir_op (op_And      ); op_And       = NULL;
+  free_ir_op (op_Or       ); op_Or        = NULL;
+  free_ir_op (op_Eor      ); op_Eor       = NULL;
+  free_ir_op (op_Not      ); op_Not       = NULL;
+  free_ir_op (op_Cmp      ); op_Cmp       = NULL;
+  free_ir_op (op_Shl      ); op_Shl       = NULL;
+  free_ir_op (op_Shr      ); op_Shr       = NULL;
+  free_ir_op (op_Shrs     ); op_Shrs      = NULL;
+  free_ir_op (op_Rot      ); op_Rot       = NULL;
+  free_ir_op (op_Conv     ); op_Conv      = NULL;
+  free_ir_op (op_Cast     ); op_Cast      = NULL;
+
+  free_ir_op (op_Phi      ); op_Phi       = NULL;
+
+  free_ir_op (op_Load     ); op_Load      = NULL;
+  free_ir_op (op_Store    ); op_Store     = NULL;
+  free_ir_op (op_Alloc    ); op_Alloc     = NULL;
+  free_ir_op (op_Free     ); op_Free      = NULL;
+  free_ir_op (op_Sync     ); op_Sync      = NULL;
+
+  free_ir_op (op_Proj     ); op_Proj      = NULL;
+  free_ir_op (op_Tuple    ); op_Tuple     = NULL;
+  free_ir_op (op_Id       ); op_Id        = NULL;
+  free_ir_op (op_Bad      ); op_Bad       = NULL;
+  free_ir_op (op_Confirm  ); op_Confirm   = NULL;
+
+  free_ir_op (op_Unknown  ); op_Unknown   = NULL;
+  free_ir_op (op_Filter   ); op_Filter    = NULL;
+  free_ir_op (op_Break    ); op_Break     = NULL;
+  free_ir_op (op_CallBegin); op_CallBegin = NULL;
+  free_ir_op (op_EndReg   ); op_EndReg    = NULL;
+  free_ir_op (op_EndExcept); op_EndExcept = NULL;
+}
+
 /* Returns the string for the opcode. */
 const char *get_op_name (const ir_op *op) {
   return get_id_str(op->name);
index c3b2949..c645d6f 100644 (file)
 struct ir_op {
   opcode code;
   ident *name;
-  size_t attr_size;     /**< Space needed in memory for private attributes */
-  int labeled;          /**< Output edge labels on in-edges in vcg graph */
-  int pinned;           /**< How to deal with the node in cse, pre. */
+  size_t attr_size;       /**< Space needed in memory for private attributes */
+  int labeled;            /**< Output edge labels on in-edges in vcg graph */
+  int pinned;             /**< How to deal with the node in cse, pre. */
+  int reqires_fexible_in; /**< The node must always have a flexible array as in. */
+                          /** @@@@ Change constructors for ir_op, and new_ir_node!!!
+                             new_ir_node not only checks the arity, but also the op!!! @@@ */
 };
 
 /**
@@ -41,4 +44,7 @@ ir_op * new_ir_op (opcode code, const char *name, op_pinned p,
 /** initialize the irop module */
 void init_op (void);
 
+/* free memory used by irop module. */
+void finish_op(void);
+
 #endif /* _IROP_T_H_ */
index b0c2b63..25a90f3 100644 (file)
@@ -76,6 +76,18 @@ ir_prog *new_ir_prog (void) {
   return res;
 }
 
+/* frees all memory used by irp.  Types in type list, irgs in irg
+    list and entities in global type must be freed by hand before. */
+void     free_ir_prog() {
+  free_type(irp->glob_type);
+  /* @@@ * free_ir_graph(irp->const_code_irg); * ?? End has no in?? */
+  DEL_ARR_F(irp->graphs);
+  DEL_ARR_F(irp->types);
+
+  irp->kind = k_BAD;
+  irp->const_code_irg = NULL;
+}
+
 /** Functions to access the fields of ir_prog **/
 
 
index 636da18..529ae7d 100644 (file)
@@ -76,6 +76,10 @@ void init_irprog(void);
    Automatically called by init_firm() through init_irprog.  */
 ir_prog *new_ir_prog (void);
 
+/** frees all memory used by irp.  Types in type list and irgs in irg
+    list must be freed by hand before. */
+void     free_ir_prog(void);
+
 /** Gets the main routine of the compiled program. */
 ir_graph *get_irp_main_irg(void);
 
index 8665d57..0cd48b9 100644 (file)
@@ -96,12 +96,13 @@ new_entity (type *owner, ident *name, type *type)
     res->variability = variability_uninitialized;
     res->value  = NULL;
     res->values = NULL;
+    res->val_paths = NULL;
   }
   res->peculiarity   = peculiarity_existent;
   res->volatility    = volatility_non_volatile;
   res->ld_name       = NULL;
-  res->overwrites    = NEW_ARR_F(entity *, 1);
-  res->overwrittenby = NEW_ARR_F(entity *, 1);
+  res->overwrites    = NEW_ARR_F(entity *, 0);
+  res->overwrittenby = NEW_ARR_F(entity *, 0);
 
   res->irg = NULL;
 
@@ -121,12 +122,30 @@ new_d_entity (type *owner, ident *name, type *type, dbg_info *db) {
   set_entity_dbg_info(res, db);
   return res;
 }
+
+INLINE void    free_compound_graph_path (compound_graph_path *gr);
+INLINE int     is_compound_graph_path(void *thing);
+INLINE int     get_compound_graph_path_length(compound_graph_path *gr);
+INLINE entity *get_compound_graph_path_node(compound_graph_path *gr, int pos);
+INLINE int     get_compound_ent_n_values(entity *ent);
+
 INLINE void free_entity_attrs(entity *ent) {
+  int i;
   assert(ent);
   if (get_type_tpop(get_entity_owner(ent)) == type_class) {
-    DEL_ARR_F(ent->overwrites);
-    DEL_ARR_F(ent->overwrittenby);
+    DEL_ARR_F(ent->overwrites);    ent->overwrites = NULL;
+    DEL_ARR_F(ent->overwrittenby); ent->overwrittenby = NULL;
+  }
+  //if (ent->values) DEL_ARR_F(ent->values); /* @@@ warum nich? */
+  if (ent->val_paths) {
+    if (is_compound_entity(ent))
+      for (i = 0; i < get_compound_ent_n_values(ent); i++)
+       if (ent->val_paths[i])
+          free_compound_graph_path(ent->val_paths[i]) ;  /* @@@ warum nich? */
+    //DEL_ARR_F(ent->val_paths);
   }
+  ent->val_paths = NULL;
+  ent->values = NULL;
 }
 
 entity *
@@ -145,13 +164,13 @@ copy_entity_own (entity *old, type *new_owner) {
     new->overwrittenby = DUP_ARR_F(entity *, old->overwrittenby);
   } else if ((get_type_tpop(get_entity_owner(old)) != type_class) &&
             (get_type_tpop(new_owner) == type_class)) {
-    new->overwrites = NEW_ARR_F(entity *, 1);
-    new->overwrittenby = NEW_ARR_F(entity *, 1);
+    new->overwrites = NEW_ARR_F(entity *, 0);
+    new->overwrittenby = NEW_ARR_F(entity *, 0);
   }
   */
   if (is_class_type(new_owner)) {
-    new->overwrites = NEW_ARR_F(entity *, 1);
-    new->overwrittenby = NEW_ARR_F(entity *, 1);
+    new->overwrites = NEW_ARR_F(entity *, 0);
+    new->overwrittenby = NEW_ARR_F(entity *, 0);
   }
 #ifdef DEBUG_libfirm
   new->nr = get_irp_new_node_nr();
@@ -342,15 +361,15 @@ set_entity_variability (entity *ent, ent_variability var)
   if ((is_compound_type(ent->type)) &&
       (ent->variability == variability_uninitialized) && (var != variability_uninitialized)) {
     /* Allocate datastructures for constant values */
-    ent->values = NEW_ARR_F(ir_node *, 1);
-    ent->val_paths = NEW_ARR_F(compound_graph_path *, 1);
+    ent->values    = NEW_ARR_F(ir_node *, 0);
+    ent->val_paths = NEW_ARR_F(compound_graph_path *, 0);
   }
 
   if ((is_compound_type(ent->type)) &&
       (var == variability_uninitialized) && (ent->variability != variability_uninitialized)) {
     /* Free datastructures for constant values */
-    DEL_ARR_F(ent->values);
-    DEL_ARR_F(ent->val_paths);
+    DEL_ARR_F(ent->values);    ent->values    = NULL;
+    DEL_ARR_F(ent->val_paths); ent->val_paths = NULL;
   }
   ent->variability = var;
 }
@@ -528,7 +547,7 @@ INLINE int is_proper_compound_graph_path(compound_graph_path *gr, int pos) {
     if (get_entity_owner(node) != owner) return false;
     owner = get_entity_type(node);
   }
-  if (pos == get_compound_graph_path_length(gr) -1)
+  if (pos == get_compound_graph_path_length(gr))
     if (!is_atomic_type(owner)) return false;
   return true;
 }
@@ -567,33 +586,33 @@ add_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *pa
 INLINE void
 set_compound_ent_value_w_path(entity *ent, ir_node *val, compound_graph_path *path, int pos) {
   assert(ent && is_compound_entity(ent) && (ent->variability != variability_uninitialized));
-  ent->values[pos+1] = val;
-  ent->val_paths[pos+1] = path;
+  ent->values[pos] = val;
+  ent->val_paths[pos] = path;
 }
 
 INLINE int
 get_compound_ent_n_values(entity *ent) {
   assert(ent && is_compound_entity(ent) && (ent->variability != variability_uninitialized));
-  return (ARR_LEN (ent->values))-1;
+  return (ARR_LEN (ent->values));
 }
 
 INLINE ir_node  *
 get_compound_ent_value(entity *ent, int pos) {
   assert(ent && is_compound_entity(ent) && (ent->variability != variability_uninitialized));
-  return ent->values[pos+1];
+  return ent->values[pos];
 }
 
 INLINE compound_graph_path *
 get_compound_ent_value_path(entity *ent, int pos) {
   assert(ent && is_compound_entity(ent) && (ent->variability != variability_uninitialized));
-  return ent->val_paths[pos+1];
+  return ent->val_paths[pos];
 }
 
 void
 remove_compound_ent_value(entity *ent, entity *value_ent) {
   int i;
   assert(ent && is_compound_entity(ent) && (ent->variability != variability_uninitialized));
-  for (i = 1; i < (ARR_LEN (ent->val_paths)); i++) {
+  for (i = 0; i < (ARR_LEN (ent->val_paths)); i++) {
     compound_graph_path *path = ent->val_paths[i];
     if (path->nodes[path->len-1] == value_ent) {
       for(; i < (ARR_LEN (ent->val_paths))-1; i++) {
@@ -700,7 +719,7 @@ INLINE int
 get_entity_n_overwrites (entity *ent) {
   assert(ent);
   assert(is_class_type(get_entity_owner(ent)));
-  return (ARR_LEN (ent->overwrites))-1;
+  return (ARR_LEN (ent->overwrites));
 }
 
 int
@@ -718,7 +737,7 @@ get_entity_overwrites   (entity *ent, int pos) {
   assert(ent);
   assert(is_class_type(get_entity_owner(ent)));
   assert(pos < get_entity_n_overwrites(ent));
-  return ent->overwrites[pos+1];
+  return ent->overwrites[pos];
 }
 
 INLINE void
@@ -726,14 +745,14 @@ set_entity_overwrites   (entity *ent, int pos, entity *overwritten) {
   assert(ent);
   assert(is_class_type(get_entity_owner(ent)));
   assert(pos < get_entity_n_overwrites(ent));
-  ent->overwrites[pos+1] = overwritten;
+  ent->overwrites[pos] = overwritten;
 }
 
 void
 remove_entity_overwrites(entity *ent, entity *overwritten) {
   int i;
   assert(ent && is_class_type(get_entity_owner(ent)));
-  for (i = 1; i < (ARR_LEN (ent->overwrites)); i++)
+  for (i = 0; i < (ARR_LEN (ent->overwrites)); i++)
     if (ent->overwrites[i] == overwritten) {
       for(; i < (ARR_LEN (ent->overwrites))-1; i++)
        ent->overwrites[i] = ent->overwrites[i+1];
@@ -753,7 +772,7 @@ INLINE int
 get_entity_n_overwrittenby (entity *ent) {
   assert(ent);
   assert(is_class_type(get_entity_owner(ent)));
-  return (ARR_LEN (ent->overwrittenby))-1;
+  return (ARR_LEN (ent->overwrittenby));
 }
 
 int
@@ -771,7 +790,7 @@ get_entity_overwrittenby   (entity *ent, int pos) {
   assert(ent);
   assert(is_class_type(get_entity_owner(ent)));
   assert(pos < get_entity_n_overwrittenby(ent));
-  return ent->overwrittenby[pos+1];
+  return ent->overwrittenby[pos];
 }
 
 INLINE void
@@ -779,13 +798,13 @@ set_entity_overwrittenby   (entity *ent, int pos, entity *overwrites) {
   assert(ent);
   assert(is_class_type(get_entity_owner(ent)));
   assert(pos < get_entity_n_overwrittenby(ent));
-  ent->overwrittenby[pos+1] = overwrites;
+  ent->overwrittenby[pos] = overwrites;
 }
 
 void    remove_entity_overwrittenby(entity *ent, entity *overwrites) {
   int i;
   assert(ent && is_class_type(get_entity_owner(ent)));
-  for (i = 1; i < (ARR_LEN (ent->overwrittenby)); i++)
+  for (i = 0; i < (ARR_LEN (ent->overwrittenby)); i++)
     if (ent->overwrittenby[i] == overwrites) {
       for(; i < (ARR_LEN (ent->overwrittenby))-1; i++)
        ent->overwrittenby[i] = ent->overwrittenby[i+1];
index 2800dd7..8c75b3e 100644 (file)
@@ -90,20 +90,6 @@ INLINE void set_master_type_visited(unsigned long val) { type_visited = val; }
 INLINE unsigned long get_master_type_visited() { return type_visited; }
 INLINE void inc_master_type_visited() { type_visited++; }
 
-void        free_type(type *tp) {
-  if ((get_type_tpop(tp) == tpop_none) || (get_type_tpop(tp) == tpop_unknown))
-    return;
-  /* Remove from list of all types */
-  remove_irp_type(tp);
-  /* Free the attributes of the type. */
-  free_type_attrs(tp);
-  /* Free entities automatically allocated with the type */
-  if (is_array_type(tp))
-    free_entity(get_array_element_entity(tp));
-  /* And now the type itself... */
-  tp->kind = k_BAD;
-  free(tp);
-}
 
 INLINE type *
 new_type(tp_op *type_op, ir_mode *mode, ident* name) {
@@ -132,6 +118,35 @@ new_type(tp_op *type_op, ir_mode *mode, ident* name) {
   return res;
 }
 
+void        free_type(type *tp) {
+  if ((get_type_tpop(tp) == tpop_none) || (get_type_tpop(tp) == tpop_unknown))
+    return;
+  /* Remove from list of all types */
+  remove_irp_type(tp);
+  /* Free the attributes of the type. */
+  free_type_attrs(tp);
+  /* Free entities automatically allocated with the type */
+  if (is_array_type(tp))
+    free_entity(get_array_element_entity(tp));
+  /* And now the type itself... */
+  tp->kind = k_BAD;
+  free(tp);
+}
+
+void free_type_entities(type *tp) {
+  switch(get_type_tpop_code(tp)) {
+  case tpo_class:       { free_class_entities(tp);       } break;
+  case tpo_struct:      { free_struct_entities(tp);      } break;
+  case tpo_method:      { free_method_entities(tp);      } break;
+  case tpo_union:       { free_union_entities(tp);       } break;
+  case tpo_array:       { free_array_entities(tp);       } break;
+  case tpo_enumeration: { free_enumeration_entities(tp); } break;
+  case tpo_pointer:     { free_pointer_entities(tp);     } break;
+  case tpo_primitive:   { free_primitive_entities(tp);   } break;
+  default: break;
+  }
+}
+
 void free_type_attrs(type *tp) {
   switch(get_type_tpop_code(tp)) {
   case tpo_class:       { free_class_attrs(tp);       } break;
@@ -606,6 +621,14 @@ type   *new_d_type_class (ident *name, dbg_info* db) {
   set_type_dbg_info(res, db);
   return res;
 }
+
+INLINE void free_class_entities(type *clss) {
+  int i;
+  assert(clss && (clss->type_op == type_class));
+  for (i = get_class_n_members(clss)-1; i >= 0; --i)
+    free_entity(get_class_member(clss, i));
+}
+
 INLINE void free_class_attrs(type *clss) {
   assert(clss && (clss->type_op == type_class));
   DEL_ARR_F(clss->attr.ca.members);
@@ -809,6 +832,12 @@ type   *new_d_type_struct (ident *name, dbg_info* db) {
   set_type_dbg_info(res, db);
   return res;
 }
+INLINE void free_struct_entities (type *strct) {
+  int i;
+  assert(strct && (strct->type_op == type_struct));
+  for (i = get_struct_n_members(strct)-1; i >= 0; --i)
+    free_entity(get_struct_member(strct, i));
+}
 INLINE void free_struct_attrs (type *strct) {
   assert(strct && (strct->type_op == type_struct));
   DEL_ARR_F(strct->attr.sa.members);
@@ -898,10 +927,22 @@ type *new_d_type_method (ident *name, int n_param, int n_res, dbg_info* db) {
   return res;
 }
 
+INLINE void free_method_entities(type *method) {
+  assert(method && (method->type_op == type_method));
+}
+/* Attention: also frees entities in value parameter subtypes! */
 INLINE void free_method_attrs(type *method) {
   assert(method && (method->type_op == type_method));
   free(method->attr.ma.param_type);
   free(method->attr.ma.res_type);
+  if (method->attr.ma.value_params) {
+    free_type_entities(method->attr.ma.value_params);
+    free_type(method->attr.ma.value_params);
+  }
+  if (method->attr.ma.value_ress) {
+    free_type_entities(method->attr.ma.value_ress);
+    free_type(method->attr.ma.value_ress);
+  }
 }
 
 /* manipulate private fields of method. */
@@ -1034,6 +1075,12 @@ type  *new_d_type_union (ident *name, dbg_info* db) {
   set_type_dbg_info(res, db);
   return res;
 }
+INLINE void free_union_entities (type *uni) {
+  int i;
+  assert(uni && (uni->type_op == type_union));
+  for (i = get_union_n_members(uni)-1; i >= 0; --i)
+    free_entity(get_union_member(uni, i));
+}
 INLINE void free_union_attrs (type *uni) {
   assert(uni && (uni->type_op == type_union));
   DEL_ARR_F(uni->attr.ua.members);
@@ -1145,6 +1192,9 @@ type *new_d_type_array (ident *name, int n_dimensions,
   return res;
 }
 
+INLINE void free_array_entities (type *array) {
+  assert(array && (array->type_op == type_array));
+}
 INLINE void free_array_attrs (type *array) {
   assert(array && (array->type_op == type_array));
   free(array->attr.aa.lower_bound);
@@ -1280,6 +1330,9 @@ type   *new_d_type_enumeration    (ident *name, int n_enums, dbg_info* db) {
   return res;
 }
 
+INLINE void free_enumeration_entities(type *enumeration) {
+  assert(enumeration && (enumeration->type_op == type_enumeration));
+}
 INLINE void free_enumeration_attrs(type *enumeration) {
   assert(enumeration && (enumeration->type_op == type_enumeration));
   free(enumeration->attr.ea.enumer);
@@ -1343,6 +1396,9 @@ type *new_d_type_pointer (ident *name, type *points_to, ir_mode *ptr_mode, dbg_i
   set_type_dbg_info(res, db);
   return res;
 }
+INLINE void free_pointer_entities (type *pointer) {
+  assert(pointer && (pointer->type_op == type_pointer));
+}
 INLINE void free_pointer_attrs (type *pointer) {
   assert(pointer && (pointer->type_op == type_pointer));
 }
@@ -1396,6 +1452,9 @@ type *new_d_type_primitive (ident *name, ir_mode *mode, dbg_info* db) {
   set_type_dbg_info(res, db);
   return res;
 }
+INLINE void free_primitive_entities (type *primitive) {
+  assert(primitive && (primitive->type_op == type_primitive));
+}
 INLINE void free_primitive_attrs (type *primitive) {
   assert(primitive && (primitive->type_op == type_primitive));
 }
index 33fe124..b2b07af 100644 (file)
@@ -119,9 +119,17 @@ typedef struct type type;
 
 # include "type_or_entity.h"
 
+/** frees all entities associated with a type.
+    Does not free array entity.
+    Warning: make sure these entities are not referenced anywhere else.
+*/
+void        free_type_entities(type *tp);
+
 /** Frees the memory used by the type.   Does not free the entities
-   belonging to the type, except for the array element entity.
-   Does not free if tp is "none" or "unknown". */
+    belonging to the type, except for the array element entity.
+    Does not free if tp is "none" or "unknown".
+    Frees entities in value param subtypes of method types!!! Make sure these
+    are not referenced any more. */
 void        free_type(type *tp);
 
 tp_op*      get_type_tpop(type *tp);
index db2968e..a9a94b2 100644 (file)
@@ -145,6 +145,15 @@ new_type(tp_op *type_op,
         ident* name);
 void free_type_attrs       (type *tp);
 
+INLINE void free_class_entities      (type *clss);
+INLINE void free_struct_entities     (type *strct);
+INLINE void free_method_entities     (type *method);
+INLINE void free_union_entities      (type *uni);
+INLINE void free_array_entities      (type *array);
+INLINE void free_enumeration_entities(type *enumeration);
+INLINE void free_pointer_entities    (type *pointer);
+INLINE void free_primitive_entities  (type *primitive);
+
 INLINE void free_class_attrs      (type *clss);
 INLINE void free_struct_attrs     (type *strct);
 INLINE void free_method_attrs     (type *method);
@@ -155,6 +164,8 @@ INLINE void free_pointer_attrs    (type *pointer);
 INLINE void free_primitive_attrs  (type *primitive);
 
 
+
+
 /** initialize the type module */
 void init_type (void);
 
index ef9795d..23304ea 100644 (file)
@@ -1567,6 +1567,10 @@ void init_fltcalc(int precision)
   }
 }
 
+void finish_fltcalc (void) {
+  free(calc_buffer); calc_buffer = NULL;
+}
+
 /* definition of interface functions */
 FC_DEFINE2(add)
 FC_DEFINE2(sub)
index 8079a67..b25c7ad 100644 (file)
@@ -235,4 +235,6 @@ fc_rounding_mode_t fc_get_rounding_mode(void);
 unsigned char fc_sub_bits(const void *val, unsigned num_bit, unsigned byte_ofs);
 
 void init_fltcalc(int precision);
+void finish_fltcalc (void);
+
 #endif /* _FLTCALC_H_ */
index ba7a638..fd3a3b6 100644 (file)
@@ -1515,7 +1515,7 @@ void init_strcalc(int precision)
     CALC_BUFFER_SIZE = (precision / 2);
     MAX_VALUE_SIZE   = (precision / 4);
 
-    calc_buffer = malloc(CALC_BUFFER_SIZE+1 * sizeof(char));
+    calc_buffer   = malloc(CALC_BUFFER_SIZE+1 * sizeof(char));
     output_buffer = malloc(BIT_PATTERN_SIZE+1 * sizeof(char));
 
     if (calc_buffer == NULL || output_buffer == NULL)
@@ -1527,6 +1527,12 @@ void init_strcalc(int precision)
     DEBUGPRINTF(("init strcalc: \n\tPRECISION: %d\n\tCALC_BUFFER_SIZE = %d\n\tMAX_VALUE_SIZE = %d\n\tbuffer pointer: %p\n", precision, CALC_BUFFER_SIZE, MAX_VALUE_SIZE, calc_buffer));
   }
 }
+
+
+void finish_strcalc() {
+  free(calc_buffer);   calc_buffer   = NULL;
+  free(output_buffer); output_buffer = NULL;
+}
 int sc_get_precision(void)
 {
   return BIT_PATTERN_SIZE;
index 68498dd..ed94515 100644 (file)
@@ -153,6 +153,7 @@ const char *sc_print(const void *val1, unsigned bits, enum base_t base);
  *   for calculations. The reason for being multiples of 8 eludes me
  */
 void init_strcalc(int precision_in_bytes);
+void finish_strcalc(void);
 int sc_get_precision(void);
 
 #endif /* _STRCALC_H_ */
index 4e86d0c..7a1364e 100644 (file)
@@ -1675,6 +1675,14 @@ void init_tarval_2(void)
   tarval_set_mode_output_option(mode_P,  &reference_output);
 }
 
+/* free all memory occupied by tarval. */
+void finish_tarval(void) {
+  finish_strcalc ();
+  finish_fltcalc ();
+  del_set(tarvals); tarvals = NULL;
+  del_set(values);  values = NULL;
+}
+
 /****************************************************************************
  *   end of tv.c
  ****************************************************************************/
index 8614272..1eeab60 100644 (file)
@@ -594,6 +594,8 @@ void init_tarval_1(void);
  */
 void init_tarval_2(void);
 
+void finish_tarval(void);
+
 /**
  * Output of tarvals to a buffer.
  */