updated Header
[libfirm] / ir / stat / const_stat.c
1 /*
2  * Copyright (C) 1995-2007 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  * @version $Id$
25  */
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include "firmstat_t.h"
31 #include "tv_t.h"
32
33 /**
34  * calculated the dual logarithm of |value|
35  */
36 static unsigned log2abs(long value) {
37         unsigned res = 0;
38
39         if (value < 0)
40                 value = -value;
41
42         if (value > 0xFFFF) {
43                 res += 16;
44                 value >>= 16;
45         }
46         if (value > 0xFF) {
47                 res += 8;
48                 value >>= 8;
49         }
50         if (value > 0xF) {
51                 res += 4;
52                 value >>= 4;
53         }
54         if (value > 3) {
55                 res += 2;
56                 value >>= 2;
57         }
58         if (value > 1) {
59                 res += 1;
60         }
61
62         return res;
63 }
64
65 /**
66  * classify the value of a float tarval
67  */
68 static float_classify_t classify_float_value(tarval *tv) {
69         ir_mode *mode = get_tarval_mode(tv);
70
71         if (tv == get_mode_null(mode))
72                 return STAT_FC_1;
73         else if (tv == get_mode_one(mode))
74                 return STAT_FC_1;
75
76         return STAT_FC_OTHER;
77 }
78
79 /* return a human readable name for an float classification */
80 const char *stat_fc_name(float_classify_t classification) {
81         switch (classification) {
82         case STAT_FC_0:     return "0.0";
83         case STAT_FC_1:     return "1.0";
84         case STAT_FC_2:     return "2.0";
85         case STAT_FC_0_5:   return "0.5";
86         case STAT_FC_EXACT: return "exact";
87         case STAT_FC_OTHER: return "other";
88         default:            return "<UNKNOWN>";
89         }
90 }
91
92 /* update info on Consts */
93 void stat_update_const(stat_info_t *status, ir_node *node, graph_entry_t *graph)
94 {
95         ir_mode *mode = get_irn_mode(node);
96         tarval *tv;
97         unsigned bits;
98
99         if (mode_is_int(mode)) {
100                 tv   = get_Const_tarval(node);
101
102                 /* FIXME: */
103                 if (! tarval_is_long(tv))
104                         return;
105
106                 bits = log2abs(get_tarval_long(tv));
107
108                 if (bits > ARR_SIZE(status->const_info.int_bits_count))
109                         bits = ARR_SIZE(status->const_info.int_bits_count);
110
111                 cnt_inc(&status->const_info.int_bits_count[bits]);
112         } else if (mode_is_float(mode)) {
113                 tv = get_Const_tarval(node);
114
115                 cnt_inc(&status->const_info.floats[classify_float_value(tv)]);
116         } else {
117                 /* something different */
118                 cnt_inc(&status->const_info.others);
119         }
120 }
121
122 /* clears the const statistics for a new snapshot */
123 void stat_const_clear(stat_info_t *status) {
124         int i;
125
126         for (i = 0; i < ARR_SIZE(status->const_info.int_bits_count); ++i)
127                 cnt_clr(&status->const_info.int_bits_count[i]);
128
129         for (i = 0; i < ARR_SIZE(status->const_info.floats); ++i)
130                 cnt_clr(&status->const_info.floats[i]);
131
132         cnt_clr(&status->const_info.others);
133 }
134
135 /* initialize the Const statistic. */
136 void stat_init_const_cnt(stat_info_t *status) {
137         /* currently nothing */
138 }