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 size_t 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)
76 if (! phase->data_init)
79 idx = get_irn_idx(irn);
80 if (phase->data_ptr[idx])
81 phase->data_init(phase, irn, phase->data_ptr[idx]);
85 * Returns the first node of the phase having some data assigned.
87 * @param phase The phase.
89 * @return The first irn having some data assigned, NULL otherwise
91 ir_node *phase_get_first_node(const ir_phase *phase);
94 * Returns the next node after @p start having some data assigned.
96 * @param phase The phase.
97 * @param start The node to start from
99 * @return The next node after start having some data assigned, NULL otherwise
101 ir_node *phase_get_next_node(const ir_phase *phase, ir_node *start);
104 * Convenience macro to iterate over all nodes of a phase
105 * having some data assigned.
107 * @param phase The phase.
108 * @param irn A local variable that will hold the current node inside the loop.
110 #define foreach_phase_irn(phase, irn) \
111 for (irn = phase_get_first_node(phase); irn; irn = phase_get_next_node(phase, irn))
114 * Get the irg the phase runs on.
116 * @param phase The phase.
118 static inline ir_graph *phase_get_irg(const ir_phase *phase)
124 * Get private data pointer as passed on creating the phase.
126 * @param phase The phase.
128 static inline void *phase_get_private(const ir_phase *phase)
134 * Attach pointer with private data to phase
136 static inline void phase_set_private(ir_phase *phase, void *priv)
141 static inline void *phase_alloc(ir_phase *phase, size_t size)
143 return obstack_alloc(&phase->obst, size);
147 * Get the obstack of a phase.
149 * @param phase The phase.
151 static inline struct obstack *phase_obst(ir_phase *phase)
157 * Get the phase node data for an irn.
159 * @param phase The phase.
160 * @param irn The irn to get data for.
162 * @return A pointer to the node data or NULL if the irn has no phase data allocated yet.
164 static inline void *phase_get_irn_data(const ir_phase *ph, const ir_node *irn)
166 unsigned idx = get_irn_idx(irn);
167 return idx < ph->n_data_ptr ? ph->data_ptr[idx] : NULL;
171 * This is private and just here for performance reasons.
173 static inline void private_phase_enlarge(ir_phase *phase, unsigned max_idx)
175 unsigned last_irg_idx = get_irg_last_idx(phase->irg);
176 size_t old_cap = phase->n_data_ptr;
179 /* make the maximum index at least as big as the largest index in the graph. */
180 max_idx = MAX(max_idx, last_irg_idx);
181 new_cap = (size_t) (max_idx + 256);
183 phase->data_ptr = XREALLOC(phase->data_ptr, void*, new_cap);
185 /* initialize the newly allocated memory. */
186 memset(phase->data_ptr + old_cap, 0, (new_cap - old_cap) * sizeof(phase->data_ptr[0]));
187 phase->n_data_ptr = new_cap;
191 * This is private and only here for performance reasons.
193 static inline void private_phase_assure_capacity(ir_phase *ph, unsigned max_idx)
195 if (max_idx >= ph->n_data_ptr)
196 private_phase_enlarge(ph, max_idx);
201 * Get or set phase data for an irn.
203 * @param phase The phase.
204 * @param irn The irn to get (or set) node data for.
206 * @return A (non-NULL) pointer to phase data for the irn. Either existent one or newly allocated one.
208 static inline void *phase_get_or_set_irn_data(ir_phase *ph, const ir_node *irn)
210 unsigned idx = get_irn_idx(irn);
213 /* Assure that there's a sufficient amount of slots. */
214 private_phase_assure_capacity(ph, idx + 1);
216 res = ph->data_ptr[idx];
218 /* If there has no irn data allocated yet, do that now. */
220 phase_irn_init *data_init = ph->data_init;
222 /* call the node data structure allocator/constructor. */
223 res = ph->data_ptr[idx] = data_init(ph, irn, NULL);
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;
255 * convenience function that returns phase information attached to a node
257 static inline void *get_irn_phase_info(const ir_node *irn, ir_phase_id id)
259 const ir_graph *irg = get_irn_irg(irn);
260 const ir_phase *ph = irg_get_phase(irg, id);
261 return phase_get_irn_data(ph, irn);
265 * Get or set information a phase holds about a node.
266 * If the given phase does not hold information of the node,
267 * the information structure will be created, initialized (see the data_init 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, void *data)
280 const ir_graph *irg = get_irn_irg(irn);
281 ir_phase *ph = irg_get_phase(irg, id);
282 return phase_set_irn_data(ph, irn, data);