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 * @author Michael Beck
23 * @brief A value set, containing expression for values.
33 static ir_valueset_entry_t null_valueset_entry;
36 #define HashSet ir_valueset_t
37 #define HashSetIterator ir_valueset_iterator_t
38 #define ValueType ir_valueset_entry_t
39 #define NullValue null_valueset_entry
40 #define KeyType ir_node*
41 #define ConstKeyType const ir_node*
42 #define GetKey(entry) (entry).value
43 #define InitData(self,entry,key) do { (entry).value = (key); (entry).list.next = NULL; (entry).list.prev = NULL; } while(0)
44 #define Hash(self,key) ir_node_hash(key)
45 #define KeysEqual(self,key1,key2) (key1) == (key2)
46 #define SetRangeEmpty(ptr,size) memset(ptr, 0, (size) * sizeof((ptr)[0]))
47 #define EntrySetEmpty(entry) (entry).value = NULL
48 #define EntrySetDeleted(entry) do { (entry).data.value = (ir_node*) -1; list_del(&(entry).data.list); } while(0)
49 #define EntryIsEmpty(entry) ((entry).data.value == NULL)
50 #define EntryIsDeleted(entry) ((entry).data.value == (ir_node*)-1)
52 #define hashset_init ir_valueset_init
53 #define hashset_init_size ir_valueset_init_size
54 #define hashset_destroy ir_valueset_destroy
55 #define hashset_insert _ir_valueset_insert
56 #define hashset_remove ir_valueset_remove
57 #define hashset_find _ir_valueset_find
58 #define hashset_size ir_valueset_size
60 #define ADDITIONAL_INIT INIT_LIST_HEAD(&self->elem_list); INIT_LIST_HEAD(&self->all_iters);
61 #define ADDITIONAL_TERM INIT_LIST_HEAD(&self->elem_list); INIT_LIST_HEAD(&self->all_iters);
64 #define HAVE_OWN_RESIZE
73 void resize(HashSet *self, size_t new_size)
75 HashSetEntry *old_entries = self->entries;
76 HashSetEntry *new_entries;
77 list_head list = self->elem_list;
81 /* allocate a new array with double size */
82 new_entries = Alloc(new_size);
83 SetRangeEmpty(new_entries, new_size);
85 /* use the new array */
86 self->entries = new_entries;
87 self->num_buckets = new_size;
88 self->num_elements = 0;
89 self->num_deleted = 0;
91 self->entries_version++;
93 reset_thresholds(self);
95 assert(!list_empty(&self->elem_list));
96 list.next->prev = &list;
97 list.prev->next = &list;
99 /* reinsert all elements */
100 INIT_LIST_HEAD(&self->elem_list);
101 list_for_each_entry(ValueType, entry, &list, list) {
102 res &= ir_valueset_insert(self, entry->value, entry->expr);
104 /* all re-inserted data must be new, if not, we found a node twice ... */
107 /* now we can free the old array */
111 int ir_valueset_insert(ir_valueset_t *valueset, ir_node *value, ir_node *expr)
113 ir_valueset_entry_t *entry = _ir_valueset_insert(valueset, value);
115 if (entry->list.next != NULL) {
116 /* this value is already inserted, do nothing */
120 /* new element added */
122 list_add_tail(&entry->list, &valueset->elem_list);
126 int ir_valueset_replace(ir_valueset_t *valueset, ir_node *value, ir_node *expr)
129 ir_valueset_entry_t *entry = _ir_valueset_insert(valueset, value);
131 if (entry->expr != expr) {
135 if (entry->list.next == NULL) {
136 /* we have added a new element */
137 list_add_tail(&entry->list, &valueset->elem_list);
143 void *ir_valueset_lookup(const ir_valueset_t *valueset, const ir_node *value)
145 ir_valueset_entry_t *entry = _ir_valueset_find(valueset, value);
151 void ir_valueset_iterator_init(ir_valueset_iterator_t *iterator,
152 const ir_valueset_t *valueset) {
153 iterator->iter = valueset->elem_list.next;
154 iterator->valueset = valueset;
157 ir_node *ir_valueset_iterator_next(ir_valueset_iterator_t *iterator, ir_node **expr) {
158 ir_valueset_entry_t *entry;
160 if (iterator->iter == &iterator->valueset->elem_list) {
165 entry = list_entry(iterator->iter, ir_valueset_entry_t, list);
166 iterator->iter = iterator->iter->next;
172 void ir_valueset_remove_iterator(ir_valueset_t *valueset, ir_valueset_iterator_t *iterator) {
173 ir_valueset_entry_t *rem = list_entry(iterator->iter->prev, ir_valueset_entry_t, list);
175 ir_valueset_remove(valueset, rem->value);