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