indentation changed
[libfirm] / ir / ana / execfreq.c
index 22fdfb9..e7a4a7a 100644 (file)
@@ -1,13 +1,28 @@
 /*
- * Project:     libFIRM
- * File name:   ir/ana/execfreq.c
- * Purpose:     Compute an estimate of basic block executions.
- * Author:      Adam M. Szalkowski
- * Modified by:
- * Created:     28.05.2006
- * CVS-ID:      $Id$
- * Copyright:   (c) 2006 Universität Karlsruhe
- * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief       Compute an estimate of basic block executions.
+ * @author      Adam M. Szalkowski
+ * @date        28.05.2006
+ * @version     $Id$
  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -30,6 +45,7 @@
 #include "firm_common_t.h"
 #include "set.h"
 #include "hashptr.h"
+#include "debug.h"
 
 #include "irprog_t.h"
 #include "irgraph_t.h"
@@ -38,6 +54,7 @@
 #include "irgwalk.h"
 #include "iredges.h"
 #include "irprintf.h"
+#include "irtools.h"
 #include "irhooks.h"
 
 #include "execfreq.h"
@@ -71,6 +88,7 @@ cmp_freq(const void *a, const void *b, size_t size)
 {
        const freq_t *p = a;
        const freq_t *q = b;
+       (void) size;
 
        return !(p->irn == q->irn);
 }
@@ -167,7 +185,7 @@ solve_lgs(double * A, double * b, size_t size)
     return NULL;
   }
 }
-#endif
+#endif /* USE_GSL */
 
 static double
 get_cf_probability(ir_node *bb, int pos, double loop_weight)
@@ -209,6 +227,7 @@ ir_exec_freq *create_execfreq(ir_graph *irg)
        execfreq->hook.context = execfreq;
        execfreq->hook.hook._hook_node_info = exec_freq_node_info;
        register_hook(hook_node_info, &execfreq->hook);
+       (void) irg;
 
        return execfreq;
 }
@@ -242,7 +261,11 @@ compute_execfreq(ir_graph * irg, double loop_weight)
        freqs = ef->set = new_set(cmp_freq, 32);
 
        construct_cf_backedges(irg);
-       edges_assure(irg);
+       /* TODO: edges are corrupt for EDGE_KIND_BLOCK after the local optimize
+                graph phase merges blocks in the x86 backend */
+       edges_deactivate(irg);
+       edges_activate(irg);
+       /* edges_assure(irg); */
 
        wd.idx = 0;
        wd.set = freqs;
@@ -276,90 +299,91 @@ compute_execfreq(ir_graph * irg, double loop_weight)
        }
 
        x = solve_lgs(matrix, rhs, size);
