- get_Block_cfgpred_arr() IS supported, but should not be in the official
[libfirm] / ir / ir / irphase_t.h
1 /*
2  * Copyright (C) 1995-2008 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   Phase information handling using node indexes.
23  * @author  Sebastian Hack
24  * @version $Id$
25  */
26 #ifndef FIRM_IR_PHASE_T_H
27 #define FIRM_IR_PHASE_T_H
28
29 #include "firm_types.h"
30 #include "obst.h"
31 #include "irgraph_t.h"
32 #include "irtools.h"
33 #include "irphases_t.h"
34
35 struct _ir_phase_info {
36         ir_phase_id      id;
37         const char       buf[128];
38 };
39
40 typedef struct _ir_phase_info ir_phase_info;
41
42 typedef void *(phase_irn_init)(ir_phase *phase, const ir_node *irn, void *old);
43
44 /**
45  * A default node initializer.
46  * It does nothing and returns NULL.
47  */
48 extern phase_irn_init phase_irn_init_default;
49
50 /**
51  * A phase object.
52  */
53 struct _ir_phase {
54         struct obstack     obst;           /**< The obstack where the irn phase data will be stored on. */
55         ir_phase_id        id;             /**< The phase ID. */
56         const char        *name;           /**< The name of the phase. */
57         ir_graph          *irg;            /**< The irg this phase will we applied to. */
58         unsigned           growth_factor;  /**< The factor to leave room for additional nodes. 256 means 1.0. */
59         void              *priv;           /**< Some pointer private to the user of the phase. */
60         size_t             n_data_ptr;     /**< The length of the data_ptr array. */
61         void             **data_ptr;       /**< Map node indexes to irn data on the obstack. */
62         phase_irn_init    *data_init;      /**< A callback that is called to initialize newly created node data. */
63 };
64
65 #define PHASE_DEFAULT_GROWTH (256)
66
67
68 /**
69  * For statistics: A type containing statistic data of a phase object.
70  */
71 typedef struct {
72         unsigned node_slots;       /**< The number of allocated node slots. */
73         unsigned node_slots_used;  /**< The number of used node slots, i.e. nodes that have node data. */
74         unsigned node_map_bytes;   /**< Number of used bytes for the node map. */
75         unsigned overall_bytes;    /**< Overall number of used bytes for the phase. */
76 } phase_stat_t;
77
78 /**
79  * Collect Phase statistics.
80  *
81  * @param phase  The phase.
82  * @param stat   Will be filled with the statistical data.
83  */
84 phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat);
85
86 /**
87  * Initialize a phase object.
88  *
89  * @param name          The name of the phase. Just for debugging.
90  * @param irg           The graph the phase will run on.
91  * @param growth_factor A factor denoting how many node slots will be additionally allocated,
92  *                      if the node => data is full. The factor is given in units of 1/256, so
93  *                      256 means 1.0.
94  * @param irn_data_init A callback that is called to initialize newly created node data.
95  *                      Must be non-null.
96  * @param priv          Some private pointer which is kept in the phase and can be retrieved with phase_get_private().
97  * @return              A new phase object.
98  */
99 ir_phase *phase_init(ir_phase *ph, const char *name, ir_graph *irg, unsigned growth_factor, phase_irn_init *data_init, void *priv);
100
101 /**
102  * Init an irg managed phase.
103  *
104  * The first sizeof(ir_phase) bytes will be considered to be a phase object;
105  * they will be properly initialized. The remaining bytes are at the user's disposal.
106  * The returned phase object will be inserted in the phase slot of the @p irg designated by the phase ID (@p id).
107  * Note that you cannot allocate phases with an ID <code>PHASE_NOT_IRG_MANAGED</code>.
108  *
109  * @param ph        The memory of the phase to initialize.
110  * @param irg       The irg.
111  * @param id        The ID of the irg-managed phase (see irphaselist.h).
112  * @param data_init The node data initialization function.
113  * @return          The allocated phase object.
114  */
115 ir_phase *init_irg_phase(ir_graph *irg, ir_phase_id id, size_t size, phase_irn_init *data_init);
116
117 void free_irg_phase(ir_graph *irg, ir_phase_id id);
118
119 /**
120  * Free the phase and all node data associated with it.
121  *
122  * @param phase  The phase.
123  */
124 void phase_free(ir_phase *phase);
125
126 /**
127  * Re-initialize the irn data for all nodes in the node => data map using the given callback.
128  *
129  * @param phase  The phase.
130  */
131 void phase_reinit_irn_data(ir_phase *phase);
132
133 /**
134  * Re-initialize the irn data for all nodes having phase data in the given block.
135  *
136  * @param phase  The phase.
137  * @param block  The block.
138  *
139  * @note Beware: iterates over all nodes in the graph to find the nodes of the given block.
140  */
141 void phase_reinit_block_irn_data(ir_phase *phase, ir_node *block);
142
143 /**
144  * Re-initialize the irn data for the given node.
145  *
146  * @param phase  The phase.
147  * @param irn    The irn.
148  */
149 #define phase_reinit_single_irn_data(phase, irn) _phase_reinit_single_irn_data((phase), (irn))
150
151 /**
152  * Returns the first node of the phase having some data assigned.
153  *
154  * @param phase  The phase.
155  *
156  * @return The first irn having some data assigned, NULL otherwise
157  */
158 ir_node *phase_get_first_node(const ir_phase *phase);
159
160 /**
161  * Returns the next node after @p start having some data assigned.
162  *
163  * @param phase  The phase.
164  * @param start  The node to start from
165  *
166  * @return The next node after start having some data assigned, NULL otherwise
167  */
168 ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start);
169
170 /**
171  * Convenience macro to iterate over all nodes of a phase
172  * having some data assigned.
173  *
174  * @param phase  The phase.
175  * @param irn    A local variable that will hold the current node inside the loop.
176  */
177 #define foreach_phase_irn(phase, irn) \
178         for (irn = phase_get_first_node(phase); irn; irn = phase_get_next_node(phase, irn))
179
180 /**
181  * Get the name of the phase.
182  *
183  * @param phase  The phase.
184  */
185 #define phase_get_name(phase)                 ((phase)->name)
186
187 /**
188  * Get the irg the phase runs on.
189  *
190  * @param phase  The phase.
191  */
192 #define phase_get_irg(phase)                  ((phase)->irg)
193
194 /**
195  * Get private data pointer as passed on creating the phase.
196  *
197  * @param phase  The phase.
198  */
199 #define phase_get_private(phase)              ((phase)->priv)
200
201 /**
202  * Allocate memory in the phase's memory pool.
203  *
204  * @param phase  The phase.
205  * @param size   Number of bytes to allocate.
206  */
207 #define phase_alloc(phase, size)              obstack_alloc(phase_obst(phase), (size))
208
209 /**
210  * Get the obstack of a phase.
211  *
212  * @param phase  The phase.
213  */
214 #define phase_obst(phase)                     (&(phase)->obst)
215
216 /**
217  * Get the phase node data for an irn.
218  *
219  * @param phase   The phase.
220  * @param irn     The irn to get data for.
221  *
222  * @return A pointer to the node data or NULL if the irn has no phase data allocated yet.
223  */
224 #define phase_get_irn_data(phase, irn)        _phase_get_irn_data((phase), (irn))
225
226 /**
227  * Get or set phase data for an irn.
228  *
229  * @param phase  The phase.
230  * @param irn    The irn to get (or set) node data for.
231  *
232  * @return A (non-NULL) pointer to phase data for the irn. Either existent one or newly allocated one.
233  */
234 #define phase_get_or_set_irn_data(phase, irn) _phase_get_or_set_irn_data((phase), (irn))
235
236 /**
237  * Set the node data for an irn.
238  *
239  * @param phase  The phase.
240  * @param irn    The node.
241  * @param data   The node data.
242  *
243  * @return The old data or NULL if there was none.
244  */
245 #define phase_set_irn_data(phase, irn, data)  _phase_set_irn_data((phase), (irn), (data))
246
247 /**
248  * Get the irg-managed phase for a givedn phase ID.
249  * @param irg The irg.
250  * @param id  The ID.
251  * @return The corresponding phase, or NULL if there is none.
252  */
253 #define get_irg_phase(irg, id)                _get_irg_phase((irg), (id))
254
255 /**
256  * Get the information a phase holds about a node.
257  * @param irn The node.
258  * @param id  The ID of the phase.
259  */
260 #define get_irn_phase_info(irn, id)           _get_phase_irn_info((irn), (id))
261
262 /**
263  * Get or set information a phase holds about a node.
264  * If the given phase does not hold information of the node,
265  * the information structure will be created, initialized (see the data_init function of ir_phase), and returned.
266  * @param irn The node.
267  * @param id  The ID of the phase.
268  */
269 #define get_or_set_irn_phase_info(irn, id)    _get_or_set_irn_phase_info((irn), (id))
270
271 #define set_irn_phase_info(irn, id)           _set_irn_phase_info((irn), (id))
272
273 /**
274  * This is private and only here for performance reasons.
275  */
276 static inline void _phase_reinit_single_irn_data(ir_phase *phase, ir_node *irn)
277 {
278         int idx;
279
280         if (! phase->data_init)
281                 return;
282
283         idx = get_irn_idx(irn);
284         if (phase->data_ptr[idx])
285                 phase->data_init(phase, irn, phase->data_ptr[idx]);
286 }
287
288
289 /**
290  * This is private and just here for performance reasons.
291  */
292 static inline void _private_phase_enlarge(ir_phase *phase, unsigned max_idx)
293 {
294         unsigned last_irg_idx = get_irg_last_idx(phase->irg);
295         size_t old_cap        = phase->n_data_ptr;
296         size_t new_cap;
297
298         /* make the maximum index at least as big as the largest index in the graph. */
299         max_idx = MAX(max_idx, last_irg_idx);
300         new_cap = (size_t) (max_idx * phase->growth_factor / 256);
301
302         phase->data_ptr = XREALLOC(phase->data_ptr, void*, new_cap);
303
304         /* initialize the newly allocated memory. */
305         memset(phase->data_ptr + old_cap, 0, (new_cap - old_cap) * sizeof(phase->data_ptr[0]));
306         phase->n_data_ptr = new_cap;
307 }
308
309 /**
310  * This is private and only here for performance reasons.
311  */
312 #define _private_phase_assure_capacity(ph, max_idx) ((max_idx) >= (ph)->n_data_ptr ? (_private_phase_enlarge((ph), (max_idx)), 1) : 1)
313
314 static inline void *_phase_get_irn_data(const ir_phase *ph, const ir_node *irn)
315 {
316         unsigned idx = get_irn_idx(irn);
317         return idx < ph->n_data_ptr ? ph->data_ptr[idx] : NULL;
318 }
319
320 static inline void *_phase_set_irn_data(ir_phase *ph, const ir_node *irn, void *data)
321 {
322         unsigned idx = get_irn_idx(irn);
323         void *res;
324
325         /* Assure that there's a sufficient amount of slots. */
326         _private_phase_assure_capacity(ph, idx);
327
328         res = ph->data_ptr[idx];
329         ph->data_ptr[idx] = data;
330
331         return res;
332 }
333
334
335 static inline void *_phase_get_or_set_irn_data(ir_phase *ph, const ir_node *irn)
336 {
337         unsigned idx = get_irn_idx(irn);
338         void *res;
339
340         /* Assure that there's a sufficient amount of slots. */
341         _private_phase_assure_capacity(ph, idx);
342
343         res = ph->data_ptr[idx];
344
345         /* If there has no irn data allocated yet, do that now. */
346         if(!res) {
347                 phase_irn_init *data_init = ph->data_init;
348
349                 /* call the node data structure allocator/constructor. */
350                 res = ph->data_ptr[idx] = data_init(ph, irn, NULL);
351
352         }
353         return res;
354 }
355
356 static inline ir_phase *_get_irg_phase(const ir_graph *irg, ir_phase_id id)
357 {
358         return irg->phases[id];
359 }
360
361 static inline void *_get_irn_phase_info(const ir_node *irn, ir_phase_id id)
362 {
363         const ir_graph *irg = get_irn_irg(irn);
364         const ir_phase *ph  = get_irg_phase(irg, id);
365         assert(ph && "phase info has to be computed");
366         return _phase_get_irn_data(ph, irn);
367 }
368
369 static inline void *_get_or_set_irn_phase_info(const ir_node *irn, ir_phase_id id)
370 {
371         const ir_graph *irg = get_irn_irg(irn);
372         ir_phase *ph  = get_irg_phase(irg, id);
373         assert(ph && "phase info has to be computed");
374         return _phase_get_or_set_irn_data(ph, irn);
375 }
376
377 static inline void *_set_irn_phase_info(const ir_node *irn, ir_phase_id id, void *data)
378 {
379         const ir_graph *irg = get_irn_irg(irn);
380         ir_phase *ph  = get_irg_phase(irg, id);
381         assert(ph && "phase info has to be computed");
382         return _phase_set_irn_data(ph, irn, data);
383 }
384
385
386 #endif