LCOV - code coverage report
Current view: top level - gcc - pointer-query.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 2 2 100.0 %
Date: 2023-07-19 08:18:47 Functions: 0 0 -

          Line data    Source code
       1             : /* Definitions of the pointer_query and related classes.
       2             : 
       3             :    Copyright (C) 2020-2023 Free Software Foundation, Inc.
       4             : 
       5             :    This file is part of GCC.
       6             : 
       7             :    GCC is free software; you can redistribute it and/or modify it under
       8             :    the terms of the GNU General Public License as published by the Free
       9             :    Software Foundation; either version 3, or (at your option) any later
      10             :    version.
      11             : 
      12             :    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13             :    WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14             :    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15             :    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_POINTER_QUERY_H
      22             : #define GCC_POINTER_QUERY_H
      23             : 
      24             : /* Describes recursion limits used by functions that follow use-def
      25             :    chains of SSA_NAMEs.  */
      26             : 
      27             : class ssa_name_limit_t
      28             : {
      29             :   bitmap visited;         /* Bitmap of visited SSA_NAMEs.  */
      30             :   unsigned ssa_def_max;   /* Longest chain of SSA_NAMEs to follow.  */
      31             : 
      32             :   /* Not copyable or assignable.  */
      33             :   DISABLE_COPY_AND_ASSIGN (ssa_name_limit_t);
      34             : 
      35             : public:
      36             : 
      37             :   ssa_name_limit_t ()
      38             :     : visited (),
      39             :       ssa_def_max (param_ssa_name_def_chain_limit) { }
      40             : 
      41             :   /* Set a bit for the PHI in VISITED and return true if it wasn't
      42             :      already set.  */
      43             :   bool visit_phi (tree);
      44             :   /* Clear a bit for the PHI in VISITED.  */
      45             :   void leave_phi (tree);
      46             :   /* Return false if the SSA_NAME chain length counter has reached
      47             :      the limit, otherwise increment the counter and return true.  */
      48             :   bool next ();
      49             : 
      50             :   /* If the SSA_NAME has already been "seen" return a positive value.
      51             :      Otherwise add it to VISITED.  If the SSA_NAME limit has been
      52             :      reached, return a negative value.  Otherwise return zero.  */
      53             :   int next_phi (tree);
      54             : 
      55             :   ~ssa_name_limit_t ();
      56             : };
      57             : 
      58             : class pointer_query;
      59             : 
      60             : /* Describes a reference to an object used in an access.  */
      61             : struct access_ref
      62             : {
      63             :   /* Set the bounds of the reference.  */
      64             :   access_ref ();
      65             : 
      66             :   /* Return the PHI node REF refers to or null if it doesn't.  */
      67             :   gphi *phi () const;
      68             : 
      69             :   /* Merge the result for a pointer with *THIS.  */
      70             :   void merge_ref (vec<access_ref> *all_refs, tree, gimple *, int, bool,
      71             :                   ssa_name_limit_t &, pointer_query &);
      72             : 
      73             :   /* Return the object to which REF refers.  */
      74             :   tree get_ref (vec<access_ref> *, access_ref * = nullptr, int = 1,
      75             :                 ssa_name_limit_t * = nullptr, pointer_query * = nullptr) const;
      76             : 
      77             :   /* Return true if OFFRNG is the constant zero.  */
      78             :   bool offset_zero () const
      79             :   {
      80             :     return offrng[0] == 0 && offrng[1] == 0;
      81             :   }
      82             : 
      83             :   /* Return true if OFFRNG is bounded to a subrange of offset values
      84             :      valid for the largest possible object.  */
      85             :   bool offset_bounded () const;
      86             : 
      87             :   /* Return the maximum amount of space remaining and if non-null, set
      88             :      argument to the minimum.  */
      89             :   offset_int size_remaining (offset_int * = nullptr) const;
      90             : 
      91             :   /* Return true if the offset and object size are in range for SIZE.  */
      92             :   bool offset_in_range (const offset_int &) const;
      93             : 
      94             :   /* Return true if *THIS is an access to a declared object.  */
      95             :   bool ref_declared () const
      96             :   {
      97             :     return DECL_P (ref) && base0 && deref < 1;
      98             :   }
      99             : 
     100             :   /* Set the size range to the maximum.  */
     101             :   void set_max_size_range ()
     102             :   {
     103             :     sizrng[0] = 0;
     104             :     sizrng[1] = wi::to_offset (max_object_size ());
     105             :   }
     106             : 
     107             :   /* Add OFF to the offset range.  */
     108             :   void add_offset (const offset_int &off)
     109             :   {
     110             :     add_offset (off, off);
     111             :   }
     112             : 
     113             :   /* Add the range [MIN, MAX] to the offset range.  */
     114             :   void add_offset (const offset_int &, const offset_int &);
     115             : 
     116             :   /* Add the maximum representable offset to the offset range.  */
     117             :   void add_max_offset ()
     118             :   {
     119             :     offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
     120             :     add_offset (-maxoff - 1, maxoff);
     121             :   }
     122             : 
     123             :   /* Issue an informational message describing the target of an access
     124             :      with the given mode.  */
     125             :   void inform_access (access_mode, int = 1) const;
     126             : 
     127             :   /* Dump *THIS to a file.  */
     128             :   void dump (FILE *) const;
     129             : 
     130             :   /* Reference to the accessed object(s).  */
     131             :   tree ref;
     132             : 
     133             :   /* Range of byte offsets into and sizes of the object(s).  */
     134             :   offset_int offrng[2];
     135             :   offset_int sizrng[2];
     136             :   /* The minimum and maximum offset computed.  */
     137             :   offset_int offmax[2];
     138             : 
     139             :   /* Used to fold integer expressions when called from front ends.  */
     140             :   tree (*eval)(tree);
     141             :   /* Positive when REF is dereferenced, negative when its address is
     142             :      taken.  */
     143             :   int deref;
     144             :   /* The following indicates if heuristics interpreted 'ref' is interpreted
     145             :      as (offsetted) nullptr.  */
     146             :   bool ref_nullptr_p;
     147             :   /* Set if trailing one-element arrays should be treated as flexible
     148             :      array members.  */
     149             :   bool trail1special;
     150             :   /* Set if valid offsets must start at zero (for declared and allocated
     151             :      objects but not for others referenced by pointers).  */
     152             :   bool base0;
     153             :   /* Set if REF refers to a function array parameter not declared
     154             :      static.  */
     155             :   bool parmarray;
     156             : };
     157             : 
     158             : class range_query;
     159             : 
     160             : /* Queries and caches compute_objsize results.  */
     161             : class pointer_query
     162             : {
     163             :   DISABLE_COPY_AND_ASSIGN (pointer_query);
     164             : 
     165             :   /* Type of the two-level cache object defined by clients of the class
     166             :      to have pointer SSA_NAMEs cached for speedy access.  */
     167             :   struct cache_type
     168             :   {
     169             :     /* 1-based indices into cache.  */
     170             :     auto_vec<unsigned> indices;
     171             :     /* The cache itself.  */
     172             :     auto_vec<access_ref> access_refs;
     173             :   };
     174             : 
     175             : public:
     176             :   /* Construct an object with the given Ranger instance.  */
     177             :   explicit pointer_query (range_query * = nullptr);
     178             : 
     179             :   /* Retrieve the access_ref for a variable from cache if it's there.  */
     180             :   const access_ref* get_ref (tree, int = 1) const;
     181             : 
     182             :   /* Retrieve the access_ref for a variable from cache or compute it.  */
     183             :   bool get_ref (tree, gimple *, access_ref*, int = 1);
     184             : 
     185             :   /* Add an access_ref for the SSA_NAME to the cache.  */
     186             :   void put_ref (tree, const access_ref&, int = 1);
     187             : 
     188             :   /* Flush the cache.  */
     189             :   void flush_cache ();
     190             : 
     191             :   /* Dump statistics and optionally cache contents to DUMP_FILE.  */
     192             :   void dump (FILE *, bool = false);
     193             : 
     194             :   /* A Ranger instance.  May be null to use global ranges.  */
     195             :   range_query *rvals;
     196             : 
     197             :   /* Cache performance counters.  */
     198             :   mutable unsigned hits;
     199             :   mutable unsigned misses;
     200             :   mutable unsigned failures;
     201             :   mutable unsigned depth;
     202             :   mutable unsigned max_depth;
     203             : 
     204             : private:
     205             :   /* Cache of SSA_NAMEs.  May be null to disable caching.  */
     206             :   cache_type var_cache;
     207             : };
     208             : 
     209             : /* Describes a pair of references used in an access by built-in
     210             :    functions like memcpy.  */
     211             : struct access_data
     212             : {
     213             :   /* Set the access to at most MAXWRITE and MAXREAD bytes, and
     214             :      at least 1 when MINWRITE or MINREAD, respectively, is set.  */
     215             :   access_data (range_query *, gimple *, access_mode,
     216             :                tree = NULL_TREE, bool = false,
     217             :                tree = NULL_TREE, bool = false);
     218             : 
     219             :   /* Set the access to at most MAXWRITE and MAXREAD bytes, and
     220             :      at least 1 when MINWRITE or MINREAD, respectively, is set.  */
     221             :   access_data (range_query *, tree, access_mode,
     222             :                tree = NULL_TREE, bool = false,
     223             :                tree = NULL_TREE, bool = false);
     224             : 
     225             :   /* Constructor helper.  */
     226             :   static void set_bound (offset_int[2], tree, bool, range_query *, gimple *);
     227             : 
     228             :   /* Access statement.  */
     229             :   gimple *stmt;
     230             :   /* Built-in function call.  */
     231             :   tree call;
     232             :   /* Destination and source of the access.  */
     233             :   access_ref dst, src;
     234             : 
     235             :   /* Range of the bound of the access: denotes that the access is at
     236             :      least XXX_BNDRNG[0] bytes but no more than XXX_BNDRNG[1].  For
     237             :      string functions the size of the actual access is further
     238             :      constrained by the length of the string.  */
     239             :   offset_int dst_bndrng[2];
     240             :   offset_int src_bndrng[2];
     241             : 
     242             :   /* Read-only for functions like memcmp or strlen, write-only
     243             :      for memset, read-write for memcpy or strcat.  */
     244             :   access_mode mode;
     245             :   /* The object size type.  */
     246             :   int ostype;
     247             : };
     248             : 
     249             : enum size_range_flags
     250             :   {
     251             :    /* Set to consider zero a valid range.  */
     252             :    SR_ALLOW_ZERO = 1,
     253             :    /* Set to use the largest subrange of a set of ranges as opposed
     254             :       to the smallest.  */
     255             :    SR_USE_LARGEST = 2
     256             :   };
     257             : extern bool get_size_range (tree, tree[2], int = 0);
     258             : extern bool get_size_range (range_query *, tree, gimple *, tree[2], int = 0);
     259             : 
     260             : class range_query;
     261             : extern tree gimple_call_alloc_size (gimple *, wide_int[2] = nullptr,
     262             :                                     range_query * = nullptr);
     263             : 
     264             : /* Compute the size of an object referenced by the first argument in
     265             :    a statement given by second argument, using Object Size Type given
     266             :    by third argument.  Store result in an access_ref.  */
     267             : extern tree compute_objsize (tree, gimple *, int, access_ref *,
     268             :                              range_query * = nullptr);
     269             : extern tree compute_objsize (tree, gimple *, int, access_ref *,
     270             :                              pointer_query *);
     271       49327 : inline tree compute_objsize (tree ptr, int ostype, access_ref *pref)
     272             : {
     273       49327 :   return compute_objsize (ptr, nullptr, ostype, pref, (range_query *)nullptr);
     274             : }
     275             : 
     276             : /* Legacy/transitional API.  Should not be used in new code.  */
     277             : extern tree compute_objsize (tree, gimple *, int, tree * = nullptr,
     278             :                              tree * = nullptr, range_query * = nullptr);
     279             : inline tree compute_objsize (tree ptr, int ostype, tree *pdecl = nullptr,
     280             :                              tree *poff = nullptr, range_query *rvals = nullptr)
     281             : {
     282             :   return compute_objsize (ptr, nullptr, ostype, pdecl, poff, rvals);
     283             : }
     284             : 
     285             : /* Return the field at the constant offset.  */
     286             : extern tree field_at_offset (tree, tree, HOST_WIDE_INT,
     287             :                              HOST_WIDE_INT * = nullptr,
     288             :                              HOST_WIDE_INT * = nullptr);
     289             : /* Return the array at the constant offset.  */
     290             : extern tree array_elt_at_offset (tree, HOST_WIDE_INT,
     291             :                                  HOST_WIDE_INT * = nullptr,
     292             :                                  HOST_WIDE_INT * = nullptr);
     293             : 
     294             : /* Helper to build an array type that can be printed.  */
     295             : extern tree build_printable_array_type (tree, unsigned HOST_WIDE_INT);
     296             : 
     297             : #endif   // GCC_POINTER_QUERY_H

Generated by: LCOV version 1.16