From 086d97be84478819ccd27bd0c421a35648f134c6 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 3 Nov 2016 14:10:48 -0400 Subject: [PATCH 16/28] FIXME: WIP on adding reuse_rtx --- gcc/print-rtl-function.c | 5 ++ gcc/print-rtl-reuse.h | 52 ++++++++++++++++++ gcc/print-rtl.c | 139 +++++++++++++++++++++++++++++++++++++++++++++-- gcc/rtl-tests.c | 31 +++++++++++ 4 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 gcc/print-rtl-reuse.h diff --git a/gcc/print-rtl-function.c b/gcc/print-rtl-function.c index f37e1b7..2ccd617 100644 --- a/gcc/print-rtl-function.c +++ b/gcc/print-rtl-function.c @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "basic-block.h" #include "print-rtl.h" +#include "print-rtl-reuse.h" #include "langhooks.h" #include "memmodel.h" #include "emit-rtl.h" @@ -191,6 +192,10 @@ print_rtx_function (FILE *outfile, function *fn, bool compact) { rtx_writer w (outfile, 0, false, compact); + rtx_reuse r; + for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn)) + r.preprocess (insn); + tree fdecl = fn->decl; const char *dname = lang_hooks.decl_printable_name (fdecl, 2); diff --git a/gcc/print-rtl-reuse.h b/gcc/print-rtl-reuse.h new file mode 100644 index 0000000..505d5be --- /dev/null +++ b/gcc/print-rtl-reuse.h @@ -0,0 +1,52 @@ +/* Track pointer reuse when printing RTL. + Copyright (C) 2016 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_PRINT_RTL_REUSE_H +#define GCC_PRINT_RTL_REUSE_H + +#ifndef GENERATOR_FILE + +#include "bitmap.h" + +/* Track repeated occurrences of things like SCRATCH, so we can emit + them as "reuse_rtx". */ +class rtx_reuse +{ + public: + rtx_reuse (); + ~rtx_reuse (); + static rtx_reuse *get () { return singleton; } + + void preprocess (const_rtx x); + bool has_reuse_id (const_rtx x, int *out); + + bool seen_def_p (int id); + void set_seen_def (int id); + + private: + static rtx_reuse *singleton; + hash_map m_rtx_occurrence_count; + hash_map m_rtx_reuse_ids; + bitmap_head m_defs_seen; + int m_next_id; +}; + +#endif /* #ifndef GENERATOR_FILE */ + +#endif // GCC_PRINT_RTL_REUSE_H diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index a8e9f84..3262928 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see #endif #include "print-rtl.h" +#include "print-rtl-reuse.h" +#include "rtl-iter.h" /* 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 @@ -81,6 +83,110 @@ rtx_writer::rtx_writer (FILE *outf, int ind, bool simple, bool compact) } #ifndef GENERATOR_FILE + +/* FIXME. */ + +rtx_reuse *rtx_reuse::singleton = NULL; + +/* FIXME. */ + +rtx_reuse::rtx_reuse () +: m_next_id (0) +{ + gcc_assert (singleton == NULL); + singleton = this; + + bitmap_initialize (&m_defs_seen, NULL); +} + +/* FIXME. */ + +rtx_reuse::~rtx_reuse () +{ + gcc_assert (singleton == this); + singleton = NULL; +} + +/* FIXME. */ + +static bool +uses_rtx_reuse_p (const_rtx x) +{ + if (x == NULL) + return false; + + switch (GET_CODE (x)) + { + case DEBUG_EXPR: + case VALUE: + case SCRATCH: + //CASE_CONST_UNIQUE: + return true; + + default: + return false; + } +} + +/* FIXME. */ + +void +rtx_reuse::preprocess (const_rtx x) +{ + /* FIXME: locate dups. */ + + subrtx_iterator::array_type array; + FOR_EACH_SUBRTX (iter, array, x, NONCONST) + if (uses_rtx_reuse_p (*iter)) + { + if (int *count = m_rtx_occurrence_count.get (*iter)) + { + if (*count == 1) + { + m_rtx_reuse_ids.put (*iter, m_next_id++); + } + (*count)++; + } + else + m_rtx_occurrence_count.put (*iter, 1); + } +} + +/* FIXME. */ + +bool +rtx_reuse::has_reuse_id (const_rtx x, int *out) +{ + int *id = m_rtx_reuse_ids.get (x); + if (id) + { + if (out) + *out = *id; + return true; + } + else + return false; +} + +/* FIXME. */ + +bool +rtx_reuse::seen_def_p (int id) +{ + return bitmap_bit_p (&m_defs_seen, id); +} + +/* FIXME. */ + +void +rtx_reuse::set_seen_def (int id) +{ + bitmap_set_bit (&m_defs_seen, id); +} + +#endif /* #ifndef GENERATOR_FILE */ + +#ifndef GENERATOR_FILE void print_mem_expr (FILE *outfile, const_tree expr) { @@ -631,8 +737,33 @@ rtx_writer::print_rtx (const_rtx in_rtx) return; } + fputc ('(', m_outfile); + /* Print name of expression code. */ + /* Handle reuse. */ +#ifndef GENERATOR_FILE + if (rtx_reuse::get ()) + { + int reuse_id; + if (rtx_reuse::get ()->has_reuse_id (in_rtx, &reuse_id)) + { + /* Have we already seen the defn of this rtx? */ + if (rtx_reuse::get ()->seen_def_p (reuse_id)) + { + fprintf (m_outfile, "reuse_rtx %i)", reuse_id); + m_sawclose = 1; + return; + } + else + { + fprintf (m_outfile, "%i|", reuse_id); + rtx_reuse::get ()->set_seen_def (reuse_id); + } + } + } +#endif /* #ifndef GENERATOR_FILE */ + /* In compact mode, prefix the code of insns with "c", giving "cinsn", "cnote" etc. */ if (m_compact && is_a (in_rtx)) @@ -641,14 +772,14 @@ rtx_writer::print_rtx (const_rtx in_rtx) just "clabel". */ rtx_code code = GET_CODE (in_rtx); if (code == CODE_LABEL) - fprintf (m_outfile, "(clabel"); + fprintf (m_outfile, "clabel"); else - fprintf (m_outfile, "(c%s", GET_RTX_NAME (code)); + fprintf (m_outfile, "c%s", GET_RTX_NAME (code)); } else if (m_simple && CONST_INT_P (in_rtx)) - fputc ('(', m_outfile); + ; /* no code. */ else - fprintf (m_outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx))); + fprintf (m_outfile, "%s", GET_RTX_NAME (GET_CODE (in_rtx))); if (! m_simple) { diff --git a/gcc/rtl-tests.c b/gcc/rtl-tests.c index 228226b..3904fa5 100644 --- a/gcc/rtl-tests.c +++ b/gcc/rtl-tests.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "pretty-print.h" #include "cfgbuild.h" #include "print-rtl.h" +#include "print-rtl-reuse.h" #include "selftest.h" #include "selftest-rtl.h" #include "function.h" @@ -126,6 +127,36 @@ test_dumping_insns () LABEL_NAME (label)= "some_label"; ASSERT_RTL_DUMP_EQ ("(clabel 0 42 (\"some_label\"))\n", label); + + /* Manually exercise the rtx_reuse code. */ + { + rtx x = rtx_alloc (SCRATCH); + rtx y = rtx_alloc (SCRATCH); + rtx_reuse r; + r.preprocess (x); + r.preprocess (x); + r.preprocess (y); + r.preprocess (y); + ASSERT_RTL_DUMP_EQ ("(0|scratch)", x); + ASSERT_RTL_DUMP_EQ ("(reuse_rtx 0)", x); + ASSERT_RTL_DUMP_EQ ("(1|scratch)", y); + ASSERT_RTL_DUMP_EQ ("(reuse_rtx 1)", y); + } + + /* Test dumping an insn with repeated references to the same SCRATCH. */ +#ifdef I386_OPTS_H + { + rtx pat = gen_memory_blockage (); + rtx_reuse r; + r.preprocess (pat); + ASSERT_RTL_DUMP_EQ + ("(cinsn (set (mem/v:BLK (0|scratch:DI) [0 A8])\n" + " (unspec:BLK [\n" + " (mem/v:BLK (reuse_rtx 0) [0 A8])\n" + " ] UNSPEC_MEMORY_BLOCKAGE))\n" + " (nil))\n", pat); + } +#endif /* #ifdef I386_OPTS_H */ } /* Unit testing of "single_set". */ -- 1.8.5.3