execfreq stroes set internally now
[libfirm] / ir / ana / execfreq.c
index 9807c1a..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,7 +80,7 @@ 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;
 
@@ -139,34 +141,31 @@ solve_lgs(double * A, double * b, size_t size)
 #endif
 
 static double
-get_cf_probability(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, n;
+  int     i;
   ir_node *pred = get_Block_cfgpred_block(bb, pos);
 
-  cur = get_loop_depth(get_irn_loop(bb)) < get_loop_depth(get_irn_loop(pred)) ? 1.0 : 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);
 
-    sum += get_loop_depth(get_irn_loop(succ)) < get_loop_depth(get_irn_loop(pred)) ? 1.0 : 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
@@ -175,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;
@@ -183,9 +185,9 @@ 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) {
@@ -204,14 +206,14 @@ compute_execfreq(ir_graph * irg)
       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) {
@@ -231,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);
 }