1 /* Call stacks at program points.
2 Copyright (C) 2019-2022 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
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)
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.
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/>. */
21 #ifndef GCC_ANALYZER_CALL_STRING_H
22 #define GCC_ANALYZER_CALL_STRING_H
29 class return_superedge
;
32 /* A string of return_superedge pointers, representing a call stack
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.
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
42 Instances of call_string are consolidated by the region_model_manager,
43 which effectively owns them: it owns the root/empty call_string, and each
44 call_string instance tracks its children, lazily creating them on demand,
45 so that the call_string instances form a tree-like hierarchy in memory. */
50 /* A struct representing an element in the call_string.
52 Each element represents a path from m_callee to m_caller which represents
53 returning from function. */
57 element_t (const supernode
*caller
, const supernode
*callee
)
58 : m_caller (caller
), m_callee (callee
)
62 bool operator== (const element_t
&other
) const;
63 bool operator!= (const element_t
&other
) const;
66 function
*get_caller_function () const;
67 function
*get_callee_function () const;
69 const supernode
*m_caller
;
70 const supernode
*m_callee
;
73 void print (pretty_printer
*pp
) const;
75 json::value
*to_json () const;
77 bool empty_p () const { return m_elements
.is_empty (); }
79 const call_string
*push_call (const supergraph
&sg
,
80 const call_superedge
*sedge
) const;
82 const call_string
*push_call (const supernode
*src
,
83 const supernode
*dest
) const;
84 const call_string
*get_parent () const { return m_parent
; }
86 int calc_recursion_depth () const;
88 static int cmp (const call_string
&a
,
89 const call_string
&b
);
91 static int cmp_ptr_ptr (const void *, const void *);
95 const supernode
*get_callee_node () const;
96 const supernode
*get_caller_node () const;
97 unsigned length () const { return m_elements
.length (); }
98 element_t
operator[] (unsigned idx
) const
100 return m_elements
[idx
];
102 const element_t
&get_top_of_stack () const
104 gcc_assert (m_elements
.length () > 0);
105 return m_elements
[m_elements
.length () - 1];
108 void validate () const;
111 struct hashmap_traits_t
113 typedef element_t key_type
;
114 typedef const call_string
*value_type
;
116 static const bool maybe_mx
= false;
117 static inline hashval_t
hash (const key_type
&k
)
119 inchash::hash hstate
;
120 hstate
.add_ptr (k
.m_caller
);
121 hstate
.add_ptr (k
.m_callee
);
122 return hstate
.end ();
124 static inline bool equal_keys (const key_type
&k1
, const key_type
&k2
)
128 template <typename T
> static inline void remove (T
&entry
)
130 entry
.m_key
= element_t (NULL
, NULL
);
132 static const bool empty_zero_p
= true;
133 template <typename T
> static inline bool is_empty (const T
&entry
)
135 return entry
.m_key
.m_caller
== NULL
;
137 template <typename T
> static inline bool is_deleted (const T
&entry
)
139 return entry
.m_key
.m_caller
== reinterpret_cast<const supernode
*> (1);
141 template <typename T
> static inline void mark_empty (T
&entry
)
143 entry
.m_key
= element_t (NULL
, NULL
);
144 entry
.m_value
= NULL
;
146 template <typename T
> static inline void mark_deleted (T
&entry
)
148 entry
.m_key
.m_caller
= reinterpret_cast<const supernode
*> (1);
152 friend class region_model_manager
;
154 DISABLE_COPY_AND_ASSIGN (call_string
);
157 call_string (const call_string
&parent
, const element_t
&to_push
);
160 void recursive_log (logger
*logger
) const;
162 const call_string
*m_parent
;
163 auto_vec
<element_t
> m_elements
;
164 mutable hash_map
<element_t
, const call_string
*, hashmap_traits_t
> m_children
;
169 #endif /* GCC_ANALYZER_CALL_STRING_H */