From 8dc4091a707bf66377da637d17cb20080847bf1c Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=B6tz=20Lindenmaier?= Date: Thu, 26 Feb 2004 08:54:46 +0000 Subject: [PATCH] added routines to free memory [r2458] --- TODO | 4 +++ ir/ana/Makefile.in | 5 +-- ir/ana/cgana.h | 2 +- ir/ana/irscc.c | 2 +- ir/ana/irtypeinfo.c | 2 -- ir/common/firm.c | 21 +++++++++++ ir/common/firm.h | 5 +++ ir/ident/ident.c | 5 +++ ir/ident/ident_t.h | 1 + ir/ir/irgopt.c | 10 ++++-- ir/ir/irgraph.c | 12 +++++-- ir/ir/irmode.c | 32 +++++++++++++++++ ir/ir/irmode.h | 3 ++ ir/ir/irnode.c | 2 +- ir/ir/irop.c | 65 +++++++++++++++++++++++++++++++++ ir/ir/irop_t.h | 12 +++++-- ir/ir/irprog.c | 12 +++++++ ir/ir/irprog.h | 4 +++ ir/tr/entity.c | 73 +++++++++++++++++++++++-------------- ir/tr/type.c | 87 +++++++++++++++++++++++++++++++++++++-------- ir/tr/type.h | 12 +++++-- ir/tr/type_t.h | 11 ++++++ ir/tv/fltcalc.c | 4 +++ ir/tv/fltcalc.h | 2 ++ ir/tv/strcalc.c | 8 ++++- ir/tv/strcalc.h | 1 + ir/tv/tv.c | 8 +++++ ir/tv/tv.h | 2 ++ 28 files changed, 349 insertions(+), 58 deletions(-) diff --git a/TODO b/TODO index 102ef872f..e58f508c4 100644 --- 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). diff --git a/ir/ana/Makefile.in b/ir/ana/Makefile.in index beaa83261..b6226991e 100644 --- a/ir/ana/Makefile.in +++ b/ir/ana/Makefile.in @@ -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 diff --git a/ir/ana/cgana.h b/ir/ana/cgana.h index 7efbe0e84..6be446fbd 100644 --- a/ir/ana/cgana.h +++ b/ir/ana/cgana.h @@ -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). * diff --git a/ir/ana/irscc.c b/ir/ana/irscc.c index 272773214..dfdfa6c2c 100644 --- a/ir/ana/irscc.c +++ b/ir/ana/irscc.c @@ -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 diff --git a/ir/ana/irtypeinfo.c b/ir/ana/irtypeinfo.c index ab63ada68..3a34fba33 100644 --- a/ir/ana/irtypeinfo.c +++ b/ir/ana/irtypeinfo.c @@ -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; diff --git a/ir/common/firm.c b/ir/common/firm.c index 54f3b7676..4df89dc59 100644 --- a/ir/common/firm.c +++ b/ir/common/firm.c @@ -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(); +} diff --git a/ir/common/firm.h b/ir/common/firm.h index 7da17dd7b..eec1a4dda 100644 --- a/ir/common/firm.h +++ b/ir/common/firm.h @@ -110,4 +110,9 @@ */ 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_ */ diff --git a/ir/ident/ident.c b/ir/ident/ident.c index 027f02df3..3f92131ad 100644 --- a/ir/ident/ident.c +++ b/ir/ident/ident.c @@ -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); diff --git a/ir/ident/ident_t.h b/ir/ident/ident_t.h index 6cdb55c54..0a9df314c 100644 --- a/ir/ident/ident_t.h +++ b/ir/ident/ident_t.h @@ -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 \ diff --git a/ir/ir/irgopt.c b/ir/ir/irgopt.c index 1c5c25b90..4a5422db1 100644 --- a/ir/ir/irgopt.c +++ b/ir/ir/irgopt.c @@ -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. -- */ diff --git a/ir/ir/irgraph.c b/ir/ir/irgraph.c index c38ec22bf..d7bd8a1f5 100644 --- a/ir/ir/irgraph.c +++ b/ir/ir/irgraph.c @@ -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); } diff --git a/ir/ir/irmode.c b/ir/ir/irmode.c index 232c688be..d926e90c4 100644 --- a/ir/ir/irmode.c +++ b/ir/ir/irmode.c @@ -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; +} diff --git a/ir/ir/irmode.h b/ir/ir/irmode.h index e66dbb597..0a24a0523 100644 --- a/ir/ir/irmode.h +++ b/ir/ir/irmode.h @@ -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_ */ diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 94cbf54f2..3ac55bb39 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -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 ... */ } diff --git a/ir/ir/irop.c b/ir/ir/irop.c index b42ec1073..16909ccec 100644 --- a/ir/ir/irop.c +++ b/ir/ir/irop.c @@ -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); diff --git a/ir/ir/irop_t.h b/ir/ir/irop_t.h index c3b294988..c645d6fcf 100644 --- a/ir/ir/irop_t.h +++ b/ir/ir/irop_t.h @@ -20,9 +20,12 @@ 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_ */ diff --git a/ir/ir/irprog.c b/ir/ir/irprog.c index b0c2b637b..25a90f382 100644 --- a/ir/ir/irprog.c +++ b/ir/ir/irprog.c @@ -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 **/ diff --git a/ir/ir/irprog.h b/ir/ir/irprog.h index 636da1886..529ae7df2 100644 --- a/ir/ir/irprog.h +++ b/ir/ir/irprog.h @@ -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); diff --git a/ir/tr/entity.c b/ir/tr/entity.c index 8665d572f..0cd48b932 100644 --- a/ir/tr/entity.c +++ b/ir/tr/entity.c @@ -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]; diff --git a/ir/tr/type.c b/ir/tr/type.c index 2800dd74c..8c75b3e0f 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -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)); } diff --git a/ir/tr/type.h b/ir/tr/type.h index 33fe124a8..b2b07af15 100644 --- a/ir/tr/type.h +++ b/ir/tr/type.h @@ -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); diff --git a/ir/tr/type_t.h b/ir/tr/type_t.h index db2968e11..a9a94b26d 100644 --- a/ir/tr/type_t.h +++ b/ir/tr/type_t.h @@ -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); diff --git a/ir/tv/fltcalc.c b/ir/tv/fltcalc.c index ef9795dbd..23304ea5e 100644 --- a/ir/tv/fltcalc.c +++ b/ir/tv/fltcalc.c @@ -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) diff --git a/ir/tv/fltcalc.h b/ir/tv/fltcalc.h index 8079a6748..b25c7ad2b 100644 --- a/ir/tv/fltcalc.h +++ b/ir/tv/fltcalc.h @@ -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_ */ diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index ba7a63882..fd3a3b65c 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -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; diff --git a/ir/tv/strcalc.h b/ir/tv/strcalc.h index 68498dd57..ed94515d5 100644 --- a/ir/tv/strcalc.h +++ b/ir/tv/strcalc.h @@ -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_ */ diff --git a/ir/tv/tv.c b/ir/tv/tv.c index 4e86d0c57..7a1364e12 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -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 ****************************************************************************/ diff --git a/ir/tv/tv.h b/ir/tv/tv.h index 8614272c3..1eeab6008 100644 --- a/ir/tv/tv.h +++ b/ir/tv/tv.h @@ -594,6 +594,8 @@ void init_tarval_1(void); */ void init_tarval_2(void); +void finish_tarval(void); + /** * Output of tarvals to a buffer. */ -- 2.20.1