On Tue, 2016-10-25 at 14:47 +0200, Bernd Schmidt wrote: > On 10/21/2016 10:27 PM, David Malcolm wrote: > > Thanks. I attemped to use those fields of recog_data, but it > > doesn't > > seem to be exactly what's needed here. > > Yeah, I may have been confused. I'm not sure that just looking at > SCRATCHes is the right thing either, but I think you're on the right > track, and we can use something like your patch for now and extend it > later if necessary. > > > + public: > > + rtx_reuse_manager (); > > + ~rtx_reuse_manager (); > > + static rtx_reuse_manager *get () { return singleton; } > > OTOH, this setup looks a bit odd to me. Are you trying to avoid > converting the print_rtx stuff to its own class, or avoid passing the > reuse manager as an argument to a lot of functions?
[...snip...] I attempted to convert the print_rtx stuff to its own class, but ran into a bug which stumped me for a while, hence I was trying to avoid the need for it. I've now fixed that bug. The following patch moves various global state in print-rtl.c into a new "rtx_writer" class, giving us a place to stash additional state relating to dumping (and the possibility of putting extra setup/cleanup in ctor/dtor). I didn't bother renaming the variables (e.g. converting "indent" to "m_indent"), to minimize churn, but I could do that also if you prefer. Various functions become methods, but everything labelled as DEBUG_FUNCTION remains a function after the patch. Successfully bootstrapped®rtested on x86_64-pc-linux-gnu. OK for trunk? If so, then I can try to rewrite the proposed rtx-reuse code using rtx_writer. gcc/ChangeLog: * print-rtl-function.c (flag_compact): Delete global. (print_rtx_function): Rewrite in terms of class rtx_writer. * print-rtl.c (outfile): Delete global. (sawclose): Likewise. (indent): Likewise. (in_call_function_usage): Likewise. (flag_compact): Likewise. (flag_simple): Likewise. (rtx_writer::rtx_writer): New ctor. (print_rtx_operand_code_0): Convert to... (rtx_writer::print_rtx_operand_code_0): ...this. (print_rtx_operand_code_e): Convert to... (rtx_writer::print_rtx_operand_code_e): ...this. (print_rtx_operand_codes_E_and_V): Convert to... (rtx_writer::print_rtx_operand_codes_E_and_V): ...this. (print_rtx_operand_code_i): Convert to... (rtx_writer::print_rtx_operand_code_i): ...this. (print_rtx_operand_code_r): Convert to... (rtx_writer::print_rtx_operand_code_r): ...this. (print_rtx_operand_code_u): Convert to... (rtx_writer::print_rtx_operand_code_u): ...this. (print_rtx_operand): Convert to... (rtx_writer::print_rtx_operand): ...this. (print_rtx): Convert to... (rtx_writer::print_rtx): ...this. (print_inline_rtx): Rewrite in terms of class rtx_writer. (debug_rtx): Likewise. (print_rtl): Convert to... (rtx_writer::print_rtl): ...this. (print_rtl): Reimplement in terms of class rtx_writer. (print_rtl_single): Rewrite in terms of class rtx_writer. (print_rtl_single_with_indent): Convert to.. (rtx_writer::print_rtl_single_with_indent): ...this. (print_simple_rtl): Rewrite in terms of class rtx_writer. * print-rtl.h (flag_compact): Delete decl. (class rtx_writer): New class. --- gcc/print-rtl-function.c | 8 ++-- gcc/print-rtl.c | 121 +++++++++++++++++++++-------------------------- gcc/print-rtl.h | 39 ++++++++++++++- gcc/rtl-tests.c | 5 +- 4 files changed, 98 insertions(+), 75 deletions(-) diff --git a/gcc/print-rtl-function.c b/gcc/print-rtl-function.c index 7ce1b90..f37e1b7 100644 --- a/gcc/print-rtl-function.c +++ b/gcc/print-rtl-function.c @@ -189,7 +189,7 @@ can_have_basic_block_p (const rtx_insn *insn) DEBUG_FUNCTION void print_rtx_function (FILE *outfile, function *fn, bool compact) { - flag_compact = compact; + rtx_writer w (outfile, 0, false, compact); tree fdecl = fn->decl; @@ -213,7 +213,7 @@ print_rtx_function (FILE *outfile, function *fn, bool compact) curr_bb = insn_bb; begin_any_block (outfile, curr_bb); } - print_rtl_single_with_indent (outfile, insn, curr_bb ? 6 : 4); + w.print_rtl_single_with_indent (insn, curr_bb ? 6 : 4); } end_any_block (outfile, curr_bb); fprintf (outfile, " ) ;; insn-chain\n"); @@ -221,11 +221,9 @@ print_rtx_function (FILE *outfile, function *fn, bool compact) /* Additional RTL state. */ fprintf (outfile, " (crtl\n"); fprintf (outfile, " (return_rtx \n"); - print_rtl_single_with_indent (outfile, crtl->return_rtx, 6); + w.print_rtl_single_with_indent (crtl->return_rtx, 6); fprintf (outfile, " ) ;; return_rtx\n"); fprintf (outfile, " ) ;; crtl\n"); fprintf (outfile, ") ;; function \"%s\"\n", dname); - - flag_compact = false; } diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 46f3c4d..2625409 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -52,23 +52,6 @@ along with GCC; see the file COPYING3. If not see #include "print-rtl.h" -static FILE *outfile; - -static int sawclose = 0; - -static int indent; - -static bool in_call_function_usage; - -/* If true, use compact dump format: - - INSN_UIDs are omitted, except for jumps and CODE_LABELs, - - INSN_CODEs are omitted, - - register numbers are omitted for hard and virtual regs - - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc). */ -bool flag_compact; - -static void print_rtx (const_rtx); - /* String printed at beginning of each RTL when it is dumped. This string is set to ASM_COMMENT_START when the RTL is dumped in the assembly output file. */ @@ -89,8 +72,13 @@ int flag_dump_unnumbered = 0; int flag_dump_unnumbered_links = 0; #endif -/* Nonzero means use simplified format without flags, modes, etc. */ -int flag_simple = 0; +/* Constructor for rtx_writer. */ + +rtx_writer::rtx_writer (FILE *outf, int ind, bool simple, bool compact) +: outfile (outf), sawclose (0), indent (ind), in_call_function_usage (false), + flag_simple (simple), flag_compact (compact) +{ +} #ifndef GENERATOR_FILE void @@ -107,9 +95,9 @@ print_mem_expr (FILE *outfile, const_tree expr) of a NOTE, where it indicates that the field has several different valid contents. */ -static void -print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED, - int idx ATTRIBUTE_UNUSED) +void +rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED, + int idx ATTRIBUTE_UNUSED) { #ifndef GENERATOR_FILE if (idx == 1 && GET_CODE (in_rtx) == SYMBOL_REF) @@ -223,8 +211,8 @@ print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED, Also called by print_rtx_operand_code_u for handling code 'u' for LABEL_REFs when they don't reference a CODE_LABEL. */ -static void -print_rtx_operand_code_e (const_rtx in_rtx, int idx) +void +rtx_writer::print_rtx_operand_code_e (const_rtx in_rtx, int idx) { indent += 2; if (idx == 6 && INSN_P (in_rtx)) @@ -246,8 +234,8 @@ print_rtx_operand_code_e (const_rtx in_rtx, int idx) /* Subroutine of print_rtx_operand for handling codes 'E' and 'V'. */ -static void -print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx) +void +rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx) { indent += 2; if (sawclose) @@ -278,8 +266,8 @@ print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx) /* Subroutine of print_rtx_operand for handling code 'i'. */ -static void -print_rtx_operand_code_i (const_rtx in_rtx, int idx) +void +rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx) { if (idx == 4 && INSN_P (in_rtx)) { @@ -366,8 +354,8 @@ print_rtx_operand_code_i (const_rtx in_rtx, int idx) /* Subroutine of print_rtx_operand for handling code 'r'. */ -static void -print_rtx_operand_code_r (const_rtx in_rtx) +void +rtx_writer::print_rtx_operand_code_r (const_rtx in_rtx) { int is_insn = INSN_P (in_rtx); unsigned int regno = REGNO (in_rtx); @@ -432,8 +420,8 @@ print_rtx_operand_code_r (const_rtx in_rtx) /* Subroutine of print_rtx_operand for handling code 'u'. */ -static void -print_rtx_operand_code_u (const_rtx in_rtx, int idx) +void +rtx_writer::print_rtx_operand_code_u (const_rtx in_rtx, int idx) { /* Don't print insn UIDs in compact mode, apart from in LABEL_REFs. */ if (flag_compact && GET_CODE (in_rtx) != LABEL_REF) @@ -479,8 +467,8 @@ print_rtx_operand_code_u (const_rtx in_rtx, int idx) /* Subroutine of print_rtx. Print operand IDX of IN_RTX. */ -static void -print_rtx_operand (const_rtx in_rtx, int idx) +void +rtx_writer::print_rtx_operand (const_rtx in_rtx, int idx) { const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)); @@ -578,8 +566,8 @@ print_rtx_operand (const_rtx in_rtx, int idx) /* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */ -static void -print_rtx (const_rtx in_rtx) +void +rtx_writer::print_rtx (const_rtx in_rtx) { int idx = 0; @@ -778,15 +766,8 @@ print_rtx (const_rtx in_rtx) void print_inline_rtx (FILE *outf, const_rtx x, int ind) { - int oldsaw = sawclose; - int oldindent = indent; - - sawclose = 0; - indent = ind; - outfile = outf; - print_rtx (x); - sawclose = oldsaw; - indent = oldindent; + rtx_writer w (outf, ind, false, false); + w.print_rtx (x); } /* Call this function from the debugger to see what X looks like. */ @@ -794,9 +775,8 @@ print_inline_rtx (FILE *outf, const_rtx x, int ind) DEBUG_FUNCTION void debug_rtx (const_rtx x) { - outfile = stderr; - sawclose = 0; - print_rtx (x); + rtx_writer w (stderr, 0, false, false); + w.print_rtx (x); fprintf (stderr, "\n"); } @@ -892,23 +872,20 @@ debug_rtx_find (const rtx_insn *x, int uid) } /* External entry point for printing a chain of insns - starting with RTX_FIRST onto file OUTF. + starting with RTX_FIRST. A blank line separates insns. If RTX_FIRST is not an insn, then it alone is printed, with no newline. */ void -print_rtl (FILE *outf, const_rtx rtx_first) +rtx_writer::print_rtl (const_rtx rtx_first) { const rtx_insn *tmp_rtx; - outfile = outf; - sawclose = 0; - if (rtx_first == 0) { - fputs (print_rtx_head, outf); - fputs ("(nil)\n", outf); + fputs (print_rtx_head, outfile); + fputs ("(nil)\n", outfile); } else switch (GET_CODE (rtx_first)) @@ -936,32 +913,45 @@ print_rtl (FILE *outf, const_rtx rtx_first) } } +/* External entry point for printing a chain of insns + starting with RTX_FIRST onto file OUTF. + A blank line separates insns. + + If RTX_FIRST is not an insn, then it alone is printed, with no newline. */ + +void +print_rtl (FILE *outf, const_rtx rtx_first) +{ + rtx_writer w (outf, 0, false, false); + w.print_rtl (rtx_first); +} + /* Like print_rtx, except specify a file. */ /* Return nonzero if we actually printed anything. */ int print_rtl_single (FILE *outf, const_rtx x) { - return print_rtl_single_with_indent (outf, x, 0); + rtx_writer w (outf, 0, false, false); + return w.print_rtl_single_with_indent (x, 0); } -/* Like print_rtl_single, except specify a file and indentation. */ +/* Like print_rtl_single, except specify an indentation. */ int -print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind) +rtx_writer::print_rtl_single_with_indent (const_rtx x, int ind) { - int old_indent = indent; char *s_indent = (char *) alloca ((size_t) ind + 1); memset ((void *) s_indent, ' ', (size_t) ind); s_indent[ind] = '\0'; + fputs (s_indent, outfile); + fputs (print_rtx_head, outfile); + int old_indent = indent; indent = ind; - outfile = outf; sawclose = 0; - fputs (s_indent, outfile); - fputs (print_rtx_head, outfile); print_rtx (x); - putc ('\n', outf); + putc ('\n', outfile); indent = old_indent; return 1; } @@ -973,9 +963,8 @@ print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind) void print_simple_rtl (FILE *outf, const_rtx x) { - flag_simple = 1; - print_rtl (outf, x); - flag_simple = 0; + rtx_writer w (outf, 0, true, false); + w.print_rtl (x); } /* Print the elements of VEC to FILE. */ diff --git a/gcc/print-rtl.h b/gcc/print-rtl.h index 8dfba8b..a7a63c7 100644 --- a/gcc/print-rtl.h +++ b/gcc/print-rtl.h @@ -20,7 +20,44 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_PRINT_RTL_H #define GCC_PRINT_RTL_H -extern bool flag_compact; +/* A class for writing rtx to a FILE *. */ + +class rtx_writer +{ + public: + rtx_writer (FILE *outfile, int ind, bool simple, bool compact); + + void print_rtx (const_rtx in_rtx); + void print_rtl (const_rtx rtx_first); + int print_rtl_single_with_indent (const_rtx x, int ind); + + private: + void print_rtx_operand_code_0 (const_rtx in_rtx, int idx); + void print_rtx_operand_code_e (const_rtx in_rtx, int idx); + void print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx); + void print_rtx_operand_code_i (const_rtx in_rtx, int idx); + void print_rtx_operand_code_r (const_rtx in_rtx); + void print_rtx_operand_code_u (const_rtx in_rtx, int idx); + void print_rtx_operand (const_rtx in_rtx, int idx); + + private: + FILE *outfile; + int sawclose; + int indent; + bool in_call_function_usage; + + /* True means use simplified format without flags, modes, etc. */ + bool flag_simple; + + /* If true, use compact dump format: + - INSN_UIDs are omitted, except for jumps and CODE_LABELs, + - INSN_CODEs are omitted, + - register numbers are omitted for hard and virtual regs, and + non-virtual pseudos are offset relative to the first such reg, and + printed with a '%' sigil e.g. "%0" for (LAST_VIRTUAL_REGISTER + 1), + - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc). */ + bool flag_compact; +}; #ifdef BUFSIZ extern void print_rtl (FILE *, const_rtx); diff --git a/gcc/rtl-tests.c b/gcc/rtl-tests.c index b723560..36f423b 100644 --- a/gcc/rtl-tests.c +++ b/gcc/rtl-tests.c @@ -65,9 +65,8 @@ assert_rtl_dump_eq (const location &loc, const char *expected_dump, rtx x) { named_temp_file tmp_out (".rtl"); FILE *outfile = fopen (tmp_out.get_filename (), "w"); - flag_compact = true; - print_rtl (outfile, x); - flag_compact = false; + rtx_writer w (outfile, 0, false, true); + w.print_rtl (x); fclose (outfile); char *dump = read_file (SELFTEST_LOCATION, tmp_out.get_filename ()); -- 1.8.5.3