2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Phase information handling using node indexes.
23 * @author Sebastian Hack
26 #ifndef FIRM_IR_PHASE_T_H
27 #define FIRM_IR_PHASE_T_H
29 #include "firm_types.h"
31 #include "irgraph_t.h"
39 void **data_ptr; /**< Map node indexes to irn data on the obstack. */
40 ir_graph *irg; /**< The irg this phase will we applied to. */
41 phase_irn_init *data_init; /**< A callback that is called to initialize newly created node data. */
42 unsigned n_data_ptr; /**< The length of the data_ptr array. */
43 struct obstack obst; /**< The obstack where the irn phase data will be stored on. */
44 void *priv; /**< Some pointer private to the user of the phase. */
48 * For statistics: A type containing statistic data of a phase object.
51 unsigned node_slots; /**< The number of allocated node slots. */
52 unsigned node_slots_used; /**< The number of used node slots, i.e. nodes that have node data. */
53 unsigned node_map_bytes; /**< Number of used bytes for the node map. */
54 unsigned overall_bytes; /**< Overall number of used bytes for the phase. */
58 * Collect Phase statistics.
60 * @param phase The phase.
61 * @param stat Will be filled with the statistical data.
63 phase_stat_t *phase_stat(const ir_phase *phase, phase_stat_t *stat);
67 * Re-initialize the irn data for the given node.
69 * @param phase The phase.
72 static inline void phase_reinit_single_irn_data(ir_phase *phase, ir_node *irn,
73 phase_irn_reinit *reinit)
77 if (! phase->data_init)
80 idx = get_irn_idx(irn);
81 if (phase->data_ptr[idx])
82 reinit(phase, irn, phase->data_ptr[idx]);
86 * Returns the first node of the phase having some data assigned.
88 * @param phase The phase.
90 * @return The first irn having some data assigned, NULL otherwise
92 ir_node *phase_get_first_node(const ir_phase *phase);
95 * Returns the next node after @p start having some data assigned.
97 * @param phase The phase.
98 * @param start The node to start from
100 * @return The next node after start having some data assigned, NULL otherwise
102 ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start);
105 * Convenience macro to iterate over all nodes of a phase
106 * having some data assigned.
108 * @param phase The phase.
109 * @param irn A local variable that will hold the current node inside the loop.
111 #define foreach_phase_irn(phase, irn) \
112 for (irn = phase_get_first_node(phase); irn; irn = phase_get_next_node(phase, irn))
115 * Get the irg the phase runs on.
117 * @param phase The phase.
119 static inline ir_graph *phase_get_irg(const ir_phase *phase)
125 * Get private data pointer as passed on creating the phase.
127 * @param phase The phase.
129 static inline void *phase_get_private(const ir_phase *phase)
135 * Attach pointer with private data to phase
137 static inline void phase_set_private(ir_phase *phase, void *priv)
142 static inline void *phase_alloc(ir_phase *phase, size_t size)
144 return obstack_alloc(&phase->obst, size);
148 * Get the obstack of a phase.
150 * @param phase The phase.
152 static inline struct obstack *phase_obst(ir_phase *phase)
158 * Get the phase node data for an irn.
160 * @param phase The phase.
161 * @param irn The irn to get data for.
163 * @return A pointer to the node data or NULL if the irn has no phase data allocated yet.
165 static inline void *phase_get_irn_data(const ir_phase *ph, const ir_node *irn)
167 unsigned idx = get_irn_idx(irn);
168 return idx < ph->n_data_ptr ? ph->data_ptr[idx] : NULL;
172 * This is private and just here for performance reasons.
174 static inline void private_phase_enlarge(ir_phase *phase, unsigned max_idx)
176 unsigned last_irg_idx = get_irg_last_idx(phase->irg);
177 size_t old_cap = phase->n_data_ptr;
180 /* make the maximum index at least as big as the largest index in the graph. */
181 max_idx = MAX(max_idx, last_irg_idx);
182 new_cap = (size_t) (max_idx + 256);
184 phase->data_ptr = XREALLOC(phase->data_ptr, void*, new_cap);
186 /* initialize the newly allocated memory. */
187 memset(phase->data_ptr + old_cap, 0, (new_cap - old_cap) * sizeof(phase->data_ptr[0]));
188 phase->n_data_ptr = new_cap;
192 * This is private and only here for performance reasons.
194 static inline void private_phase_assure_capacity(ir_phase *ph, unsigned max_idx)
196 if (max_idx >= ph->n_data_ptr)
197 private_phase_enlarge(ph, max_idx);
202 * Get or set phase data for an irn.
204 * @param phase The phase.
205 * @param irn The irn to get (or set) node data for.
207 * @return A (non-NULL) pointer to phase data for the irn. Either existent one or newly allocated one.
209 static inline void *phase_get_or_set_irn_data(ir_phase *ph, const ir_node *irn)
211 unsigned idx = get_irn_idx(irn);
214 /* Assure that there's a sufficient amount of slots. */
215 private_phase_assure_capacity(ph, idx + 1);
217 res = ph->data_ptr[idx];
219 /* If there has no irn data allocated yet, do that now. */
221 phase_irn_init *data_init = ph->data_init;
223 /* call the node data structure allocator/constructor. */
224 res = ph->data_ptr[idx] = data_init(ph, irn);
230 * Set the node data for an irn.
232 * @param phase The phase.
233 * @param irn The node.
234 * @param data The node data.
236 * @return The old data or NULL if there was none.
238 static inline void *phase_set_irn_data(ir_phase *ph, const ir_node *irn,
241 unsigned idx = get_irn_idx(irn);
244 /* Assure that there's a sufficient amount of slots. */
245 private_phase_assure_capacity(ph, idx + 1);
247 res = ph->data_ptr[idx];
248 ph->data_ptr[idx] = data;
254 * convenience function that returns phase information attached to a node
256 static inline void *get_irn_phase_info(const ir_node *irn, ir_phase_id id)
258 const ir_graph *irg = get_irn_irg(irn);
259 const ir_phase *ph = irg_get_phase(irg, id);
260 return phase_get_irn_data(ph, irn);
264 * Get or set information a phase holds about a node.
265 * If the given phase does not hold information of the node,
266 * the information structure will be created, initialized (see the data_init
267 * function of ir_phase), and returned.
268 * @param irn The node.
269 * @param id The ID of the phase.
271 static inline void *get_or_set_irn_phase_info(const ir_node *irn, ir_phase_id id)
273 const ir_graph *irg = get_irn_irg(irn);
274 ir_phase *ph = irg_get_phase(irg, id);
275 return phase_get_or_set_irn_data(ph, irn);
278 static inline void *set_irn_phase_info(const ir_node *irn, ir_phase_id id,
281 const ir_graph *irg = get_irn_irg(irn);
282 ir_phase *ph = irg_get_phase(irg, id);
283 return phase_set_irn_data(ph, irn, data);