-       if(x == NULL) {
+       if (x == NULL) {
+               DEBUG_ONLY(ir_fprintf(stderr, "Debug Warning: Couldn't estimate execution frequencies for %+F\n", irg));
                ef->infeasible = 1;
-               return ef;
-       }
-
-       ef->max = 0.0;
+       } else {
+               ef->max = 0.0;
 
-       set_foreach(freqs, freq) {
-               const ir_node *bb = freq->irn;
-               size_t        idx = PTR_TO_INT(get_irn_link(bb));
+               set_foreach(freqs, freq) {
+                       const ir_node *bb = freq->irn;
+                       size_t        idx = PTR_TO_INT(get_irn_link(bb));
 
 #ifdef USE_GSL
-               freq->freq = UNDEF(gsl_vector_get(x, idx)) ? EPSILON : gsl_vector_get(x, idx);
+                       freq->freq = UNDEF(gsl_vector_get(x, idx)) ? EPSILON : gsl_vector_get(x, idx);
 #else
-               freq->freq = UNDEF(x[idx]) ? EPSILON : x[idx];
+                       freq->freq = UNDEF(x[idx]) ? EPSILON : x[idx];
 #endif
 
-               /* get the maximum exec freq */
-               ef->max = MAX(ef->max, freq->freq);
+                       /* get the maximum exec freq */
+                       ef->max = MAX(ef->max, freq->freq);
 
-               /* Get the minimum non-zero execution frequency. */
-               if(freq->freq > 0.0)
-                       ef->min_non_zero = MIN(ef->min_non_zero, freq->freq);
-       }
+                       /* Get the minimum non-zero execution frequency. */
+                       if(freq->freq > 0.0)
+                               ef->min_non_zero = MIN(ef->min_non_zero, freq->freq);
+               }
 
-       /* compute m and b of the transformation used to convert the doubles into scaled ints */
-       {
-               double smallest_diff = 1.0;
+               /* compute m and b of the transformation used to convert the doubles into scaled ints */
+               {
+                       double smallest_diff = 1.0;
 
-               double l2 = ef->min_non_zero;
-               double h2 = ef->max;
-               double l1 = 1.0;
-               double h1 = MAX_INT_FREQ;
+                       double l2 = ef->min_non_zero;
+                       double h2 = ef->max;
+                       double l1 = 1.0;
+                       double h1 = MAX_INT_FREQ;
 
-               double *fs = malloc(set_count(freqs) * sizeof(fs[0]));
-               int i, j, n = 0;
+                       double *fs = malloc(set_count(freqs) * sizeof(fs[0]));
+                       int i, j, n = 0;
 
-               set_foreach(freqs, freq)
-                       fs[n++] = freq->freq;
+                       set_foreach(freqs, freq)
+                               fs[n++] = freq->freq;
 
-               /*
-                * find the smallest difference of the execution frequencies
-                * we try to ressolve it with 1 integer.
-                */
-               for(i = 0; i < n; ++i) {
-                       if(fs[i] <= 0.0)
-                               continue;
+                       /*
+                        * find the smallest difference of the execution frequencies
+                        * we try to ressolve it with 1 integer.
+                        */
+                       for(i = 0; i < n; ++i) {
+                               if(fs[i] <= 0.0)
+                                       continue;
 
-                       for(j = i + 1; j < n; ++j) {
-                               double diff = fabs(fs[i] - fs[j]);
+                               for(j = i + 1; j < n; ++j) {
+                                       double diff = fabs(fs[i] - fs[j]);
 
-                               if(!UNDEF(diff))
-                                       smallest_diff = MIN(diff, smallest_diff);
+                                       if(!UNDEF(diff))
+                                               smallest_diff = MIN(diff, smallest_diff);
+                               }
                        }
-               }
-
-               /* according to that the slope of the translation function is 1.0 / smallest diff */
-               ef->m = 1.0 / smallest_diff;
 
-               /* the abscissa is then given by */
-               ef->b = l1 - ef->m * l2;
+                       /* according to that the slope of the translation function is 1.0 / smallest diff */
+                       ef->m = 1.0 / smallest_diff;
 
-               /*
-                * if the slope is so high that the largest integer would be larger than MAX_INT_FREQ
-                * set the largest int freq to that upper limit and recompute the translation function
-                */
-               if(ef->m * h2 + ef->b > MAX_INT_FREQ) {
-                       ef->m = (h1 - l1) / (h2 - l2);
+                       /* the abscissa is then given by */
                        ef->b = l1 - ef->m * l2;
-               }
 
-               // printf("smallest_diff: %g, l1: %f, h1: %f, l2: %f, h2: %f, m: %f, b: %f\n", smallest_diff, l1, h1, l2, h2, ef->m, ef->b);
-               free(fs);
-       }
+                       /*
+                        * if the slope is so high that the largest integer would be larger than MAX_INT_FREQ
+                        * set the largest int freq to that upper limit and recompute the translation function
+                        */
+                       if(ef->m * h2 + ef->b > MAX_INT_FREQ) {
+                               ef->m = (h1 - l1) / (h2 - l2);
+                               ef->b = l1 - ef->m * l2;
+                       }
+
+                       // printf("smallest_diff: %g, l1: %f, h1: %f, l2: %f, h2: %f, m: %f, b: %f\n", smallest_diff, l1, h1, l2, h2, ef->m, ef->b);
+                       free(fs);
+               }
 
 #ifdef USE_GSL
-       gsl_vector_free(x);
+               gsl_vector_free(x);
 #endif
-       free(matrix);
+               memset(&ef->hook, 0, sizeof(ef->hook));
+               ef->hook.context = ef;
+               ef->hook.hook._hook_node_info = exec_freq_node_info;
+               register_hook(hook_node_info, &ef->hook);
+       }
 
-       memset(&ef->hook, 0, sizeof(ef->hook));
-       ef->hook.context = ef;
-       ef->hook.hook._hook_node_info = exec_freq_node_info;
-       register_hook(hook_node_info, &ef->hook);
+       free(matrix);
+       free(rhs);
 
        return ef;
 }
@@ -371,5 +395,3 @@ free_execfreq(ir_exec_freq *ef)
        unregister_hook(hook_node_info, &ef->hook);
        free(ef);
 }
-
-#undef ELEM