valtrack.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /* Infrastructure for tracking user variable locations and values
  2. throughout compilation.
  3. Copyright (C) 2010-2015 Free Software Foundation, Inc.
  4. Contributed by Alexandre Oliva <aoliva@redhat.com>.
  5. This file is part of GCC.
  6. GCC is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU General Public License as published by the Free
  8. Software Foundation; either version 3, or (at your option) any later
  9. version.
  10. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GCC; see the file COPYING3. If not see
  16. <http://www.gnu.org/licenses/>. */
  17. #include "config.h"
  18. #include "system.h"
  19. #include "coretypes.h"
  20. #include "tm.h"
  21. #include "rtl.h"
  22. #include "predict.h"
  23. #include "basic-block.h"
  24. #include "valtrack.h"
  25. #include "hashtab.h"
  26. #include "hash-set.h"
  27. #include "vec.h"
  28. #include "machmode.h"
  29. #include "hard-reg-set.h"
  30. #include "input.h"
  31. #include "function.h"
  32. #include "regs.h"
  33. #include "emit-rtl.h"
  34. /* gen_lowpart_no_emit hook implementation for DEBUG_INSNs. In DEBUG_INSNs,
  35. all lowpart SUBREGs are valid, despite what the machine requires for
  36. instructions. */
  37. static rtx
  38. gen_lowpart_for_debug (machine_mode mode, rtx x)
  39. {
  40. rtx result = gen_lowpart_if_possible (mode, x);
  41. if (result)
  42. return result;
  43. if (GET_MODE (x) != VOIDmode)
  44. return gen_rtx_raw_SUBREG (mode, x,
  45. subreg_lowpart_offset (mode, GET_MODE (x)));
  46. return NULL_RTX;
  47. }
  48. /* Replace auto-increment addressing modes with explicit operations to access
  49. the same addresses without modifying the corresponding registers. */
  50. static rtx
  51. cleanup_auto_inc_dec (rtx src, machine_mode mem_mode ATTRIBUTE_UNUSED)
  52. {
  53. rtx x = src;
  54. #ifdef AUTO_INC_DEC
  55. const RTX_CODE code = GET_CODE (x);
  56. int i;
  57. const char *fmt;
  58. switch (code)
  59. {
  60. case REG:
  61. CASE_CONST_ANY:
  62. case SYMBOL_REF:
  63. case CODE_LABEL:
  64. case PC:
  65. case CC0:
  66. case SCRATCH:
  67. /* SCRATCH must be shared because they represent distinct values. */
  68. return x;
  69. case CLOBBER:
  70. /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
  71. clobbers or clobbers of hard registers that originated as pseudos.
  72. This is needed to allow safe register renaming. */
  73. if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
  74. && ORIGINAL_REGNO (XEXP (x, 0)) == REGNO (XEXP (x, 0)))
  75. return x;
  76. break;
  77. case CONST:
  78. if (shared_const_p (x))
  79. return x;
  80. break;
  81. case MEM:
  82. mem_mode = GET_MODE (x);
  83. break;
  84. case PRE_INC:
  85. case PRE_DEC:
  86. gcc_assert (mem_mode != VOIDmode && mem_mode != BLKmode);
  87. return gen_rtx_PLUS (GET_MODE (x),
  88. cleanup_auto_inc_dec (XEXP (x, 0), mem_mode),
  89. gen_int_mode (code == PRE_INC
  90. ? GET_MODE_SIZE (mem_mode)
  91. : -GET_MODE_SIZE (mem_mode),
  92. GET_MODE (x)));
  93. case POST_INC:
  94. case POST_DEC:
  95. case PRE_MODIFY:
  96. case POST_MODIFY:
  97. return cleanup_auto_inc_dec (code == PRE_MODIFY
  98. ? XEXP (x, 1) : XEXP (x, 0),
  99. mem_mode);
  100. default:
  101. break;
  102. }
  103. /* Copy the various flags, fields, and other information. We assume
  104. that all fields need copying, and then clear the fields that should
  105. not be copied. That is the sensible default behavior, and forces
  106. us to explicitly document why we are *not* copying a flag. */
  107. x = shallow_copy_rtx (x);
  108. /* We do not copy the USED flag, which is used as a mark bit during
  109. walks over the RTL. */
  110. RTX_FLAG (x, used) = 0;
  111. /* We do not copy FRAME_RELATED for INSNs. */
  112. if (INSN_P (x))
  113. RTX_FLAG (x, frame_related) = 0;
  114. fmt = GET_RTX_FORMAT (code);
  115. for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
  116. if (fmt[i] == 'e')
  117. XEXP (x, i) = cleanup_auto_inc_dec (XEXP (x, i), mem_mode);
  118. else if (fmt[i] == 'E' || fmt[i] == 'V')
  119. {
  120. int j;
  121. XVEC (x, i) = rtvec_alloc (XVECLEN (x, i));
  122. for (j = 0; j < XVECLEN (x, i); j++)
  123. XVECEXP (x, i, j)
  124. = cleanup_auto_inc_dec (XVECEXP (src, i, j), mem_mode);
  125. }
  126. #else /* !AUTO_INC_DEC */
  127. x = copy_rtx (x);
  128. #endif /* !AUTO_INC_DEC */
  129. return x;
  130. }
  131. /* Auxiliary data structure for propagate_for_debug_stmt. */
  132. struct rtx_subst_pair
  133. {
  134. rtx to;
  135. bool adjusted;
  136. };
  137. /* DATA points to an rtx_subst_pair. Return the value that should be
  138. substituted. */
  139. static rtx
  140. propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data)
  141. {
  142. struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
  143. if (!rtx_equal_p (from, old_rtx))
  144. return NULL_RTX;
  145. if (!pair->adjusted)
  146. {
  147. pair->adjusted = true;
  148. pair->to = cleanup_auto_inc_dec (pair->to, VOIDmode);
  149. pair->to = make_compound_operation (pair->to, SET);
  150. return pair->to;
  151. }
  152. return copy_rtx (pair->to);
  153. }
  154. /* Replace all the occurrences of DEST with SRC in DEBUG_INSNs between INSN
  155. and LAST, not including INSN, but including LAST. Also stop at the end
  156. of THIS_BASIC_BLOCK. */
  157. void
  158. propagate_for_debug (rtx_insn *insn, rtx_insn *last, rtx dest, rtx src,
  159. basic_block this_basic_block)
  160. {
  161. rtx_insn *next, *end = NEXT_INSN (BB_END (this_basic_block));
  162. rtx loc;
  163. rtx (*saved_rtl_hook_no_emit) (machine_mode, rtx);
  164. struct rtx_subst_pair p;
  165. p.to = src;
  166. p.adjusted = false;
  167. next = NEXT_INSN (insn);
  168. last = NEXT_INSN (last);
  169. saved_rtl_hook_no_emit = rtl_hooks.gen_lowpart_no_emit;
  170. rtl_hooks.gen_lowpart_no_emit = gen_lowpart_for_debug;
  171. while (next != last && next != end)
  172. {
  173. insn = next;
  174. next = NEXT_INSN (insn);
  175. if (DEBUG_INSN_P (insn))
  176. {
  177. loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
  178. dest, propagate_for_debug_subst, &p);
  179. if (loc == INSN_VAR_LOCATION_LOC (insn))
  180. continue;
  181. INSN_VAR_LOCATION_LOC (insn) = loc;
  182. df_insn_rescan (insn);
  183. }
  184. }
  185. rtl_hooks.gen_lowpart_no_emit = saved_rtl_hook_no_emit;
  186. }
  187. /* Initialize DEBUG to an empty list, and clear USED, if given. */
  188. void
  189. dead_debug_global_init (struct dead_debug_global *debug, bitmap used)
  190. {
  191. debug->used = used;
  192. debug->htab = NULL;
  193. if (used)
  194. bitmap_clear (used);
  195. }
  196. /* Initialize DEBUG to an empty list, and clear USED, if given. Link
  197. back to GLOBAL, if given, and bring in used bits from it. */
  198. void
  199. dead_debug_local_init (struct dead_debug_local *debug, bitmap used,
  200. struct dead_debug_global *global)
  201. {
  202. if (!used && global && global->used)
  203. used = BITMAP_ALLOC (NULL);
  204. debug->head = NULL;
  205. debug->global = global;
  206. debug->used = used;
  207. debug->to_rescan = NULL;
  208. if (used)
  209. {
  210. if (global && global->used)
  211. bitmap_copy (used, global->used);
  212. else
  213. bitmap_clear (used);
  214. }
  215. }
  216. /* Locate the entry for REG in GLOBAL->htab. */
  217. static dead_debug_global_entry *
  218. dead_debug_global_find (struct dead_debug_global *global, rtx reg)
  219. {
  220. dead_debug_global_entry temp_entry;
  221. temp_entry.reg = reg;
  222. dead_debug_global_entry *entry = global->htab->find (&temp_entry);
  223. gcc_checking_assert (entry && entry->reg == temp_entry.reg);
  224. return entry;
  225. }
  226. /* Insert an entry mapping REG to DTEMP in GLOBAL->htab. */
  227. static dead_debug_global_entry *
  228. dead_debug_global_insert (struct dead_debug_global *global, rtx reg, rtx dtemp)
  229. {
  230. dead_debug_global_entry temp_entry;
  231. temp_entry.reg = reg;
  232. temp_entry.dtemp = dtemp;
  233. if (!global->htab)
  234. global->htab = new hash_table<dead_debug_hash_descr> (31);
  235. dead_debug_global_entry **slot = global->htab->find_slot (&temp_entry,
  236. INSERT);
  237. gcc_checking_assert (!*slot);
  238. *slot = XNEW (dead_debug_global_entry);
  239. **slot = temp_entry;
  240. return *slot;
  241. }
  242. /* If UREGNO, referenced by USE, is a pseudo marked as used in GLOBAL,
  243. replace it with with a USE of the debug temp recorded for it, and
  244. return TRUE. Otherwise, just return FALSE.
  245. If PTO_RESCAN is given, instead of rescanning modified INSNs right
  246. away, add their UIDs to the bitmap, allocating one of *PTO_RESCAN
  247. is NULL. */
  248. static bool
  249. dead_debug_global_replace_temp (struct dead_debug_global *global,
  250. df_ref use, unsigned int uregno,
  251. bitmap *pto_rescan)
  252. {
  253. if (!global || uregno < FIRST_PSEUDO_REGISTER
  254. || !global->used
  255. || !REG_P (*DF_REF_REAL_LOC (use))
  256. || REGNO (*DF_REF_REAL_LOC (use)) != uregno
  257. || !bitmap_bit_p (global->used, uregno))
  258. return false;
  259. dead_debug_global_entry *entry
  260. = dead_debug_global_find (global, *DF_REF_REAL_LOC (use));
  261. gcc_checking_assert (GET_CODE (entry->reg) == REG
  262. && REGNO (entry->reg) == uregno);
  263. if (!entry->dtemp)
  264. return true;
  265. *DF_REF_REAL_LOC (use) = entry->dtemp;
  266. if (!pto_rescan)
  267. df_insn_rescan (DF_REF_INSN (use));
  268. else
  269. {
  270. if (!*pto_rescan)
  271. *pto_rescan = BITMAP_ALLOC (NULL);
  272. bitmap_set_bit (*pto_rescan, INSN_UID (DF_REF_INSN (use)));
  273. }
  274. return true;
  275. }
  276. /* Reset all debug uses in HEAD, and clear DEBUG->to_rescan bits of
  277. each reset insn. DEBUG is not otherwise modified. If HEAD is
  278. DEBUG->head, DEBUG->head will be set to NULL at the end.
  279. Otherwise, entries from DEBUG->head that pertain to reset insns
  280. will be removed, and only then rescanned. */
  281. static void
  282. dead_debug_reset_uses (struct dead_debug_local *debug,
  283. struct dead_debug_use *head)
  284. {
  285. bool got_head = (debug->head == head);
  286. bitmap rescan;
  287. struct dead_debug_use **tailp = &debug->head;
  288. struct dead_debug_use *cur;
  289. bitmap_iterator bi;
  290. unsigned int uid;
  291. if (got_head)
  292. rescan = NULL;
  293. else
  294. rescan = BITMAP_ALLOC (NULL);
  295. while (head)
  296. {
  297. struct dead_debug_use *next = head->next;
  298. rtx_insn *insn;
  299. insn = DF_REF_INSN (head->use);
  300. if (!next || DF_REF_INSN (next->use) != insn)
  301. {
  302. INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
  303. if (got_head)
  304. df_insn_rescan_debug_internal (insn);
  305. else
  306. bitmap_set_bit (rescan, INSN_UID (insn));
  307. if (debug->to_rescan)
  308. bitmap_clear_bit (debug->to_rescan, INSN_UID (insn));
  309. }
  310. XDELETE (head);
  311. head = next;
  312. }
  313. if (got_head)
  314. {
  315. debug->head = NULL;
  316. return;
  317. }
  318. while ((cur = *tailp))
  319. if (bitmap_bit_p (rescan, INSN_UID (DF_REF_INSN (cur->use))))
  320. {
  321. *tailp = cur->next;
  322. XDELETE (cur);
  323. }
  324. else
  325. tailp = &cur->next;
  326. EXECUTE_IF_SET_IN_BITMAP (rescan, 0, uid, bi)
  327. {
  328. struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
  329. if (insn_info)
  330. df_insn_rescan_debug_internal (insn_info->insn);
  331. }
  332. BITMAP_FREE (rescan);
  333. }
  334. /* Promote pending local uses of pseudos in DEBUG to global
  335. substitutions. Uses of non-pseudos are left alone for
  336. resetting. */
  337. static void
  338. dead_debug_promote_uses (struct dead_debug_local *debug)
  339. {
  340. for (struct dead_debug_use *head = debug->head, **headp = &debug->head;
  341. head; head = *headp)
  342. {
  343. rtx reg = *DF_REF_REAL_LOC (head->use);
  344. df_ref ref;
  345. dead_debug_global_entry *entry;
  346. if (GET_CODE (reg) != REG
  347. || REGNO (reg) < FIRST_PSEUDO_REGISTER)
  348. {
  349. headp = &head->next;
  350. continue;
  351. }
  352. if (!debug->global->used)
  353. debug->global->used = BITMAP_ALLOC (NULL);
  354. bool added = bitmap_set_bit (debug->global->used, REGNO (reg));
  355. gcc_checking_assert (added);
  356. entry = dead_debug_global_insert (debug->global, reg,
  357. make_debug_expr_from_rtl (reg));
  358. gcc_checking_assert (entry->dtemp);
  359. /* Tentatively remove the USE from the list. */
  360. *headp = head->next;
  361. if (!debug->to_rescan)
  362. debug->to_rescan = BITMAP_ALLOC (NULL);
  363. for (ref = DF_REG_USE_CHAIN (REGNO (reg)); ref;
  364. ref = DF_REF_NEXT_REG (ref))
  365. if (DEBUG_INSN_P (DF_REF_INSN (ref)))
  366. {
  367. if (!dead_debug_global_replace_temp (debug->global, ref,
  368. REGNO (reg),
  369. &debug->to_rescan))
  370. {
  371. rtx_insn *insn = DF_REF_INSN (ref);
  372. INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
  373. bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
  374. }
  375. }
  376. for (ref = DF_REG_DEF_CHAIN (REGNO (reg)); ref;
  377. ref = DF_REF_NEXT_REG (ref))
  378. if (!dead_debug_insert_temp (debug, REGNO (reg), DF_REF_INSN (ref),
  379. DEBUG_TEMP_BEFORE_WITH_VALUE))
  380. {
  381. rtx bind;
  382. bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
  383. DEBUG_EXPR_TREE_DECL (entry->dtemp),
  384. gen_rtx_UNKNOWN_VAR_LOC (),
  385. VAR_INIT_STATUS_INITIALIZED);
  386. rtx_insn *insn = emit_debug_insn_before (bind, DF_REF_INSN (ref));
  387. bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
  388. }
  389. entry->dtemp = NULL;
  390. XDELETE (head);
  391. }
  392. }
  393. /* Reset all debug insns with pending uses. Release the bitmap in it,
  394. unless it is USED. USED must be the same bitmap passed to
  395. dead_debug_local_init. */
  396. void
  397. dead_debug_local_finish (struct dead_debug_local *debug, bitmap used)
  398. {
  399. if (debug->global)
  400. dead_debug_promote_uses (debug);
  401. if (debug->used != used)
  402. BITMAP_FREE (debug->used);
  403. dead_debug_reset_uses (debug, debug->head);
  404. if (debug->to_rescan)
  405. {
  406. bitmap_iterator bi;
  407. unsigned int uid;
  408. EXECUTE_IF_SET_IN_BITMAP (debug->to_rescan, 0, uid, bi)
  409. {
  410. struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
  411. if (insn_info)
  412. df_insn_rescan (insn_info->insn);
  413. }
  414. BITMAP_FREE (debug->to_rescan);
  415. }
  416. }
  417. /* Release GLOBAL->used unless it is the same as USED. Release the
  418. mapping hash table if it was initialized. */
  419. void
  420. dead_debug_global_finish (struct dead_debug_global *global, bitmap used)
  421. {
  422. if (global->used != used)
  423. BITMAP_FREE (global->used);
  424. delete global->htab;
  425. global->htab = NULL;
  426. }
  427. /* Add USE to DEBUG, or substitute it right away if it's a pseudo in
  428. the global substitution list. USE must be a dead reference to
  429. UREGNO in a debug insn. Create a bitmap for DEBUG as needed. */
  430. void
  431. dead_debug_add (struct dead_debug_local *debug, df_ref use, unsigned int uregno)
  432. {
  433. if (dead_debug_global_replace_temp (debug->global, use, uregno,
  434. &debug->to_rescan))
  435. return;
  436. struct dead_debug_use *newddu = XNEW (struct dead_debug_use);
  437. newddu->use = use;
  438. newddu->next = debug->head;
  439. debug->head = newddu;
  440. if (!debug->used)
  441. debug->used = BITMAP_ALLOC (NULL);
  442. /* ??? If we dealt with split multi-registers below, we should set
  443. all registers for the used mode in case of hardware
  444. registers. */
  445. bitmap_set_bit (debug->used, uregno);
  446. }
  447. /* Like lowpart_subreg, but if a subreg is not valid for machine, force
  448. it anyway - for use in debug insns. */
  449. static rtx
  450. debug_lowpart_subreg (machine_mode outer_mode, rtx expr,
  451. machine_mode inner_mode)
  452. {
  453. if (inner_mode == VOIDmode)
  454. inner_mode = GET_MODE (expr);
  455. int offset = subreg_lowpart_offset (outer_mode, inner_mode);
  456. rtx ret = simplify_gen_subreg (outer_mode, expr, inner_mode, offset);
  457. if (ret)
  458. return ret;
  459. return gen_rtx_raw_SUBREG (outer_mode, expr, offset);
  460. }
  461. /* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
  462. before or after INSN (depending on WHERE), that binds a (possibly
  463. global) debug temp to the widest-mode use of UREGNO, if WHERE is
  464. *_WITH_REG, or the value stored in UREGNO by INSN otherwise, and
  465. replace all uses of UREGNO in DEBUG with uses of the debug temp.
  466. INSN must be where UREGNO dies, if WHERE is *_BEFORE_*, or where it
  467. is set otherwise. Return the number of debug insns emitted. */
  468. int
  469. dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
  470. rtx_insn *insn, enum debug_temp_where where)
  471. {
  472. struct dead_debug_use **tailp = &debug->head;
  473. struct dead_debug_use *cur;
  474. struct dead_debug_use *uses = NULL;
  475. struct dead_debug_use **usesp = &uses;
  476. rtx reg = NULL_RTX;
  477. rtx breg;
  478. rtx dval = NULL_RTX;
  479. rtx bind;
  480. bool global;
  481. if (!debug->used)
  482. return 0;
  483. global = (debug->global && debug->global->used
  484. && bitmap_bit_p (debug->global->used, uregno));
  485. if (!global && !bitmap_clear_bit (debug->used, uregno))
  486. return 0;
  487. /* Move all uses of uregno from debug->head to uses, setting mode to
  488. the widest referenced mode. */
  489. while ((cur = *tailp))
  490. {
  491. if (DF_REF_REGNO (cur->use) == uregno)
  492. {
  493. /* If this loc has been changed e.g. to debug_expr already
  494. as part of a multi-register use, just drop it. */
  495. if (!REG_P (*DF_REF_REAL_LOC (cur->use)))
  496. {
  497. *tailp = cur->next;
  498. XDELETE (cur);
  499. continue;
  500. }
  501. *usesp = cur;
  502. usesp = &cur->next;
  503. *tailp = cur->next;
  504. cur->next = NULL;
  505. if (!reg
  506. || (GET_MODE_BITSIZE (GET_MODE (reg))
  507. < GET_MODE_BITSIZE (GET_MODE (*DF_REF_REAL_LOC (cur->use)))))
  508. reg = *DF_REF_REAL_LOC (cur->use);
  509. }
  510. else
  511. tailp = &(*tailp)->next;
  512. }
  513. /* We may have dangling bits in debug->used for registers that were part
  514. of a multi-register use, one component of which has been reset. */
  515. if (reg == NULL)
  516. {
  517. gcc_checking_assert (!uses);
  518. if (!global)
  519. return 0;
  520. }
  521. if (global)
  522. {
  523. if (!reg)
  524. reg = regno_reg_rtx[uregno];
  525. dead_debug_global_entry *entry
  526. = dead_debug_global_find (debug->global, reg);
  527. gcc_checking_assert (entry->reg == reg);
  528. dval = entry->dtemp;
  529. if (!dval)
  530. return 0;
  531. }
  532. gcc_checking_assert (uses || global);
  533. breg = reg;
  534. /* Recover the expression INSN stores in REG. */
  535. if (where == DEBUG_TEMP_BEFORE_WITH_VALUE)
  536. {
  537. rtx set = single_set (insn);
  538. rtx dest, src;
  539. if (set)
  540. {
  541. dest = SET_DEST (set);
  542. src = SET_SRC (set);
  543. /* Lose if the REG-setting insn is a CALL. */
  544. if (GET_CODE (src) == CALL)
  545. {
  546. while (uses)
  547. {
  548. cur = uses->next;
  549. XDELETE (uses);
  550. uses = cur;
  551. }
  552. return 0;
  553. }
  554. }
  555. /* ??? Should we try to extract it from a PARALLEL? */
  556. if (!set)
  557. breg = NULL;
  558. /* Cool, it's the same REG, we can use SRC. */
  559. else if (dest == reg)
  560. breg = cleanup_auto_inc_dec (src, VOIDmode);
  561. else if (REG_P (dest))
  562. {
  563. /* Hmm... Something's fishy, we should be setting REG here. */
  564. if (REGNO (dest) != REGNO (reg))
  565. breg = NULL;
  566. /* If we're not overwriting all the hardware registers that
  567. setting REG in its mode would, we won't know what to bind
  568. the debug temp to. ??? We could bind the debug_expr to a
  569. CONCAT or PARALLEL with the split multi-registers, and
  570. replace them as we found the corresponding sets. */
  571. else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
  572. && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
  573. != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
  574. breg = NULL;
  575. /* Ok, it's the same (hardware) REG, but with a different
  576. mode, so SUBREG it. */
  577. else
  578. breg = debug_lowpart_subreg (GET_MODE (reg),
  579. cleanup_auto_inc_dec (src, VOIDmode),
  580. GET_MODE (dest));
  581. }
  582. else if (GET_CODE (dest) == SUBREG)
  583. {
  584. /* We should be setting REG here. Lose. */
  585. if (REGNO (SUBREG_REG (dest)) != REGNO (reg))
  586. breg = NULL;
  587. /* Lose if we're setting something other than the lowpart of
  588. REG. */
  589. else if (!subreg_lowpart_p (dest))
  590. breg = NULL;
  591. /* If we're not overwriting all the hardware registers that
  592. setting REG in its mode would, we won't know what to bind
  593. the debug temp to. */
  594. else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
  595. && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
  596. != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
  597. breg = NULL;
  598. /* Yay, we can use SRC, just adjust its mode. */
  599. else
  600. breg = debug_lowpart_subreg (GET_MODE (reg),
  601. cleanup_auto_inc_dec (src, VOIDmode),
  602. GET_MODE (dest));
  603. }
  604. /* Oh well, we're out of luck. */
  605. else
  606. breg = NULL;
  607. /* We couldn't figure out the value stored in REG, so reset all
  608. of its pending debug uses. */
  609. if (!breg)
  610. {
  611. dead_debug_reset_uses (debug, uses);
  612. return 0;
  613. }
  614. }
  615. /* If there's a single (debug) use of an otherwise unused REG, and
  616. the debug use is not part of a larger expression, then it
  617. probably doesn't make sense to introduce a new debug temp. */
  618. if (where == DEBUG_TEMP_AFTER_WITH_REG && !uses->next)
  619. {
  620. rtx_insn *next = DF_REF_INSN (uses->use);
  621. if (DEBUG_INSN_P (next) && reg == INSN_VAR_LOCATION_LOC (next))
  622. {
  623. XDELETE (uses);
  624. return 0;
  625. }
  626. }
  627. if (!global)
  628. /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL). */
  629. dval = make_debug_expr_from_rtl (reg);
  630. /* Emit a debug bind insn before the insn in which reg dies. */
  631. bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
  632. DEBUG_EXPR_TREE_DECL (dval), breg,
  633. VAR_INIT_STATUS_INITIALIZED);
  634. if (where == DEBUG_TEMP_AFTER_WITH_REG
  635. || where == DEBUG_TEMP_AFTER_WITH_REG_FORCE)
  636. bind = emit_debug_insn_after (bind, insn);
  637. else
  638. bind = emit_debug_insn_before (bind, insn);
  639. if (debug->to_rescan == NULL)
  640. debug->to_rescan = BITMAP_ALLOC (NULL);
  641. bitmap_set_bit (debug->to_rescan, INSN_UID (bind));
  642. /* Adjust all uses. */
  643. while ((cur = uses))
  644. {
  645. if (GET_MODE (*DF_REF_REAL_LOC (cur->use)) == GET_MODE (reg))
  646. *DF_REF_REAL_LOC (cur->use) = dval;
  647. else
  648. *DF_REF_REAL_LOC (cur->use)
  649. = debug_lowpart_subreg (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval,
  650. GET_MODE (dval));
  651. /* ??? Should we simplify subreg of subreg? */
  652. bitmap_set_bit (debug->to_rescan, INSN_UID (DF_REF_INSN (cur->use)));
  653. uses = cur->next;
  654. XDELETE (cur);
  655. }
  656. return 1;
  657. }