tree-iterator.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /* Iterator routines for manipulating GENERIC and GIMPLE tree statements.
  2. Copyright (C) 2003-2015 Free Software Foundation, Inc.
  3. Contributed by Andrew MacLeod <amacleod@redhat.com>
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. GCC is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GCC; see the file COPYING3. If not see
  15. <http://www.gnu.org/licenses/>. */
  16. #include "config.h"
  17. #include "system.h"
  18. #include "coretypes.h"
  19. #include "hash-set.h"
  20. #include "machmode.h"
  21. #include "vec.h"
  22. #include "double-int.h"
  23. #include "input.h"
  24. #include "alias.h"
  25. #include "symtab.h"
  26. #include "options.h"
  27. #include "wide-int.h"
  28. #include "inchash.h"
  29. #include "tree.h"
  30. #include "tree-iterator.h"
  31. #include "ggc.h"
  32. /* This is a cache of STATEMENT_LIST nodes. We create and destroy them
  33. fairly often during gimplification. */
  34. static GTY ((deletable (""))) vec<tree, va_gc> *stmt_list_cache;
  35. tree
  36. alloc_stmt_list (void)
  37. {
  38. tree list;
  39. if (!vec_safe_is_empty (stmt_list_cache))
  40. {
  41. list = stmt_list_cache->pop ();
  42. memset (list, 0, sizeof (struct tree_base));
  43. TREE_SET_CODE (list, STATEMENT_LIST);
  44. }
  45. else
  46. list = make_node (STATEMENT_LIST);
  47. TREE_TYPE (list) = void_type_node;
  48. return list;
  49. }
  50. void
  51. free_stmt_list (tree t)
  52. {
  53. gcc_assert (!STATEMENT_LIST_HEAD (t));
  54. gcc_assert (!STATEMENT_LIST_TAIL (t));
  55. vec_safe_push (stmt_list_cache, t);
  56. }
  57. /* A subroutine of append_to_statement_list{,_force}. T is not NULL. */
  58. static void
  59. append_to_statement_list_1 (tree t, tree *list_p)
  60. {
  61. tree list = *list_p;
  62. tree_stmt_iterator i;
  63. if (!list)
  64. {
  65. if (t && TREE_CODE (t) == STATEMENT_LIST)
  66. {
  67. *list_p = t;
  68. return;
  69. }
  70. *list_p = list = alloc_stmt_list ();
  71. }
  72. else if (TREE_CODE (list) != STATEMENT_LIST)
  73. {
  74. tree first = list;
  75. *list_p = list = alloc_stmt_list ();
  76. i = tsi_last (list);
  77. tsi_link_after (&i, first, TSI_CONTINUE_LINKING);
  78. }
  79. i = tsi_last (list);
  80. tsi_link_after (&i, t, TSI_CONTINUE_LINKING);
  81. }
  82. /* Add T to the end of the list container pointed to by LIST_P.
  83. If T is an expression with no effects, it is ignored. */
  84. void
  85. append_to_statement_list (tree t, tree *list_p)
  86. {
  87. if (t && TREE_SIDE_EFFECTS (t))
  88. append_to_statement_list_1 (t, list_p);
  89. }
  90. /* Similar, but the statement is always added, regardless of side effects. */
  91. void
  92. append_to_statement_list_force (tree t, tree *list_p)
  93. {
  94. if (t != NULL_TREE)
  95. append_to_statement_list_1 (t, list_p);
  96. }
  97. /* Links a statement, or a chain of statements, before the current stmt. */
  98. void
  99. tsi_link_before (tree_stmt_iterator *i, tree t, enum tsi_iterator_update mode)
  100. {
  101. struct tree_statement_list_node *head, *tail, *cur;
  102. /* Die on looping. */
  103. gcc_assert (t != i->container);
  104. if (TREE_CODE (t) == STATEMENT_LIST)
  105. {
  106. head = STATEMENT_LIST_HEAD (t);
  107. tail = STATEMENT_LIST_TAIL (t);
  108. STATEMENT_LIST_HEAD (t) = NULL;
  109. STATEMENT_LIST_TAIL (t) = NULL;
  110. free_stmt_list (t);
  111. /* Empty statement lists need no work. */
  112. if (!head || !tail)
  113. {
  114. gcc_assert (head == tail);
  115. return;
  116. }
  117. }
  118. else
  119. {
  120. head = ggc_alloc<tree_statement_list_node> ();
  121. head->prev = NULL;
  122. head->next = NULL;
  123. head->stmt = t;
  124. tail = head;
  125. }
  126. TREE_SIDE_EFFECTS (i->container) = 1;
  127. cur = i->ptr;
  128. /* Link it into the list. */
  129. if (cur)
  130. {
  131. head->prev = cur->prev;
  132. if (head->prev)
  133. head->prev->next = head;
  134. else
  135. STATEMENT_LIST_HEAD (i->container) = head;
  136. tail->next = cur;
  137. cur->prev = tail;
  138. }
  139. else
  140. {
  141. head->prev = STATEMENT_LIST_TAIL (i->container);
  142. if (head->prev)
  143. head->prev->next = head;
  144. else
  145. STATEMENT_LIST_HEAD (i->container) = head;
  146. STATEMENT_LIST_TAIL (i->container) = tail;
  147. }
  148. /* Update the iterator, if requested. */
  149. switch (mode)
  150. {
  151. case TSI_NEW_STMT:
  152. case TSI_CONTINUE_LINKING:
  153. case TSI_CHAIN_START:
  154. i->ptr = head;
  155. break;
  156. case TSI_CHAIN_END:
  157. i->ptr = tail;
  158. break;
  159. case TSI_SAME_STMT:
  160. break;
  161. }
  162. }
  163. /* Links a statement, or a chain of statements, after the current stmt. */
  164. void
  165. tsi_link_after (tree_stmt_iterator *i, tree t, enum tsi_iterator_update mode)
  166. {
  167. struct tree_statement_list_node *head, *tail, *cur;
  168. /* Die on looping. */
  169. gcc_assert (t != i->container);
  170. if (TREE_CODE (t) == STATEMENT_LIST)
  171. {
  172. head = STATEMENT_LIST_HEAD (t);
  173. tail = STATEMENT_LIST_TAIL (t);
  174. STATEMENT_LIST_HEAD (t) = NULL;
  175. STATEMENT_LIST_TAIL (t) = NULL;
  176. free_stmt_list (t);
  177. /* Empty statement lists need no work. */
  178. if (!head || !tail)
  179. {
  180. gcc_assert (head == tail);
  181. return;
  182. }
  183. }
  184. else
  185. {
  186. head = ggc_alloc<tree_statement_list_node> ();
  187. head->prev = NULL;
  188. head->next = NULL;
  189. head->stmt = t;
  190. tail = head;
  191. }
  192. TREE_SIDE_EFFECTS (i->container) = 1;
  193. cur = i->ptr;
  194. /* Link it into the list. */
  195. if (cur)
  196. {
  197. tail->next = cur->next;
  198. if (tail->next)
  199. tail->next->prev = tail;
  200. else
  201. STATEMENT_LIST_TAIL (i->container) = tail;
  202. head->prev = cur;
  203. cur->next = head;
  204. }
  205. else
  206. {
  207. gcc_assert (!STATEMENT_LIST_TAIL (i->container));
  208. STATEMENT_LIST_HEAD (i->container) = head;
  209. STATEMENT_LIST_TAIL (i->container) = tail;
  210. }
  211. /* Update the iterator, if requested. */
  212. switch (mode)
  213. {
  214. case TSI_NEW_STMT:
  215. case TSI_CHAIN_START:
  216. i->ptr = head;
  217. break;
  218. case TSI_CONTINUE_LINKING:
  219. case TSI_CHAIN_END:
  220. i->ptr = tail;
  221. break;
  222. case TSI_SAME_STMT:
  223. gcc_assert (cur);
  224. break;
  225. }
  226. }
  227. /* Remove a stmt from the tree list. The iterator is updated to point to
  228. the next stmt. */
  229. void
  230. tsi_delink (tree_stmt_iterator *i)
  231. {
  232. struct tree_statement_list_node *cur, *next, *prev;
  233. cur = i->ptr;
  234. next = cur->next;
  235. prev = cur->prev;
  236. if (prev)
  237. prev->next = next;
  238. else
  239. STATEMENT_LIST_HEAD (i->container) = next;
  240. if (next)
  241. next->prev = prev;
  242. else
  243. STATEMENT_LIST_TAIL (i->container) = prev;
  244. if (!next && !prev)
  245. TREE_SIDE_EFFECTS (i->container) = 0;
  246. i->ptr = next;
  247. }
  248. /* Return the first expression in a sequence of COMPOUND_EXPRs,
  249. or in a STATEMENT_LIST. */
  250. tree
  251. expr_first (tree expr)
  252. {
  253. if (expr == NULL_TREE)
  254. return expr;
  255. if (TREE_CODE (expr) == STATEMENT_LIST)
  256. {
  257. struct tree_statement_list_node *n = STATEMENT_LIST_HEAD (expr);
  258. return n ? n->stmt : NULL_TREE;
  259. }
  260. while (TREE_CODE (expr) == COMPOUND_EXPR)
  261. expr = TREE_OPERAND (expr, 0);
  262. return expr;
  263. }
  264. /* Return the last expression in a sequence of COMPOUND_EXPRs,
  265. or in a STATEMENT_LIST. */
  266. tree
  267. expr_last (tree expr)
  268. {
  269. if (expr == NULL_TREE)
  270. return expr;
  271. if (TREE_CODE (expr) == STATEMENT_LIST)
  272. {
  273. struct tree_statement_list_node *n = STATEMENT_LIST_TAIL (expr);
  274. return n ? n->stmt : NULL_TREE;
  275. }
  276. while (TREE_CODE (expr) == COMPOUND_EXPR)
  277. expr = TREE_OPERAND (expr, 1);
  278. return expr;
  279. }
  280. #include "gt-tree-iterator.h"