]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/function-abi.cc
Remove global call sets: haifa-sched.c
[thirdparty/gcc.git] / gcc / function-abi.cc
CommitLineData
bd785b44
RS
1/* Information about fuunction binary interfaces.
2 Copyright (C) 2019 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
6ee2cc70 53 targetm.hard_regno_call_part_clobbered (m_id, R, M) is true.
bd785b44
RS
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
6ee2cc70 69 && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
bd785b44
RS
70 SET_HARD_REG_BIT (m_full_and_partial_reg_clobbers, 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 (m_full_reg_clobbers, mode, regno)
6ee2cc70 92 && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
bd785b44
RS
93 remove_from_hard_reg_set (&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 (m_full_reg_clobbers, mode, regno)
6ee2cc70 107 && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
bd785b44
RS
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 (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);
127}
128
129/* Return the predefined ABI used by functions with type TYPE. */
130
131const predefined_function_abi &
132fntype_abi (const_tree type)
133{
134 gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
002ffd3c
RS
135 if (targetm.calls.fntype_abi)
136 return targetm.calls.fntype_abi (type);
bd785b44
RS
137 return default_function_abi;
138}
139
140/* Return the ABI of function decl FNDECL. */
141
142function_abi
143fndecl_abi (const_tree fndecl)
144{
145 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
5a5a3bc5
RS
146 const predefined_function_abi &base_abi = fntype_abi (TREE_TYPE (fndecl));
147
148 if (flag_ipa_ra && decl_binds_to_current_def_p (fndecl))
149 if (cgraph_rtl_info *info = cgraph_node::rtl_info (fndecl))
150 return function_abi (base_abi, info->function_used_regs);
151
152 return base_abi;
153}
154
155/* Return the ABI of the function called by INSN. */
156
157function_abi
158insn_callee_abi (const rtx_insn *insn)
159{
160 gcc_assert (insn && CALL_P (insn));
161
162 if (flag_ipa_ra)
163 if (tree fndecl = get_call_fndecl (insn))
164 return fndecl_abi (fndecl);
165
166 if (targetm.calls.insn_callee_abi)
167 return targetm.calls.insn_callee_abi (insn);
168
169 return default_function_abi;
bd785b44 170}