(root)/
gcc-13.2.0/
gcc/
analyzer/
program-point.h
       1  /* Classes for representing locations within the program.
       2     Copyright (C) 2019-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 it
       8  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, but
      13  WITHOUT ANY WARRANTY; without even the implied warranty of
      14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15  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  #ifndef GCC_ANALYZER_PROGRAM_POINT_H
      22  #define GCC_ANALYZER_PROGRAM_POINT_H
      23  
      24  #include "pretty-print.h"
      25  #include "analyzer/call-string.h"
      26  
      27  namespace ana {
      28  
      29  class exploded_graph;
      30  
      31  /* An enum for distinguishing the various kinds of program_point.  */
      32  
      33  enum point_kind {
      34    /* A "fake" node which has edges to all entrypoints.  */
      35    PK_ORIGIN,
      36  
      37    PK_BEFORE_SUPERNODE,
      38    PK_BEFORE_STMT,
      39    PK_AFTER_SUPERNODE,
      40  
      41    /* Special values used for hash_map:  */
      42    PK_EMPTY,
      43    PK_DELETED,
      44  
      45    NUM_POINT_KINDS
      46  };
      47  
      48  extern const char *point_kind_to_string (enum point_kind pk);
      49  
      50  class format
      51  {
      52  public:
      53    format (bool newlines) : m_newlines (newlines) {}
      54  
      55    void spacer (pretty_printer *pp) const
      56    {
      57      if (m_newlines)
      58        pp_newline (pp);
      59      else
      60        pp_space (pp);
      61    }
      62  
      63    bool m_newlines;
      64  };
      65  
      66  /* A class for representing a location within the program, without
      67     interprocedural information.
      68  
      69     This represents a fine-grained location within the supergraph (or
      70     within one of its nodes).  */
      71  
      72  class function_point
      73  {
      74  public:
      75    function_point (const supernode *supernode,
      76  		  const superedge *from_edge,
      77  		  unsigned stmt_idx,
      78  		  enum point_kind kind);
      79  
      80    void print (pretty_printer *pp, const format &f) const;
      81    void print_source_line (pretty_printer *pp) const;
      82    void dump () const;
      83  
      84    hashval_t hash () const;
      85    bool operator== (const function_point &other) const
      86    {
      87      return (m_supernode == other.m_supernode
      88  	    && m_from_edge == other.m_from_edge
      89  	    && m_stmt_idx == other.m_stmt_idx
      90  	    && m_kind == other.m_kind);
      91    }
      92  
      93    /* Accessors.  */
      94  
      95    const supernode *get_supernode () const { return m_supernode; }
      96    function *get_function () const;
      97    const gimple *get_stmt () const;
      98    location_t get_location () const;
      99    enum point_kind get_kind () const { return m_kind; }
     100    const superedge *get_from_edge () const
     101    {
     102      return m_from_edge;
     103    }
     104    unsigned get_stmt_idx () const
     105    {
     106      gcc_assert (m_kind == PK_BEFORE_STMT);
     107      return m_stmt_idx;
     108    }
     109  
     110    bool final_stmt_p () const;
     111  
     112    /* Factory functions for making various kinds of program_point.  */
     113  
     114    static function_point from_function_entry (const supergraph &sg,
     115  					     function *fun);
     116  
     117    static function_point before_supernode (const supernode *supernode,
     118  					  const superedge *from_edge);
     119  
     120    static function_point before_stmt (const supernode *supernode,
     121  				     unsigned stmt_idx)
     122    {
     123      return function_point (supernode, NULL, stmt_idx, PK_BEFORE_STMT);
     124    }
     125  
     126    static function_point after_supernode (const supernode *supernode)
     127    {
     128      return function_point (supernode, NULL, 0, PK_AFTER_SUPERNODE);
     129    }
     130  
     131    /* Support for hash_map.  */
     132  
     133    static function_point empty ()
     134    {
     135      return function_point (NULL, NULL, 0, PK_EMPTY);
     136    }
     137    static function_point deleted ()
     138    {
     139      return function_point (NULL, NULL, 0, PK_DELETED);
     140    }
     141  
     142    static int cmp_within_supernode_1 (const function_point &point_a,
     143  				     const function_point &point_b);
     144    static int cmp_within_supernode (const function_point &point_a,
     145  				   const function_point &point_b);
     146    static int cmp (const function_point &point_a,
     147  		  const function_point &point_b);
     148    static int cmp_ptr (const void *p1, const void *p2);
     149  
     150    /* For before_stmt, go to next stmt.  */
     151    void next_stmt ();
     152  
     153    function_point get_next () const;
     154  
     155   private:
     156    const supernode *m_supernode;
     157  
     158    /* For PK_BEFORE_SUPERNODE, and only for CFG edges.  */
     159    const superedge *m_from_edge;
     160  
     161    /* Only for PK_BEFORE_STMT.  */
     162    unsigned m_stmt_idx;
     163  
     164    enum point_kind m_kind;
     165  };
     166  
     167  /* A class for representing a location within the program, including
     168     interprocedural information.
     169  
     170     This represents a fine-grained location within the supergraph (or
     171     within one of its nodes), along with a call string giving the
     172     interprocedural context.  */
     173  
     174  class program_point
     175  {
     176  public:
     177    program_point (const function_point &fn_point,
     178  		 const call_string &call_string)
     179    : m_function_point (fn_point),
     180      m_call_string (&call_string)
     181    {
     182    }
     183  
     184    void print (pretty_printer *pp, const format &f) const;
     185    void dump () const;
     186  
     187    json::object *to_json () const;
     188  
     189    hashval_t hash () const;
     190    bool operator== (const program_point &other) const
     191    {
     192      return (m_function_point == other.m_function_point
     193  	    && m_call_string == other.m_call_string);
     194    }
     195    bool operator!= (const program_point &other) const
     196    {
     197      return !(*this == other);
     198    }
     199  
     200    /* Accessors.  */
     201  
     202    const function_point &get_function_point () const { return m_function_point; }
     203    const call_string &get_call_string () const { return *m_call_string; }
     204  
     205    const supernode *get_supernode () const
     206    {
     207      return m_function_point.get_supernode ();
     208    }
     209    function *get_function () const
     210    {
     211      return m_function_point.get_function ();
     212    }
     213    function *get_function_at_depth (unsigned depth) const;
     214    tree get_fndecl () const
     215    {
     216      gcc_assert (get_kind () != PK_ORIGIN);
     217      return get_function ()->decl;
     218    }
     219    const gimple *get_stmt () const
     220    {
     221      return m_function_point.get_stmt ();
     222    }
     223    location_t get_location () const
     224    {
     225      return m_function_point.get_location ();
     226    }
     227    enum point_kind get_kind () const
     228    {
     229      return m_function_point.get_kind ();
     230    }
     231    const superedge *get_from_edge () const
     232    {
     233      return m_function_point.get_from_edge ();
     234    }
     235    unsigned get_stmt_idx () const
     236    {
     237      return m_function_point.get_stmt_idx ();
     238    }
     239  
     240    /* Get the number of frames we expect at this program point.
     241       This will be one more than the length of the call_string
     242       (which stores the parent callsites), apart from the origin
     243       node, which doesn't have any frames.  */
     244    int get_stack_depth () const
     245    {
     246      if (get_kind () == PK_ORIGIN)
     247        return 0;
     248      return get_call_string ().length () + 1;
     249    }
     250  
     251    /* Factory functions for making various kinds of program_point.  */
     252    static program_point origin (const region_model_manager &mgr);
     253    static program_point from_function_entry (const region_model_manager &mgr,
     254  					    const supergraph &sg,
     255  					    function *fun);
     256  
     257    static program_point before_supernode (const supernode *supernode,
     258  					 const superedge *from_edge,
     259  					 const call_string &call_string)
     260    {
     261      return program_point (function_point::before_supernode (supernode,
     262  							    from_edge),
     263  			  call_string);
     264    }
     265  
     266    static program_point before_stmt (const supernode *supernode,
     267  				    unsigned stmt_idx,
     268  				    const call_string &call_string)
     269    {
     270      return program_point (function_point::before_stmt (supernode, stmt_idx),
     271  			  call_string);
     272    }
     273  
     274    static program_point after_supernode (const supernode *supernode,
     275  					const call_string &call_string)
     276    {
     277      return program_point (function_point::after_supernode (supernode),
     278  			  call_string);
     279    }
     280  
     281    /* Support for hash_map.  */
     282  
     283    static program_point empty ()
     284    {
     285      return program_point (function_point::empty ());
     286    }
     287    static program_point deleted ()
     288    {
     289      return program_point (function_point::deleted ());
     290    }
     291  
     292    bool on_edge (exploded_graph &eg, const superedge *succ);
     293    void push_to_call_stack (const supernode *caller, const supernode *callee);
     294    void pop_from_call_stack ();
     295    void validate () const;
     296  
     297    /* For before_stmt, go to next stmt.  */
     298    void next_stmt () { m_function_point.next_stmt (); }
     299  
     300    program_point get_next () const;
     301  
     302    static bool effectively_intraprocedural_p (const program_point &point_a,
     303  					     const program_point &point_b);
     304  
     305   private:
     306    program_point (const function_point &fn_point)
     307    : m_function_point (fn_point),
     308      m_call_string (NULL)
     309    {
     310    }
     311  
     312    function_point m_function_point;
     313    const call_string *m_call_string;
     314  };
     315  
     316  } // namespace ana
     317  
     318  #endif /* GCC_ANALYZER_PROGRAM_POINT_H */