Home | History | Annotate | Line # | Download | only in analyzer
      1 /* Call stacks at program points.
      2    Copyright (C) 2019-2022 Free Software Foundation, Inc.
      3    Contributed by David Malcolm <dmalcolm (at) 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_CALL_STRING_H
     22 #define GCC_ANALYZER_CALL_STRING_H
     23 
     24 namespace ana {
     25 
     26 class supergraph;
     27 class supernode;
     28 class call_superedge;
     29 class return_superedge;
     30 
     31 
     32 /* A string of return_superedge pointers, representing a call stack
     33    at a program point.
     34 
     35    This is used to ensure that we generate interprocedurally valid paths
     36    i.e. that we return to the same callsite that called us.
     37 
     38    The class stores returning calls ( which may be represented by a
     39    returning superedge ). We do so because this is what we need to compare
     40    against.  */
     41 
     42 class call_string
     43 {
     44 public:
     45   /* A struct representing an element in the call_string.
     46 
     47    Each element represents a path from m_callee to m_caller which represents
     48    returning from function.  */
     49 
     50   struct element_t
     51   {
     52     element_t (const supernode *caller, const supernode *callee)
     53     :  m_caller (caller), m_callee (callee)
     54     {
     55     }
     56 
     57     bool operator== (const element_t &other) const;
     58     bool operator!= (const element_t &other) const;
     59 
     60     /* Accessors */
     61     function *get_caller_function () const;
     62     function *get_callee_function () const;
     63 
     64     const supernode *m_caller;
     65     const supernode *m_callee;
     66   };
     67 
     68   call_string () : m_elements () {}
     69   call_string (const call_string &other);
     70   call_string& operator= (const call_string &other);
     71 
     72   bool operator== (const call_string &other) const;
     73 
     74   void print (pretty_printer *pp) const;
     75 
     76   json::value *to_json () const;
     77 
     78   hashval_t hash () const;
     79 
     80   bool empty_p () const { return m_elements.is_empty (); }
     81 
     82   void push_call (const supergraph &sg,
     83 		  const call_superedge *sedge);
     84 
     85   void push_call (const supernode *src,
     86     const supernode *dest);
     87 
     88   element_t pop ();
     89 
     90   int calc_recursion_depth () const;
     91 
     92   static int cmp (const call_string &a,
     93 		  const call_string &b);
     94 
     95   /* Accessors */
     96 
     97   const supernode *get_callee_node () const;
     98   const supernode *get_caller_node () const;
     99   unsigned length () const { return m_elements.length (); }
    100   element_t operator[] (unsigned idx) const
    101   {
    102     return m_elements[idx];
    103   }
    104 
    105   void validate () const;
    106 
    107 private:
    108   auto_vec<element_t> m_elements;
    109 };
    110 
    111 } // namespace ana
    112 
    113 #endif /* GCC_ANALYZER_CALL_STRING_H */
    114