From df44219548e55e6962d446f1d5f91227e8030b70 Mon Sep 17 00:00:00 2001 From: Sebastian Hack Date: Sun, 5 Aug 2007 18:50:34 +0000 Subject: [PATCH] Fixed (some) memory leaks. and some bugs [r15473] --- ir/be/bespillbelady2.c | 80 +++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/ir/be/bespillbelady2.c b/ir/be/bespillbelady2.c index 30898de32..eecea5704 100644 --- a/ir/be/bespillbelady2.c +++ b/ir/be/bespillbelady2.c @@ -78,7 +78,9 @@ #define DBG_WORKSET 128 #define DBG_GLOBAL 256 -#define DEAD UINT_MAX +#define DEAD UINT_MAX +#define LIVE_END (DEAD-1) + DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) /** @@ -89,8 +91,7 @@ typedef struct _loc_t { unsigned time; /**< A use time (see beuses.h). */ unsigned version; /**< That is used in the global pass below. For usage see the comments below. - In the local belady pass, this is not - important. */ + In the local belady pass, this is not important. */ } loc_t; typedef struct _workset_t { @@ -351,6 +352,29 @@ static INLINE void advance_current_use(block_info_t *bi, const ir_node *irn) phase_set_irn_data(&bi->next_uses, irn, use->next); } +static INLINE unsigned get_curr_distance(block_info_t *bi, const ir_node *irn, int is_usage) +{ + belady_env_t *env = bi->bel; + next_use_t *use = get_current_use(bi, irn); + int curr_step = sched_get_time_step(env->instr); + int flags = arch_irn_get_flags(env->arch, irn); + + assert(!(flags & arch_irn_flags_ignore)); + + /* We have to keep nonspillable nodes in the workingset */ + if(flags & arch_irn_flags_dont_spill) + return 0; + + if (!is_usage && use && use->step == curr_step) + use = use->next; + + if (use) { + assert(use->step >= curr_step); + return use->step - curr_step; + } + + return be_is_live_end(env->lv, bi->bl, irn) ? LIVE_END : DEAD; +} static INLINE int is_local_phi(const ir_node *bl, const ir_node *irn) { @@ -442,20 +466,15 @@ static void displace(block_info_t *bi, workset_t *new_vals, int is_usage) { /* Only make more free room if we do not have enough */ if (len > max_allowed) { - int curr_step = sched_get_time_step(env->instr); + // int curr_step = sched_get_time_step(env->instr); DBG((dbg, DBG_DECIDE, " disposing %d values\n", len - max_allowed)); /* get current next-use distance */ for (i = 0; i < ws->len; ++i) { - ir_node *val = workset_get_val(ws, i); - next_use_t *use = phase_get_irn_data(&bi->next_uses, val); - assert(use == NULL || use->step >= curr_step); - - if (!is_usage && use) - use = use->next; - - workset_set_time(ws, i, use ? (unsigned) (use->step - curr_step) : DEAD); + ir_node *val = workset_get_val(ws, i); + unsigned dist = get_curr_distance(bi, val, is_usage); + workset_set_time(ws, i, dist); } /* sort entries by increasing nextuse-distance*/ @@ -486,6 +505,7 @@ static void displace(block_info_t *bi, workset_t *new_vals, int is_usage) { static void belady(ir_node *block, void *data) { belady_env_t *env = data; block_info_t *block_info = new_block_info(env, block); + void *obst_state = obstack_base(&env->ob); workset_t *new_vals; ir_node *irn; @@ -563,6 +583,7 @@ static void belady(ir_node *block, void *data) { } phase_free(&block_info->next_uses); + obstack_free(&env->ob, obst_state); /* Remember end-workset for this block */ block_info->ws_end = workset_clone(env, &env->ob, env->ws); @@ -835,23 +856,6 @@ static void materialize_and_commit_end_state(global_end_state_t *ges) DBG((dbg, DBG_GLOBAL, "\t\tadding reload of %+F at end of %+F\n", bes->irn, bes->bl)); } - end_pressure = 0; - for (idx = workset_get_length(bes->end_state) - 1; idx >= 0; --idx) - if (bes->end_state->vals[idx].version >= ges->version) - end_pressure += 1; - - /* - * if the variable is live through the block, - * update the pressure indicator. - */ - DBG((dbg, DBG_GLOBAL, "\t\told pressure %d, ", bi->pressure)); - - bi->pressure = MAX(bi->pressure + bes->live_through, end_pressure); - - DBG((dbg, DBG_GLOBAL, "new pressure: %d, end pressure: %d, end length: %d\n", - bi->pressure, end_pressure, workset_get_length(bes->end_state))); - -// workset_print(bes->end_state); idx = workset_get_index(bes->end_state, bes->irn); if (is_local_phi(bes->bl, bes->irn) && bes->live_through) @@ -870,6 +874,23 @@ static void materialize_and_commit_end_state(global_end_state_t *ges) bes->end_state->vals[idx].version = ges->version; workset_copy(env, bi->ws_end, bes->end_state); } + + end_pressure = 0; + for (idx = workset_get_length(bes->end_state) - 1; idx >= 0; --idx) + if (bes->end_state->vals[idx].version >= ges->version) + end_pressure += 1; + + /* + * if the variable is live through the block, + * update the pressure indicator. + */ + DBG((dbg, DBG_GLOBAL, "\t\told pressure %d, ", bi->pressure)); + + bi->pressure = MAX(bi->pressure + bes->live_through, end_pressure); + + DBG((dbg, DBG_GLOBAL, "new pressure: %d, end pressure: %d, end length: %d\n", + bi->pressure, end_pressure, workset_get_length(bes->end_state))); + } } @@ -966,6 +987,7 @@ static void global_assign(belady_env_t *env) } } + DEL_ARR_F(ges.end_info); } static void collect_blocks(ir_node *bl, void *data) -- 2.20.1