c++: retval dtor on rethrow [PR112301]
[official-gcc.git] / gcc / function-abi.cc
blob2ab9b2c564920fff283dfdf14aff684dfbf23536
1 /* Information about fuunction binary interfaces.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
4 This file is part of GCC
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "regs.h"
28 #include "function-abi.h"
29 #include "varasm.h"
30 #include "cgraph.h"
32 target_function_abi_info default_target_function_abi_info;
33 #if SWITCHABLE_TARGET
34 target_function_abi_info *this_target_function_abi_info
35 = &default_target_function_abi_info;
36 #endif
38 /* Initialize a predefined function ABI with the given values of
39 ID and FULL_REG_CLOBBERS. */
41 void
42 predefined_function_abi::initialize (unsigned int id,
43 const_hard_reg_set full_reg_clobbers)
45 m_id = id;
46 m_initialized = true;
47 m_full_reg_clobbers = full_reg_clobbers;
49 /* Set up the value of m_full_and_partial_reg_clobbers.
51 If the ABI specifies that part of a hard register R is call-clobbered,
52 we should be able to find a single-register mode M for which
53 targetm.hard_regno_call_part_clobbered (m_id, R, M) is true.
54 In other words, it shouldn't be the case that R can hold all
55 single-register modes across a call, but can't hold part of
56 a multi-register mode.
58 If that assumption doesn't hold for a future target, we would need
59 to change the interface of TARGET_HARD_REGNO_CALL_PART_CLOBBERED so
60 that it tells us which registers in a multi-register value are
61 actually clobbered. */
62 m_full_and_partial_reg_clobbers = full_reg_clobbers;
63 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
65 machine_mode mode = (machine_mode) i;
66 for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
67 if (targetm.hard_regno_mode_ok (regno, mode)
68 && hard_regno_nregs (regno, mode) == 1
69 && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
70 SET_HARD_REG_BIT (m_full_and_partial_reg_clobbers, regno);
73 /* For each mode MODE, work out which registers are unable to hold
74 any part of a MODE value across a call, i.e. those for which no
75 overlapping call-preserved (reg:MODE REGNO) exists.
77 We assume that this can be flipped around to say that a call
78 preserves (reg:MODE REGNO) unless the register overlaps this set.
79 The usual reason for this being true is that if (reg:MODE REGNO)
80 contains a part-clobbered register, that register would be
81 part-clobbered regardless of which part of MODE it holds.
82 For example, if (reg:M 2) occupies two registers and if the
83 register 3 portion of it is part-clobbered, (reg:M 3) is usually
84 either invalid or also part-clobbered. */
85 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
87 machine_mode mode = (machine_mode) i;
88 m_mode_clobbers[i] = m_full_and_partial_reg_clobbers;
89 for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
90 if (targetm.hard_regno_mode_ok (regno, mode)
91 && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
92 && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
93 remove_from_hard_reg_set (&m_mode_clobbers[i], mode, regno);
96 /* Check that the assumptions above actually hold, i.e. that testing
97 for single-register modes makes sense, and that overlap tests for
98 mode_clobbers work as expected. */
99 if (flag_checking)
100 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
102 machine_mode mode = (machine_mode) i;
103 const_hard_reg_set all_clobbers = m_full_and_partial_reg_clobbers;
104 for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
105 if (targetm.hard_regno_mode_ok (regno, mode)
106 && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
107 && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
108 gcc_assert (overlaps_hard_reg_set_p (all_clobbers, mode, regno)
109 && overlaps_hard_reg_set_p (m_mode_clobbers[i],
110 mode, regno));
114 /* If the ABI has been initialized, add REGNO to the set of registers
115 that can be completely altered by a call. */
117 void
118 predefined_function_abi::add_full_reg_clobber (unsigned int regno)
120 if (!m_initialized)
121 return;
123 SET_HARD_REG_BIT (m_full_reg_clobbers, regno);
124 SET_HARD_REG_BIT (m_full_and_partial_reg_clobbers, regno);
125 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
126 SET_HARD_REG_BIT (m_mode_clobbers[i], regno);
129 /* Return the set of registers that the caller of the recorded functions must
130 save in order to honor the requirements of CALLER_ABI. */
132 HARD_REG_SET
133 function_abi_aggregator::
134 caller_save_regs (const function_abi &caller_abi) const
136 HARD_REG_SET result;
137 CLEAR_HARD_REG_SET (result);
138 for (unsigned int abi_id = 0; abi_id < NUM_ABI_IDS; ++abi_id)
140 const predefined_function_abi &callee_abi = function_abis[abi_id];
142 /* Skip cases that clearly aren't problematic. */
143 if (abi_id == caller_abi.id ()
144 || hard_reg_set_empty_p (m_abi_clobbers[abi_id]))
145 continue;
147 /* Collect the set of registers that can be "more clobbered" by
148 CALLEE_ABI than by CALLER_ABI. */
149 HARD_REG_SET extra_clobbers;
150 CLEAR_HARD_REG_SET (extra_clobbers);
151 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
153 machine_mode mode = (machine_mode) i;
154 extra_clobbers |= (callee_abi.mode_clobbers (mode)
155 & ~caller_abi.mode_clobbers (mode));
158 /* Restrict it to the set of registers that we actually saw
159 clobbers for (e.g. taking -fipa-ra into account). */
160 result |= (extra_clobbers & m_abi_clobbers[abi_id]);
162 return result;
165 /* Return the set of registers that cannot be used to hold a value of
166 mode MODE across the calls in a region described by ABIS and MASK, where:
168 * Bit ID of ABIS is set if the region contains a call with
169 function_abi identifier ID.
171 * MASK contains all the registers that are fully or partially
172 clobbered by calls in the region.
174 This is not quite as accurate as testing each individual call,
175 but it's a close and conservatively-correct approximation.
176 It's much better for some targets than just using MASK. */
178 HARD_REG_SET
179 call_clobbers_in_region (unsigned int abis, const_hard_reg_set mask,
180 machine_mode mode)
182 HARD_REG_SET result;
183 CLEAR_HARD_REG_SET (result);
184 for (unsigned int id = 0; abis; abis >>= 1, ++id)
185 if (abis & 1)
186 result |= function_abis[id].mode_clobbers (mode);
187 return result & mask;
190 /* Return the predefined ABI used by functions with type TYPE. */
192 const predefined_function_abi &
193 fntype_abi (const_tree type)
195 gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
196 if (targetm.calls.fntype_abi)
197 return targetm.calls.fntype_abi (type);
198 return default_function_abi;
201 /* Return the ABI of function decl FNDECL. */
203 function_abi
204 fndecl_abi (const_tree fndecl)
206 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
207 const predefined_function_abi &base_abi = fntype_abi (TREE_TYPE (fndecl));
209 if (flag_ipa_ra && decl_binds_to_current_def_p (fndecl))
210 if (cgraph_rtl_info *info = cgraph_node::rtl_info (fndecl))
211 return function_abi (base_abi, info->function_used_regs);
213 return base_abi;
216 /* Return the ABI of the function called by INSN. */
218 function_abi
219 insn_callee_abi (const rtx_insn *insn)
221 gcc_assert (insn && CALL_P (insn));
223 if (flag_ipa_ra)
224 if (tree fndecl = get_call_fndecl (insn))
225 return fndecl_abi (fndecl);
227 if (targetm.calls.insn_callee_abi)
228 return targetm.calls.insn_callee_abi (insn);
230 return default_function_abi;
233 /* Return the ABI of the function called by CALL_EXPR EXP. Return the
234 default ABI for erroneous calls. */
236 function_abi
237 expr_callee_abi (const_tree exp)
239 gcc_assert (TREE_CODE (exp) == CALL_EXPR);
241 if (tree fndecl = get_callee_fndecl (exp))
242 return fndecl_abi (fndecl);
244 tree callee = CALL_EXPR_FN (exp);
245 if (callee == error_mark_node)
246 return default_function_abi;
248 tree type = TREE_TYPE (callee);
249 if (type == error_mark_node)
250 return default_function_abi;
252 gcc_assert (POINTER_TYPE_P (type));
253 return fntype_abi (TREE_TYPE (type));