Home | History | Annotate | Line # | Download | only in gcc
      1 /* Information about fuunction binary interfaces.
      2    Copyright (C) 2019-2022 Free Software Foundation, Inc.
      3 
      4 This file is part of GCC
      5 
      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.
     10 
     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.
     15 
     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/>.  */
     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 
     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
     37 
     38 /* Initialize a predefined function ABI with the given values of
     39    ID and FULL_REG_CLOBBERS.  */
     40 
     41 void
     42 predefined_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 (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)
     92 	    && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
     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)
    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 
    117 void
    118 predefined_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 set of registers that the caller of the recorded functions must
    130    save in order to honor the requirements of CALLER_ABI.  */
    131 
    132 HARD_REG_SET
    133 function_abi_aggregator::
    134 caller_save_regs (const function_abi &caller_abi) const
    135 {
    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)
    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 (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 (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 
    178 HARD_REG_SET
    179 call_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 (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 
    192 const predefined_function_abi &
    193 fntype_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 
    203 function_abi
    204 fndecl_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 
    218 function_abi
    219 insn_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 
    236 function_abi
    237 expr_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