#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 {
}
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;
#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
double *x;
#endif
+ free_execfreq();
+ freqs = new_set(cmp_freq, 32);
+
construct_cf_backedges(irg);
wd.idx = 0;
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);
#else
freq->freq = ZERO(x[idx]) ? 0.0 : x[idx];
#endif
- ir_fprintf(stderr, "execfreq %+F: %f\n", bb, freq->freq);
+// ir_fprintf(stderr, "execfreq %+F: %f\n", bb, freq->freq);
}
#ifdef USE_GSL
#endif
free(matrix);
- return freqs;
+ return;
}
void
-free_execfreq(set * freqs)
+free_execfreq()
{
if(freqs) del_set(freqs);
}