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: 2024-03-23 14:05:01 Functions: 87.5 % 8 7
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Information about fuunction binary interfaces.
       2                 :             :    Copyright (C) 2019-2024 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                 :      828156 : predefined_function_abi::initialize (unsigned int id,
      43                 :             :                                      const_hard_reg_set full_reg_clobbers)
      44                 :             : {
      45                 :      828156 :   m_id = id;
      46                 :      828156 :   m_initialized = true;
      47                 :      828156 :   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                 :      828156 :   m_full_and_partial_reg_clobbers = full_reg_clobbers;
      63                 :   108488436 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
      64                 :             :     {
      65                 :             :       machine_mode mode = (machine_mode) i;
      66                 : 10012406040 :       for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
      67                 :  9904745760 :         if (targetm.hard_regno_mode_ok (regno, mode)
      68                 :  1797434007 :             && hard_regno_nregs (regno, mode) == 1
      69                 : 11408914977 :             && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
      70                 :   126092000 :           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                 :   108488436 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
      86                 :             :     {
      87                 :   107660280 :       machine_mode mode = (machine_mode) i;
      88                 :   107660280 :       m_mode_clobbers[i] = m_full_and_partial_reg_clobbers;
      89                 : 10012406040 :       for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
      90                 :  9904745760 :         if (targetm.hard_regno_mode_ok (regno, mode)
      91                 :  1797434007 :             && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
      92                 : 10155457625 :             && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
      93                 :   249542357 :           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                 :      828156 :   if (flag_checking)
     100                 :   108485554 :     for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     101                 :             :       {
     102                 :   107657420 :         machine_mode mode = (machine_mode) i;
     103                 :   107657420 :         const_hard_reg_set all_clobbers = m_full_and_partial_reg_clobbers;
     104                 : 10012140060 :         for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
     105                 :  9904482640 :           if (targetm.hard_regno_mode_ok (regno, mode)
     106                 :  1797390997 :               && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
     107                 : 10155188411 :               && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
     108                 :     1169508 :             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                 :      828156 : }
     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                 :         784 : predefined_function_abi::add_full_reg_clobber (unsigned int regno)
     119                 :             : {
     120                 :         784 :   if (!m_initialized)
     121                 :             :     return;
     122                 :             : 
     123                 :          98 :   SET_HARD_REG_BIT (m_full_reg_clobbers, regno);
     124                 :          98 :   SET_HARD_REG_BIT (m_full_and_partial_reg_clobbers, regno);
     125                 :       12838 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     126                 :       12740 :     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                 :     1419736 : function_abi_aggregator::
     134                 :             : caller_save_regs (const function_abi &caller_abi) const
     135                 :             : {
     136                 :     1419736 :   HARD_REG_SET result;
     137                 :     1419736 :   CLEAR_HARD_REG_SET (result);
     138                 :    12777624 :   for (unsigned int abi_id = 0; abi_id < NUM_ABI_IDS; ++abi_id)
     139                 :             :     {
     140                 :    11357888 :       const predefined_function_abi &callee_abi = function_abis[abi_id];
     141                 :             : 
     142                 :             :       /* Skip cases that clearly aren't problematic.  */
     143                 :    11357888 :       if (abi_id == caller_abi.id ()
     144                 :    21296040 :           || hard_reg_set_empty_p (m_abi_clobbers[abi_id]))
     145                 :    11357860 :         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                 :        3668 :       CLEAR_HARD_REG_SET (extra_clobbers);
     151                 :        3668 :       for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     152                 :             :         {
     153                 :        3640 :           machine_mode mode = (machine_mode) i;
     154                 :        7280 :           extra_clobbers |= (callee_abi.mode_clobbers (mode)
     155                 :        7280 :                              & ~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                 :          56 :       result |= (extra_clobbers & m_abi_clobbers[abi_id]);
     161                 :             :     }
     162                 :     1419736 :   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                 :    69007213 : call_clobbers_in_region (unsigned int abis, const_hard_reg_set mask,
     180                 :             :                          machine_mode mode)
     181                 :             : {
     182                 :    69007213 :   HARD_REG_SET result;
     183                 :    69007213 :   CLEAR_HARD_REG_SET (result);
     184                 :   119570447 :   for (unsigned int id = 0; abis; abis >>= 1, ++id)
     185                 :    50563234 :     if (abis & 1)
     186                 :   101119678 :       result |= function_abis[id].mode_clobbers (mode);
     187                 :    69007213 :   return result & mask;
     188                 :             : }
     189                 :             : 
     190                 :             : /* Return the predefined ABI used by functions with type TYPE.  */
     191                 :             : 
     192                 :             : const predefined_function_abi &
     193                 :   322094054 : fntype_abi (const_tree type)
     194                 :             : {
     195                 :   322094054 :   gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
     196                 :   322094054 :   if (targetm.calls.fntype_abi)
     197                 :           0 :     return targetm.calls.fntype_abi (type);
     198                 :   322094054 :   return default_function_abi;
     199                 :             : }
     200                 :             : 
     201                 :             : /* Return the ABI of function decl FNDECL.  */
     202                 :             : 
     203                 :             : function_abi
     204                 :   239919602 : fndecl_abi (const_tree fndecl)
     205                 :             : {
     206                 :   239919602 :   gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
     207                 :   239919602 :   const predefined_function_abi &base_abi = fntype_abi (TREE_TYPE (fndecl));
     208                 :             : 
     209                 :   239919602 :   if (flag_ipa_ra && decl_binds_to_current_def_p (fndecl))
     210                 :    43514220 :     if (cgraph_rtl_info *info = cgraph_node::rtl_info (fndecl))
     211                 :    39754126 :       return function_abi (base_abi, info->function_used_regs);
     212                 :             : 
     213                 :   200165476 :   return base_abi;
     214                 :             : }
     215                 :             : 
     216                 :             : /* Return the ABI of the function called by INSN.  */
     217                 :             : 
     218                 :             : function_abi
     219                 :   483005656 : insn_callee_abi (const rtx_insn *insn)
     220                 :             : {
     221                 :   483005656 :   gcc_assert (insn && CALL_P (insn));
     222                 :             : 
     223                 :   483005656 :   if (flag_ipa_ra)
     224                 :   250596079 :     if (tree fndecl = get_call_fndecl (insn))
     225                 :   238493137 :       return fndecl_abi (fndecl);
     226                 :             : 
     227                 :   244512519 :   if (targetm.calls.insn_callee_abi)
     228                 :   244512519 :     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.0-1

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.