optimize next_use calculation (quadratic in number of outs not number of nodes in...
[libfirm] / ir / be / bepressurestat.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       Register Pressure Statistics.
23  * @author      Adam M. Szalkowski
24  * @date        06.04.2006
25  * @version     $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <math.h>
32
33 #include "hashptr.h"
34 #include "debug.h"
35 #include "obst.h"
36 #include "set.h"
37 #include "list.h"
38 #include "pmap.h"
39
40 #include "irprintf.h"
41 #include "irgwalk.h"
42 #include "irdump_t.h"
43 #include "irnode_t.h"
44 #include "ircons_t.h"
45 #include "irloop_t.h"
46 #include "phiclass.h"
47 #include "iredges.h"
48 #include "execfreq.h"
49 #include "irtools.h"
50
51 #include <libcore/lc_bitset.h>
52
53 #include "be_t.h"
54 #include "belive_t.h"
55 #include "besched_t.h"
56 #include "beirgmod.h"
57 #include "bearch_t.h"
58 #include "benode_t.h"
59 #include "beutil.h"
60 #include "bespillremat.h"
61 #include "bespill.h"
62 #include "beirg_t.h"
63
64 #define MAXPRESSURE 128
65
66 typedef struct _regpressure_ana_t {
67         arch_env_t                   *arch_env;
68         const arch_register_class_t  *cls;
69         const be_lv_t                *lv;
70         unsigned int                 *stat;
71         DEBUG_ONLY(firm_dbg_module_t *dbg);
72 } regpressure_ana_t;
73
74 static INLINE int has_reg_class(const regpressure_ana_t *ra, const ir_node *irn)
75 {
76         return arch_irn_consider_in_reg_alloc(ra->arch_env, ra->cls, irn);
77 }
78
79 static INLINE int regpressure(pset *live) {
80         int pressure = pset_count(live);
81         return MIN(pressure, MAXPRESSURE);
82 }
83
84 static void
85 regpressureanawalker(ir_node *bb, void *data)
86 {
87         regpressure_ana_t  *ra   = data;
88         pset               *live = pset_new_ptr_default();
89         const ir_node      *irn;
90         unsigned int       *stat = ra->stat;
91         int                i;
92         const be_lv_t      *lv   = ra->lv;
93
94         be_lv_foreach(lv, bb, be_lv_state_end, i) {
95                 ir_node *value = be_lv_get_irn(lv, bb, i);
96                 if (has_reg_class(ra, value)) {
97                         pset_insert_ptr(live, value);
98                 }
99         }
100         stat[regpressure(live)]++;
101
102         sched_foreach_reverse(bb, irn) {
103
104                 if (is_Phi(irn)) break;
105
106                 if (has_reg_class(ra, irn)) {
107                         pset_remove_ptr(live, irn);
108                 }
109
110                 for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
111                         ir_node  *arg = get_irn_n(irn, i);
112
113                         if (has_reg_class(ra, arg)) {
114                                 pset_insert_ptr(live, arg);
115                         }
116                 }
117
118                 if (! is_Proj(irn))
119                         stat[regpressure(live)]++;
120         }
121 }
122
123 void be_analyze_regpressure(be_irg_t *birg, const arch_register_class_t *cls, const char *suffix)
124 {
125         regpressure_ana_t ra;
126         unsigned int      stat[MAXPRESSURE+1];
127         unsigned int      i;
128         char              fname[256];
129         FILE              *f;
130         ir_graph          *irg = be_get_birg_irg(birg);
131
132         ir_snprintf(fname, sizeof(fname), "%F_%s%s_pressure.stat", irg, cls->name, suffix);
133         f = fopen(fname, "w");
134         assert(f);
135
136         be_assure_liveness(birg);
137
138         FIRM_DBG_REGISTER(ra.dbg, "firm.be.regpressureana");
139
140         ra.arch_env = birg->main_env->arch_env;
141         ra.lv       = be_get_birg_liveness(birg);
142         ra.cls      = cls;
143         ra.stat     = stat;
144
145         memset(stat, 0, sizeof(stat));
146
147         irg_block_walk_graph(irg, regpressureanawalker, NULL, &ra);
148
149         for (i = 0; i <= MAXPRESSURE; ++i) {
150                 fprintf(f, "%d\n", stat[i]);
151         }
152
153         fclose(f);
154 }