LCOV - code coverage report
Current view: top level - gcc - gimple-range-trace.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 6.1 % 98 6
Test Date: 2026-02-28 14:20:25 Functions: 7.7 % 13 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Code for GIMPLE range trace and debugging related routines.
       2              :    Copyright (C) 2019-2026 Free Software Foundation, Inc.
       3              :    Contributed by Andrew MacLeod <amacleod@redhat.com>
       4              :    and Aldy Hernandez <aldyh@redhat.com>.
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful,
      14              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16              : GNU General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "backend.h"
      26              : #include "tree.h"
      27              : #include "gimple.h"
      28              : #include "ssa.h"
      29              : #include "gimple-pretty-print.h"
      30              : #include "gimple-iterator.h"
      31              : #include "tree-cfg.h"
      32              : #include "fold-const.h"
      33              : #include "tree-cfg.h"
      34              : #include "cfgloop.h"
      35              : #include "tree-scalar-evolution.h"
      36              : #include "gimple-range.h"
      37              : 
      38              : 
      39              : // Breakpoint to trap at a specific index.  From GDB, this provides a simple
      40              : // place to put a breakpoint to stop at a given trace line.
      41              : // ie.  b range_tracer::breakpoint if index == 45678
      42              : 
      43              : void
      44            0 : range_tracer::breakpoint (unsigned index ATTRIBUTE_UNUSED)
      45              : {
      46            0 : }
      47              : 
      48              : // Construct a range_tracer with component NAME.
      49              : 
      50     55762106 : range_tracer::range_tracer (const char *name)
      51              : {
      52     55762106 :   gcc_checking_assert (strlen(name) < name_len -1);
      53     55762106 :   strcpy (component, name);
      54     55762106 :   indent = 0;
      55     55762106 :   tracing = false;
      56     55762106 : }
      57              : 
      58              : // This routine does the initial line spacing/indenting for a trace.
      59              : // If BLANKS is false, then IDX is printed, otherwise spaces.
      60              : 
      61              : void
      62            0 : range_tracer::print_prefix (unsigned idx, bool blanks)
      63              : {
      64              :   // Print counter index as well as INDENT spaces.
      65            0 :   if (!blanks)
      66            0 :     fprintf (dump_file, "%-7u ", idx);
      67              :   else
      68            0 :     fprintf (dump_file, "        ");
      69            0 :   fprintf (dump_file, "%s ", component);
      70            0 :   unsigned x;
      71            0 :   for (x = 0; x< indent; x++)
      72            0 :     fputc (' ', dump_file);
      73              : 
      74            0 : }
      75              : // If dumping, return the next call index and print the prefix for the next
      76              : // output line.  If not, return 0.
      77              : // Counter is static to monotonically increase across the compilation unit.
      78              : 
      79              : unsigned
      80            0 : range_tracer::do_header (const char *str)
      81              : {
      82            0 :   static unsigned trace_count = 0;
      83              : 
      84            0 :   unsigned idx = ++trace_count;
      85            0 :   print_prefix (idx, false);
      86            0 :   fprintf (dump_file, "%s", str);
      87            0 :   indent += bump;
      88            0 :   breakpoint (idx);
      89            0 :   return idx;
      90              : }
      91              : 
      92              : // Print a line without starting or ending a trace.
      93              : 
      94              : void
      95            0 : range_tracer::print (unsigned counter, const char *str)
      96              : {
      97            0 :   print_prefix (counter, true);
      98            0 :   fprintf (dump_file, "%s", str);
      99            0 : }
     100              : 
     101              : // End a trace and print the CALLER, NAME, and RESULT and range R,
     102              : 
     103              : void
     104            0 : range_tracer::trailer (unsigned counter, const char *caller, bool result,
     105              :                       tree name, const vrange &r)
     106              : {
     107            0 :   gcc_checking_assert (tracing && counter != 0);
     108              : 
     109            0 :   indent -= bump;
     110            0 :   print_prefix (counter, true);
     111            0 :   fputs(result ? "TRUE : " : "FALSE : ", dump_file);
     112            0 :   fprintf (dump_file, "(%u) ", counter);
     113            0 :   fputs (caller, dump_file);
     114            0 :   fputs (" (",dump_file);
     115            0 :   if (name)
     116            0 :     print_generic_expr (dump_file, name, TDF_SLIM);
     117            0 :   fputs (") ",dump_file);
     118            0 :   if (result)
     119              :     {
     120            0 :       r.dump (dump_file);
     121            0 :       fputc('\n', dump_file);
     122              :     }
     123              :   else
     124            0 :     fputc('\n', dump_file);
     125            0 : }
     126              : 
     127              : // =========================================
     128              : // Debugging helpers.
     129              : // =========================================
     130              : 
     131              : // Query all statements in the IL to precalculate computable ranges in RANGER.
     132              : 
     133              : DEBUG_FUNCTION void
     134            0 : debug_seed_ranger (gimple_ranger &ranger)
     135              : {
     136              :   // Recalculate SCEV to make sure the dump lists everything.
     137            0 :   if (scev_initialized_p ())
     138              :     {
     139            0 :       scev_finalize ();
     140            0 :       scev_initialize ();
     141              :     }
     142              : 
     143            0 :   basic_block bb;
     144            0 :   gimple_stmt_iterator gsi;
     145            0 :   FOR_EACH_BB_FN (bb, cfun)
     146            0 :     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     147              :       {
     148            0 :         gimple *stmt = gsi_stmt (gsi);
     149              : 
     150            0 :         if (is_gimple_debug (stmt))
     151            0 :           continue;
     152              : 
     153            0 :         if (tree type = gimple_range_type (stmt))
     154              :           {
     155            0 :             value_range r (type);
     156            0 :             ranger.range_of_stmt (r, stmt);
     157            0 :           }
     158              :       }
     159            0 : }
     160              : 
     161              : // Change the current dump_file and dump_flags to F and FLAGS while
     162              : // saving them for later restoring.
     163              : 
     164            0 : push_dump_file::push_dump_file (FILE *f, dump_flags_t flags)
     165              : {
     166            0 :   old_dump_file = dump_file;
     167            0 :   old_dump_flags = dump_flags;
     168            0 :   dump_file = f;
     169            0 :   dump_flags = flags;
     170            0 : }
     171              : 
     172              : // Restore saved dump_file and dump_flags.
     173              : 
     174            0 : push_dump_file::~push_dump_file ()
     175              : {
     176            0 :   dump_file = old_dump_file;
     177            0 :   dump_flags = old_dump_flags;
     178            0 : }
     179              : 
     180              : // Dump all that ranger knows for the current function.
     181              : 
     182              : void
     183            0 : dump_ranger (FILE *out)
     184              : {
     185            0 :   push_dump_file save (out, dump_flags);
     186            0 :   gimple_ranger ranger;
     187              : 
     188            0 :   fprintf (out, ";; Function ");
     189            0 :   print_generic_expr (out, current_function_decl);
     190            0 :   fprintf (out, "\n");
     191              : 
     192            0 :   debug_seed_ranger (ranger);
     193            0 :   ranger.dump (out);
     194            0 : }
     195              : 
     196              : DEBUG_FUNCTION void
     197            0 : debug_ranger ()
     198              : {
     199            0 :   dump_ranger (stderr);
     200            0 : }
     201              : 
     202              : // Dump all that ranger knows on a path of BBs.
     203              : //
     204              : // Note that the blocks are in reverse order, thus the exit block is
     205              : // path[0].
     206              : 
     207              : void
     208            0 : dump_ranger (FILE *dump_file, const vec<basic_block> &path)
     209              : {
     210            0 :   if (path.length () == 0)
     211              :     {
     212            0 :       fprintf (dump_file, "empty\n");
     213            0 :       return;
     214              :     }
     215              : 
     216            0 :   gimple_ranger ranger;
     217            0 :   debug_seed_ranger (ranger);
     218              : 
     219            0 :   unsigned i = path.length ();
     220            0 :   do
     221              :     {
     222            0 :       i--;
     223            0 :       ranger.dump_bb (dump_file, path[i]);
     224              :     }
     225            0 :   while (i > 0);
     226            0 : }
     227              : 
     228              : DEBUG_FUNCTION void
     229            0 : debug_ranger (const vec<basic_block> &path)
     230              : {
     231            0 :   dump_ranger (stderr, path);
     232            0 : }
     233              : 
     234              : #include "gimple-range-tests.cc"
        

Generated by: LCOV version 2.4-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.