isl_id.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. #include <string.h>
  10. #include <isl_ctx_private.h>
  11. #include <isl_id_private.h>
  12. #undef EL_BASE
  13. #define EL_BASE id
  14. #include <isl_list_templ.c>
  15. #include <isl_list_read_templ.c>
  16. /* A special, static isl_id to use as domains (and ranges)
  17. * of sets and parameters domains.
  18. * The user should never get a hold on this isl_id.
  19. */
  20. isl_id isl_id_none = {
  21. .ref = -1,
  22. .ctx = NULL,
  23. .name = "#none",
  24. .user = NULL
  25. };
  26. isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id)
  27. {
  28. return id ? id->ctx : NULL;
  29. }
  30. void *isl_id_get_user(__isl_keep isl_id *id)
  31. {
  32. return id ? id->user : NULL;
  33. }
  34. const char *isl_id_get_name(__isl_keep isl_id *id)
  35. {
  36. return id ? id->name : NULL;
  37. }
  38. static __isl_give isl_id *id_alloc(isl_ctx *ctx, const char *name, void *user)
  39. {
  40. const char *copy = name ? strdup(name) : NULL;
  41. isl_id *id;
  42. if (name && !copy)
  43. return NULL;
  44. id = isl_calloc_type(ctx, struct isl_id);
  45. if (!id)
  46. goto error;
  47. id->ctx = ctx;
  48. isl_ctx_ref(id->ctx);
  49. id->ref = 1;
  50. id->name = copy;
  51. id->user = user;
  52. id->hash = isl_hash_init();
  53. if (name)
  54. id->hash = isl_hash_string(id->hash, name);
  55. else
  56. id->hash = isl_hash_builtin(id->hash, user);
  57. return id;
  58. error:
  59. free((char *)copy);
  60. return NULL;
  61. }
  62. uint32_t isl_id_get_hash(__isl_keep isl_id *id)
  63. {
  64. return id ? id->hash : 0;
  65. }
  66. struct isl_name_and_user {
  67. const char *name;
  68. void *user;
  69. };
  70. static isl_bool isl_id_has_name_and_user(const void *entry, const void *val)
  71. {
  72. isl_id *id = (isl_id *)entry;
  73. struct isl_name_and_user *nu = (struct isl_name_and_user *) val;
  74. if (id->user != nu->user)
  75. return isl_bool_false;
  76. if (id->name == nu->name)
  77. return isl_bool_true;
  78. if (!id->name || !nu->name)
  79. return isl_bool_false;
  80. return isl_bool_ok(!strcmp(id->name, nu->name));
  81. }
  82. __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, const char *name, void *user)
  83. {
  84. struct isl_hash_table_entry *entry;
  85. uint32_t id_hash;
  86. struct isl_name_and_user nu = { name, user };
  87. if (!ctx)
  88. return NULL;
  89. id_hash = isl_hash_init();
  90. if (name)
  91. id_hash = isl_hash_string(id_hash, name);
  92. else
  93. id_hash = isl_hash_builtin(id_hash, user);
  94. entry = isl_hash_table_find(ctx, &ctx->id_table, id_hash,
  95. isl_id_has_name_and_user, &nu, 1);
  96. if (!entry)
  97. return NULL;
  98. if (entry->data)
  99. return isl_id_copy(entry->data);
  100. entry->data = id_alloc(ctx, name, user);
  101. if (!entry->data)
  102. ctx->id_table.n--;
  103. return entry->data;
  104. }
  105. /* If the id has a negative refcount, then it is a static isl_id
  106. * which should not be changed.
  107. */
  108. __isl_give isl_id *isl_id_copy(isl_id *id)
  109. {
  110. if (!id)
  111. return NULL;
  112. if (id->ref < 0)
  113. return id;
  114. id->ref++;
  115. return id;
  116. }
  117. /* Compare two isl_ids.
  118. *
  119. * The order is fairly arbitrary. We do keep the comparison of
  120. * the user pointers as a last resort since these pointer values
  121. * may not be stable across different systems or even different runs.
  122. */
  123. int isl_id_cmp(__isl_keep isl_id *id1, __isl_keep isl_id *id2)
  124. {
  125. if (id1 == id2)
  126. return 0;
  127. if (!id1)
  128. return -1;
  129. if (!id2)
  130. return 1;
  131. if (!id1->name != !id2->name)
  132. return !id1->name - !id2->name;
  133. if (id1->name) {
  134. int cmp = strcmp(id1->name, id2->name);
  135. if (cmp != 0)
  136. return cmp;
  137. }
  138. if (id1->user < id2->user)
  139. return -1;
  140. else
  141. return 1;
  142. }
  143. static isl_bool isl_id_eq(const void *entry, const void *name)
  144. {
  145. return isl_bool_ok(entry == name);
  146. }
  147. uint32_t isl_hash_id(uint32_t hash, __isl_keep isl_id *id)
  148. {
  149. if (id)
  150. isl_hash_hash(hash, id->hash);
  151. return hash;
  152. }
  153. /* Replace the free_user callback by "free_user".
  154. */
  155. __isl_give isl_id *isl_id_set_free_user(__isl_take isl_id *id,
  156. void (*free_user)(void *user))
  157. {
  158. if (!id)
  159. return NULL;
  160. id->free_user = free_user;
  161. return id;
  162. }
  163. /* If the id has a negative refcount, then it is a static isl_id
  164. * and should not be freed.
  165. */
  166. __isl_null isl_id *isl_id_free(__isl_take isl_id *id)
  167. {
  168. struct isl_hash_table_entry *entry;
  169. if (!id)
  170. return NULL;
  171. if (id->ref < 0)
  172. return NULL;
  173. if (--id->ref > 0)
  174. return NULL;
  175. entry = isl_hash_table_find(id->ctx, &id->ctx->id_table, id->hash,
  176. isl_id_eq, id, 0);
  177. if (!entry)
  178. return NULL;
  179. if (entry == isl_hash_table_entry_none)
  180. isl_die(id->ctx, isl_error_unknown,
  181. "unable to find id", (void)0);
  182. else
  183. isl_hash_table_remove(id->ctx, &id->ctx->id_table, entry);
  184. if (id->free_user)
  185. id->free_user(id->user);
  186. free((char *)id->name);
  187. isl_ctx_deref(id->ctx);
  188. free(id);
  189. return NULL;
  190. }
  191. __isl_give isl_printer *isl_printer_print_id(__isl_take isl_printer *p,
  192. __isl_keep isl_id *id)
  193. {
  194. if (!id)
  195. goto error;
  196. if (id->name)
  197. p = isl_printer_print_str(p, id->name);
  198. if (id->user) {
  199. char buffer[50];
  200. snprintf(buffer, sizeof(buffer), "@%p", id->user);
  201. p = isl_printer_print_str(p, buffer);
  202. }
  203. return p;
  204. error:
  205. isl_printer_free(p);
  206. return NULL;
  207. }
  208. /* Read an isl_id from "s" based on its name.
  209. */
  210. __isl_give isl_id *isl_stream_read_id(__isl_keep isl_stream *s)
  211. {
  212. struct isl_token *tok;
  213. char *str;
  214. isl_ctx *ctx;
  215. isl_id *id;
  216. if (!s)
  217. return NULL;
  218. tok = isl_stream_next_token(s);
  219. if (!tok) {
  220. isl_stream_error(s, NULL, "unexpected EOF");
  221. return NULL;
  222. }
  223. ctx = isl_stream_get_ctx(s);
  224. str = isl_token_get_str(ctx, tok);
  225. isl_token_free(tok);
  226. if (!str)
  227. return NULL;
  228. id = isl_id_alloc(ctx, str, NULL);
  229. free(str);
  230. return id;
  231. }
  232. /* Read an isl_id object from the string "str".
  233. */
  234. __isl_give isl_id *isl_id_read_from_str(isl_ctx *ctx, const char *str)
  235. {
  236. isl_id *id;
  237. isl_stream *s = isl_stream_new_str(ctx, str);
  238. if (!s)
  239. return NULL;
  240. id = isl_stream_read_id(s);
  241. isl_stream_free(s);
  242. return id;
  243. }
  244. /* Is "id1" (obviously) equal to "id2"?
  245. *
  246. * isl_id objects can be compared by pointer value, but
  247. * isl_multi_*_plain_is_equal needs an isl_*_plain_is_equal.
  248. */
  249. static isl_bool isl_id_plain_is_equal(__isl_keep isl_id *id1,
  250. __isl_keep isl_id *id2)
  251. {
  252. if (!id1 || !id2)
  253. return isl_bool_error;
  254. return id1 == id2;
  255. }
  256. #undef BASE
  257. #define BASE id
  258. #include <isl_multi_no_domain_templ.c>
  259. #include <isl_multi_no_explicit_domain.c>
  260. #include <isl_multi_templ.c>