2 * Copyright (C) 1995-2011 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 Everlasting outs -- private header.
23 * @author Sebastian Hack, Andreas Schoesser
26 #ifndef FIRM_IR_EDGES_T_H
27 #define FIRM_IR_EDGES_T_H
35 #include "irgraph_t.h"
37 #include "iredgekinds.h"
40 #define get_irn_n_edges_kind(irn, kind) get_irn_n_edges_kind_(irn, kind)
41 #define get_edge_src_irn(edge) get_edge_src_irn_(edge)
42 #define get_edge_src_pos(edge) get_edge_src_pos_(edge)
43 #define get_irn_out_edge_next(irn, last) get_irn_out_edge_next_(irn, last)
44 #define get_irn_n_edges(irn) get_irn_n_edges_kind_(irn, EDGE_KIND_NORMAL)
45 #define get_irn_out_edge_first(irn) get_irn_out_edge_first_kind_(irn, EDGE_KIND_NORMAL)
46 #define get_block_succ_first(irn) get_irn_out_edge_first_kind_(irn, EDGE_KIND_BLOCK)
47 #define get_block_succ_next(irn, last) get_irn_out_edge_next_(irn, last)
53 ir_node *src; /**< The source node of the edge. */
54 int pos; /**< The position of the edge at @p src. */
55 unsigned invalid : 1; /**< edges that are removed are marked invalid. */
56 unsigned present : 1; /**< Used by the verifier. Don't rely on its content. */
57 unsigned kind : 4; /**< The kind of the edge. */
58 struct list_head list; /**< The list head to queue all out edges at a node. */
61 /** Accessor for private irn info. */
62 static inline irn_edge_info_t *get_irn_edge_info(ir_node *node,
65 return &node->edge_info[kind];
68 static inline const irn_edge_info_t *get_irn_edge_info_const(
69 const ir_node *node, ir_edge_kind_t kind)
71 return &node->edge_info[kind];
74 /** Accessor for private irg info. */
75 static inline irg_edge_info_t *get_irg_edge_info(ir_graph *irg,
78 return &irg->edge_info[kind];
81 /** Accessor for private irg info. */
82 static inline const irg_edge_info_t *get_irg_edge_info_const(
83 const ir_graph *irg, ir_edge_kind_t kind)
85 return &irg->edge_info[kind];
89 * Get the first edge pointing to some node.
90 * @note There is no order on out edges. First in this context only
91 * means, that you get some starting point into the list of edges.
92 * @param irn The node.
93 * @return The first out edge that points to this node.
95 static inline const ir_edge_t *get_irn_out_edge_first_kind_(const ir_node *irn, ir_edge_kind_t kind)
97 const struct list_head *head;
98 assert(edges_activated_kind(get_irn_irg(irn), kind));
99 head = &get_irn_edge_info_const(irn, kind)->outs_head;
100 return list_empty(head) ? NULL : list_entry(head->next, ir_edge_t, list);
104 * Get the next edge in the out list of some node.
105 * @param irn The node.
106 * @param last The last out edge you have seen.
107 * @return The next out edge in @p irn 's out list after @p last.
109 static inline const ir_edge_t *get_irn_out_edge_next_(const ir_node *irn, const ir_edge_t *last)
111 struct list_head *next = last->list.next;
112 const struct list_head *head
113 = &get_irn_edge_info_const(irn, (ir_edge_kind_t)last->kind)->outs_head;
114 return next == head ? NULL : list_entry(next, ir_edge_t, list);
118 * Get the number of edges pointing to a node.
119 * @param irn The node.
120 * @return The number of edges pointing to this node.
122 static inline int get_irn_n_edges_kind_(const ir_node *irn, ir_edge_kind_t kind)
124 return get_irn_edge_info_const(irn, kind)->out_count;
127 static inline int edges_activated_kind_(const ir_graph *irg, ir_edge_kind_t kind)
129 return get_irg_edge_info_const(irg, kind)->activated;
132 static inline int edges_activated_(const ir_graph *irg)
134 return edges_activated_kind(irg, EDGE_KIND_NORMAL)
135 && edges_activated_kind(irg, EDGE_KIND_BLOCK);
139 * Assure, that the edges information is present for a certain graph.
140 * @param irg The graph.
142 static inline void edges_assure_kind_(ir_graph *irg, ir_edge_kind_t kind)
144 if(!edges_activated_kind_(irg, kind))
145 edges_activate_kind(irg, kind);
148 void edges_init_graph_kind(ir_graph *irg, ir_edge_kind_t kind);
150 void edges_node_deleted(ir_node *irn);
153 * A node might be revivaled by CSE.
155 void edges_node_revival(ir_node *node);
157 void edges_invalidate_kind(ir_node *irn, ir_edge_kind_t kind);
159 static inline ir_node *get_edge_src_irn_(const ir_edge_t *edge)
164 static inline int get_edge_src_pos_(const ir_edge_t *edge)
170 * Returns the edge object of an outgoing edge at a node.
171 * @param irn The node at which the edge originates.
172 * @param pos The position of the edge.
173 * @param kind The kind of the edge.
174 * @return The corresponding edge object or NULL,
175 * if no such edge exists.
177 FIRM_API const ir_edge_t *get_irn_edge_kind(const ir_node *irn,
178 int pos, ir_edge_kind_t kind);
181 * Initialize the out edges.
182 * This must be called before firm is initialized.
184 extern void init_edges(void);
186 void edges_invalidate_all(ir_node *irn);
189 * Helper function to dump the edge set of a graph,
190 * unused in normal code.
192 void edges_dump_kind(ir_graph *irg, ir_edge_kind_t kind);
195 * Notify normal and block edges.
197 void edges_notify_edge(ir_node *src, int pos, ir_node *tgt,
198 ir_node *old_tgt, ir_graph *irg);