1/* Information about fuunction binary interfaces.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3
4This file is part of GCC
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
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"
31
32target_function_abi_info default_target_function_abi_info;
33#if SWITCHABLE_TARGET
34target_function_abi_info *this_target_function_abi_info
35 = &default_target_function_abi_info;
36#endif
37
38/* Initialize a predefined function ABI with the given values of
39 ID and FULL_REG_CLOBBERS. */
40
41void
42predefined_function_abi::initialize (unsigned int id,
43 const_hard_reg_set full_reg_clobbers)
44{
45 m_id = id;
46 m_initialized = true;
47 m_full_reg_clobbers = full_reg_clobbers;
48
49 /* Set up the value of m_full_and_partial_reg_clobbers.
50
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.
57
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)
64 {
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 (set&: m_full_and_partial_reg_clobbers, bit: regno);
71 }
72
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.
76
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)
86 {
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 (regs: m_full_reg_clobbers, mode, regno)
92 && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
93 remove_from_hard_reg_set (regs: &m_mode_clobbers[i], mode, regno);
94 }
95
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)
101 {
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 (regs: 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));
111 }
112}
113
114/* If the ABI has been initialized, add REGNO to the set of registers
115 that can be completely altered by a call. */
116
117void
118predefined_function_abi::add_full_reg_clobber (unsigned int regno)
119{
120 if (!m_initialized)
121 return;
122
123 SET_HARD_REG_BIT (set&: m_full_reg_clobbers, bit: regno);
124 SET_HARD_REG_BIT (set&: m_full_and_partial_reg_clobbers, bit: regno);
125 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
126 SET_HARD_REG_BIT (set&: m_mode_clobbers[i], bit: regno);
127}
128
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. */
131
132HARD_REG_SET
133function_abi_aggregator::
134caller_save_regs (const function_abi &caller_abi) const
135{
136 HARD_REG_SET result;
137 CLEAR_HARD_REG_SET (set&: result);
138 for (unsigned int abi_id = 0; abi_id < NUM_ABI_IDS; ++abi_id)
139 {
140 const predefined_function_abi &callee_abi = function_abis[abi_id];
141
142 /* Skip cases that clearly aren't problematic. */
143 if (abi_id == caller_abi.id ()
144 || hard_reg_set_empty_p (x: m_abi_clobbers[abi_id]))
145 continue;
146
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 (set&: extra_clobbers);
151 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
152 {
153 machine_mode mode = (machine_mode) i;
154 extra_clobbers |= (callee_abi.mode_clobbers (mode)
155 & ~caller_abi.mode_clobbers (mode));
156 }
157
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]);
161 }
162 return result;
163}
164
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:
167
168 * Bit ID of ABIS is set if the region contains a call with
169 function_abi identifier ID.
170
171 * MASK contains all the registers that are fully or partially
172 clobbered by calls in the region.
173
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. */
177
178HARD_REG_SET
179call_clobbers_in_region (unsigned int abis, const_hard_reg_set mask,
180 machine_mode mode)
181{
182 HARD_REG_SET result;
183 CLEAR_HARD_REG_SET (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;
188}
189
190/* Return the predefined ABI used by functions with type TYPE. */
191
192const predefined_function_abi &
193fntype_abi (const_tree type)
194{
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;
199}
200
201/* Return the ABI of function decl FNDECL. */
202
203function_abi
204fndecl_abi (const_tree fndecl)
205{
206 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
207 const predefined_function_abi &base_abi = fntype_abi (TREE_TYPE (fndecl));
208
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);
212
213 return base_abi;
214}
215
216/* Return the ABI of the function called by INSN. */
217
218function_abi
219insn_callee_abi (const rtx_insn *insn)
220{
221 gcc_assert (insn && CALL_P (insn));
222
223 if (flag_ipa_ra)
224 if (tree fndecl = get_call_fndecl (insn))
225 return fndecl_abi (fndecl);
226
227 if (targetm.calls.insn_callee_abi)
228 return targetm.calls.insn_callee_abi (insn);
229
230 return default_function_abi;
231}
232
233/* Return the ABI of the function called by CALL_EXPR EXP. Return the
234 default ABI for erroneous calls. */
235
236function_abi
237expr_callee_abi (const_tree exp)
238{
239 gcc_assert (TREE_CODE (exp) == CALL_EXPR);
240
241 if (tree fndecl = get_callee_fndecl (exp))
242 return fndecl_abi (fndecl);
243
244 tree callee = CALL_EXPR_FN (exp);
245 if (callee == error_mark_node)
246 return default_function_abi;
247
248 tree type = TREE_TYPE (callee);
249 if (type == error_mark_node)
250 return default_function_abi;
251
252 gcc_assert (POINTER_TYPE_P (type));
253 return fntype_abi (TREE_TYPE (type));
254}
255

source code of gcc/function-abi.cc