(root)/
gcc-13.2.0/
gcc/
dump-context.h
       1  /* Support code for handling the various dump_* calls in dumpfile.h
       2     Copyright (C) 2018-2023 Free Software Foundation, Inc.
       3     Contributed by David Malcolm <dmalcolm@redhat.com>.
       4  
       5  This file is part of GCC.
       6  
       7  GCC is free software; you can redistribute it and/or modify
       8  it under the terms of the GNU General Public License as published by
       9  the Free Software Foundation; either version 3, or (at your option)
      10  any later version.
      11  
      12  GCC is distributed in the hope that it will be useful,
      13  but WITHOUT ANY WARRANTY; without even the implied warranty of
      14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15  GNU General Public License for more details.
      16  
      17  You should have received a copy of the GNU General Public License
      18  along with GCC; see the file COPYING3.  If not see
      19  <http://www.gnu.org/licenses/>.  */
      20  
      21  
      22  #ifndef GCC_DUMP_CONTEXT_H
      23  #define GCC_DUMP_CONTEXT_H 1
      24  
      25  #include "dumpfile.h"
      26  #include "pretty-print.h"
      27  #include "selftest.h"
      28  #include "optinfo.h"
      29  
      30  class optrecord_json_writer;
      31  namespace selftest { class temp_dump_context; }
      32  class debug_dump_context;
      33  
      34  /* A class for handling the various dump_* calls.
      35  
      36     In particular, this class has responsibility for consolidating
      37     the "dump_*" calls into optinfo instances (delimited by "dump_*_loc"
      38     calls), and emitting them.
      39  
      40     Putting this in a class (rather than as global state) allows
      41     for selftesting of this code.  */
      42  
      43  class dump_context
      44  {
      45    friend class selftest::temp_dump_context;
      46    friend class debug_dump_context;
      47  
      48   public:
      49    static dump_context &get () { return *s_current; }
      50  
      51    ~dump_context ();
      52  
      53    void refresh_dumps_are_enabled ();
      54  
      55    void dump_loc (const dump_metadata_t &metadata,
      56  		 const dump_user_location_t &loc);
      57    void dump_loc_immediate (dump_flags_t dump_kind,
      58  			   const dump_user_location_t &loc);
      59  
      60    void dump_gimple_stmt (const dump_metadata_t &metadata,
      61  			 dump_flags_t extra_dump_flags,
      62  			 gimple *gs, int spc);
      63  
      64    void dump_gimple_stmt_loc (const dump_metadata_t &metadata,
      65  			     const dump_user_location_t &loc,
      66  			     dump_flags_t extra_dump_flags,
      67  			     gimple *gs, int spc);
      68  
      69    void dump_gimple_expr (const dump_metadata_t &metadata,
      70  			 dump_flags_t extra_dump_flags,
      71  			 gimple *gs, int spc);
      72  
      73    void dump_gimple_expr_loc (const dump_metadata_t &metadata,
      74  			     const dump_user_location_t &loc,
      75  			     dump_flags_t extra_dump_flags,
      76  			     gimple *gs,
      77  			     int spc);
      78  
      79    void dump_generic_expr (const dump_metadata_t &metadata,
      80  			  dump_flags_t extra_dump_flags,
      81  			  tree t);
      82  
      83    void dump_generic_expr_loc (const dump_metadata_t &metadata,
      84  			      const dump_user_location_t &loc,
      85  			      dump_flags_t extra_dump_flags,
      86  			      tree t);
      87  
      88    void dump_printf_va (const dump_metadata_t &metadata, const char *format,
      89  		       va_list *ap) ATTRIBUTE_GCC_DUMP_PRINTF (3, 0);
      90  
      91    void dump_printf_loc_va (const dump_metadata_t &metadata,
      92  			   const dump_user_location_t &loc,
      93  			   const char *format, va_list *ap)
      94      ATTRIBUTE_GCC_DUMP_PRINTF (4, 0);
      95  
      96    template<unsigned int N, typename C>
      97    void dump_dec (const dump_metadata_t &metadata, const poly_int<N, C> &value);
      98  
      99    void dump_symtab_node (const dump_metadata_t &metadata, symtab_node *node);
     100  
     101    /* Managing nested scopes.  */
     102    unsigned int get_scope_depth () const;
     103    void begin_scope (const char *name,
     104  		    const dump_user_location_t &user_location,
     105  		    const dump_impl_location_t &impl_location);
     106    void end_scope ();
     107  
     108    /* Should optinfo instances be created?
     109       All creation of optinfos should be guarded by this predicate.
     110       Return true if any optinfo destinations are active.  */
     111    bool optinfo_enabled_p () const;
     112  
     113    bool optimization_records_enabled_p () const
     114    {
     115      return m_json_writer != NULL;
     116    }
     117    void set_json_writer (optrecord_json_writer *writer);
     118    void finish_any_json_writer ();
     119  
     120    void end_any_optinfo ();
     121  
     122    void emit_optinfo (const optinfo *info);
     123    void emit_item (optinfo_item *item, dump_flags_t dump_kind);
     124  
     125    bool apply_dump_filter_p (dump_flags_t dump_kind, dump_flags_t filter) const;
     126  
     127   private:
     128    optinfo &ensure_pending_optinfo (const dump_metadata_t &metadata);
     129    optinfo &begin_next_optinfo (const dump_metadata_t &metadata,
     130  			       const dump_user_location_t &loc);
     131  
     132    /* The current nesting depth of dump scopes, for showing nesting
     133       via indentation).  */
     134    unsigned int m_scope_depth;
     135  
     136    /* The optinfo currently being accumulated since the last dump_*_loc call,
     137       if any.  */
     138    optinfo *m_pending;
     139  
     140    /* If -fsave-optimization-record is enabled, the heap-allocated JSON writer
     141       instance, otherwise NULL.  */
     142    optrecord_json_writer *m_json_writer;
     143  
     144    /* For use in selftests: if non-NULL, then items are to be printed
     145       to this, using the given flags.  */
     146    pretty_printer *m_test_pp;
     147    dump_flags_t m_test_pp_flags;
     148  
     149    /* The currently active dump_context, for use by the dump_* API calls.  */
     150    static dump_context *s_current;
     151  
     152    /* The default active context.  */
     153    static dump_context s_default;
     154  };
     155  
     156  /* A subclass of pretty_printer for implementing dump_context::dump_printf_va.
     157     In particular, the formatted chunks are captured as optinfo_item instances,
     158     thus retaining metadata about the entities being dumped (e.g. source
     159     locations), rather than just as plain text.  */
     160  
     161  class dump_pretty_printer : public pretty_printer
     162  {
     163  public:
     164    dump_pretty_printer (dump_context *context, dump_flags_t dump_kind);
     165  
     166    void emit_items (optinfo *dest);
     167  
     168  private:
     169    /* Information on an optinfo_item that was generated during phase 2 of
     170       formatting.  */
     171    class stashed_item
     172    {
     173    public:
     174      stashed_item (const char **buffer_ptr_, optinfo_item *item_)
     175        : buffer_ptr (buffer_ptr_), item (item_) {}
     176      const char **buffer_ptr;
     177      optinfo_item *item;
     178    };
     179  
     180    static bool format_decoder_cb (pretty_printer *pp, text_info *text,
     181  				 const char *spec, int /*precision*/,
     182  				 bool /*wide*/, bool /*set_locus*/,
     183  				 bool /*verbose*/, bool */*quoted*/,
     184  				 const char **buffer_ptr);
     185  
     186    bool decode_format (text_info *text, const char *spec,
     187  		      const char **buffer_ptr);
     188  
     189    void stash_item (const char **buffer_ptr, optinfo_item *item);
     190  
     191    void emit_any_pending_textual_chunks (optinfo *dest);
     192  
     193    void emit_item (optinfo_item *item, optinfo *dest);
     194  
     195    dump_context *m_context;
     196    dump_flags_t m_dump_kind;
     197    auto_vec<stashed_item> m_stashed_items;
     198  };
     199  
     200  /* An RAII-style class for use in debug dumpers for temporarily using a
     201     different dump_context.  It enables full details and outputs to
     202     stderr instead of the currently active dump_file.  */
     203  
     204  class debug_dump_context
     205  {
     206   public:
     207    debug_dump_context (FILE *f = stderr);
     208    ~debug_dump_context ();
     209  
     210   private:
     211    dump_context m_context;
     212    dump_context *m_saved;
     213    dump_flags_t m_saved_flags;
     214    dump_flags_t m_saved_pflags;
     215    FILE *m_saved_file;
     216  };
     217  
     218  
     219  #if CHECKING_P
     220  
     221  namespace selftest {
     222  
     223  /* An RAII-style class for use in selftests for temporarily using a different
     224     dump_context.  */
     225  
     226  class temp_dump_context
     227  {
     228   public:
     229    temp_dump_context (bool forcibly_enable_optinfo,
     230  		     bool forcibly_enable_dumping,
     231  		     dump_flags_t test_pp_flags);
     232    ~temp_dump_context ();
     233  
     234    /* Support for selftests.  */
     235    optinfo *get_pending_optinfo () const { return m_context.m_pending; }
     236    const char *get_dumped_text ();
     237  
     238   private:
     239    pretty_printer m_pp;
     240    dump_context m_context;
     241    dump_context *m_saved;
     242  };
     243  
     244  /* Implementation detail of ASSERT_DUMPED_TEXT_EQ.  */
     245  
     246  extern void verify_dumped_text (const location &loc,
     247  				temp_dump_context *context,
     248  				const char *expected_text);
     249  
     250  /* Verify that the text dumped so far in CONTEXT equals
     251     EXPECTED_TEXT.
     252     As a side-effect, the internal buffer is 0-terminated.  */
     253  
     254  #define ASSERT_DUMPED_TEXT_EQ(CONTEXT, EXPECTED_TEXT)			\
     255    SELFTEST_BEGIN_STMT							\
     256      verify_dumped_text (SELFTEST_LOCATION, &(CONTEXT), (EXPECTED_TEXT)); \
     257    SELFTEST_END_STMT
     258  
     259  
     260  /* Verify that ITEM has the expected values.  */
     261  
     262  void
     263  verify_item (const location &loc,
     264  	     const optinfo_item *item,
     265  	     enum optinfo_item_kind expected_kind,
     266  	     location_t expected_location,
     267  	     const char *expected_text);
     268  
     269  /* Verify that ITEM is a text item, with EXPECTED_TEXT.  */
     270  
     271  #define ASSERT_IS_TEXT(ITEM, EXPECTED_TEXT) \
     272    SELFTEST_BEGIN_STMT						    \
     273      verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_TEXT, \
     274  		 UNKNOWN_LOCATION, (EXPECTED_TEXT));		    \
     275    SELFTEST_END_STMT
     276  
     277  /* Verify that ITEM is a tree item, with the expected values.  */
     278  
     279  #define ASSERT_IS_TREE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
     280    SELFTEST_BEGIN_STMT						    \
     281      verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_TREE, \
     282  		 (EXPECTED_LOCATION), (EXPECTED_TEXT));	    \
     283    SELFTEST_END_STMT
     284  
     285  /* Verify that ITEM is a gimple item, with the expected values.  */
     286  
     287  #define ASSERT_IS_GIMPLE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
     288    SELFTEST_BEGIN_STMT						    \
     289      verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_GIMPLE, \
     290  		 (EXPECTED_LOCATION), (EXPECTED_TEXT));	    \
     291    SELFTEST_END_STMT
     292  
     293  /* Verify that ITEM is a symtab node, with the expected values.  */
     294  
     295  #define ASSERT_IS_SYMTAB_NODE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
     296    SELFTEST_BEGIN_STMT						    \
     297      verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_SYMTAB_NODE, \
     298  		 (EXPECTED_LOCATION), (EXPECTED_TEXT));	    \
     299    SELFTEST_END_STMT
     300  
     301  } // namespace selftest
     302  
     303  #endif /* CHECKING_P */
     304  
     305  #endif /* GCC_DUMP_CONTEXT_H */