1 /* Information about fuunction binary interfaces.
2 Copyright (C) 2019-2024 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
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
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/>. */
22 #include "coretypes.h"
28 #include "function-abi.h"
32 target_function_abi_info default_target_function_abi_info
;
34 target_function_abi_info
*this_target_function_abi_info
35 = &default_target_function_abi_info
;
38 /* Initialize a predefined function ABI with the given values of
39 ID and FULL_REG_CLOBBERS. */
42 predefined_function_abi::initialize (unsigned int id
,
43 const_hard_reg_set full_reg_clobbers
)
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. */
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
],
114 /* If the ABI has been initialized, add REGNO to the set of registers
115 that can be completely altered by a call. */
118 predefined_function_abi::add_full_reg_clobber (unsigned int regno
)
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. */
133 function_abi_aggregator::
134 caller_save_regs (const function_abi
&caller_abi
) const
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
]))
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
]);
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. */
179 call_clobbers_in_region (unsigned int abis
, const_hard_reg_set mask
,
183 CLEAR_HARD_REG_SET (result
);
184 for (unsigned int id
= 0; abis
; abis
>>= 1, ++id
)
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. */
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
);
216 /* Return the ABI of the function called by INSN. */
219 insn_callee_abi (const rtx_insn
*insn
)
221 gcc_assert (insn
&& CALL_P (insn
));
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. */
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
));