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