iropt: Remove repeated get_irn_irg().
[libfirm] / ir / ir / irnodemap.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   A nodemap. This variant is a thin wrapper around an ARR_F which
23  *          uses node-indices for access. It is preferable over ir_nodehashmap
24  *          if the info is dense (i.e. something is mapped for most nodes in
25  *          the graph)
26  * @author  Matthias Braun
27  */
28 #ifndef FIRM_IRNODEMAP_H
29 #define FIRM_IRNODEMAP_H
30
31 #include "firm_types.h"
32 #include "irgraph_t.h"
33 #include "array.h"
34
35 typedef struct ir_nodemap ir_nodemap;
36
37 /**
38  * Allocate and initialize a new nodemap object
39  *
40  * @param irg           The graph the nodemap will run on.
41  * @return              A new nodemap object.
42  */
43 static inline void ir_nodemap_init(ir_nodemap *nodemap, const ir_graph *irg)
44 {
45         unsigned max_idx = get_irg_last_idx(irg) + 32;
46         nodemap->data = NEW_ARR_FZ(void*, max_idx);
47 }
48
49 /**
50  * frees all internal memory used by the nodemap but does not free the
51  * nodemap struct itself.
52  */
53 static inline void ir_nodemap_destroy(ir_nodemap *nodemap)
54 {
55         DEL_ARR_F(nodemap->data);
56         nodemap->data = NULL;
57 }
58
59 /**
60  * Insert a mapping from @p node to @p data.
61  */
62 static inline void ir_nodemap_insert(ir_nodemap *nodemap, const ir_node *node,
63                                      void *data)
64 {
65         unsigned idx = get_irn_idx(node);
66         size_t   len = ARR_LEN(nodemap->data);
67         if (idx >= len) {
68                 ARR_RESIZE(void*, nodemap->data, idx+1);
69                 memset(nodemap->data + len, 0, (idx-len) * sizeof(nodemap->data[0]));
70         }
71         nodemap->data[idx] = data;
72 }
73
74 /**
75  * Insert a mapping from @p node to @p data (fast version).
76  *
77  * @attention You must only use this version if you can be sure that the nodemap
78  * already has enough space to store the mapping. This is the case if @p node
79  * already existed at nodemap_init() time or ir_nodemap_insert() has been used
80  * for this node)
81  */
82 static inline void ir_nodemap_insert_fast(ir_nodemap *nodemap,
83                                           const ir_node *node, void *data)
84 {
85         unsigned idx = get_irn_idx(node);
86         nodemap->data[idx] = data;
87 }
88
89 /**
90  * Removed mapping for @p node.
91  *
92  * This is really a shorthand form for ir_nodemap_insert(nodemap, node, NULL);
93  */
94 static inline void ir_nodemap_remove(ir_nodemap *nodemap, const ir_node *node)
95 {
96         ir_nodemap_insert(nodemap, node, NULL);
97 }
98
99 /**
100  * Get mapping for @p node. Returns NULL if nothing is mapped.
101  */
102 static inline void *ir_nodemap_get(const ir_nodemap *nodemap,
103                                    const ir_node *node)
104 {
105         unsigned idx = get_irn_idx(node);
106         if (idx >= ARR_LEN(nodemap->data))
107                 return NULL;
108         return nodemap->data[idx];
109 }
110
111 #define ir_nodemap_get(type, nodemap, node) ((type*)ir_nodemap_get(nodemap, node))
112
113 /**
114  * Get mapping for @p node (fast version). Returns NULL if nothing is mapped.
115  *
116  * @attention You must only use this function if you can be sure that the
117  * nodemap has enough space to potentially contain the mapping. This is the
118  * case if @p node already existed at nodemap_init() time or ir_nodemap_insert()
119  * has been used for this node)
120  */
121 static inline void *ir_nodemap_get_fast(const ir_nodemap *nodemap,
122                                         const ir_node *node)
123 {
124         unsigned idx = get_irn_idx(node);
125         return nodemap->data[idx];
126 }
127
128 #endif