print-rtl.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157
  1. /* Print RTL for GCC.
  2. Copyright (C) 1987-2020 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 "alias.h"
  30. #include "tree.h"
  31. #include "basic-block.h"
  32. #include "print-tree.h"
  33. #include "flags.h"
  34. #include "predict.h"
  35. #include "function.h"
  36. #include "cfg.h"
  37. #include "basic-block.h"
  38. #include "diagnostic.h"
  39. #include "tree-pretty-print.h"
  40. #include "alloc-pool.h"
  41. #include "cselib.h"
  42. #include "dumpfile.h" /* for dump_flags */
  43. #include "dwarf2out.h"
  44. #include "pretty-print.h"
  45. #endif
  46. #include "print-rtl.h"
  47. #include "rtl-iter.h"
  48. /* Disable warnings about quoting issues in the pp_xxx calls below
  49. that (intentionally) don't follow GCC diagnostic conventions. */
  50. #if __GNUC__ >= 10
  51. # pragma GCC diagnostic push
  52. # pragma GCC diagnostic ignored "-Wformat-diag"
  53. #endif
  54. /* String printed at beginning of each RTL when it is dumped.
  55. This string is set to ASM_COMMENT_START when the RTL is dumped in
  56. the assembly output file. */
  57. const char *print_rtx_head = "";
  58. #ifdef GENERATOR_FILE
  59. /* These are defined from the .opt file when not used in generator
  60. programs. */
  61. /* Nonzero means suppress output of instruction numbers
  62. in debugging dumps.
  63. This must be defined here so that programs like gencodes can be linked. */
  64. int flag_dump_unnumbered = 0;
  65. /* Nonzero means suppress output of instruction numbers for previous
  66. and next insns in debugging dumps.
  67. This must be defined here so that programs like gencodes can be linked. */
  68. int flag_dump_unnumbered_links = 0;
  69. #endif
  70. /* Constructor for rtx_writer. */
  71. rtx_writer::rtx_writer (FILE *outf, int ind, bool simple, bool compact,
  72. rtx_reuse_manager *reuse_manager)
  73. : m_outfile (outf), m_sawclose (0), m_indent (ind),
  74. m_in_call_function_usage (false), m_simple (simple), m_compact (compact),
  75. m_rtx_reuse_manager (reuse_manager)
  76. {
  77. }
  78. #ifndef GENERATOR_FILE
  79. /* rtx_reuse_manager's ctor. */
  80. rtx_reuse_manager::rtx_reuse_manager ()
  81. : m_next_id (0)
  82. {
  83. }
  84. /* Determine if X is of a kind suitable for dumping via reuse_rtx. */
  85. static bool
  86. uses_rtx_reuse_p (const_rtx x)
  87. {
  88. if (x == NULL)
  89. return false;
  90. switch (GET_CODE (x))
  91. {
  92. case DEBUG_EXPR:
  93. case VALUE:
  94. case SCRATCH:
  95. return true;
  96. /* We don't use reuse_rtx for consts. */
  97. CASE_CONST_UNIQUE:
  98. default:
  99. return false;
  100. }
  101. }
  102. /* Traverse X and its descendents, determining if we see any rtx more than
  103. once. Any rtx suitable for "reuse_rtx" that is seen more than once is
  104. assigned an ID. */
  105. void
  106. rtx_reuse_manager::preprocess (const_rtx x)
  107. {
  108. subrtx_iterator::array_type array;
  109. FOR_EACH_SUBRTX (iter, array, x, NONCONST)
  110. if (uses_rtx_reuse_p (*iter))
  111. {
  112. if (int *count = m_rtx_occurrence_count.get (*iter))
  113. {
  114. if (*(count++) == 1)
  115. m_rtx_reuse_ids.put (*iter, m_next_id++);
  116. }
  117. else
  118. m_rtx_occurrence_count.put (*iter, 1);
  119. }
  120. }
  121. /* Return true iff X has been assigned a reuse ID. If it has,
  122. and OUT is non-NULL, then write the reuse ID to *OUT. */
  123. bool
  124. rtx_reuse_manager::has_reuse_id (const_rtx x, int *out)
  125. {
  126. int *id = m_rtx_reuse_ids.get (x);
  127. if (id)
  128. {
  129. if (out)
  130. *out = *id;
  131. return true;
  132. }
  133. else
  134. return false;
  135. }
  136. /* Determine if set_seen_def has been called for the given reuse ID. */
  137. bool
  138. rtx_reuse_manager::seen_def_p (int reuse_id)
  139. {
  140. return bitmap_bit_p (m_defs_seen, reuse_id);
  141. }
  142. /* Record that the definition of the given reuse ID has been seen. */
  143. void
  144. rtx_reuse_manager::set_seen_def (int reuse_id)
  145. {
  146. bitmap_set_bit (m_defs_seen, reuse_id);
  147. }
  148. #endif /* #ifndef GENERATOR_FILE */
  149. #ifndef GENERATOR_FILE
  150. void
  151. print_mem_expr (FILE *outfile, const_tree expr)
  152. {
  153. fputc (' ', outfile);
  154. print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
  155. }
  156. #endif
  157. /* Print X to FILE. */
  158. static void
  159. print_poly_int (FILE *file, poly_int64 x)
  160. {
  161. HOST_WIDE_INT const_x;
  162. if (x.is_constant (&const_x))
  163. fprintf (file, HOST_WIDE_INT_PRINT_DEC, const_x);
  164. else
  165. {
  166. fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC, x.coeffs[0]);
  167. for (int i = 1; i < NUM_POLY_INT_COEFFS; ++i)
  168. fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC, x.coeffs[i]);
  169. fprintf (file, "]");
  170. }
  171. }
  172. /* Subroutine of print_rtx_operand for handling code '0'.
  173. 0 indicates a field for internal use that should not be printed.
  174. However there are various special cases, such as the third field
  175. of a NOTE, where it indicates that the field has several different
  176. valid contents. */
  177. void
  178. rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED,
  179. int idx ATTRIBUTE_UNUSED)
  180. {
  181. #ifndef GENERATOR_FILE
  182. if (idx == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
  183. {
  184. int flags = SYMBOL_REF_FLAGS (in_rtx);
  185. if (flags)
  186. fprintf (m_outfile, " [flags %#x]", flags);
  187. tree decl = SYMBOL_REF_DECL (in_rtx);
  188. if (decl)
  189. print_node_brief (m_outfile, "", decl, dump_flags);
  190. }
  191. else if (idx == 3 && NOTE_P (in_rtx))
  192. {
  193. switch (NOTE_KIND (in_rtx))
  194. {
  195. case NOTE_INSN_EH_REGION_BEG:
  196. case NOTE_INSN_EH_REGION_END:
  197. if (flag_dump_unnumbered)
  198. fprintf (m_outfile, " #");
  199. else
  200. fprintf (m_outfile, " %d", NOTE_EH_HANDLER (in_rtx));
  201. m_sawclose = 1;
  202. break;
  203. case NOTE_INSN_BLOCK_BEG:
  204. case NOTE_INSN_BLOCK_END:
  205. dump_addr (m_outfile, " ", NOTE_BLOCK (in_rtx));
  206. m_sawclose = 1;
  207. break;
  208. case NOTE_INSN_BASIC_BLOCK:
  209. {
  210. basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
  211. if (bb != 0)
  212. fprintf (m_outfile, " [bb %d]", bb->index);
  213. break;
  214. }
  215. case NOTE_INSN_DELETED_LABEL:
  216. case NOTE_INSN_DELETED_DEBUG_LABEL:
  217. {
  218. const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
  219. if (label)
  220. fprintf (m_outfile, " (\"%s\")", label);
  221. else
  222. fprintf (m_outfile, " \"\"");
  223. }
  224. break;
  225. case NOTE_INSN_SWITCH_TEXT_SECTIONS:
  226. {
  227. basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
  228. if (bb != 0)
  229. fprintf (m_outfile, " [bb %d]", bb->index);
  230. break;
  231. }
  232. case NOTE_INSN_VAR_LOCATION:
  233. fputc (' ', m_outfile);
  234. print_rtx (NOTE_VAR_LOCATION (in_rtx));
  235. break;
  236. case NOTE_INSN_CFI:
  237. fputc ('\n', m_outfile);
  238. output_cfi_directive (m_outfile, NOTE_CFI (in_rtx));
  239. fputc ('\t', m_outfile);
  240. break;
  241. case NOTE_INSN_BEGIN_STMT:
  242. case NOTE_INSN_INLINE_ENTRY:
  243. #ifndef GENERATOR_FILE
  244. {
  245. expanded_location xloc
  246. = expand_location (NOTE_MARKER_LOCATION (in_rtx));
  247. fprintf (m_outfile, " %s:%i", xloc.file, xloc.line);
  248. }
  249. #endif
  250. break;
  251. default:
  252. break;
  253. }
  254. }
  255. else if (idx == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL
  256. && !m_compact)
  257. {
  258. /* Output the JUMP_LABEL reference. */
  259. fprintf (m_outfile, "\n%s%*s -> ", print_rtx_head, m_indent * 2, "");
  260. if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
  261. fprintf (m_outfile, "return");
  262. else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
  263. fprintf (m_outfile, "simple_return");
  264. else
  265. fprintf (m_outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
  266. }
  267. else if (idx == 0 && GET_CODE (in_rtx) == VALUE)
  268. {
  269. cselib_val *val = CSELIB_VAL_PTR (in_rtx);
  270. fprintf (m_outfile, " %u:%u", val->uid, val->hash);
  271. dump_addr (m_outfile, " @", in_rtx);
  272. dump_addr (m_outfile, "/", (void*)val);
  273. }
  274. else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
  275. {
  276. fprintf (m_outfile, " D#%i",
  277. DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
  278. }
  279. else if (idx == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
  280. {
  281. m_indent += 2;
  282. if (!m_sawclose)
  283. fprintf (m_outfile, " ");
  284. print_rtx (ENTRY_VALUE_EXP (in_rtx));
  285. m_indent -= 2;
  286. }
  287. #endif
  288. }
  289. /* Subroutine of print_rtx_operand for handling code 'e'.
  290. Also called by print_rtx_operand_code_u for handling code 'u'
  291. for LABEL_REFs when they don't reference a CODE_LABEL. */
  292. void
  293. rtx_writer::print_rtx_operand_code_e (const_rtx in_rtx, int idx)
  294. {
  295. m_indent += 2;
  296. if (idx == 6 && INSN_P (in_rtx))
  297. /* Put REG_NOTES on their own line. */
  298. fprintf (m_outfile, "\n%s%*s",
  299. print_rtx_head, m_indent * 2, "");
  300. if (!m_sawclose)
  301. fprintf (m_outfile, " ");
  302. if (idx == 7 && CALL_P (in_rtx))
  303. {
  304. m_in_call_function_usage = true;
  305. print_rtx (XEXP (in_rtx, idx));
  306. m_in_call_function_usage = false;
  307. }
  308. else
  309. print_rtx (XEXP (in_rtx, idx));
  310. m_indent -= 2;
  311. }
  312. /* Subroutine of print_rtx_operand for handling codes 'E' and 'V'. */
  313. void
  314. rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
  315. {
  316. m_indent += 2;
  317. if (m_sawclose)
  318. {
  319. fprintf (m_outfile, "\n%s%*s",
  320. print_rtx_head, m_indent * 2, "");
  321. m_sawclose = 0;
  322. }
  323. fputs (" [", m_outfile);
  324. if (XVEC (in_rtx, idx) != NULL)
  325. {
  326. m_indent += 2;
  327. if (XVECLEN (in_rtx, idx))
  328. m_sawclose = 1;
  329. for (int j = 0; j < XVECLEN (in_rtx, idx); j++)
  330. {
  331. int j1;
  332. print_rtx (XVECEXP (in_rtx, idx, j));
  333. for (j1 = j + 1; j1 < XVECLEN (in_rtx, idx); j1++)
  334. if (XVECEXP (in_rtx, idx, j) != XVECEXP (in_rtx, idx, j1))
  335. break;
  336. if (j1 != j + 1)
  337. {
  338. fprintf (m_outfile, " repeated x%i", j1 - j);
  339. j = j1 - 1;
  340. }
  341. }
  342. m_indent -= 2;
  343. }
  344. if (m_sawclose)
  345. fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
  346. fputs ("]", m_outfile);
  347. m_sawclose = 1;
  348. m_indent -= 2;
  349. }
  350. /* Subroutine of print_rtx_operand for handling code 'i'. */
  351. void
  352. rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
  353. {
  354. if (idx == 4 && INSN_P (in_rtx))
  355. {
  356. #ifndef GENERATOR_FILE
  357. const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx);
  358. /* Pretty-print insn locations. Ignore scoping as it is mostly
  359. redundant with line number information and do not print anything
  360. when there is no location information available. */
  361. if (INSN_HAS_LOCATION (in_insn))
  362. {
  363. expanded_location xloc = insn_location (in_insn);
  364. fprintf (m_outfile, " \"%s\":%i:%i", xloc.file, xloc.line,
  365. xloc.column);
  366. }
  367. #endif
  368. }
  369. else if (idx == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
  370. {
  371. #ifndef GENERATOR_FILE
  372. if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
  373. fprintf (m_outfile, " %s:%i",
  374. LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
  375. LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  376. #endif
  377. }
  378. else if (idx == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  379. {
  380. #ifndef GENERATOR_FILE
  381. if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
  382. fprintf (m_outfile, " %s:%i",
  383. LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
  384. LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  385. #endif
  386. }
  387. else if (idx == 5 && NOTE_P (in_rtx))
  388. {
  389. /* This field is only used for NOTE_INSN_DELETED_LABEL, and
  390. other times often contains garbage from INSN->NOTE death. */
  391. if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
  392. || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
  393. fprintf (m_outfile, " %d", XINT (in_rtx, idx));
  394. }
  395. #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
  396. else if (idx == 1
  397. && GET_CODE (in_rtx) == UNSPEC_VOLATILE
  398. && XINT (in_rtx, 1) >= 0
  399. && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
  400. fprintf (m_outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
  401. #endif
  402. #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
  403. else if (idx == 1
  404. && (GET_CODE (in_rtx) == UNSPEC
  405. || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
  406. && XINT (in_rtx, 1) >= 0
  407. && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
  408. fprintf (m_outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
  409. #endif
  410. else
  411. {
  412. int value = XINT (in_rtx, idx);
  413. const char *name;
  414. int is_insn = INSN_P (in_rtx);
  415. /* Don't print INSN_CODEs in compact mode. */
  416. if (m_compact && is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx))
  417. {
  418. m_sawclose = 0;
  419. return;
  420. }
  421. if (flag_dump_unnumbered
  422. && (is_insn || NOTE_P (in_rtx)))
  423. fputc ('#', m_outfile);
  424. else
  425. fprintf (m_outfile, " %d", value);
  426. if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx)
  427. && XINT (in_rtx, idx) >= 0
  428. && (name = get_insn_name (XINT (in_rtx, idx))) != NULL)
  429. fprintf (m_outfile, " {%s}", name);
  430. m_sawclose = 0;
  431. }
  432. }
  433. /* Subroutine of print_rtx_operand for handling code 'r'. */
  434. void
  435. rtx_writer::print_rtx_operand_code_r (const_rtx in_rtx)
  436. {
  437. int is_insn = INSN_P (in_rtx);
  438. unsigned int regno = REGNO (in_rtx);
  439. #ifndef GENERATOR_FILE
  440. /* For hard registers and virtuals, always print the
  441. regno, except in compact mode. */
  442. if (regno <= LAST_VIRTUAL_REGISTER && !m_compact)
  443. fprintf (m_outfile, " %d", regno);
  444. if (regno < FIRST_PSEUDO_REGISTER)
  445. fprintf (m_outfile, " %s", reg_names[regno]);
  446. else if (regno <= LAST_VIRTUAL_REGISTER)
  447. {
  448. if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
  449. fprintf (m_outfile, " virtual-incoming-args");
  450. else if (regno == VIRTUAL_STACK_VARS_REGNUM)
  451. fprintf (m_outfile, " virtual-stack-vars");
  452. else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
  453. fprintf (m_outfile, " virtual-stack-dynamic");
  454. else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
  455. fprintf (m_outfile, " virtual-outgoing-args");
  456. else if (regno == VIRTUAL_CFA_REGNUM)
  457. fprintf (m_outfile, " virtual-cfa");
  458. else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
  459. fprintf (m_outfile, " virtual-preferred-stack-boundary");
  460. else
  461. fprintf (m_outfile, " virtual-reg-%d", regno-FIRST_VIRTUAL_REGISTER);
  462. }
  463. else
  464. #endif
  465. if (flag_dump_unnumbered && is_insn)
  466. fputc ('#', m_outfile);
  467. else if (m_compact)
  468. {
  469. /* In compact mode, print pseudos with '< and '>' wrapping the regno,
  470. offseting it by (LAST_VIRTUAL_REGISTER + 1), so that the
  471. first non-virtual pseudo is dumped as "<0>". */
  472. gcc_assert (regno > LAST_VIRTUAL_REGISTER);
  473. fprintf (m_outfile, " <%d>", regno - (LAST_VIRTUAL_REGISTER + 1));
  474. }
  475. else
  476. fprintf (m_outfile, " %d", regno);
  477. #ifndef GENERATOR_FILE
  478. if (REG_ATTRS (in_rtx))
  479. {
  480. fputs (" [", m_outfile);
  481. if (regno != ORIGINAL_REGNO (in_rtx))
  482. fprintf (m_outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
  483. if (REG_EXPR (in_rtx))
  484. print_mem_expr (m_outfile, REG_EXPR (in_rtx));
  485. if (maybe_ne (REG_OFFSET (in_rtx), 0))
  486. {
  487. fprintf (m_outfile, "+");
  488. print_poly_int (m_outfile, REG_OFFSET (in_rtx));
  489. }
  490. fputs (" ]", m_outfile);
  491. }
  492. if (regno != ORIGINAL_REGNO (in_rtx))
  493. fprintf (m_outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
  494. #endif
  495. }
  496. /* Subroutine of print_rtx_operand for handling code 'u'. */
  497. void
  498. rtx_writer::print_rtx_operand_code_u (const_rtx in_rtx, int idx)
  499. {
  500. /* Don't print insn UIDs for PREV/NEXT_INSN in compact mode. */
  501. if (m_compact && INSN_CHAIN_CODE_P (GET_CODE (in_rtx)) && idx < 2)
  502. return;
  503. if (XEXP (in_rtx, idx) != NULL)
  504. {
  505. rtx sub = XEXP (in_rtx, idx);
  506. enum rtx_code subc = GET_CODE (sub);
  507. if (GET_CODE (in_rtx) == LABEL_REF)
  508. {
  509. if (subc == NOTE
  510. && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
  511. {
  512. if (flag_dump_unnumbered)
  513. fprintf (m_outfile, " [# deleted]");
  514. else
  515. fprintf (m_outfile, " [%d deleted]", INSN_UID (sub));
  516. m_sawclose = 0;
  517. return;
  518. }
  519. if (subc != CODE_LABEL)
  520. {
  521. print_rtx_operand_code_e (in_rtx, idx);
  522. return;
  523. }
  524. }
  525. if (flag_dump_unnumbered
  526. || (flag_dump_unnumbered_links && idx <= 1
  527. && (INSN_P (in_rtx) || NOTE_P (in_rtx)
  528. || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
  529. fputs (" #", m_outfile);
  530. else
  531. fprintf (m_outfile, " %d", INSN_UID (sub));
  532. }
  533. else
  534. fputs (" 0", m_outfile);
  535. m_sawclose = 0;
  536. }
  537. /* Subroutine of print_rtx. Print operand IDX of IN_RTX. */
  538. void
  539. rtx_writer::print_rtx_operand (const_rtx in_rtx, int idx)
  540. {
  541. const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
  542. switch (format_ptr[idx])
  543. {
  544. const char *str;
  545. case 'T':
  546. str = XTMPL (in_rtx, idx);
  547. goto string;
  548. case 'S':
  549. case 's':
  550. str = XSTR (in_rtx, idx);
  551. string:
  552. if (str == 0)
  553. fputs (" (nil)", m_outfile);
  554. else
  555. fprintf (m_outfile, " (\"%s\")", str);
  556. m_sawclose = 1;
  557. break;
  558. case '0':
  559. print_rtx_operand_code_0 (in_rtx, idx);
  560. break;
  561. case 'e':
  562. print_rtx_operand_code_e (in_rtx, idx);
  563. break;
  564. case 'E':
  565. case 'V':
  566. print_rtx_operand_codes_E_and_V (in_rtx, idx);
  567. break;
  568. case 'w':
  569. if (! m_simple)
  570. fprintf (m_outfile, " ");
  571. fprintf (m_outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, idx));
  572. if (! m_simple && !m_compact)
  573. fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
  574. (unsigned HOST_WIDE_INT) XWINT (in_rtx, idx));
  575. break;
  576. case 'i':
  577. print_rtx_operand_code_i (in_rtx, idx);
  578. break;
  579. case 'p':
  580. fprintf (m_outfile, " ");
  581. print_poly_int (m_outfile, SUBREG_BYTE (in_rtx));
  582. break;
  583. case 'r':
  584. print_rtx_operand_code_r (in_rtx);
  585. break;
  586. /* Print NOTE_INSN names rather than integer codes. */
  587. case 'n':
  588. fprintf (m_outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, idx)));
  589. m_sawclose = 0;
  590. break;
  591. case 'u':
  592. print_rtx_operand_code_u (in_rtx, idx);
  593. break;
  594. case 't':
  595. #ifndef GENERATOR_FILE
  596. if (idx == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
  597. print_mem_expr (m_outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
  598. else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
  599. print_mem_expr (m_outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
  600. else
  601. dump_addr (m_outfile, " ", XTREE (in_rtx, idx));
  602. #endif
  603. break;
  604. case '*':
  605. fputs (" Unknown", m_outfile);
  606. m_sawclose = 0;
  607. break;
  608. case 'B':
  609. /* Don't print basic block ids in compact mode. */
  610. if (m_compact)
  611. break;
  612. #ifndef GENERATOR_FILE
  613. if (XBBDEF (in_rtx, idx))
  614. fprintf (m_outfile, " %i", XBBDEF (in_rtx, idx)->index);
  615. #endif
  616. break;
  617. default:
  618. gcc_unreachable ();
  619. }
  620. }
  621. /* Subroutine of rtx_writer::print_rtx.
  622. In compact mode, determine if operand IDX of IN_RTX is interesting
  623. to dump, or (if in a trailing position) it can be omitted. */
  624. bool
  625. rtx_writer::operand_has_default_value_p (const_rtx in_rtx, int idx)
  626. {
  627. const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
  628. switch (format_ptr[idx])
  629. {
  630. case 'e':
  631. case 'u':
  632. return XEXP (in_rtx, idx) == NULL_RTX;
  633. case 's':
  634. return XSTR (in_rtx, idx) == NULL;
  635. case '0':
  636. switch (GET_CODE (in_rtx))
  637. {
  638. case JUMP_INSN:
  639. /* JUMP_LABELs are always omitted in compact mode, so treat
  640. any value here as omittable, so that earlier operands can
  641. potentially be omitted also. */
  642. return m_compact;
  643. default:
  644. return false;
  645. }
  646. default:
  647. return false;
  648. }
  649. }
  650. /* Print IN_RTX onto m_outfile. This is the recursive part of printing. */
  651. void
  652. rtx_writer::print_rtx (const_rtx in_rtx)
  653. {
  654. int idx = 0;
  655. if (m_sawclose)
  656. {
  657. if (m_simple)
  658. fputc (' ', m_outfile);
  659. else
  660. fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
  661. m_sawclose = 0;
  662. }
  663. if (in_rtx == 0)
  664. {
  665. fputs ("(nil)", m_outfile);
  666. m_sawclose = 1;
  667. return;
  668. }
  669. else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
  670. {
  671. fprintf (m_outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx),
  672. print_rtx_head, m_indent * 2, "");
  673. m_sawclose = 1;
  674. return;
  675. }
  676. fputc ('(', m_outfile);
  677. /* Print name of expression code. */
  678. /* Handle reuse. */
  679. #ifndef GENERATOR_FILE
  680. if (m_rtx_reuse_manager)
  681. {
  682. int reuse_id;
  683. if (m_rtx_reuse_manager->has_reuse_id (in_rtx, &reuse_id))
  684. {
  685. /* Have we already seen the defn of this rtx? */
  686. if (m_rtx_reuse_manager->seen_def_p (reuse_id))
  687. {
  688. fprintf (m_outfile, "reuse_rtx %i)", reuse_id);
  689. m_sawclose = 1;
  690. return;
  691. }
  692. else
  693. {
  694. /* First time we've seen this reused-rtx. */
  695. fprintf (m_outfile, "%i|", reuse_id);
  696. m_rtx_reuse_manager->set_seen_def (reuse_id);
  697. }
  698. }
  699. }
  700. #endif /* #ifndef GENERATOR_FILE */
  701. /* In compact mode, prefix the code of insns with "c",
  702. giving "cinsn", "cnote" etc. */
  703. if (m_compact && is_a <const rtx_insn *, const struct rtx_def> (in_rtx))
  704. {
  705. /* "ccode_label" is slightly awkward, so special-case it as
  706. just "clabel". */
  707. rtx_code code = GET_CODE (in_rtx);
  708. if (code == CODE_LABEL)
  709. fprintf (m_outfile, "clabel");
  710. else
  711. fprintf (m_outfile, "c%s", GET_RTX_NAME (code));
  712. }
  713. else if (m_simple && CONST_INT_P (in_rtx))
  714. ; /* no code. */
  715. else
  716. fprintf (m_outfile, "%s", GET_RTX_NAME (GET_CODE (in_rtx)));
  717. if (! m_simple)
  718. {
  719. if (RTX_FLAG (in_rtx, in_struct))
  720. fputs ("/s", m_outfile);
  721. if (RTX_FLAG (in_rtx, volatil))
  722. fputs ("/v", m_outfile);
  723. if (RTX_FLAG (in_rtx, unchanging))
  724. fputs ("/u", m_outfile);
  725. if (RTX_FLAG (in_rtx, frame_related))
  726. fputs ("/f", m_outfile);
  727. if (RTX_FLAG (in_rtx, jump))
  728. fputs ("/j", m_outfile);
  729. if (RTX_FLAG (in_rtx, call))
  730. fputs ("/c", m_outfile);
  731. if (RTX_FLAG (in_rtx, return_val))
  732. fputs ("/i", m_outfile);
  733. /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */
  734. if ((GET_CODE (in_rtx) == EXPR_LIST
  735. || GET_CODE (in_rtx) == INSN_LIST
  736. || GET_CODE (in_rtx) == INT_LIST)
  737. && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
  738. && !m_in_call_function_usage)
  739. fprintf (m_outfile, ":%s",
  740. GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
  741. /* For other rtl, print the mode if it's not VOID. */
  742. else if (GET_MODE (in_rtx) != VOIDmode)
  743. fprintf (m_outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
  744. #ifndef GENERATOR_FILE
  745. if (GET_CODE (in_rtx) == VAR_LOCATION)
  746. {
  747. if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
  748. fputs (" <debug string placeholder>", m_outfile);
  749. else
  750. print_mem_expr (m_outfile, PAT_VAR_LOCATION_DECL (in_rtx));
  751. fputc (' ', m_outfile);
  752. print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
  753. if (PAT_VAR_LOCATION_STATUS (in_rtx)
  754. == VAR_INIT_STATUS_UNINITIALIZED)
  755. fprintf (m_outfile, " [uninit]");
  756. m_sawclose = 1;
  757. idx = GET_RTX_LENGTH (VAR_LOCATION);
  758. }
  759. #endif
  760. }
  761. #ifndef GENERATOR_FILE
  762. if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
  763. idx = 5;
  764. #endif
  765. /* For insns, print the INSN_UID. */
  766. if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
  767. {
  768. if (flag_dump_unnumbered)
  769. fprintf (m_outfile, " #");
  770. else
  771. fprintf (m_outfile, " %d", INSN_UID (in_rtx));
  772. }
  773. /* Determine which is the final operand to print.
  774. In compact mode, skip trailing operands that have the default values
  775. e.g. trailing "(nil)" values. */
  776. int limit = GET_RTX_LENGTH (GET_CODE (in_rtx));
  777. if (m_compact)
  778. while (limit > idx && operand_has_default_value_p (in_rtx, limit - 1))
  779. limit--;
  780. /* Get the format string and skip the first elements if we have handled
  781. them already. */
  782. for (; idx < limit; idx++)
  783. print_rtx_operand (in_rtx, idx);
  784. switch (GET_CODE (in_rtx))
  785. {
  786. #ifndef GENERATOR_FILE
  787. case MEM:
  788. if (__builtin_expect (final_insns_dump_p, false))
  789. fprintf (m_outfile, " [");
  790. else
  791. fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_DEC,
  792. (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
  793. if (MEM_EXPR (in_rtx))
  794. print_mem_expr (m_outfile, MEM_EXPR (in_rtx));
  795. else
  796. fputc (' ', m_outfile);
  797. if (MEM_OFFSET_KNOWN_P (in_rtx))
  798. {
  799. fprintf (m_outfile, "+");
  800. print_poly_int (m_outfile, MEM_OFFSET (in_rtx));
  801. }
  802. if (MEM_SIZE_KNOWN_P (in_rtx))
  803. {
  804. fprintf (m_outfile, " S");
  805. print_poly_int (m_outfile, MEM_SIZE (in_rtx));
  806. }
  807. if (MEM_ALIGN (in_rtx) != 1)
  808. fprintf (m_outfile, " A%u", MEM_ALIGN (in_rtx));
  809. if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
  810. fprintf (m_outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
  811. fputc (']', m_outfile);
  812. break;
  813. case CONST_DOUBLE:
  814. if (FLOAT_MODE_P (GET_MODE (in_rtx)))
  815. {
  816. char s[60];
  817. real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
  818. sizeof (s), 0, 1);
  819. fprintf (m_outfile, " %s", s);
  820. real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
  821. sizeof (s), 0, 1);
  822. fprintf (m_outfile, " [%s]", s);
  823. }
  824. break;
  825. case CONST_WIDE_INT:
  826. fprintf (m_outfile, " ");
  827. cwi_output_hex (m_outfile, in_rtx);
  828. break;
  829. case CONST_POLY_INT:
  830. fprintf (m_outfile, " [");
  831. print_dec (CONST_POLY_INT_COEFFS (in_rtx)[0], m_outfile, SIGNED);
  832. for (unsigned int i = 1; i < NUM_POLY_INT_COEFFS; ++i)
  833. {
  834. fprintf (m_outfile, ", ");
  835. print_dec (CONST_POLY_INT_COEFFS (in_rtx)[i], m_outfile, SIGNED);
  836. }
  837. fprintf (m_outfile, "]");
  838. break;
  839. #endif
  840. case CODE_LABEL:
  841. if (!m_compact)
  842. fprintf (m_outfile, " [%d uses]", LABEL_NUSES (in_rtx));
  843. switch (LABEL_KIND (in_rtx))
  844. {
  845. case LABEL_NORMAL: break;
  846. case LABEL_STATIC_ENTRY: fputs (" [entry]", m_outfile); break;
  847. case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", m_outfile); break;
  848. case LABEL_WEAK_ENTRY: fputs (" [weak entry]", m_outfile); break;
  849. default: gcc_unreachable ();
  850. }
  851. break;
  852. default:
  853. break;
  854. }
  855. fputc (')', m_outfile);
  856. m_sawclose = 1;
  857. }
  858. /* Emit a closing parenthesis and newline. */
  859. void
  860. rtx_writer::finish_directive ()
  861. {
  862. fprintf (m_outfile, ")\n");
  863. m_sawclose = 0;
  864. }
  865. /* Print an rtx on the current line of FILE. Initially indent IND
  866. characters. */
  867. void
  868. print_inline_rtx (FILE *outf, const_rtx x, int ind)
  869. {
  870. rtx_writer w (outf, ind, false, false, NULL);
  871. w.print_rtx (x);
  872. }
  873. /* Call this function from the debugger to see what X looks like. */
  874. DEBUG_FUNCTION void
  875. debug_rtx (const_rtx x)
  876. {
  877. rtx_writer w (stderr, 0, false, false, NULL);
  878. w.print_rtx (x);
  879. fprintf (stderr, "\n");
  880. }
  881. /* Dump rtx REF. */
  882. DEBUG_FUNCTION void
  883. debug (const rtx_def &ref)
  884. {
  885. debug_rtx (&ref);
  886. }
  887. DEBUG_FUNCTION void
  888. debug (const rtx_def *ptr)
  889. {
  890. if (ptr)
  891. debug (*ptr);
  892. else
  893. fprintf (stderr, "<nil>\n");
  894. }
  895. /* Like debug_rtx but with no newline, as debug_helper will add one.
  896. Note: No debug_slim(rtx_insn *) variant implemented, as this
  897. function can serve for both rtx and rtx_insn. */
  898. static void
  899. debug_slim (const_rtx x)
  900. {
  901. rtx_writer w (stderr, 0, false, false, NULL);
  902. w.print_rtx (x);
  903. }
  904. DEFINE_DEBUG_VEC (rtx_def *)
  905. DEFINE_DEBUG_VEC (rtx_insn *)
  906. DEFINE_DEBUG_HASH_SET (rtx_def *)
  907. DEFINE_DEBUG_HASH_SET (rtx_insn *)
  908. /* Count of rtx's to print with debug_rtx_list.
  909. This global exists because gdb user defined commands have no arguments. */
  910. DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
  911. /* Call this function to print list from X on.
  912. N is a count of the rtx's to print. Positive values print from the specified
  913. rtx_insn on. Negative values print a window around the rtx_insn.
  914. EG: -5 prints 2 rtx_insn's on either side (in addition to the specified
  915. rtx_insn). */
  916. DEBUG_FUNCTION void
  917. debug_rtx_list (const rtx_insn *x, int n)
  918. {
  919. int i,count;
  920. const rtx_insn *insn;
  921. count = n == 0 ? 1 : n < 0 ? -n : n;
  922. /* If we are printing a window, back up to the start. */
  923. if (n < 0)
  924. for (i = count / 2; i > 0; i--)
  925. {
  926. if (PREV_INSN (x) == 0)
  927. break;
  928. x = PREV_INSN (x);
  929. }
  930. for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
  931. {
  932. debug_rtx (insn);
  933. fprintf (stderr, "\n");
  934. }
  935. }
  936. /* Call this function to print an rtx_insn list from START to END
  937. inclusive. */
  938. DEBUG_FUNCTION void
  939. debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
  940. {
  941. while (1)
  942. {
  943. debug_rtx (start);
  944. fprintf (stderr, "\n");
  945. if (!start || start == end)
  946. break;
  947. start = NEXT_INSN (start);
  948. }
  949. }
  950. /* Call this function to search an rtx_insn list to find one with insn uid UID,
  951. and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
  952. The found insn is returned to enable further debugging analysis. */
  953. DEBUG_FUNCTION const rtx_insn *
  954. debug_rtx_find (const rtx_insn *x, int uid)
  955. {
  956. while (x != 0 && INSN_UID (x) != uid)
  957. x = NEXT_INSN (x);
  958. if (x != 0)
  959. {
  960. debug_rtx_list (x, debug_rtx_count);
  961. return x;
  962. }
  963. else
  964. {
  965. fprintf (stderr, "insn uid %d not found\n", uid);
  966. return 0;
  967. }
  968. }
  969. /* External entry point for printing a chain of insns
  970. starting with RTX_FIRST.
  971. A blank line separates insns.
  972. If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
  973. void
  974. rtx_writer::print_rtl (const_rtx rtx_first)
  975. {
  976. const rtx_insn *tmp_rtx;
  977. if (rtx_first == 0)
  978. {
  979. fputs (print_rtx_head, m_outfile);
  980. fputs ("(nil)\n", m_outfile);
  981. }
  982. else
  983. switch (GET_CODE (rtx_first))
  984. {
  985. case INSN:
  986. case JUMP_INSN:
  987. case CALL_INSN:
  988. case NOTE:
  989. case CODE_LABEL:
  990. case JUMP_TABLE_DATA:
  991. case BARRIER:
  992. for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
  993. tmp_rtx != 0;
  994. tmp_rtx = NEXT_INSN (tmp_rtx))
  995. {
  996. fputs (print_rtx_head, m_outfile);
  997. print_rtx (tmp_rtx);
  998. fprintf (m_outfile, "\n");
  999. }
  1000. break;
  1001. default:
  1002. fputs (print_rtx_head, m_outfile);
  1003. print_rtx (rtx_first);
  1004. }
  1005. }
  1006. /* External entry point for printing a chain of insns
  1007. starting with RTX_FIRST onto file OUTF.
  1008. A blank line separates insns.
  1009. If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
  1010. void
  1011. print_rtl (FILE *outf, const_rtx rtx_first)
  1012. {
  1013. rtx_writer w (outf, 0, false, false, NULL);
  1014. w.print_rtl (rtx_first);
  1015. }
  1016. /* Like print_rtx, except specify a file. */
  1017. /* Return nonzero if we actually printed anything. */
  1018. int
  1019. print_rtl_single (FILE *outf, const_rtx x)
  1020. {
  1021. rtx_writer w (outf, 0, false, false, NULL);
  1022. return w.print_rtl_single_with_indent (x, 0);
  1023. }
  1024. /* Like print_rtl_single, except specify an indentation. */
  1025. int
  1026. rtx_writer::print_rtl_single_with_indent (const_rtx x, int ind)
  1027. {
  1028. char *s_indent = (char *) alloca ((size_t) ind + 1);
  1029. memset ((void *) s_indent, ' ', (size_t) ind);
  1030. s_indent[ind] = '\0';
  1031. fputs (s_indent, m_outfile);
  1032. fputs (print_rtx_head, m_outfile);
  1033. int old_indent = m_indent;
  1034. m_indent = ind;
  1035. m_sawclose = 0;
  1036. print_rtx (x);
  1037. putc ('\n', m_outfile);
  1038. m_indent = old_indent;
  1039. return 1;
  1040. }
  1041. /* Like print_rtl except without all the detail; for example,
  1042. if RTX is a CONST_INT then print in decimal format. */
  1043. void
  1044. print_simple_rtl (FILE *outf, const_rtx x)
  1045. {
  1046. rtx_writer w (outf, 0, true, false, NULL);
  1047. w.print_rtl (x);
  1048. }
  1049. /* Print the elements of VEC to FILE. */
  1050. void
  1051. print_rtx_insn_vec (FILE *file, const vec<rtx_insn *> &vec)
  1052. {
  1053. fputc('{', file);
  1054. unsigned int len = vec.length ();
  1055. for (unsigned int i = 0; i < len; i++)
  1056. {
  1057. print_rtl (file, vec[i]);
  1058. if (i < len - 1)
  1059. fputs (", ", file);
  1060. }
  1061. fputc ('}', file);
  1062. }
  1063. #ifndef GENERATOR_FILE
  1064. /* The functions below try to print RTL in a form resembling assembler
  1065. mnemonics. Because this form is more concise than the "traditional" form
  1066. of RTL printing in Lisp-style, the form printed by this file is called
  1067. "slim". RTL dumps in slim format can be obtained by appending the "-slim"
  1068. option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
  1069. always printed in slim form.
  1070. The normal interface to the functionality provided in this pretty-printer
  1071. is through the dump_*_slim functions to print to a stream, or via the
  1072. print_*_slim functions to print into a user's pretty-printer.
  1073. It is also possible to obtain a string for a single pattern as a string
  1074. pointer, via str_pattern_slim, but this usage is discouraged. */
  1075. /* For insns we print patterns, and for some patterns we print insns... */
  1076. static void print_insn_with_notes (pretty_printer *, const rtx_insn *);
  1077. /* This recognizes rtx'en classified as expressions. These are always
  1078. represent some action on values or results of other expression, that
  1079. may be stored in objects representing values. */
  1080. static void
  1081. print_exp (pretty_printer *pp, const_rtx x, int verbose)
  1082. {
  1083. const char *st[4];
  1084. const char *fun;
  1085. rtx op[4];
  1086. int i;
  1087. fun = (char *) 0;
  1088. for (i = 0; i < 4; i++)
  1089. {
  1090. st[i] = (char *) 0;
  1091. op[i] = NULL_RTX;
  1092. }
  1093. switch (GET_CODE (x))
  1094. {
  1095. case PLUS:
  1096. op[0] = XEXP (x, 0);
  1097. if (CONST_INT_P (XEXP (x, 1))
  1098. && INTVAL (XEXP (x, 1)) < 0)
  1099. {
  1100. st[1] = "-";
  1101. op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
  1102. }
  1103. else
  1104. {
  1105. st[1] = "+";
  1106. op[1] = XEXP (x, 1);
  1107. }
  1108. break;
  1109. case LO_SUM:
  1110. op[0] = XEXP (x, 0);
  1111. st[1] = "+low(";
  1112. op[1] = XEXP (x, 1);
  1113. st[2] = ")";
  1114. break;
  1115. case MINUS:
  1116. op[0] = XEXP (x, 0);
  1117. st[1] = "-";
  1118. op[1] = XEXP (x, 1);
  1119. break;
  1120. case COMPARE:
  1121. fun = "cmp";
  1122. op[0] = XEXP (x, 0);
  1123. op[1] = XEXP (x, 1);
  1124. break;
  1125. case NEG:
  1126. st[0] = "-";
  1127. op[0] = XEXP (x, 0);
  1128. break;
  1129. case FMA:
  1130. st[0] = "{";
  1131. op[0] = XEXP (x, 0);
  1132. st[1] = "*";
  1133. op[1] = XEXP (x, 1);
  1134. st[2] = "+";
  1135. op[2] = XEXP (x, 2);
  1136. st[3] = "}";
  1137. break;
  1138. case MULT:
  1139. op[0] = XEXP (x, 0);
  1140. st[1] = "*";
  1141. op[1] = XEXP (x, 1);
  1142. break;
  1143. case DIV:
  1144. op[0] = XEXP (x, 0);
  1145. st[1] = "/";
  1146. op[1] = XEXP (x, 1);
  1147. break;
  1148. case UDIV:
  1149. fun = "udiv";
  1150. op[0] = XEXP (x, 0);
  1151. op[1] = XEXP (x, 1);
  1152. break;
  1153. case MOD:
  1154. op[0] = XEXP (x, 0);
  1155. st[1] = "%";
  1156. op[1] = XEXP (x, 1);
  1157. break;
  1158. case UMOD:
  1159. fun = "umod";
  1160. op[0] = XEXP (x, 0);
  1161. op[1] = XEXP (x, 1);
  1162. break;
  1163. case SMIN:
  1164. fun = "smin";
  1165. op[0] = XEXP (x, 0);
  1166. op[1] = XEXP (x, 1);
  1167. break;
  1168. case SMAX:
  1169. fun = "smax";
  1170. op[0] = XEXP (x, 0);
  1171. op[1] = XEXP (x, 1);
  1172. break;
  1173. case UMIN:
  1174. fun = "umin";
  1175. op[0] = XEXP (x, 0);
  1176. op[1] = XEXP (x, 1);
  1177. break;
  1178. case UMAX:
  1179. fun = "umax";
  1180. op[0] = XEXP (x, 0);
  1181. op[1] = XEXP (x, 1);
  1182. break;
  1183. case NOT:
  1184. st[0] = "~";
  1185. op[0] = XEXP (x, 0);
  1186. break;
  1187. case AND:
  1188. op[0] = XEXP (x, 0);
  1189. st[1] = "&";
  1190. op[1] = XEXP (x, 1);
  1191. break;
  1192. case IOR:
  1193. op[0] = XEXP (x, 0);
  1194. st[1] = "|";
  1195. op[1] = XEXP (x, 1);
  1196. break;
  1197. case XOR:
  1198. op[0] = XEXP (x, 0);
  1199. st[1] = "^";
  1200. op[1] = XEXP (x, 1);
  1201. break;
  1202. case ASHIFT:
  1203. op[0] = XEXP (x, 0);
  1204. st[1] = "<<";
  1205. op[1] = XEXP (x, 1);
  1206. break;
  1207. case LSHIFTRT:
  1208. op[0] = XEXP (x, 0);
  1209. st[1] = " 0>>";
  1210. op[1] = XEXP (x, 1);
  1211. break;
  1212. case ASHIFTRT:
  1213. op[0] = XEXP (x, 0);
  1214. st[1] = ">>";
  1215. op[1] = XEXP (x, 1);
  1216. break;
  1217. case ROTATE:
  1218. op[0] = XEXP (x, 0);
  1219. st[1] = "<-<";
  1220. op[1] = XEXP (x, 1);
  1221. break;
  1222. case ROTATERT:
  1223. op[0] = XEXP (x, 0);
  1224. st[1] = ">->";
  1225. op[1] = XEXP (x, 1);
  1226. break;
  1227. case NE:
  1228. op[0] = XEXP (x, 0);
  1229. st[1] = "!=";
  1230. op[1] = XEXP (x, 1);
  1231. break;
  1232. case EQ:
  1233. op[0] = XEXP (x, 0);
  1234. st[1] = "==";
  1235. op[1] = XEXP (x, 1);
  1236. break;
  1237. case GE:
  1238. op[0] = XEXP (x, 0);
  1239. st[1] = ">=";
  1240. op[1] = XEXP (x, 1);
  1241. break;
  1242. case GT:
  1243. op[0] = XEXP (x, 0);
  1244. st[1] = ">";
  1245. op[1] = XEXP (x, 1);
  1246. break;
  1247. case LE:
  1248. op[0] = XEXP (x, 0);
  1249. st[1] = "<=";
  1250. op[1] = XEXP (x, 1);
  1251. break;
  1252. case LT:
  1253. op[0] = XEXP (x, 0);
  1254. st[1] = "<";
  1255. op[1] = XEXP (x, 1);
  1256. break;
  1257. case SIGN_EXTRACT:
  1258. fun = (verbose) ? "sign_extract" : "sxt";
  1259. op[0] = XEXP (x, 0);
  1260. op[1] = XEXP (x, 1);
  1261. op[2] = XEXP (x, 2);
  1262. break;
  1263. case ZERO_EXTRACT:
  1264. fun = (verbose) ? "zero_extract" : "zxt";
  1265. op[0] = XEXP (x, 0);
  1266. op[1] = XEXP (x, 1);
  1267. op[2] = XEXP (x, 2);
  1268. break;
  1269. case SIGN_EXTEND:
  1270. fun = (verbose) ? "sign_extend" : "sxn";
  1271. op[0] = XEXP (x, 0);
  1272. break;
  1273. case ZERO_EXTEND:
  1274. fun = (verbose) ? "zero_extend" : "zxn";
  1275. op[0] = XEXP (x, 0);
  1276. break;
  1277. case FLOAT_EXTEND:
  1278. fun = (verbose) ? "float_extend" : "fxn";
  1279. op[0] = XEXP (x, 0);
  1280. break;
  1281. case TRUNCATE:
  1282. fun = (verbose) ? "trunc" : "trn";
  1283. op[0] = XEXP (x, 0);
  1284. break;
  1285. case FLOAT_TRUNCATE:
  1286. fun = (verbose) ? "float_trunc" : "ftr";
  1287. op[0] = XEXP (x, 0);
  1288. break;
  1289. case FLOAT:
  1290. fun = (verbose) ? "float" : "flt";
  1291. op[0] = XEXP (x, 0);
  1292. break;
  1293. case UNSIGNED_FLOAT:
  1294. fun = (verbose) ? "uns_float" : "ufl";
  1295. op[0] = XEXP (x, 0);
  1296. break;
  1297. case FIX:
  1298. fun = "fix";
  1299. op[0] = XEXP (x, 0);
  1300. break;
  1301. case UNSIGNED_FIX:
  1302. fun = (verbose) ? "uns_fix" : "ufx";
  1303. op[0] = XEXP (x, 0);
  1304. break;
  1305. case PRE_DEC:
  1306. st[0] = "--";
  1307. op[0] = XEXP (x, 0);
  1308. break;
  1309. case PRE_INC:
  1310. st[0] = "++";
  1311. op[0] = XEXP (x, 0);
  1312. break;
  1313. case POST_DEC:
  1314. op[0] = XEXP (x, 0);
  1315. st[1] = "--";
  1316. break;
  1317. case POST_INC:
  1318. op[0] = XEXP (x, 0);
  1319. st[1] = "++";
  1320. break;
  1321. case PRE_MODIFY:
  1322. st[0] = "pre ";
  1323. op[0] = XEXP (XEXP (x, 1), 0);
  1324. st[1] = "+=";
  1325. op[1] = XEXP (XEXP (x, 1), 1);
  1326. break;
  1327. case POST_MODIFY:
  1328. st[0] = "post ";
  1329. op[0] = XEXP (XEXP (x, 1), 0);
  1330. st[1] = "+=";
  1331. op[1] = XEXP (XEXP (x, 1), 1);
  1332. break;
  1333. case CALL:
  1334. st[0] = "call ";
  1335. op[0] = XEXP (x, 0);
  1336. if (verbose)
  1337. {
  1338. st[1] = " argc:";
  1339. op[1] = XEXP (x, 1);
  1340. }
  1341. break;
  1342. case IF_THEN_ELSE:
  1343. st[0] = "{(";
  1344. op[0] = XEXP (x, 0);
  1345. st[1] = ")?";
  1346. op[1] = XEXP (x, 1);
  1347. st[2] = ":";
  1348. op[2] = XEXP (x, 2);
  1349. st[3] = "}";
  1350. break;
  1351. case TRAP_IF:
  1352. fun = "trap_if";
  1353. op[0] = TRAP_CONDITION (x);
  1354. break;
  1355. case PREFETCH:
  1356. fun = "prefetch";
  1357. op[0] = XEXP (x, 0);
  1358. op[1] = XEXP (x, 1);
  1359. op[2] = XEXP (x, 2);
  1360. break;
  1361. case UNSPEC:
  1362. case UNSPEC_VOLATILE:
  1363. {
  1364. pp_string (pp, "unspec");
  1365. if (GET_CODE (x) == UNSPEC_VOLATILE)
  1366. pp_string (pp, "/v");
  1367. pp_left_bracket (pp);
  1368. for (i = 0; i < XVECLEN (x, 0); i++)
  1369. {
  1370. if (i != 0)
  1371. pp_comma (pp);
  1372. print_pattern (pp, XVECEXP (x, 0, i), verbose);
  1373. }
  1374. pp_string (pp, "] ");
  1375. pp_decimal_int (pp, XINT (x, 1));
  1376. }
  1377. break;
  1378. default:
  1379. {
  1380. /* Most unhandled codes can be printed as pseudo-functions. */
  1381. if (GET_RTX_CLASS (GET_CODE (x)) == RTX_UNARY)
  1382. {
  1383. fun = GET_RTX_NAME (GET_CODE (x));
  1384. op[0] = XEXP (x, 0);
  1385. }
  1386. else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_COMPARE
  1387. || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_COMPARE
  1388. || GET_RTX_CLASS (GET_CODE (x)) == RTX_BIN_ARITH
  1389. || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_ARITH)
  1390. {
  1391. fun = GET_RTX_NAME (GET_CODE (x));
  1392. op[0] = XEXP (x, 0);
  1393. op[1] = XEXP (x, 1);
  1394. }
  1395. else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY)
  1396. {
  1397. fun = GET_RTX_NAME (GET_CODE (x));
  1398. op[0] = XEXP (x, 0);
  1399. op[1] = XEXP (x, 1);
  1400. op[2] = XEXP (x, 2);
  1401. }
  1402. else
  1403. /* Give up, just print the RTX name. */
  1404. st[0] = GET_RTX_NAME (GET_CODE (x));
  1405. }
  1406. break;
  1407. }
  1408. /* Print this as a function? */
  1409. if (fun)
  1410. {
  1411. pp_string (pp, fun);
  1412. pp_left_paren (pp);
  1413. }
  1414. for (i = 0; i < 4; i++)
  1415. {
  1416. if (st[i])
  1417. pp_string (pp, st[i]);
  1418. if (op[i])
  1419. {
  1420. if (fun && i != 0)
  1421. pp_comma (pp);
  1422. print_value (pp, op[i], verbose);
  1423. }
  1424. }
  1425. if (fun)
  1426. pp_right_paren (pp);
  1427. } /* print_exp */
  1428. /* Prints rtxes, I customarily classified as values. They're constants,
  1429. registers, labels, symbols and memory accesses. */
  1430. void
  1431. print_value (pretty_printer *pp, const_rtx x, int verbose)
  1432. {
  1433. char tmp[1024];
  1434. if (!x)
  1435. {
  1436. pp_string (pp, "(nil)");
  1437. return;
  1438. }
  1439. switch (GET_CODE (x))
  1440. {
  1441. case CONST_INT:
  1442. pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
  1443. (unsigned HOST_WIDE_INT) INTVAL (x));
  1444. break;
  1445. case CONST_WIDE_INT:
  1446. {
  1447. const char *sep = "<";
  1448. int i;
  1449. for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
  1450. {
  1451. pp_string (pp, sep);
  1452. sep = ",";
  1453. sprintf (tmp, HOST_WIDE_INT_PRINT_HEX,
  1454. (unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (x, i));
  1455. pp_string (pp, tmp);
  1456. }
  1457. pp_greater (pp);
  1458. }
  1459. break;
  1460. case CONST_POLY_INT:
  1461. pp_left_bracket (pp);
  1462. pp_wide_int (pp, CONST_POLY_INT_COEFFS (x)[0], SIGNED);
  1463. for (unsigned int i = 1; i < NUM_POLY_INT_COEFFS; ++i)
  1464. {
  1465. pp_string (pp, ", ");
  1466. pp_wide_int (pp, CONST_POLY_INT_COEFFS (x)[i], SIGNED);
  1467. }
  1468. pp_right_bracket (pp);
  1469. break;
  1470. case CONST_DOUBLE:
  1471. if (FLOAT_MODE_P (GET_MODE (x)))
  1472. {
  1473. real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
  1474. sizeof (tmp), 0, 1);
  1475. pp_string (pp, tmp);
  1476. }
  1477. else
  1478. pp_printf (pp, "<%wx,%wx>",
  1479. (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
  1480. (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
  1481. break;
  1482. case CONST_FIXED:
  1483. fixed_to_decimal (tmp, CONST_FIXED_VALUE (x), sizeof (tmp));
  1484. pp_string (pp, tmp);
  1485. break;
  1486. case CONST_STRING:
  1487. pp_string (pp, "\"");
  1488. pretty_print_string (pp, XSTR (x, 0), strlen (XSTR (x, 0)));
  1489. pp_string (pp, "\"");
  1490. break;
  1491. case SYMBOL_REF:
  1492. pp_printf (pp, "`%s'", XSTR (x, 0));
  1493. break;
  1494. case LABEL_REF:
  1495. pp_printf (pp, "L%d", INSN_UID (label_ref_label (x)));
  1496. break;
  1497. case CONST:
  1498. case HIGH:
  1499. case STRICT_LOW_PART:
  1500. pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
  1501. print_value (pp, XEXP (x, 0), verbose);
  1502. pp_right_paren (pp);
  1503. break;
  1504. case REG:
  1505. if (REGNO (x) < FIRST_PSEUDO_REGISTER)
  1506. {
  1507. if (ISDIGIT (reg_names[REGNO (x)][0]))
  1508. pp_modulo (pp);
  1509. pp_string (pp, reg_names[REGNO (x)]);
  1510. }
  1511. else
  1512. pp_printf (pp, "r%d", REGNO (x));
  1513. if (verbose)
  1514. pp_printf (pp, ":%s", GET_MODE_NAME (GET_MODE (x)));
  1515. break;
  1516. case SUBREG:
  1517. print_value (pp, SUBREG_REG (x), verbose);
  1518. pp_printf (pp, "#");
  1519. pp_wide_integer (pp, SUBREG_BYTE (x));
  1520. break;
  1521. case SCRATCH:
  1522. case CC0:
  1523. case PC:
  1524. pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
  1525. break;
  1526. case MEM:
  1527. pp_left_bracket (pp);
  1528. print_value (pp, XEXP (x, 0), verbose);
  1529. pp_right_bracket (pp);
  1530. break;
  1531. case DEBUG_EXPR:
  1532. pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
  1533. break;
  1534. default:
  1535. print_exp (pp, x, verbose);
  1536. break;
  1537. }
  1538. } /* print_value */
  1539. /* The next step in insn detalization, its pattern recognition. */
  1540. void
  1541. print_pattern (pretty_printer *pp, const_rtx x, int verbose)
  1542. {
  1543. if (! x)
  1544. {
  1545. pp_string (pp, "(nil)");
  1546. return;
  1547. }
  1548. switch (GET_CODE (x))
  1549. {
  1550. case SET:
  1551. print_value (pp, SET_DEST (x), verbose);
  1552. pp_equal (pp);
  1553. print_value (pp, SET_SRC (x), verbose);
  1554. break;
  1555. case RETURN:
  1556. case SIMPLE_RETURN:
  1557. case EH_RETURN:
  1558. pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
  1559. break;
  1560. case CALL:
  1561. print_exp (pp, x, verbose);
  1562. break;
  1563. case CLOBBER:
  1564. case USE:
  1565. pp_printf (pp, "%s ", GET_RTX_NAME (GET_CODE (x)));
  1566. print_value (pp, XEXP (x, 0), verbose);
  1567. break;
  1568. case VAR_LOCATION:
  1569. pp_string (pp, "loc ");
  1570. print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
  1571. break;
  1572. case COND_EXEC:
  1573. pp_left_paren (pp);
  1574. if (GET_CODE (COND_EXEC_TEST (x)) == NE
  1575. && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
  1576. print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
  1577. else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
  1578. && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
  1579. {
  1580. pp_exclamation (pp);
  1581. print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
  1582. }
  1583. else
  1584. print_value (pp, COND_EXEC_TEST (x), verbose);
  1585. pp_string (pp, ") ");
  1586. print_pattern (pp, COND_EXEC_CODE (x), verbose);
  1587. break;
  1588. case PARALLEL:
  1589. {
  1590. int i;
  1591. pp_left_brace (pp);
  1592. for (i = 0; i < XVECLEN (x, 0); i++)
  1593. {
  1594. print_pattern (pp, XVECEXP (x, 0, i), verbose);
  1595. pp_semicolon (pp);
  1596. }
  1597. pp_right_brace (pp);
  1598. }
  1599. break;
  1600. case SEQUENCE:
  1601. {
  1602. const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
  1603. pp_string (pp, "sequence{");
  1604. if (INSN_P (seq->element (0)))
  1605. {
  1606. /* Print the sequence insns indented. */
  1607. const char * save_print_rtx_head = print_rtx_head;
  1608. char indented_print_rtx_head[32];
  1609. pp_newline (pp);
  1610. gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
  1611. snprintf (indented_print_rtx_head,
  1612. sizeof (indented_print_rtx_head),
  1613. "%s ", print_rtx_head);
  1614. print_rtx_head = indented_print_rtx_head;
  1615. for (int i = 0; i < seq->len (); i++)
  1616. print_insn_with_notes (pp, seq->insn (i));
  1617. pp_printf (pp, "%s ", save_print_rtx_head);
  1618. print_rtx_head = save_print_rtx_head;
  1619. }
  1620. else
  1621. {
  1622. for (int i = 0; i < seq->len (); i++)
  1623. {
  1624. print_pattern (pp, seq->element (i), verbose);
  1625. pp_semicolon (pp);
  1626. }
  1627. }
  1628. pp_right_brace (pp);
  1629. }
  1630. break;
  1631. case ASM_INPUT:
  1632. pp_printf (pp, "asm {%s}", XSTR (x, 0));
  1633. break;
  1634. case ADDR_VEC:
  1635. for (int i = 0; i < XVECLEN (x, 0); i++)
  1636. {
  1637. print_value (pp, XVECEXP (x, 0, i), verbose);
  1638. pp_semicolon (pp);
  1639. }
  1640. break;
  1641. case ADDR_DIFF_VEC:
  1642. for (int i = 0; i < XVECLEN (x, 1); i++)
  1643. {
  1644. print_value (pp, XVECEXP (x, 1, i), verbose);
  1645. pp_semicolon (pp);
  1646. }
  1647. break;
  1648. case TRAP_IF:
  1649. pp_string (pp, "trap_if ");
  1650. print_value (pp, TRAP_CONDITION (x), verbose);
  1651. break;
  1652. case UNSPEC:
  1653. case UNSPEC_VOLATILE:
  1654. /* Fallthru -- leave UNSPECs to print_exp. */
  1655. default:
  1656. print_value (pp, x, verbose);
  1657. }
  1658. } /* print_pattern */
  1659. /* This is the main function in slim rtl visualization mechanism.
  1660. X is an insn, to be printed into PP.
  1661. This function tries to print it properly in human-readable form,
  1662. resembling assembler mnemonics (instead of the older Lisp-style
  1663. form).
  1664. If VERBOSE is TRUE, insns are printed with more complete (but
  1665. longer) pattern names and with extra information, and prefixed
  1666. with their INSN_UIDs. */
  1667. void
  1668. print_insn (pretty_printer *pp, const rtx_insn *x, int verbose)
  1669. {
  1670. if (verbose)
  1671. {
  1672. /* Blech, pretty-print can't print integers with a specified width. */
  1673. char uid_prefix[32];
  1674. snprintf (uid_prefix, sizeof uid_prefix, " %4d: ", INSN_UID (x));
  1675. pp_string (pp, uid_prefix);
  1676. }
  1677. switch (GET_CODE (x))
  1678. {
  1679. case INSN:
  1680. print_pattern (pp, PATTERN (x), verbose);
  1681. break;
  1682. case DEBUG_INSN:
  1683. {
  1684. if (DEBUG_MARKER_INSN_P (x))
  1685. {
  1686. switch (INSN_DEBUG_MARKER_KIND (x))
  1687. {
  1688. case NOTE_INSN_BEGIN_STMT:
  1689. pp_string (pp, "debug begin stmt marker");
  1690. break;
  1691. case NOTE_INSN_INLINE_ENTRY:
  1692. pp_string (pp, "debug inline entry marker");
  1693. break;
  1694. default:
  1695. gcc_unreachable ();
  1696. }
  1697. break;
  1698. }
  1699. const char *name = "?";
  1700. char idbuf[32];
  1701. if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
  1702. {
  1703. tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
  1704. if (id)
  1705. name = IDENTIFIER_POINTER (id);
  1706. else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x))
  1707. == DEBUG_EXPR_DECL)
  1708. {
  1709. sprintf (idbuf, "D#%i",
  1710. DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
  1711. name = idbuf;
  1712. }
  1713. else
  1714. {
  1715. sprintf (idbuf, "D.%i",
  1716. DECL_UID (INSN_VAR_LOCATION_DECL (x)));
  1717. name = idbuf;
  1718. }
  1719. }
  1720. pp_printf (pp, "debug %s => ", name);
  1721. if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
  1722. pp_string (pp, "optimized away");
  1723. else
  1724. print_pattern (pp, INSN_VAR_LOCATION_LOC (x), verbose);
  1725. }
  1726. break;
  1727. case JUMP_INSN:
  1728. print_pattern (pp, PATTERN (x), verbose);
  1729. break;
  1730. case CALL_INSN:
  1731. if (GET_CODE (PATTERN (x)) == PARALLEL)
  1732. print_pattern (pp, XVECEXP (PATTERN (x), 0, 0), verbose);
  1733. else
  1734. print_pattern (pp, PATTERN (x), verbose);
  1735. break;
  1736. case CODE_LABEL:
  1737. pp_printf (pp, "L%d:", INSN_UID (x));
  1738. break;
  1739. case JUMP_TABLE_DATA:
  1740. pp_string (pp, "jump_table_data{\n");
  1741. print_pattern (pp, PATTERN (x), verbose);
  1742. pp_right_brace (pp);
  1743. break;
  1744. case BARRIER:
  1745. pp_string (pp, "barrier");
  1746. break;
  1747. case NOTE:
  1748. {
  1749. pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
  1750. switch (NOTE_KIND (x))
  1751. {
  1752. case NOTE_INSN_EH_REGION_BEG:
  1753. case NOTE_INSN_EH_REGION_END:
  1754. pp_printf (pp, " %d", NOTE_EH_HANDLER (x));
  1755. break;
  1756. case NOTE_INSN_BLOCK_BEG:
  1757. case NOTE_INSN_BLOCK_END:
  1758. pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
  1759. break;
  1760. case NOTE_INSN_BASIC_BLOCK:
  1761. pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
  1762. break;
  1763. case NOTE_INSN_DELETED_LABEL:
  1764. case NOTE_INSN_DELETED_DEBUG_LABEL:
  1765. {
  1766. const char *label = NOTE_DELETED_LABEL_NAME (x);
  1767. if (label == NULL)
  1768. label = "";
  1769. pp_printf (pp, " (\"%s\")", label);
  1770. }
  1771. break;
  1772. case NOTE_INSN_VAR_LOCATION:
  1773. pp_left_brace (pp);
  1774. print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
  1775. pp_right_brace (pp);
  1776. break;
  1777. default:
  1778. break;
  1779. }
  1780. break;
  1781. }
  1782. default:
  1783. gcc_unreachable ();
  1784. }
  1785. } /* print_insn */
  1786. /* Pretty-print a slim dump of X (an insn) to PP, including any register
  1787. note attached to the instruction. */
  1788. static void
  1789. print_insn_with_notes (pretty_printer *pp, const rtx_insn *x)
  1790. {
  1791. pp_string (pp, print_rtx_head);
  1792. print_insn (pp, x, 1);
  1793. pp_newline (pp);
  1794. if (INSN_P (x) && REG_NOTES (x))
  1795. for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
  1796. {
  1797. pp_printf (pp, "%s %s ", print_rtx_head,
  1798. GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
  1799. if (GET_CODE (note) == INT_LIST)
  1800. pp_printf (pp, "%d", XINT (note, 0));
  1801. else
  1802. print_pattern (pp, XEXP (note, 0), 1);
  1803. pp_newline (pp);
  1804. }
  1805. }
  1806. /* Print X, an RTL value node, to file F in slim format. Include
  1807. additional information if VERBOSE is nonzero.
  1808. Value nodes are constants, registers, labels, symbols and
  1809. memory. */
  1810. void
  1811. dump_value_slim (FILE *f, const_rtx x, int verbose)
  1812. {
  1813. pretty_printer rtl_slim_pp;
  1814. rtl_slim_pp.buffer->stream = f;
  1815. print_value (&rtl_slim_pp, x, verbose);
  1816. pp_flush (&rtl_slim_pp);
  1817. }
  1818. /* Emit a slim dump of X (an insn) to the file F, including any register
  1819. note attached to the instruction. */
  1820. void
  1821. dump_insn_slim (FILE *f, const rtx_insn *x)
  1822. {
  1823. pretty_printer rtl_slim_pp;
  1824. rtl_slim_pp.buffer->stream = f;
  1825. print_insn_with_notes (&rtl_slim_pp, x);
  1826. pp_flush (&rtl_slim_pp);
  1827. }
  1828. /* Same as above, but stop at LAST or when COUNT == 0.
  1829. If COUNT < 0 it will stop only at LAST or NULL rtx. */
  1830. void
  1831. dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
  1832. int count, int flags ATTRIBUTE_UNUSED)
  1833. {
  1834. const rtx_insn *insn, *tail;
  1835. pretty_printer rtl_slim_pp;
  1836. rtl_slim_pp.buffer->stream = f;
  1837. tail = last ? NEXT_INSN (last) : NULL;
  1838. for (insn = first;
  1839. (insn != NULL) && (insn != tail) && (count != 0);
  1840. insn = NEXT_INSN (insn))
  1841. {
  1842. print_insn_with_notes (&rtl_slim_pp, insn);
  1843. if (count > 0)
  1844. count--;
  1845. }
  1846. pp_flush (&rtl_slim_pp);
  1847. }
  1848. /* Dumps basic block BB to pretty-printer PP in slim form and without and
  1849. no indentation, for use as a label of a DOT graph record-node. */
  1850. void
  1851. rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
  1852. {
  1853. rtx_insn *insn;
  1854. bool first = true;
  1855. /* TODO: inter-bb stuff. */
  1856. FOR_BB_INSNS (bb, insn)
  1857. {
  1858. if (! first)
  1859. {
  1860. /* pp_bar (pp); */
  1861. /* pp_write_text_to_stream (pp); */
  1862. }
  1863. first = false;
  1864. print_insn_with_notes (pp, insn);
  1865. pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
  1866. }
  1867. }
  1868. /* Pretty-print pattern X of some insn in non-verbose mode.
  1869. Return a string pointer to the pretty-printer buffer.
  1870. This function is only exported exists only to accommodate some older users
  1871. of the slim RTL pretty printers. Please do not use it for new code. */
  1872. const char *
  1873. str_pattern_slim (const_rtx x)
  1874. {
  1875. pretty_printer rtl_slim_pp;
  1876. print_pattern (&rtl_slim_pp, x, 0);
  1877. return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
  1878. }
  1879. /* Emit a slim dump of X (an insn) to stderr. */
  1880. extern void debug_insn_slim (const rtx_insn *);
  1881. DEBUG_FUNCTION void
  1882. debug_insn_slim (const rtx_insn *x)
  1883. {
  1884. dump_insn_slim (stderr, x);
  1885. }
  1886. /* Same as above, but using dump_rtl_slim. */
  1887. extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
  1888. int, int);
  1889. DEBUG_FUNCTION void
  1890. debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
  1891. int flags)
  1892. {
  1893. dump_rtl_slim (stderr, first, last, count, flags);
  1894. }
  1895. extern void debug_bb_slim (basic_block);
  1896. DEBUG_FUNCTION void
  1897. debug_bb_slim (basic_block bb)
  1898. {
  1899. dump_bb (stderr, bb, 0, TDF_SLIM | TDF_BLOCKS);
  1900. }
  1901. extern void debug_bb_n_slim (int);
  1902. DEBUG_FUNCTION void
  1903. debug_bb_n_slim (int n)
  1904. {
  1905. basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
  1906. debug_bb_slim (bb);
  1907. }
  1908. #endif
  1909. #if __GNUC__ >= 10
  1910. # pragma GCC diagnostic pop
  1911. #endif