becopyheur2: Cache the admissible registers eagerly.
[libfirm] / ir / ir / iredges_t.h
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief   Everlasting outs -- private header.
9  * @author  Sebastian Hack, Andreas Schoesser
10  * @date    15.01.2005
11  */
12 #ifndef FIRM_IR_EDGES_T_H
13 #define FIRM_IR_EDGES_T_H
14
15 #include "debug.h"
16
17 #include "set.h"
18 #include "list.h"
19
20 #include "irnode_t.h"
21 #include "irgraph_t.h"
22
23 #include "iredgekinds.h"
24 #include "iredges.h"
25
26 #define get_irn_n_edges_kind(irn, kind)   get_irn_n_edges_kind_(irn, kind)
27 #define get_edge_src_irn(edge)            get_edge_src_irn_(edge)
28 #define get_edge_src_pos(edge)            get_edge_src_pos_(edge)
29 #define get_irn_out_edge_next(irn, last, kind)  get_irn_out_edge_next_(irn, last, kind)
30 #define get_irn_n_edges(irn)              get_irn_n_edges_kind_(irn, EDGE_KIND_NORMAL)
31 #define get_irn_out_edge_first(irn)       get_irn_out_edge_first_kind_(irn, EDGE_KIND_NORMAL)
32 #define get_block_succ_first(irn)         get_irn_out_edge_first_kind_(irn, EDGE_KIND_BLOCK)
33 #define get_block_succ_next(irn, last)    get_irn_out_edge_next_(irn, last, EDGE_KIND_BLOCK)
34
35 /**
36  * An edge.
37  */
38 struct ir_edge_t {
39         ir_node  *src;          /**< The source node of the edge. */
40         int      pos;           /**< The position of the edge at @p src. */
41 #ifdef DEBUG_libfirm
42         unsigned present : 1;   /**< Used by the verifier. Don't rely on its content. */
43 #endif
44         struct list_head list;  /**< The list head to queue all out edges at a node. */
45 };
46
47 /** Accessor for private irn info. */
48 static inline irn_edge_info_t *get_irn_edge_info(ir_node *node,
49                                                  ir_edge_kind_t kind)
50 {
51         return &node->edge_info[kind];
52 }
53
54 static inline const irn_edge_info_t *get_irn_edge_info_const(
55                 const ir_node *node, ir_edge_kind_t kind)
56 {
57         return &node->edge_info[kind];
58 }
59
60 /** Accessor for private irg info. */
61 static inline irg_edge_info_t *get_irg_edge_info(ir_graph *irg,
62                                                  ir_edge_kind_t kind)
63 {
64         return &irg->edge_info[kind];
65 }
66
67 /** Accessor for private irg info. */
68 static inline const irg_edge_info_t *get_irg_edge_info_const(
69                 const ir_graph *irg, ir_edge_kind_t kind)
70 {
71         return &irg->edge_info[kind];
72 }
73
74 /**
75  * Get the first edge pointing to some node.
76  * @note There is no order on out edges. First in this context only
77  * means, that you get some starting point into the list of edges.
78  * @param irn The node.
79  * @return The first out edge that points to this node.
80  */
81 static inline const ir_edge_t *get_irn_out_edge_first_kind_(const ir_node *irn, ir_edge_kind_t kind)
82 {
83         const struct list_head *head;
84         assert(edges_activated_kind(get_irn_irg(irn), kind));
85         head = &get_irn_edge_info_const(irn, kind)->outs_head;
86         return list_empty(head) ? NULL : list_entry(head->next, ir_edge_t, list);
87 }
88
89 /**
90  * Get the next edge in the out list of some node.
91  * @param irn The node.
92  * @param last The last out edge you have seen.
93  * @return The next out edge in @p irn 's out list after @p last.
94  */
95 static inline const ir_edge_t *get_irn_out_edge_next_(const ir_node *irn, const ir_edge_t *last, ir_edge_kind_t kind)
96 {
97         struct list_head *next = last->list.next;
98         const struct list_head *head
99                 = &get_irn_edge_info_const(irn, kind)->outs_head;
100         return next == head ? NULL : list_entry(next, ir_edge_t, list);
101 }
102
103 /**
104  * Get the number of edges pointing to a node.
105  * @param irn The node.
106  * @return The number of edges pointing to this node.
107  */
108 static inline int get_irn_n_edges_kind_(const ir_node *irn, ir_edge_kind_t kind)
109 {
110         return get_irn_edge_info_const(irn, kind)->out_count;
111 }
112
113 static inline int edges_activated_kind_(const ir_graph *irg, ir_edge_kind_t kind)
114 {
115         return get_irg_edge_info_const(irg, kind)->activated;
116 }
117
118 static inline int edges_activated_(const ir_graph *irg)
119 {
120         return edges_activated_kind(irg, EDGE_KIND_NORMAL)
121             && edges_activated_kind(irg, EDGE_KIND_BLOCK);
122 }
123
124 /**
125  * Assure, that the edges information is present for a certain graph.
126  * @param irg The graph.
127  */
128 static inline void edges_assure_kind_(ir_graph *irg, ir_edge_kind_t kind)
129 {
130         if(!edges_activated_kind_(irg, kind))
131                 edges_activate_kind(irg, kind);
132 }
133
134 void edges_init_graph_kind(ir_graph *irg, ir_edge_kind_t kind);
135
136 void edges_node_deleted(ir_node *irn);
137
138 /**
139  * A node might be revivaled by CSE.
140  */
141 void edges_node_revival(ir_node *node);
142
143 void edges_invalidate_kind(ir_node *irn, ir_edge_kind_t kind);
144
145 static inline ir_node *get_edge_src_irn_(const ir_edge_t *edge)
146 {
147         return edge->src;
148 }
149
150 static inline int get_edge_src_pos_(const ir_edge_t *edge)
151 {
152         return edge->pos;
153 }
154
155 /**
156  * Initialize the out edges.
157  * This must be called before firm is initialized.
158  */
159 extern void init_edges(void);
160
161 void edges_invalidate_all(ir_node *irn);
162
163 /**
164  * Helper function to dump the edge set of a graph,
165  * unused in normal code.
166  */
167 void edges_dump_kind(ir_graph *irg, ir_edge_kind_t kind);
168
169 void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt,
170                        ir_graph *irg);
171
172 #endif