belive: Remove duplicate assert()s.
[libfirm] / ir / stat / const_stat.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Statistic functions for constant counting.
23  * @author  Michael Beck
24  */
25 #include "config.h"
26
27 #include "firmstat_t.h"
28 #include "tv_t.h"
29 #include "util.h"
30
31 /**
32  * calculated the dual logarithm of |value|
33  */
34 static unsigned log2abs(long value)
35 {
36         unsigned res = 0;
37
38         if (value < 0)
39                 value = -value;
40
41         if (value > 0xFFFF) {
42                 res += 16;
43                 value >>= 16;
44         }
45         if (value > 0xFF) {
46                 res += 8;
47                 value >>= 8;
48         }
49         if (value > 0xF) {
50                 res += 4;
51                 value >>= 4;
52         }
53         if (value > 3) {
54                 res += 2;
55                 value >>= 2;
56         }
57         if (value > 1) {
58                 res += 1;
59         }
60
61         return res;
62 }
63
64 /**
65  * classify the value of a float tarval
66  */
67 static float_classify_t classify_float_value(ir_tarval *tv)
68 {
69         ir_mode *mode = get_tarval_mode(tv);
70
71         if (tv == get_mode_null(mode))
72                 return STAT_FC_0;
73         else if (tv == get_mode_one(mode))
74                 return STAT_FC_1;
75         else if (tarval_is_finite(tv) && tarval_zero_mantissa(tv)) {
76                 int exp = tarval_get_exponent(tv);
77
78                 if (! tarval_is_negative(tv)) {
79                         if (exp == 1)
80                                 return STAT_FC_2;
81                         else if (exp == -1)
82                                 return STAT_FC_0_5;
83                 }
84                 return STAT_FC_POWER_OF_TWO;
85         }
86         return STAT_FC_OTHER;
87 }
88
89 /* return a human readable name for an float classification */
90 const char *stat_fc_name(float_classify_t classification)
91 {
92         switch (classification) {
93         case STAT_FC_0:            return "0.0";
94         case STAT_FC_1:            return "1.0";
95         case STAT_FC_2:            return "2.0";
96         case STAT_FC_0_5:          return "0.5";
97         case STAT_FC_POWER_OF_TWO: return "2.0^x";
98         case STAT_FC_OTHER:        return "other";
99         default:                   return "<UNKNOWN>";
100         }
101 }
102
103 /* update info on Consts */
104 void stat_update_const(stat_info_t *status, ir_node *node, graph_entry_t *graph)
105 {
106         ir_mode   *mode = get_irn_mode(node);
107         ir_tarval *tv;
108         unsigned   bits;
109         (void) graph;
110
111         if (mode_is_int(mode)) {
112                 tv   = get_Const_tarval(node);
113
114                 /* FIXME: */
115                 if (! tarval_is_long(tv))
116                         return;
117
118                 bits = log2abs(get_tarval_long(tv));
119
120                 if (bits > ARRAY_SIZE(status->const_info.int_bits_count))
121                         bits = ARRAY_SIZE(status->const_info.int_bits_count);
122
123                 cnt_inc(&status->const_info.int_bits_count[bits]);
124         } else if (mode_is_float(mode)) {
125                 tv = get_Const_tarval(node);
126
127                 cnt_inc(&status->const_info.floats[classify_float_value(tv)]);
128         } else {
129                 /* something different */
130                 cnt_inc(&status->const_info.others);
131         }
132 }
133
134 /* clears the const statistics for a new snapshot */
135 void stat_const_clear(stat_info_t *status)
136 {
137         size_t i;
138
139         for (i = 0; i < ARRAY_SIZE(status->const_info.int_bits_count); ++i)
140                 cnt_clr(&status->const_info.int_bits_count[i]);
141
142         for (i = 0; i < ARRAY_SIZE(status->const_info.floats); ++i)
143                 cnt_clr(&status->const_info.floats[i]);
144
145         cnt_clr(&status->const_info.others);
146 }
147
148 /* initialize the Const statistic. */
149 void stat_init_const_cnt(stat_info_t *status)
150 {
151         (void) status;
152         /* currently nothing */
153 }