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-10-17 16:30:31 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 "cfgloop.h"
      34              : #include "tree-scalar-evolution.h"
      35              : #include "gimple-range.h"
      36              : 
      37              : 
      38              : // Breakpoint to trap at a specific index.  From GDB, this provides a simple
      39              : // place to put a breakpoint to stop at a given trace line.
      40              : // ie.  b range_tracer::breakpoint if index == 45678
      41              : 
      42              : void
      43            0 : range_tracer::breakpoint (unsigned index ATTRIBUTE_UNUSED)
      44              : {
      45            0 : }
      46              : 
      47              : // Construct a range_tracer with component NAME.
      48              : 
      49     59786473 : range_tracer::range_tracer (const char *name)
      50              : {
      51     59786473 :   gcc_checking_assert (strlen(name) < name_len -1);
      52     59786473 :   strcpy (component, name);
      53     59786473 :   indent = 0;
      54     59786473 :   tracing = false;
      55     59786473 : }
      56              : 
      57              : // This routine does the initial line spacing/indenting for a trace.
      58              : // If BLANKS is false, then IDX is printed, otherwise spaces.
      59              : 
      60              : void
      61            0 : range_tracer::print_prefix (unsigned idx, bool blanks)
      62              : {
      63              :   // Print counter index as well as INDENT spaces.
      64            0 :   if (!blanks)
      65            0 :     fprintf (dump_file, "%-7u ", idx);
      66              :   else
      67            0 :     fprintf (dump_file, "        ");
      68            0 :   fprintf (dump_file, "%s ", component);
      69            0 :   unsigned x;
      70            0 :   for (x = 0; x< indent; x++)
      71            0 :     fputc (' ', dump_file);
      72              : 
      73            0 : }
      74              : // If dumping, return the next call index and print the prefix for the next
      75              : // output line.  If not, return 0.
      76              : // Counter is static to monotonically increase across the compilation unit.
      77              : 
      78              : unsigned
      79            0 : range_tracer::do_header (const char *str)
      80              : {
      81            0 :   static unsigned trace_count = 0;
      82              : 
      83            0 :   unsigned idx = ++trace_count;
      84            0 :   print_prefix (idx, false);
      85            0 :   fprintf (dump_file, "%s", str);
      86            0 :   indent += bump;
      87            0 :   breakpoint (idx);
      88            0 :   return idx;
      89              : }
      90              : 
      91              : // Print a line without starting or ending a trace.
      92              : 
      93              : void
      94            0 : range_tracer::print (unsigned counter, const char *str)
      95              : {
      96            0 :   print_prefix (counter, true);
      97            0 :   fprintf (dump_file, "%s", str);
      98            0 : }
      99              : 
     100              : // End a trace and print the CALLER, NAME, and RESULT and range R,
     101              : 
     102              : void
     103            0 : range_tracer::trailer (unsigned counter, const char *caller, bool result,
     104              :                       tree name, const vrange &r)
     105              : {
     106            0 :   gcc_checking_assert (tracing && counter != 0);
     107              : 
     108            0 :   indent -= bump;
     109            0 :   print_prefix (counter, true);
     110            0 :   fputs(result ? "TRUE : " : "FALSE : ", dump_file);
     111            0 :   fprintf (dump_file, "(%u) ", counter);
     112            0 :   fputs (caller, dump_file);
     113            0 :   fputs (" (",dump_file);
     114            0 :   if (name)
     115            0 :     print_generic_expr (dump_file, name, TDF_SLIM);
     116            0 :   fputs (") ",dump_file);
     117            0 :   if (result)
     118              :     {
     119            0 :       r.dump (dump_file);
     120            0 :       fputc('\n', dump_file);
     121              :     }
     122              :   else
     123            0 :     fputc('\n', dump_file);
     124            0 : }
     125              : 
     126              : // =========================================
     127              : // Debugging helpers.
     128              : // =========================================
     129              : 
     130              : // Query all statements in the IL to precalculate computable ranges in RANGER.
     131              : 
     132              : DEBUG_FUNCTION void
     133            0 : debug_seed_ranger (gimple_ranger &ranger)
     134              : {
     135              :   // Recalculate SCEV to make sure the dump lists everything.
     136            0 :   if (scev_initialized_p ())
     137              :     {
     138            0 :       scev_finalize ();
     139            0 :       scev_initialize ();
     140              :     }
     141              : 
     142            0 :   basic_block bb;
     143            0 :   gimple_stmt_iterator gsi;
     144            0 :   FOR_EACH_BB_FN (bb, cfun)
     145            0 :     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     146              :       {
     147            0 :         gimple *stmt = gsi_stmt (gsi);
     148              : 
     149            0 :         if (is_gimple_debug (stmt))
     150            0 :           continue;
     151              : 
     152            0 :         if (tree type = gimple_range_type (stmt))
     153              :           {
     154            0 :             value_range r (type);
     155            0 :             ranger.range_of_stmt (r, stmt);
     156            0 :           }
     157              :       }
     158            0 : }
     159              : 
     160              : // Change the current dump_file and dump_flags to F and FLAGS while
     161              : // saving them for later restoring.
     162              : 
     163            0 : push_dump_file::push_dump_file (FILE *f, dump_flags_t flags)
     164              : {
     165            0 :   old_dump_file = dump_file;
     166            0 :   old_dump_flags = dump_flags;
     167            0 :   dump_file = f;
     168            0 :   dump_flags = flags;
     169            0 : }
     170              : 
     171              : // Restore saved dump_file and dump_flags.
     172              : 
     173            0 : push_dump_file::~push_dump_file ()
     174              : {
     175            0 :   dump_file = old_dump_file;
     176            0 :   dump_flags = old_dump_flags;
     177            0 : }
     178              : 
     179              : // Dump all that ranger knows for the current function.
     180              : 
     181              : void
     182            0 : dump_ranger (FILE *out)
     183              : {
     184            0 :   push_dump_file save (out, dump_flags);
     185            0 :   gimple_ranger ranger;
     186              : 
     187            0 :   fprintf (out, ";; Function ");
     188            0 :   print_generic_expr (out, current_function_decl);
     189            0 :   fprintf (out, "\n");
     190              : 
     191            0 :   debug_seed_ranger (ranger);
     192            0 :   ranger.dump (out);
     193            0 : }
     194              : 
     195              : DEBUG_FUNCTION void
     196            0 : debug_ranger ()
     197              : {
     198            0 :   dump_ranger (stderr);
     199            0 : }
     200              : 
     201              : // Dump all that ranger knows on a path of BBs.
     202              : //
     203              : // Note that the blocks are in reverse order, thus the exit block is
     204              : // path[0].
     205              : 
     206              : void
     207            0 : dump_ranger (FILE *dump_file, const vec<basic_block> &path)
     208              : {
     209            0 :   if (path.length () == 0)
     210              :     {
     211            0 :       fprintf (dump_file, "empty\n");
     212            0 :       return;
     213              :     }
     214              : 
     215            0 :   gimple_ranger ranger;
     216            0 :   debug_seed_ranger (ranger);
     217              : 
     218            0 :   unsigned i = path.length ();
     219            0 :   do
     220              :     {
     221            0 :       i--;
     222            0 :       ranger.dump_bb (dump_file, path[i]);
     223              :     }
     224            0 :   while (i > 0);
     225            0 : }
     226              : 
     227              : DEBUG_FUNCTION void
     228            0 : debug_ranger (const vec<basic_block> &path)
     229              : {
     230            0 :   dump_ranger (stderr, path);
     231            0 : }
     232              : 
     233              : #include "gimple-range-tests.cc"
        

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