X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fexecfreq.c;h=368e68da269801bc4b618dd75e143668a302c6da;hb=e2b4dc19ea7c56518acbaf92182691353d9faf1e;hp=7276b0a39566728d6524aa158847e1b2962e3ce9;hpb=8ec60164cb40185b52b43ce075002c18f48db9cf;p=libfirm diff --git a/ir/ana/execfreq.c b/ir/ana/execfreq.c index 7276b0a39..368e68da2 100644 --- a/ir/ana/execfreq.c +++ b/ir/ana/execfreq.c @@ -42,6 +42,8 @@ #include "execfreq.h" +static set *freqs = NULL; + #define set_foreach(s,i) for((i)=set_first((s)); (i); (i)=set_next((s))) typedef struct _walkerdata_t { @@ -78,11 +80,14 @@ set_insert_freq(set * set, const ir_node * irn) } double -get_block_execfreq(set * freqs, const ir_node * irn) +get_block_execfreq(const ir_node * irn) { + freq_t *freq; + assert(is_Block(irn)); - freq_t *freq = set_find_freq(freqs, irn); + freq = set_find_freq(freqs, irn); + assert(freq); return freq->freq; @@ -136,43 +141,31 @@ solve_lgs(double * A, double * b, size_t size) #endif static double -get_cf_probability(const ir_node * bb, int pos) +get_cf_probability(ir_node *bb, int pos, double loop_weight) { -#define LOOP_WEIGHT 9.0 + double sum = 0.0; + double cur = 0.0; + int i; + ir_node *pred = get_Block_cfgpred_block(bb, pos); - double sum = 0.0; - double cur = 0.0; - int i, - n; - ir_node *pred = get_Block_cfgpred_block(bb, pos); - - if(get_loop_depth(get_irn_loop(bb)) < get_loop_depth(get_irn_loop(pred))) { - cur = 1.0; - } else { - cur = LOOP_WEIGHT; - } + cur = get_loop_depth(get_irn_loop(bb)) < get_loop_depth(get_irn_loop(pred)) ? 1.0 : loop_weight; - for(i = 0, n = get_Block_n_cfg_outs(pred); i < n; ++i) { + for(i = get_Block_n_cfg_outs(pred) - 1; i >= 0; --i) { ir_node *succ = get_Block_cfg_out(pred, i); - if(get_loop_depth(get_irn_loop(succ)) < get_loop_depth(get_irn_loop(pred))) { - sum += 1.0; - } else { - sum += LOOP_WEIGHT; - } + sum += get_loop_depth(get_irn_loop(succ)) < get_loop_depth(get_irn_loop(pred)) ? 1.0 : loop_weight; } return cur/sum; } -set * -compute_execfreq(ir_graph * irg) +void +compute_execfreq(ir_graph * irg, double loop_weight) { - set *freqs = new_set(cmp_freq, 32); size_t size; double *matrix; double *rhs; - size_t i = 0; + int i; freq_t *freq; walkerdata_t wd; #ifdef USE_GSL @@ -181,6 +174,9 @@ compute_execfreq(ir_graph * irg) double *x; #endif + free_execfreq(); + freqs = new_set(cmp_freq, 32); + construct_cf_backedges(irg); wd.idx = 0; @@ -189,40 +185,40 @@ compute_execfreq(ir_graph * irg) irg_block_walk_graph(irg, block_walker, NULL, &wd); size = set_count(freqs); - matrix = malloc(size*size*sizeof(*matrix)); + matrix = xmalloc(size*size*sizeof(*matrix)); memset(matrix, 0, size*size*sizeof(*matrix)); - rhs = malloc(size*sizeof(*rhs)); + rhs = xmalloc(size*sizeof(*rhs)); memset(rhs, 0, size*sizeof(*rhs)); set_foreach(freqs, freq) { - const ir_node *bb = freq->irn; - size_t idx = (int)get_irn_link(bb); + ir_node *bb = (ir_node *)freq->irn; + size_t idx = (int)get_irn_link(bb); - matrix[idx*(size+1)] = -1.0; + matrix[idx * (size + 1)] = -1.0; - if(bb == get_irg_start_block(irg)) { + if (bb == get_irg_start_block(irg)) { rhs[(int)get_irn_link(bb)] = -1.0; continue; } - for(i = 0; i < get_Block_n_cfgpreds(bb); ++i) { - ir_node *pred = get_Block_cfgpred_block(bb, i); - size_t pred_idx = (int)get_irn_link(pred); + for(i = get_Block_n_cfgpreds(bb) - 1; i >= 0; --i) { + ir_node *pred = get_Block_cfgpred_block(bb, i); + size_t pred_idx = (int)get_irn_link(pred); // matrix[pred_idx + idx*size] += 1.0/(double)get_Block_n_cfg_outs(pred); - matrix[pred_idx + idx*size] += get_cf_probability(bb, i); + matrix[pred_idx + idx * size] += get_cf_probability(bb, i, loop_weight); } } x = solve_lgs(matrix, rhs, size); if(x == NULL) { del_set(freqs); - return NULL; + return; } set_foreach(freqs, freq) { - const ir_node *bb = freq->irn; - size_t idx = PTR_TO_INT(get_irn_link(bb)); + const ir_node *bb = freq->irn; + size_t idx = PTR_TO_INT(get_irn_link(bb)); #ifdef USE_GSL freq->freq = ZERO(gsl_vector_get(x, idx)) ? 0.0 : gsl_vector_get(x, idx); @@ -237,11 +233,11 @@ compute_execfreq(ir_graph * irg) #endif free(matrix); - return freqs; + return; } void -free_execfreq(set * freqs) +free_execfreq() { if(freqs) del_set(freqs); }