/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/External/isl/isl_id.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2008-2009 Katholieke Universiteit Leuven |
3 | | * |
4 | | * Use of this software is governed by the MIT license |
5 | | * |
6 | | * Written by Sven Verdoolaege, K.U.Leuven, Departement |
7 | | * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium |
8 | | */ |
9 | | |
10 | | #include <string.h> |
11 | | #include <isl_ctx_private.h> |
12 | | #include <isl_id_private.h> |
13 | | |
14 | | #undef BASE |
15 | | #define BASE id |
16 | | |
17 | | #include <isl_list_templ.c> |
18 | | |
19 | | /* A special, static isl_id to use as domains (and ranges) |
20 | | * of sets and parameters domains. |
21 | | * The user should never get a hold on this isl_id. |
22 | | */ |
23 | | isl_id isl_id_none = { |
24 | | .ref = -1, |
25 | | .ctx = NULL, |
26 | | .name = "#none", |
27 | | .user = NULL |
28 | | }; |
29 | | |
30 | | isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id) |
31 | 24.5k | { |
32 | 24.5k | return id ? id->ctx : NULL; |
33 | 24.5k | } |
34 | | |
35 | | void *isl_id_get_user(__isl_keep isl_id *id) |
36 | 33.3k | { |
37 | 33.3k | return id ? id->user33.3k : NULL; |
38 | 33.3k | } |
39 | | |
40 | | const char *isl_id_get_name(__isl_keep isl_id *id) |
41 | 15.1k | { |
42 | 15.1k | return id ? id->name : NULL; |
43 | 15.1k | } |
44 | | |
45 | | static __isl_give isl_id *id_alloc(isl_ctx *ctx, const char *name, void *user) |
46 | 75.5k | { |
47 | 75.5k | const char *copy = name ? strdup(name)75.5k : NULL; |
48 | 75.5k | isl_id *id; |
49 | 75.5k | |
50 | 75.5k | if (name && !copy75.5k ) |
51 | 0 | return NULL; |
52 | 75.5k | id = isl_calloc_type(ctx, struct isl_id); |
53 | 75.5k | if (!id) |
54 | 0 | goto error; |
55 | 75.5k | |
56 | 75.5k | id->ctx = ctx; |
57 | 75.5k | isl_ctx_ref(id->ctx); |
58 | 75.5k | id->ref = 1; |
59 | 75.5k | id->name = copy; |
60 | 75.5k | id->user = user; |
61 | 75.5k | |
62 | 75.5k | id->hash = isl_hash_init(); |
63 | 75.5k | if (name) |
64 | 75.5k | id->hash = isl_hash_string(id->hash, name); |
65 | 7 | else |
66 | 7 | id->hash = isl_hash_builtin(id->hash, user); |
67 | 75.5k | |
68 | 75.5k | return id; |
69 | 0 | error: |
70 | 0 | free((char *)copy); |
71 | 0 | return NULL; |
72 | 75.5k | } |
73 | | |
74 | | uint32_t isl_id_get_hash(__isl_keep isl_id *id) |
75 | 1.08k | { |
76 | 1.08k | return id ? id->hash : 00 ; |
77 | 1.08k | } |
78 | | |
79 | | struct isl_name_and_user { |
80 | | const char *name; |
81 | | void *user; |
82 | | }; |
83 | | |
84 | | static int isl_id_has_name_and_user(const void *entry, const void *val) |
85 | 260k | { |
86 | 260k | isl_id *id = (isl_id *)entry; |
87 | 260k | struct isl_name_and_user *nu = (struct isl_name_and_user *) val; |
88 | 260k | |
89 | 260k | if (id->user != nu->user) |
90 | 251k | return 0; |
91 | 8.97k | if (id->name == nu->name) |
92 | 8 | return 1; |
93 | 8.96k | if (!id->name || !nu->name) |
94 | 0 | return 0; |
95 | 8.96k | |
96 | 8.96k | return !strcmp(id->name, nu->name); |
97 | 8.96k | } |
98 | | |
99 | | __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, const char *name, void *user) |
100 | 84.5k | { |
101 | 84.5k | struct isl_hash_table_entry *entry; |
102 | 84.5k | uint32_t id_hash; |
103 | 84.5k | struct isl_name_and_user nu = { name, user }; |
104 | 84.5k | |
105 | 84.5k | if (!ctx) |
106 | 0 | return NULL; |
107 | 84.5k | |
108 | 84.5k | id_hash = isl_hash_init(); |
109 | 84.5k | if (name) |
110 | 84.5k | id_hash = isl_hash_string(id_hash, name); |
111 | 15 | else |
112 | 15 | id_hash = isl_hash_builtin(id_hash, user); |
113 | 84.5k | entry = isl_hash_table_find(ctx, &ctx->id_table, id_hash, |
114 | 84.5k | isl_id_has_name_and_user, &nu, 1); |
115 | 84.5k | if (!entry) |
116 | 0 | return NULL; |
117 | 84.5k | if (entry->data) |
118 | 8.97k | return isl_id_copy(entry->data); |
119 | 75.5k | entry->data = id_alloc(ctx, name, user); |
120 | 75.5k | if (!entry->data) |
121 | 0 | ctx->id_table.n--; |
122 | 75.5k | return entry->data; |
123 | 75.5k | } |
124 | | |
125 | | /* If the id has a negative refcount, then it is a static isl_id |
126 | | * which should not be changed. |
127 | | */ |
128 | | __isl_give isl_id *isl_id_copy(isl_id *id) |
129 | 10.0M | { |
130 | 10.0M | if (!id) |
131 | 15.5k | return NULL; |
132 | 10.0M | |
133 | 10.0M | if (id->ref < 0) |
134 | 2.42M | return id; |
135 | 7.62M | |
136 | 7.62M | id->ref++; |
137 | 7.62M | return id; |
138 | 7.62M | } |
139 | | |
140 | | /* Compare two isl_ids. |
141 | | * |
142 | | * The order is fairly arbitrary. We do keep the comparison of |
143 | | * the user pointers as a last resort since these pointer values |
144 | | * may not be stable across different systems or even different runs. |
145 | | */ |
146 | | int isl_id_cmp(__isl_keep isl_id *id1, __isl_keep isl_id *id2) |
147 | 5.93M | { |
148 | 5.93M | if (id1 == id2) |
149 | 5.93M | return 0; |
150 | 0 | if (!id1) |
151 | 0 | return -1; |
152 | 0 | if (!id2) |
153 | 0 | return 1; |
154 | 0 | if (!id1->name != !id2->name) |
155 | 0 | return !id1->name - !id2->name; |
156 | 0 | if (id1->name) { |
157 | 0 | int cmp = strcmp(id1->name, id2->name); |
158 | 0 | if (cmp != 0) |
159 | 0 | return cmp; |
160 | 0 | } |
161 | 0 | if (id1->user < id2->user) |
162 | 0 | return -1; |
163 | 0 | else |
164 | 0 | return 1; |
165 | 0 | } |
166 | | |
167 | | static int isl_id_eq(const void *entry, const void *name) |
168 | 105k | { |
169 | 105k | return entry == name; |
170 | 105k | } |
171 | | |
172 | | uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id) |
173 | 2.44M | { |
174 | 2.44M | if (id) |
175 | 2.44M | isl_hash_hash1.78M (hash, id->hash); |
176 | 2.44M | |
177 | 2.44M | return hash; |
178 | 2.44M | } |
179 | | |
180 | | /* Replace the free_user callback by "free_user". |
181 | | */ |
182 | | __isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id, |
183 | | void (*free_user)(void *user)) |
184 | 2.49k | { |
185 | 2.49k | if (!id) |
186 | 0 | return NULL; |
187 | 2.49k | |
188 | 2.49k | id->free_user = free_user; |
189 | 2.49k | |
190 | 2.49k | return id; |
191 | 2.49k | } |
192 | | |
193 | | /* If the id has a negative refcount, then it is a static isl_id |
194 | | * and should not be freed. |
195 | | */ |
196 | | __isl_null isl_id *isl_id_free(__isl_take isl_id *id) |
197 | 31.9M | { |
198 | 31.9M | struct isl_hash_table_entry *entry; |
199 | 31.9M | |
200 | 31.9M | if (!id) |
201 | 19.0M | return NULL; |
202 | 12.8M | |
203 | 12.8M | if (id->ref < 0) |
204 | 5.14M | return NULL; |
205 | 7.70M | |
206 | 7.70M | if (--id->ref > 0) |
207 | 7.62M | return NULL; |
208 | 75.3k | |
209 | 75.3k | entry = isl_hash_table_find(id->ctx, &id->ctx->id_table, id->hash, |
210 | 75.3k | isl_id_eq, id, 0); |
211 | 75.3k | if (!entry) |
212 | 75.3k | isl_die0 (id->ctx, isl_error_unknown, |
213 | 75.3k | "unable to find id", (void)0); |
214 | 75.3k | else |
215 | 75.3k | isl_hash_table_remove(id->ctx, &id->ctx->id_table, entry); |
216 | 75.3k | |
217 | 75.3k | if (id->free_user) |
218 | 2.49k | id->free_user(id->user); |
219 | 75.3k | |
220 | 75.3k | free((char *)id->name); |
221 | 75.3k | isl_ctx_deref(id->ctx); |
222 | 75.3k | free(id); |
223 | 75.3k | |
224 | 75.3k | return NULL; |
225 | 75.3k | } |
226 | | |
227 | | __isl_give isl_printer *isl_printer_print_id(__isl_take isl_printer *p, |
228 | | __isl_keep isl_id *id) |
229 | 0 | { |
230 | 0 | if (!id) |
231 | 0 | goto error; |
232 | 0 | |
233 | 0 | if (id->name) |
234 | 0 | p = isl_printer_print_str(p, id->name); |
235 | 0 | if (id->user) { |
236 | 0 | char buffer[50]; |
237 | 0 | snprintf(buffer, sizeof(buffer), "@%p", id->user); |
238 | 0 | p = isl_printer_print_str(p, buffer); |
239 | 0 | } |
240 | 0 | return p; |
241 | 0 | error: |
242 | 0 | isl_printer_free(p); |
243 | 0 | return NULL; |
244 | 0 | } |