Line data Source code
1 : /* Representation of thunks inside symbol table.
2 : Copyright (C) 2003-2026 Free Software Foundation, Inc.
3 : Contributed by Jan Hubicka
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_SYMTAB_THUNKS_H
22 : #define GCC_SYMTAB_THUNKS_H
23 :
24 : /* This symbol annotation holds information about thunk.
25 :
26 : Thunks are basically wrappers around methods which are introduced in case
27 : of multiple inheritance in order to adjust the value of the "this" pointer
28 : or of the returned value.
29 :
30 : In the case of this-adjusting thunks, each back-end can override the
31 : can_output_mi_thunk/output_mi_thunk target hooks to generate a minimal thunk
32 : (with a tail call for instance) directly as assembly. For the default hook
33 : or for the case where the can_output_mi_thunk hooks return false, the thunk
34 : is gimplified and lowered using the regular machinery. */
35 :
36 : struct GTY(()) thunk_info {
37 : /* Constructor. */
38 33259 : thunk_info ()
39 8714 : : fixed_offset (0),
40 28902 : virtual_value (0),
41 28902 : indirect_offset (0),
42 28902 : alias (NULL),
43 28902 : this_adjusting (false),
44 28902 : virtual_offset_p (false)
45 : {
46 : }
47 : /* Copy constructor. */
48 1126 : thunk_info (const thunk_info &t)
49 1126 : : fixed_offset (t.fixed_offset),
50 1126 : virtual_value (t.virtual_value),
51 1126 : indirect_offset (t.indirect_offset),
52 1126 : alias (t.alias),
53 1126 : this_adjusting (t.this_adjusting),
54 1126 : virtual_offset_p (t.virtual_offset_p)
55 : {
56 : }
57 :
58 : /* Compare for equiality. */
59 : bool
60 24 : operator==(const thunk_info &other) const
61 : {
62 24 : return fixed_offset == other.fixed_offset
63 24 : && virtual_value == other.virtual_value
64 24 : && indirect_offset == other.indirect_offset
65 24 : && this_adjusting == other.this_adjusting
66 48 : && virtual_offset_p == other.virtual_offset_p;
67 : }
68 : bool
69 : operator!=(const thunk_info &other) const
70 : {
71 : return !(*this == other);
72 : }
73 : /* Copy operator. */
74 : thunk_info &
75 10202 : operator=(const thunk_info &other)
76 : {
77 10202 : fixed_offset = other.fixed_offset;
78 10202 : virtual_value = other.virtual_value;
79 10202 : indirect_offset = other.indirect_offset;
80 10202 : alias = other.alias;
81 10202 : this_adjusting = other.this_adjusting;
82 10202 : virtual_offset_p = other.virtual_offset_p;
83 9840 : return *this;
84 : }
85 :
86 : /* Offset used to adjust "this". */
87 : HOST_WIDE_INT fixed_offset;
88 :
89 : /* Offset in the virtual table to get the offset to adjust "this". Valid iff
90 : VIRTUAL_OFFSET_P is true. */
91 : HOST_WIDE_INT virtual_value;
92 :
93 : /* Offset from "this" to get the offset to adjust "this". Zero means: this
94 : offset is to be ignored. */
95 : HOST_WIDE_INT indirect_offset;
96 :
97 : /* Thunk target, i.e. the method that this thunk wraps. Depending on the
98 : TARGET_USE_LOCAL_THUNK_ALIAS_P macro, this may have to be a new alias. */
99 : tree alias;
100 :
101 : /* Nonzero for a "this" adjusting thunk and zero for a result adjusting
102 : thunk. */
103 : bool this_adjusting;
104 :
105 : /* If true, this thunk is what we call a virtual thunk. In this case:
106 : * for this-adjusting thunks, after the FIXED_OFFSET based adjustment is
107 : done, add to the result the offset found in the vtable at:
108 : vptr + VIRTUAL_VALUE
109 : * for result-adjusting thunks, the FIXED_OFFSET adjustment is done after
110 : the virtual one. */
111 : bool virtual_offset_p;
112 :
113 :
114 :
115 : /* Dump thunk_info. */
116 : void dump (FILE *);
117 :
118 : /* Stream out thunk_info. */
119 : void stream_out (class lto_simple_output_block *);
120 :
121 : /* Stream in trunk_info. */
122 : void stream_in (class lto_input_block *);
123 :
124 : hashval_t hash ();
125 :
126 :
127 :
128 : /* Return thunk_info, if available. */
129 : static thunk_info *get (cgraph_node *node);
130 :
131 : /* Return thunk_info possibly creating new one. */
132 : static thunk_info *get_create (cgraph_node *node);
133 :
134 : /* Remove thunk_info. */
135 : static void remove (cgraph_node *node);
136 :
137 : /* Add unprocessed thunk. */
138 : void register_early (cgraph_node *node);
139 :
140 : /* Attach recorded thunks to cgraph_nodes. */
141 : static void process_early_thunks ();
142 :
143 : /* Release all thunk_infos. */
144 : static void release (void);
145 : };
146 :
147 : bool expand_thunk (cgraph_node *, bool, bool);
148 :
149 : /* Return thunk_info, if available. */
150 : inline thunk_info *
151 5810202 : thunk_info::get (cgraph_node *node)
152 : {
153 5810202 : if (!symtab->m_thunks)
154 : return NULL;
155 92098 : return symtab->m_thunks->get (node);
156 : }
157 :
158 : /* Remove thunk_info association for NODE. */
159 : inline void
160 18541 : thunk_info::remove (cgraph_node *node)
161 : {
162 18541 : symtab->m_thunks->remove (node);
163 : }
164 :
165 : /* Free thunk info summaries. */
166 : inline void
167 256621 : thunk_info::release ()
168 : {
169 256621 : if (symtab->m_thunks)
170 5677 : ggc_delete (symtab->m_thunks);
171 256621 : symtab->m_thunks = NULL;
172 256621 : }
173 : #endif /* GCC_SYMTAB_THUNKS_H */
|