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