More doxygen comments, typos fixed, clear some code
[libfirm] / ir / ana / field_temperature.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ana/field_temperature.c
4  * Purpose:     Compute an estimate of field temperature, i.e., field access heuristic.
5  * Author:      Goetz Lindenmaier
6  * Modified by:
7  * Created:     21.7.2004
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 2004 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #include "field_temperature.h"
14
15 #include "irnode_t.h"
16 #include "irgraph_t.h"
17 #include "irprog_t.h"
18 #include "entity_t.h"
19 #include "irgwalk.h"
20
21 #include "array.h"
22
23 /* *************************************************************************** */
24 /* initialize, global variables.                                               */
25 /* *************************************************************************** */
26
27 /* A list of Load and Store operations that have no analyseable address. */
28 static ir_node **unrecognized_access = NULL;
29
30 static void add_unrecognized_access(ir_node *n) {
31   ARR_APP1(ir_node *, unrecognized_access, n);
32 }
33
34
35 /* *************************************************************************** */
36 /*   Access routines for irnodes                                               */
37 /* *************************************************************************** */
38
39 /* The entities that can be accessed by this Sel node. */
40 int get_Sel_n_accessed_entities(ir_node *sel) {
41   return 1;
42 }
43
44 entity *get_Sel_accessed_entity(ir_node *sel, int pos) {
45   return get_Sel_entity(sel);
46 }
47
48 /* An addr node is a SymConst or a Sel. */
49 int get_addr_n_entities(ir_node *addr) {
50   int n_ents;
51
52   switch (get_irn_opcode(addr)) {
53   case iro_Sel:
54     /* Treat jack array sels? */
55     n_ents = get_Sel_n_accessed_entities(addr);
56     break;
57   case iro_SymConst:
58     if (get_SymConst_kind(addr) == symconst_addr_ent) {
59       n_ents = 1;
60       break;
61     }
62   default:
63     //assert(0 && "unexpected address expression");
64     n_ents = 0;
65   }
66
67   return n_ents;
68 }
69
70 /* An addr node is a SymConst or a Sel. */
71 entity *get_addr_entity(ir_node *addr, int pos) {
72   entity *ent;
73
74   switch (get_irn_opcode(addr)) {
75   case iro_Sel:
76     /* Treat jack array sels? */
77     assert (0 <= pos && pos < get_Sel_n_accessed_entities(addr));
78     ent = get_Sel_accessed_entity(addr, pos);
79     break;
80   case iro_SymConst:
81     if (get_SymConst_kind(addr) == symconst_addr_ent) {
82       assert(pos == 0);
83       ent = get_SymConst_entity(addr);
84       break;
85     }
86   default:
87     ent = NULL;
88   }
89
90   return ent;
91 }
92
93
94 int get_irn_loop_call_depth(ir_node *n) {
95   ir_graph *irg = get_irn_irg(n);
96   return get_irg_loop_depth(irg);
97 }
98
99 int get_irn_loop_depth(ir_node *n) {
100   return get_loop_depth(get_irn_loop(get_nodes_block(n)));
101 }
102
103 int get_irn_recursion_depth(ir_node *n) {
104   ir_graph *irg = get_irn_irg(n);
105   return get_irg_recursion_depth(irg);
106 }
107
108
109 /* *************************************************************************** */
110 /* The heuristic                                                               */
111 /* *************************************************************************** */
112
113 int get_weighted_loop_depth(ir_node *n) {
114   int loop_call_depth = get_irn_loop_call_depth(n);
115   int loop_depth      = get_irn_loop_depth(n);
116   int recursion_depth = get_irn_recursion_depth(n);
117
118   return loop_call_depth + loop_depth + recursion_depth;
119 }
120
121 /* *************************************************************************** */
122 /* The analyses                                                                */
123 /* *************************************************************************** */
124
125 static void init_field_temperature(void) {
126   assert(!unrecognized_access);
127   unrecognized_access = NEW_ARR_F(ir_node *, 0);
128 }
129
130
131 static void chain_accesses(ir_node *n, void *env) {
132   int i, n_ents;
133   ir_node *addr;
134
135   if (get_irn_op(n) == op_Alloc) {
136     add_type_allocation(get_Alloc_type(n), n);
137     return;
138   }
139
140   if (is_memop(n)) {
141     addr = get_memop_ptr(n);
142   } else if (get_irn_op(n) == op_Call) {
143     addr = get_Call_ptr(n);
144     if (get_irn_op(addr) != op_Sel) return;  /* Sels before Calls mean a Load / polymorphic Call. */
145   } else {
146     return;
147   }
148
149   n_ents = get_addr_n_entities(addr);
150   for (i = 0; i < n_ents; ++i) {
151     entity *ent = get_addr_entity(addr, i);
152     if (ent)
153       add_entity_access(ent, n);
154     else
155       add_unrecognized_access(n);
156   }
157 }
158
159
160 /* compute the field temperature. */
161 void compute_field_temperature(void) {
162
163   int i, n_irgs = get_irp_n_irgs();
164
165   init_field_temperature();
166
167   for (i=0; i < n_irgs; i++) {
168     current_ir_graph = get_irp_irg(i);
169     irg_walk_graph(current_ir_graph, NULL, chain_accesses, NULL);
170   }
171 }
172
173 /* free occupied memory, reset */
174 void free_field_temperature(void) {
175   DEL_ARR_F(unrecognized_access);
176   unrecognized_access = NULL;
177 }
178
179
180
181 /* *************************************************************************** */
182 /* Auxiliary                                                                   */
183 /* *************************************************************************** */
184
185
186 int is_jack_rts_class(type *t) {
187   ident *name = get_type_ident(t);
188
189   if (id_is_prefix(new_id_from_str("java/"), name)) return 1;
190   if (id_is_prefix(new_id_from_str("["), name)) return 1;
191   if (id_is_prefix(new_id_from_str("gnu/"), name)) return 1;
192   if (id_is_prefix(new_id_from_str("java/"), name)) return 1;
193
194   return 0;
195 }