print-rtl.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. /* Print RTL for GCC.
  2. Copyright (C) 1987-2015 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. /* This file is compiled twice: once for the generator programs,
  16. once for the compiler. */
  17. #ifdef GENERATOR_FILE
  18. #include "bconfig.h"
  19. #else
  20. #include "config.h"
  21. #endif
  22. #include "system.h"
  23. #include "coretypes.h"
  24. #include "tm.h"
  25. #include "rtl.h"
  26. /* These headers all define things which are not available in
  27. generator programs. */
  28. #ifndef GENERATOR_FILE
  29. #include "hash-set.h"
  30. #include "machmode.h"
  31. #include "vec.h"
  32. #include "double-int.h"
  33. #include "input.h"
  34. #include "alias.h"
  35. #include "symtab.h"
  36. #include "wide-int.h"
  37. #include "inchash.h"
  38. #include "tree.h"
  39. #include "print-tree.h"
  40. #include "flags.h"
  41. #include "hard-reg-set.h"
  42. #include "predict.h"
  43. #include "input.h"
  44. #include "function.h"
  45. #include "basic-block.h"
  46. #include "diagnostic.h"
  47. #include "tree-pretty-print.h"
  48. #include "cselib.h"
  49. #include "dumpfile.h" /* for dump_flags */
  50. #include "dwarf2out.h"
  51. #endif
  52. static FILE *outfile;
  53. static int sawclose = 0;
  54. static int indent;
  55. static bool in_call_function_usage;
  56. static void print_rtx (const_rtx);
  57. /* String printed at beginning of each RTL when it is dumped.
  58. This string is set to ASM_COMMENT_START when the RTL is dumped in
  59. the assembly output file. */
  60. const char *print_rtx_head = "";
  61. #ifdef GENERATOR_FILE
  62. /* These are defined from the .opt file when not used in generator
  63. programs. */
  64. /* Nonzero means suppress output of instruction numbers
  65. in debugging dumps.
  66. This must be defined here so that programs like gencodes can be linked. */
  67. int flag_dump_unnumbered = 0;
  68. /* Nonzero means suppress output of instruction numbers for previous
  69. and next insns in debugging dumps.
  70. This must be defined here so that programs like gencodes can be linked. */
  71. int flag_dump_unnumbered_links = 0;
  72. #endif
  73. /* Nonzero means use simplified format without flags, modes, etc. */
  74. int flag_simple = 0;
  75. #ifndef GENERATOR_FILE
  76. void
  77. print_mem_expr (FILE *outfile, const_tree expr)
  78. {
  79. fputc (' ', outfile);
  80. print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
  81. }
  82. #endif
  83. /* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */
  84. static void
  85. print_rtx (const_rtx in_rtx)
  86. {
  87. int i = 0;
  88. int j;
  89. const char *format_ptr;
  90. int is_insn;
  91. if (sawclose)
  92. {
  93. if (flag_simple)
  94. fputc (' ', outfile);
  95. else
  96. fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
  97. sawclose = 0;
  98. }
  99. if (in_rtx == 0)
  100. {
  101. fputs ("(nil)", outfile);
  102. sawclose = 1;
  103. return;
  104. }
  105. else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
  106. {
  107. fprintf (outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx),
  108. print_rtx_head, indent * 2, "");
  109. sawclose = 1;
  110. return;
  111. }
  112. is_insn = INSN_P (in_rtx);
  113. /* Print name of expression code. */
  114. if (flag_simple && CONST_INT_P (in_rtx))
  115. fputc ('(', outfile);
  116. else
  117. fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
  118. if (! flag_simple)
  119. {
  120. if (RTX_FLAG (in_rtx, in_struct))
  121. fputs ("/s", outfile);
  122. if (RTX_FLAG (in_rtx, volatil))
  123. fputs ("/v", outfile);
  124. if (RTX_FLAG (in_rtx, unchanging))
  125. fputs ("/u", outfile);
  126. if (RTX_FLAG (in_rtx, frame_related))
  127. fputs ("/f", outfile);
  128. if (RTX_FLAG (in_rtx, jump))
  129. fputs ("/j", outfile);
  130. if (RTX_FLAG (in_rtx, call))
  131. fputs ("/c", outfile);
  132. if (RTX_FLAG (in_rtx, return_val))
  133. fputs ("/i", outfile);
  134. /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
  135. if ((GET_CODE (in_rtx) == EXPR_LIST
  136. || GET_CODE (in_rtx) == INSN_LIST
  137. || GET_CODE (in_rtx) == INT_LIST)
  138. && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
  139. && !in_call_function_usage)
  140. fprintf (outfile, ":%s",
  141. GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
  142. /* For other rtl, print the mode if it's not VOID. */
  143. else if (GET_MODE (in_rtx) != VOIDmode)
  144. fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
  145. #ifndef GENERATOR_FILE
  146. if (GET_CODE (in_rtx) == VAR_LOCATION)
  147. {
  148. if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
  149. fputs (" <debug string placeholder>", outfile);
  150. else
  151. print_mem_expr (outfile, PAT_VAR_LOCATION_DECL (in_rtx));
  152. fputc (' ', outfile);
  153. print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
  154. if (PAT_VAR_LOCATION_STATUS (in_rtx)
  155. == VAR_INIT_STATUS_UNINITIALIZED)
  156. fprintf (outfile, " [uninit]");
  157. sawclose = 1;
  158. i = GET_RTX_LENGTH (VAR_LOCATION);
  159. }
  160. #endif
  161. }
  162. #ifndef GENERATOR_FILE
  163. if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
  164. i = 5;
  165. #endif
  166. if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
  167. {
  168. if (flag_dump_unnumbered)
  169. fprintf (outfile, " #");
  170. else
  171. fprintf (outfile, " %d", INSN_UID (in_rtx));
  172. }
  173. /* Get the format string and skip the first elements if we have handled
  174. them already. */
  175. format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
  176. for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
  177. switch (*format_ptr++)
  178. {
  179. const char *str;
  180. case 'T':
  181. str = XTMPL (in_rtx, i);
  182. goto string;
  183. case 'S':
  184. case 's':
  185. str = XSTR (in_rtx, i);
  186. string:
  187. if (str == 0)
  188. fputs (" \"\"", outfile);
  189. else
  190. fprintf (outfile, " (\"%s\")", str);
  191. sawclose = 1;
  192. break;
  193. /* 0 indicates a field for internal use that should not be printed.
  194. An exception is the third field of a NOTE, where it indicates
  195. that the field has several different valid contents. */
  196. case '0':
  197. #ifndef GENERATOR_FILE
  198. if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
  199. {
  200. int flags = SYMBOL_REF_FLAGS (in_rtx);
  201. if (flags)
  202. fprintf (outfile, " [flags %#x]", flags);
  203. tree decl = SYMBOL_REF_DECL (in_rtx);
  204. if (decl)
  205. print_node_brief (outfile, "", decl, dump_flags);
  206. }
  207. else if (i == 3 && NOTE_P (in_rtx))
  208. {
  209. switch (NOTE_KIND (in_rtx))
  210. {
  211. case NOTE_INSN_EH_REGION_BEG:
  212. case NOTE_INSN_EH_REGION_END:
  213. if (flag_dump_unnumbered)
  214. fprintf (outfile, " #");
  215. else
  216. fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
  217. sawclose = 1;
  218. break;
  219. case NOTE_INSN_BLOCK_BEG:
  220. case NOTE_INSN_BLOCK_END:
  221. dump_addr (outfile, " ", NOTE_BLOCK (in_rtx));
  222. sawclose = 1;
  223. break;
  224. case NOTE_INSN_BASIC_BLOCK:
  225. {
  226. basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
  227. if (bb != 0)
  228. fprintf (outfile, " [bb %d]", bb->index);
  229. break;
  230. }
  231. case NOTE_INSN_DELETED_LABEL:
  232. case NOTE_INSN_DELETED_DEBUG_LABEL:
  233. {
  234. const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
  235. if (label)
  236. fprintf (outfile, " (\"%s\")", label);
  237. else
  238. fprintf (outfile, " \"\"");
  239. }
  240. break;
  241. case NOTE_INSN_SWITCH_TEXT_SECTIONS:
  242. {
  243. basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
  244. if (bb != 0)
  245. fprintf (outfile, " [bb %d]", bb->index);
  246. break;
  247. }
  248. case NOTE_INSN_VAR_LOCATION:
  249. case NOTE_INSN_CALL_ARG_LOCATION:
  250. fputc (' ', outfile);
  251. print_rtx (NOTE_VAR_LOCATION (in_rtx));
  252. break;
  253. case NOTE_INSN_CFI:
  254. fputc ('\n', outfile);
  255. output_cfi_directive (outfile, NOTE_CFI (in_rtx));
  256. fputc ('\t', outfile);
  257. break;
  258. default:
  259. break;
  260. }
  261. }
  262. else if (i == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL)
  263. {
  264. /* Output the JUMP_LABEL reference. */
  265. fprintf (outfile, "\n%s%*s -> ", print_rtx_head, indent * 2, "");
  266. if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
  267. fprintf (outfile, "return");
  268. else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
  269. fprintf (outfile, "simple_return");
  270. else
  271. fprintf (outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
  272. }
  273. else if (i == 0 && GET_CODE (in_rtx) == VALUE)
  274. {
  275. cselib_val *val = CSELIB_VAL_PTR (in_rtx);
  276. fprintf (outfile, " %u:%u", val->uid, val->hash);
  277. dump_addr (outfile, " @", in_rtx);
  278. dump_addr (outfile, "/", (void*)val);
  279. }
  280. else if (i == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
  281. {
  282. fprintf (outfile, " D#%i",
  283. DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
  284. }
  285. else if (i == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
  286. {
  287. indent += 2;
  288. if (!sawclose)
  289. fprintf (outfile, " ");
  290. print_rtx (ENTRY_VALUE_EXP (in_rtx));
  291. indent -= 2;
  292. }
  293. #endif
  294. break;
  295. case 'e':
  296. do_e:
  297. indent += 2;
  298. if (i == 6 && INSN_P (in_rtx))
  299. /* Put REG_NOTES on their own line. */
  300. fprintf (outfile, "\n%s%*s",
  301. print_rtx_head, indent * 2, "");
  302. if (!sawclose)
  303. fprintf (outfile, " ");
  304. if (i == 7 && CALL_P (in_rtx))
  305. {
  306. in_call_function_usage = true;
  307. print_rtx (XEXP (in_rtx, i));
  308. in_call_function_usage = false;
  309. }
  310. else
  311. print_rtx (XEXP (in_rtx, i));
  312. indent -= 2;
  313. break;
  314. case 'E':
  315. case 'V':
  316. indent += 2;
  317. if (sawclose)
  318. {
  319. fprintf (outfile, "\n%s%*s",
  320. print_rtx_head, indent * 2, "");
  321. sawclose = 0;
  322. }
  323. fputs (" [", outfile);
  324. if (NULL != XVEC (in_rtx, i))
  325. {
  326. indent += 2;
  327. if (XVECLEN (in_rtx, i))
  328. sawclose = 1;
  329. for (j = 0; j < XVECLEN (in_rtx, i); j++)
  330. print_rtx (XVECEXP (in_rtx, i, j));
  331. indent -= 2;
  332. }
  333. if (sawclose)
  334. fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
  335. fputs ("]", outfile);
  336. sawclose = 1;
  337. indent -= 2;
  338. break;
  339. case 'w':
  340. if (! flag_simple)
  341. fprintf (outfile, " ");
  342. fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
  343. if (! flag_simple)
  344. fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
  345. (unsigned HOST_WIDE_INT) XWINT (in_rtx, i));
  346. break;
  347. case 'i':
  348. if (i == 4 && INSN_P (in_rtx))
  349. {
  350. #ifndef GENERATOR_FILE
  351. const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx);
  352. /* Pretty-print insn locations. Ignore scoping as it is mostly
  353. redundant with line number information and do not print anything
  354. when there is no location information available. */
  355. if (INSN_HAS_LOCATION (in_insn))
  356. {
  357. expanded_location xloc = insn_location (in_insn);
  358. fprintf (outfile, " %s:%i", xloc.file, xloc.line);
  359. }
  360. #endif
  361. }
  362. else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
  363. {
  364. #ifndef GENERATOR_FILE
  365. if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
  366. fprintf (outfile, " %s:%i",
  367. LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
  368. LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  369. #endif
  370. }
  371. else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  372. {
  373. #ifndef GENERATOR_FILE
  374. if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
  375. fprintf (outfile, " %s:%i",
  376. LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
  377. LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  378. #endif
  379. }
  380. else if (i == 5 && NOTE_P (in_rtx))
  381. {
  382. /* This field is only used for NOTE_INSN_DELETED_LABEL, and
  383. other times often contains garbage from INSN->NOTE death. */
  384. if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
  385. || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
  386. fprintf (outfile, " %d", XINT (in_rtx, i));
  387. }
  388. #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
  389. else if (i == 1
  390. && GET_CODE (in_rtx) == UNSPEC_VOLATILE
  391. && XINT (in_rtx, 1) >= 0
  392. && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
  393. fprintf (outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
  394. #endif
  395. #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
  396. else if (i == 1
  397. && (GET_CODE (in_rtx) == UNSPEC
  398. || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
  399. && XINT (in_rtx, 1) >= 0
  400. && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
  401. fprintf (outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
  402. #endif
  403. else
  404. {
  405. int value = XINT (in_rtx, i);
  406. const char *name;
  407. #ifndef GENERATOR_FILE
  408. if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER)
  409. fprintf (outfile, " %d %s", value, reg_names[value]);
  410. else if (REG_P (in_rtx)
  411. && (unsigned) value <= LAST_VIRTUAL_REGISTER)
  412. {
  413. if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
  414. fprintf (outfile, " %d virtual-incoming-args", value);
  415. else if (value == VIRTUAL_STACK_VARS_REGNUM)
  416. fprintf (outfile, " %d virtual-stack-vars", value);
  417. else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
  418. fprintf (outfile, " %d virtual-stack-dynamic", value);
  419. else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
  420. fprintf (outfile, " %d virtual-outgoing-args", value);
  421. else if (value == VIRTUAL_CFA_REGNUM)
  422. fprintf (outfile, " %d virtual-cfa", value);
  423. else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
  424. fprintf (outfile, " %d virtual-preferred-stack-boundary",
  425. value);
  426. else
  427. fprintf (outfile, " %d virtual-reg-%d", value,
  428. value-FIRST_VIRTUAL_REGISTER);
  429. }
  430. else
  431. #endif
  432. if (flag_dump_unnumbered
  433. && (is_insn || NOTE_P (in_rtx)))
  434. fputc ('#', outfile);
  435. else
  436. fprintf (outfile, " %d", value);
  437. #ifndef GENERATOR_FILE
  438. if (REG_P (in_rtx) && REG_ATTRS (in_rtx))
  439. {
  440. fputs (" [", outfile);
  441. if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
  442. fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
  443. if (REG_EXPR (in_rtx))
  444. print_mem_expr (outfile, REG_EXPR (in_rtx));
  445. if (REG_OFFSET (in_rtx))
  446. fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
  447. REG_OFFSET (in_rtx));
  448. fputs (" ]", outfile);
  449. }
  450. if (REG_P (in_rtx) && REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
  451. fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
  452. #endif
  453. if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
  454. && XINT (in_rtx, i) >= 0
  455. && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
  456. fprintf (outfile, " {%s}", name);
  457. sawclose = 0;
  458. }
  459. break;
  460. /* Print NOTE_INSN names rather than integer codes. */
  461. case 'n':
  462. fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
  463. sawclose = 0;
  464. break;
  465. case 'u':
  466. if (XEXP (in_rtx, i) != NULL)
  467. {
  468. rtx sub = XEXP (in_rtx, i);
  469. enum rtx_code subc = GET_CODE (sub);
  470. if (GET_CODE (in_rtx) == LABEL_REF)
  471. {
  472. if (subc == NOTE
  473. && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
  474. {
  475. if (flag_dump_unnumbered)
  476. fprintf (outfile, " [# deleted]");
  477. else
  478. fprintf (outfile, " [%d deleted]", INSN_UID (sub));
  479. sawclose = 0;
  480. break;
  481. }
  482. if (subc != CODE_LABEL)
  483. goto do_e;
  484. }
  485. if (flag_dump_unnumbered
  486. || (flag_dump_unnumbered_links && (i == 1 || i == 2)
  487. && (INSN_P (in_rtx) || NOTE_P (in_rtx)
  488. || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
  489. fputs (" #", outfile);
  490. else
  491. fprintf (outfile, " %d", INSN_UID (sub));
  492. }
  493. else
  494. fputs (" 0", outfile);
  495. sawclose = 0;
  496. break;
  497. case 't':
  498. #ifndef GENERATOR_FILE
  499. if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
  500. print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
  501. else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
  502. print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
  503. else
  504. dump_addr (outfile, " ", XTREE (in_rtx, i));
  505. #endif
  506. break;
  507. case '*':
  508. fputs (" Unknown", outfile);
  509. sawclose = 0;
  510. break;
  511. case 'B':
  512. #ifndef GENERATOR_FILE
  513. if (XBBDEF (in_rtx, i))
  514. fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index);
  515. #endif
  516. break;
  517. default:
  518. gcc_unreachable ();
  519. }
  520. switch (GET_CODE (in_rtx))
  521. {
  522. #ifndef GENERATOR_FILE
  523. case MEM:
  524. if (__builtin_expect (final_insns_dump_p, false))
  525. fprintf (outfile, " [");
  526. else
  527. fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC,
  528. (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
  529. if (MEM_EXPR (in_rtx))
  530. print_mem_expr (outfile, MEM_EXPR (in_rtx));
  531. else
  532. fputc (' ', outfile);
  533. if (MEM_OFFSET_KNOWN_P (in_rtx))
  534. fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
  535. if (MEM_SIZE_KNOWN_P (in_rtx))
  536. fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
  537. if (MEM_ALIGN (in_rtx) != 1)
  538. fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
  539. if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
  540. fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
  541. fputc (']', outfile);
  542. break;
  543. case CONST_DOUBLE:
  544. if (FLOAT_MODE_P (GET_MODE (in_rtx)))
  545. {
  546. char s[60];
  547. real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
  548. sizeof (s), 0, 1);
  549. fprintf (outfile, " %s", s);
  550. real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
  551. sizeof (s), 0, 1);
  552. fprintf (outfile, " [%s]", s);
  553. }
  554. break;
  555. case CONST_WIDE_INT:
  556. fprintf (outfile, " ");
  557. cwi_output_hex (outfile, in_rtx);
  558. break;
  559. #endif
  560. case CODE_LABEL:
  561. fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
  562. switch (LABEL_KIND (in_rtx))
  563. {
  564. case LABEL_NORMAL: break;
  565. case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break;
  566. case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break;
  567. case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break;
  568. default: gcc_unreachable ();
  569. }
  570. break;
  571. default:
  572. break;
  573. }
  574. fputc (')', outfile);
  575. sawclose = 1;
  576. }
  577. /* Print an rtx on the current line of FILE. Initially indent IND
  578. characters. */
  579. void
  580. print_inline_rtx (FILE *outf, const_rtx x, int ind)
  581. {
  582. int oldsaw = sawclose;
  583. int oldindent = indent;
  584. sawclose = 0;
  585. indent = ind;
  586. outfile = outf;
  587. print_rtx (x);
  588. sawclose = oldsaw;
  589. indent = oldindent;
  590. }
  591. /* Call this function from the debugger to see what X looks like. */
  592. DEBUG_FUNCTION void
  593. debug_rtx (const_rtx x)
  594. {
  595. outfile = stderr;
  596. sawclose = 0;
  597. print_rtx (x);
  598. fprintf (stderr, "\n");
  599. }
  600. /* Dump rtx REF. */
  601. DEBUG_FUNCTION void
  602. debug (const rtx_def &ref)
  603. {
  604. debug_rtx (&ref);
  605. }
  606. DEBUG_FUNCTION void
  607. debug (const rtx_def *ptr)
  608. {
  609. if (ptr)
  610. debug (*ptr);
  611. else
  612. fprintf (stderr, "<nil>\n");
  613. }
  614. /* Count of rtx's to print with debug_rtx_list.
  615. This global exists because gdb user defined commands have no arguments. */
  616. DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
  617. /* Call this function to print list from X on.
  618. N is a count of the rtx's to print. Positive values print from the specified
  619. rtx_insn on. Negative values print a window around the rtx_insn.
  620. EG: -5 prints 2 rtx_insn's on either side (in addition to the specified
  621. rtx_insn). */
  622. DEBUG_FUNCTION void
  623. debug_rtx_list (const rtx_insn *x, int n)
  624. {
  625. int i,count;
  626. const rtx_insn *insn;
  627. count = n == 0 ? 1 : n < 0 ? -n : n;
  628. /* If we are printing a window, back up to the start. */
  629. if (n < 0)
  630. for (i = count / 2; i > 0; i--)
  631. {
  632. if (PREV_INSN (x) == 0)
  633. break;
  634. x = PREV_INSN (x);
  635. }
  636. for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
  637. {
  638. debug_rtx (insn);
  639. fprintf (stderr, "\n");
  640. }
  641. }
  642. /* Call this function to print an rtx_insn list from START to END
  643. inclusive. */
  644. DEBUG_FUNCTION void
  645. debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
  646. {
  647. while (1)
  648. {
  649. debug_rtx (start);
  650. fprintf (stderr, "\n");
  651. if (!start || start == end)
  652. break;
  653. start = NEXT_INSN (start);
  654. }
  655. }
  656. /* Call this function to search an rtx_insn list to find one with insn uid UID,
  657. and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
  658. The found insn is returned to enable further debugging analysis. */
  659. DEBUG_FUNCTION const_rtx
  660. debug_rtx_find (const rtx_insn *x, int uid)
  661. {
  662. while (x != 0 && INSN_UID (x) != uid)
  663. x = NEXT_INSN (x);
  664. if (x != 0)
  665. {
  666. debug_rtx_list (x, debug_rtx_count);
  667. return x;
  668. }
  669. else
  670. {
  671. fprintf (stderr, "insn uid %d not found\n", uid);
  672. return 0;
  673. }
  674. }
  675. /* External entry point for printing a chain of insns
  676. starting with RTX_FIRST onto file OUTF.
  677. A blank line separates insns.
  678. If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
  679. void
  680. print_rtl (FILE *outf, const_rtx rtx_first)
  681. {
  682. const rtx_insn *tmp_rtx;
  683. outfile = outf;
  684. sawclose = 0;
  685. if (rtx_first == 0)
  686. {
  687. fputs (print_rtx_head, outf);
  688. fputs ("(nil)\n", outf);
  689. }
  690. else
  691. switch (GET_CODE (rtx_first))
  692. {
  693. case INSN:
  694. case JUMP_INSN:
  695. case CALL_INSN:
  696. case NOTE:
  697. case CODE_LABEL:
  698. case JUMP_TABLE_DATA:
  699. case BARRIER:
  700. for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
  701. tmp_rtx != 0;
  702. tmp_rtx = NEXT_INSN (tmp_rtx))
  703. {
  704. fputs (print_rtx_head, outfile);
  705. print_rtx (tmp_rtx);
  706. fprintf (outfile, "\n");
  707. }
  708. break;
  709. default:
  710. fputs (print_rtx_head, outfile);
  711. print_rtx (rtx_first);
  712. }
  713. }
  714. /* Like print_rtx, except specify a file. */
  715. /* Return nonzero if we actually printed anything. */
  716. int
  717. print_rtl_single (FILE *outf, const_rtx x)
  718. {
  719. return print_rtl_single_with_indent (outf, x, 0);
  720. }
  721. /* Like print_rtl_single, except specify a file and indentation. */
  722. int
  723. print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind)
  724. {
  725. int old_indent = indent;
  726. char *s_indent = (char *) alloca ((size_t) ind + 1);
  727. memset ((void *) s_indent, ' ', (size_t) ind);
  728. s_indent[ind] = '\0';
  729. indent = ind;
  730. outfile = outf;
  731. sawclose = 0;
  732. fputs (s_indent, outfile);
  733. fputs (print_rtx_head, outfile);
  734. print_rtx (x);
  735. putc ('\n', outf);
  736. indent = old_indent;
  737. return 1;
  738. }
  739. /* Like print_rtl except without all the detail; for example,
  740. if RTX is a CONST_INT then print in decimal format. */
  741. void
  742. print_simple_rtl (FILE *outf, const_rtx x)
  743. {
  744. flag_simple = 1;
  745. print_rtl (outf, x);
  746. flag_simple = 0;
  747. }