LCOV - code coverage report
Current view: top level - gcc - function-abi.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 84.3 % 89 75
Test Date: 2026-02-28 14:20:25 Functions: 87.5 % 8 7
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Information about fuunction binary interfaces.
       2              :    Copyright (C) 2019-2026 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       826426 : predefined_function_abi::initialize (unsigned int id,
      43              :                                      const_hard_reg_set full_reg_clobbers)
      44              : {
      45       826426 :   m_id = id;
      46       826426 :   m_initialized = true;
      47       826426 :   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       826426 :   m_full_and_partial_reg_clobbers = full_reg_clobbers;
      63    103303250 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
      64              :     {
      65              :       machine_mode mode = (machine_mode) i;
      66   9530344632 :       for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
      67   9427867808 :         if (targetm.hard_regno_mode_ok (regno, mode)
      68   1814353842 :             && hard_regno_nregs (regno, mode) == 1
      69  10949703422 :             && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
      70    144685600 :           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    103303250 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
      86              :     {
      87    102476824 :       machine_mode mode = (machine_mode) i;
      88    102476824 :       m_mode_clobbers[i] = m_full_and_partial_reg_clobbers;
      89   9530344632 :       for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
      90   9427867808 :         if (targetm.hard_regno_mode_ok (regno, mode)
      91   1814353842 :             && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
      92   9679397750 :             && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
      93    250281722 :           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       826426 :   if (flag_checking)
     100    103300875 :     for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     101              :       {
     102    102474468 :         machine_mode mode = (machine_mode) i;
     103    102474468 :         const_hard_reg_set all_clobbers = m_full_and_partial_reg_clobbers;
     104   9530125524 :         for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
     105   9427651056 :           if (targetm.hard_regno_mode_ok (regno, mode)
     106   1814316697 :               && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
     107   9679175735 :               && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
     108      1248220 :             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       826426 : }
     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         1044 : predefined_function_abi::add_full_reg_clobber (unsigned int regno)
     119              : {
     120         1044 :   if (!m_initialized)
     121              :     return;
     122              : 
     123           87 :   SET_HARD_REG_BIT (m_full_reg_clobbers, regno);
     124           87 :   SET_HARD_REG_BIT (m_full_and_partial_reg_clobbers, regno);
     125        10875 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     126        10788 :     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     10911311 : function_abi_aggregator::
     134              : caller_save_regs (const function_abi &caller_abi) const
     135              : {
     136     10911311 :   HARD_REG_SET result;
     137     10911311 :   CLEAR_HARD_REG_SET (result);
     138    141847043 :   for (unsigned int abi_id = 0; abi_id < NUM_ABI_IDS; ++abi_id)
     139              :     {
     140    130935732 :       const predefined_function_abi &callee_abi = function_abis[abi_id];
     141              : 
     142              :       /* Skip cases that clearly aren't problematic.  */
     143    130935732 :       if (abi_id == caller_abi.id ()
     144    250960153 :           || hard_reg_set_empty_p (m_abi_clobbers[abi_id]))
     145    130915306 :         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      2553250 :       CLEAR_HARD_REG_SET (extra_clobbers);
     151      2553250 :       for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     152              :         {
     153      2532824 :           machine_mode mode = (machine_mode) i;
     154      5065648 :           extra_clobbers |= (callee_abi.mode_clobbers (mode)
     155      5065648 :                              & ~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        40852 :       result |= (extra_clobbers & m_abi_clobbers[abi_id]);
     161              :     }
     162     10911311 :   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     89511683 : call_clobbers_in_region (unsigned int abis, const_hard_reg_set mask,
     180              :                          machine_mode mode)
     181              : {
     182     89511683 :   HARD_REG_SET result;
     183     89511683 :   CLEAR_HARD_REG_SET (result);
     184    158306344 :   for (unsigned int id = 0; abis; abis >>= 1, ++id)
     185     68794661 :     if (abis & 1)
     186    137584304 :       result |= function_abis[id].mode_clobbers (mode);
     187     89511683 :   return result & mask;
     188              : }
     189              : 
     190              : /* Return the predefined ABI used by functions with type TYPE.  */
     191              : 
     192              : const predefined_function_abi &
     193    397317112 : fntype_abi (const_tree type)
     194              : {
     195    397317112 :   gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
     196    397317112 :   if (targetm.calls.fntype_abi)
     197            0 :     return targetm.calls.fntype_abi (type);
     198    397317112 :   return default_function_abi;
     199              : }
     200              : 
     201              : /* Return the ABI of function decl FNDECL.  */
     202              : 
     203              : function_abi
     204    294785459 : fndecl_abi (const_tree fndecl)
     205              : {
     206    294785459 :   gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
     207    294785459 :   const predefined_function_abi &base_abi = fntype_abi (TREE_TYPE (fndecl));
     208              : 
     209    294785459 :   if (flag_ipa_ra && decl_binds_to_current_def_p (fndecl))
     210     52553502 :     if (cgraph_rtl_info *info = cgraph_node::rtl_info (fndecl))
     211     48044157 :       return function_abi (base_abi, info->function_used_regs);
     212              : 
     213    246741302 :   return base_abi;
     214              : }
     215              : 
     216              : /* Return the ABI of the function called by INSN.  */
     217              : 
     218              : function_abi
     219    541205850 : insn_callee_abi (const rtx_insn *insn)
     220              : {
     221    541205850 :   gcc_assert (insn && CALL_P (insn));
     222              : 
     223    541205850 :   if (flag_ipa_ra)
     224    307775695 :     if (tree fndecl = get_call_fndecl (insn))
     225    293307768 :       return fndecl_abi (fndecl);
     226              : 
     227    247898082 :   if (targetm.calls.insn_callee_abi)
     228    247898082 :     return targetm.calls.insn_callee_abi (insn);
     229              : 
     230            0 :   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            0 : expr_callee_abi (const_tree exp)
     238              : {
     239            0 :   gcc_assert (TREE_CODE (exp) == CALL_EXPR);
     240              : 
     241            0 :   if (tree fndecl = get_callee_fndecl (exp))
     242            0 :     return fndecl_abi (fndecl);
     243              : 
     244            0 :   tree callee = CALL_EXPR_FN (exp);
     245            0 :   if (callee == error_mark_node)
     246            0 :     return default_function_abi;
     247              : 
     248            0 :   tree type = TREE_TYPE (callee);
     249            0 :   if (type == error_mark_node)
     250            0 :     return default_function_abi;
     251              : 
     252            0 :   gcc_assert (POINTER_TYPE_P (type));
     253            0 :   return fntype_abi (TREE_TYPE (type));
     254              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.