LCOV - code coverage report
Current view: top level - gcc - print-rtl-function.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 75.6 % 86 65
Test Date: 2024-04-20 14:03:02 Functions: 71.4 % 7 5
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Print RTL functions for GCC.
       2                 :             :    Copyright (C) 2016-2024 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : #include "config.h"
      21                 :             : #include "system.h"
      22                 :             : #include "coretypes.h"
      23                 :             : #include "tm.h"
      24                 :             : #include "rtl.h"
      25                 :             : #include "alias.h"
      26                 :             : #include "tree.h"
      27                 :             : #include "flags.h"
      28                 :             : #include "predict.h"
      29                 :             : #include "function.h"
      30                 :             : #include "basic-block.h"
      31                 :             : #include "print-rtl.h"
      32                 :             : #include "langhooks.h"
      33                 :             : #include "memmodel.h"
      34                 :             : #include "emit-rtl.h"
      35                 :             : #include "varasm.h"
      36                 :             : 
      37                 :             : /* Print an "(edge-from)" or "(edge-to)" directive describing E
      38                 :             :    to OUTFILE.  */
      39                 :             : 
      40                 :             : static void
      41                 :           8 : print_edge (FILE *outfile, edge e, bool from)
      42                 :             : {
      43                 :          12 :   fprintf (outfile, "      (%s ", from ? "edge-from" : "edge-to");
      44                 :           8 :   basic_block bb = from ? e->src : e->dest;
      45                 :           8 :   gcc_assert (bb);
      46                 :           8 :   switch (bb->index)
      47                 :             :     {
      48                 :           4 :     case ENTRY_BLOCK:
      49                 :           4 :       fprintf (outfile, "entry");
      50                 :           4 :       break;
      51                 :           4 :     case EXIT_BLOCK:
      52                 :           4 :       fprintf (outfile, "exit");
      53                 :           4 :       break;
      54                 :           0 :     default:
      55                 :           0 :       fprintf (outfile, "%i", bb->index);
      56                 :           0 :       break;
      57                 :             :     }
      58                 :             : 
      59                 :             :   /* Express edge flags as a string with " | " separator.
      60                 :             :      e.g. (flags "FALLTHRU | DFS_BACK").  */
      61                 :           8 :   if (e->flags)
      62                 :             :     {
      63                 :           8 :       fprintf (outfile, " (flags \"");
      64                 :           8 :       bool seen_flag = false;
      65                 :             : #define DEF_EDGE_FLAG(NAME,IDX)                 \
      66                 :             :   do {                                          \
      67                 :             :     if (e->flags & EDGE_##NAME)                  \
      68                 :             :       {                                         \
      69                 :             :         if (seen_flag)                          \
      70                 :             :           fprintf (outfile, " | ");           \
      71                 :             :         fprintf (outfile, "%s", (#NAME));     \
      72                 :             :         seen_flag = true;                       \
      73                 :             :       }                                         \
      74                 :             :   } while (0);
      75                 :             : #include "cfg-flags.def"
      76                 :             : #undef DEF_EDGE_FLAG
      77                 :             : 
      78                 :           8 :       fprintf (outfile, "\")");
      79                 :             :     }
      80                 :             : 
      81                 :           8 :   fprintf (outfile, ")\n");
      82                 :           8 : }
      83                 :             : 
      84                 :             : /* If BB is non-NULL, print the start of a "(block)" directive for it
      85                 :             :    to OUTFILE, otherwise do nothing.  */
      86                 :             : 
      87                 :             : static void
      88                 :           4 : begin_any_block (FILE *outfile, basic_block bb)
      89                 :             : {
      90                 :           4 :   if (!bb)
      91                 :           0 :     return;
      92                 :             : 
      93                 :           4 :   edge e;
      94                 :           4 :   edge_iterator ei;
      95                 :             : 
      96                 :           4 :   fprintf (outfile, "    (block %i\n", bb->index);
      97                 :           8 :   FOR_EACH_EDGE (e, ei, bb->preds)
      98                 :           4 :     print_edge (outfile, e, true);
      99                 :             : }
     100                 :             : 
     101                 :             : /* If BB is non-NULL, print the end of a "(block)" directive for it
     102                 :             :    to OUTFILE, otherwise do nothing.  */
     103                 :             : 
     104                 :             : static void
     105                 :           8 : end_any_block (FILE *outfile, basic_block bb)
     106                 :             : {
     107                 :           8 :   if (!bb)
     108                 :           4 :     return;
     109                 :             : 
     110                 :           4 :   edge e;
     111                 :           4 :   edge_iterator ei;
     112                 :             : 
     113                 :           8 :   FOR_EACH_EDGE (e, ei, bb->succs)
     114                 :           4 :     print_edge (outfile, e, false);
     115                 :           4 :   fprintf (outfile, "    ) ;; block %i\n", bb->index);
     116                 :             : }
     117                 :             : 
     118                 :             : /* Determine if INSN is of a kind that can have a basic block.  */
     119                 :             : 
     120                 :             : static bool
     121                 :          28 : can_have_basic_block_p (const rtx_insn *insn)
     122                 :             : {
     123                 :          28 :   rtx_code code = GET_CODE (insn);
     124                 :          28 :   if (code == BARRIER)
     125                 :             :     return false;
     126                 :          28 :   gcc_assert (GET_RTX_FORMAT (code)[2] == 'B');
     127                 :             :   return true;
     128                 :             : }
     129                 :             : 
     130                 :             : /* Subroutine of print_param.  Write the name of ARG, if any, to OUTFILE.  */
     131                 :             : 
     132                 :             : static void
     133                 :           0 : print_any_param_name (FILE *outfile, tree arg)
     134                 :             : {
     135                 :           0 :   if (DECL_NAME (arg))
     136                 :           0 :     fprintf (outfile, " \"%s\"", IDENTIFIER_POINTER (DECL_NAME (arg)));
     137                 :           0 : }
     138                 :             : 
     139                 :             : /* Print a "(param)" directive for ARG to OUTFILE.  */
     140                 :             : 
     141                 :             : static void
     142                 :           0 : print_param (FILE *outfile, rtx_writer &w, tree arg)
     143                 :             : {
     144                 :           0 :   fprintf (outfile, "  (param");
     145                 :           0 :   print_any_param_name (outfile, arg);
     146                 :           0 :   fprintf (outfile, "\n");
     147                 :             : 
     148                 :             :   /* Print the value of DECL_RTL (without lazy-evaluation).  */
     149                 :           0 :   fprintf (outfile, "    (DECL_RTL ");
     150                 :           0 :   w.print_rtx (DECL_RTL_IF_SET (arg));
     151                 :           0 :   w.finish_directive ();
     152                 :             : 
     153                 :             :   /* Print DECL_INCOMING_RTL.  */
     154                 :           0 :   fprintf (outfile, "    (DECL_RTL_INCOMING ");
     155                 :           0 :   w.print_rtx (DECL_INCOMING_RTL (arg));
     156                 :           0 :   fprintf (outfile, ")");
     157                 :             : 
     158                 :           0 :   w.finish_directive ();
     159                 :           0 : }
     160                 :             : 
     161                 :             : /* Write FN to OUTFILE in a form suitable for parsing, with indentation
     162                 :             :    and comments to make the structure easy for a human to grok.  Track
     163                 :             :    the basic blocks of insns in the chain, wrapping those that are within
     164                 :             :    blocks within "(block)" directives.
     165                 :             : 
     166                 :             :    If COMPACT, then instructions are printed in a compact form:
     167                 :             :    - INSN_UIDs are omitted, except for jumps and CODE_LABELs,
     168                 :             :    - INSN_CODEs are omitted,
     169                 :             :    - register numbers are omitted for hard and virtual regs, and
     170                 :             :      non-virtual pseudos are offset relative to the first such reg, and
     171                 :             :      printed with a '%' sigil e.g. "%0" for (LAST_VIRTUAL_REGISTER + 1),
     172                 :             :    - insn names are prefixed with "c" (e.g. "cinsn", "cnote", etc)
     173                 :             : 
     174                 :             :    Example output (with COMPACT==true):
     175                 :             : 
     176                 :             :    (function "times_two"
     177                 :             :      (param "i"
     178                 :             :        (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
     179                 :             :            (const_int -4)) [1 i+0 S4 A32]))
     180                 :             :        (DECL_RTL_INCOMING (reg:SI di [ i ])))
     181                 :             :      (insn-chain
     182                 :             :        (cnote 1 NOTE_INSN_DELETED)
     183                 :             :        (block 2
     184                 :             :          (edge-from entry (flags "FALLTHRU"))
     185                 :             :          (cnote 4 [bb 2] NOTE_INSN_BASIC_BLOCK)
     186                 :             :          (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
     187                 :             :                                (const_int -4)) [1 i+0 S4 A32])
     188                 :             :                        (reg:SI di [ i ])) "t.c":2)
     189                 :             :          (cnote 3 NOTE_INSN_FUNCTION_BEG)
     190                 :             :          (cinsn 6 (set (reg:SI <2>)
     191                 :             :                        (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
     192                 :             :                                (const_int -4)) [1 i+0 S4 A32])) "t.c":3)
     193                 :             :          (cinsn 7 (parallel [
     194                 :             :                            (set (reg:SI <0> [ _2 ])
     195                 :             :                                (ashift:SI (reg:SI <2>)
     196                 :             :                                    (const_int 1)))
     197                 :             :                            (clobber (reg:CC flags))
     198                 :             :                        ]) "t.c":3
     199                 :             :                     (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
     200                 :             :                                    (const_int -4)) [1 i+0 S4 A32])
     201                 :             :                            (const_int 1))))
     202                 :             :          (cinsn 10 (set (reg:SI <1> [ <retval> ])
     203                 :             :                        (reg:SI <0> [ _2 ])) "t.c":3)
     204                 :             :          (cinsn 14 (set (reg/i:SI ax)
     205                 :             :                        (reg:SI <1> [ <retval> ])) "t.c":4)
     206                 :             :          (cinsn 15 (use (reg/i:SI ax)) "t.c":4)
     207                 :             :          (edge-to exit (flags "FALLTHRU"))
     208                 :             :        ) ;; block 2
     209                 :             :      ) ;; insn-chain
     210                 :             :      (crtl
     211                 :             :        (return_rtx
     212                 :             :          (reg/i:SI ax)
     213                 :             :        ) ;; return_rtx
     214                 :             :      ) ;; crtl
     215                 :             :    ) ;; function "times_two"
     216                 :             : */
     217                 :             : 
     218                 :             : DEBUG_FUNCTION void
     219                 :           4 : print_rtx_function (FILE *outfile, function *fn, bool compact)
     220                 :             : {
     221                 :           4 :   rtx_reuse_manager r;
     222                 :           4 :   rtx_writer w (outfile, 0, false, compact, &r);
     223                 :             : 
     224                 :             :   /* Support "reuse_rtx" in the dump.  */
     225                 :          32 :   for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
     226                 :          28 :     r.preprocess (insn);
     227                 :             : 
     228                 :           4 :   tree fdecl = fn->decl;
     229                 :             : 
     230                 :           4 :   const char *dname = lang_hooks.decl_printable_name (fdecl, 1);
     231                 :             : 
     232                 :           4 :   fprintf (outfile, "(function \"%s\"\n", dname);
     233                 :             : 
     234                 :             :   /* Params.  */
     235                 :           4 :   for (tree arg = DECL_ARGUMENTS (fdecl); arg; arg = DECL_CHAIN (arg))
     236                 :           0 :     print_param (outfile, w, arg);
     237                 :             : 
     238                 :             :   /* The instruction chain.  */
     239                 :           4 :   fprintf (outfile, "  (insn-chain\n");
     240                 :           4 :   basic_block curr_bb = NULL;
     241                 :          32 :   for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
     242                 :             :     {
     243                 :          28 :       basic_block insn_bb;
     244                 :          28 :       if (can_have_basic_block_p (insn))
     245                 :          28 :         insn_bb = BLOCK_FOR_INSN (insn);
     246                 :             :       else
     247                 :             :         insn_bb = NULL;
     248                 :          28 :       if (curr_bb != insn_bb)
     249                 :             :         {
     250                 :           4 :           end_any_block (outfile, curr_bb);
     251                 :           4 :           curr_bb = insn_bb;
     252                 :           4 :           begin_any_block (outfile, curr_bb);
     253                 :             :         }
     254                 :          32 :       w.print_rtl_single_with_indent (insn, curr_bb ? 6 : 4);
     255                 :             :     }
     256                 :           4 :   end_any_block (outfile, curr_bb);
     257                 :           4 :   fprintf (outfile, "  ) ;; insn-chain\n");
     258                 :             : 
     259                 :             :   /* Additional RTL state.  */
     260                 :           4 :   fprintf (outfile, "  (crtl\n");
     261                 :           4 :   fprintf (outfile, "    (return_rtx \n");
     262                 :           4 :   w.print_rtl_single_with_indent (crtl->return_rtx, 6);
     263                 :           4 :   fprintf (outfile, "    ) ;; return_rtx\n");
     264                 :           4 :   fprintf (outfile, "  ) ;; crtl\n");
     265                 :             : 
     266                 :           4 :   fprintf (outfile, ") ;; function \"%s\"\n", dname);
     267                 :           4 : }
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.