execfreq stroes set internally now
[libfirm] / ir / ana / execfreq.c
index 7276b0a..368e68d 100644 (file)
@@ -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);
 }