LCOV - code coverage report
Current view: top level - gcc - function-abi.cc (source / functions) Hit Total Coverage
Test: gcc.info Lines: 70 90 77.8 %
Date: 2020-04-04 11:58:09 Functions: 7 8 87.5 %
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-2020 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                 :     458396 : predefined_function_abi::initialize (unsigned int id,
      43                 :            :                                      const_hard_reg_set full_reg_clobbers)
      44                 :            : {
      45                 :     458396 :   m_id = id;
      46                 :     458396 :   m_initialized = true;
      47                 :     458396 :   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                 :     458396 :   m_full_and_partial_reg_clobbers = full_reg_clobbers;
      63                 :   51340400 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
      64                 :            :     {
      65                 : 3917910000 :       machine_mode mode = (machine_mode) i;
      66                 : 3917910000 :       for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
      67                 : 3867030000 :         if (targetm.hard_regno_mode_ok (regno, mode)
      68                 :  543163000 :             && hard_regno_nregs (regno, mode) == 1
      69                 : 4316150000 :             && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
      70                 : 3867030000 :           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                 :   51340400 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
      86                 :            :     {
      87                 :   50882000 :       machine_mode mode = (machine_mode) i;
      88                 :   50882000 :       m_mode_clobbers[i] = m_full_and_partial_reg_clobbers;
      89                 : 3917910000 :       for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
      90                 : 3867030000 :         if (targetm.hard_regno_mode_ok (regno, mode)
      91                 :  651739000 :             && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
      92                 : 3951120000 :             && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
      93                 : 3951050000 :           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                 :     458396 :   if (flag_checking)
     100                 :   51338900 :     for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     101                 :            :       {
     102                 : 3917800000 :         machine_mode mode = (machine_mode) i;
     103                 : 3917800000 :         const_hard_reg_set all_clobbers = m_full_and_partial_reg_clobbers;
     104                 : 3917800000 :         for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
     105                 : 3866920000 :           if (targetm.hard_regno_mode_ok (regno, mode)
     106                 :  651724000 :               && !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
     107                 : 3951010000 :               && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
     108                 : 3866920000 :             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                 :     458396 : }
     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                 :        560 : predefined_function_abi::add_full_reg_clobber (unsigned int regno)
     119                 :            : {
     120                 :        560 :   if (!m_initialized)
     121                 :            :     return;
     122                 :            : 
     123                 :         70 :   SET_HARD_REG_BIT (m_full_reg_clobbers, regno);
     124                 :         70 :   SET_HARD_REG_BIT (m_full_and_partial_reg_clobbers, regno);
     125                 :       7840 :   for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     126                 :       7770 :     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                 :     944096 : function_abi_aggregator::
     134                 :            : caller_save_regs (const function_abi &caller_abi) const
     135                 :            : {
     136                 :     944096 :   HARD_REG_SET result;
     137                 :     944096 :   CLEAR_HARD_REG_SET (result);
     138                 :    8496860 :   for (unsigned int abi_id = 0; abi_id < NUM_ABI_IDS; ++abi_id)
     139                 :            :     {
     140                 :    7552770 :       const predefined_function_abi &callee_abi = function_abis[abi_id];
     141                 :            : 
     142                 :            :       /* Skip cases that clearly aren't problematic.  */
     143                 :    7552770 :       if (abi_id == caller_abi.id ()
     144                 :   27378800 :           || hard_reg_set_empty_p (m_abi_clobbers[abi_id]))
     145                 :    7552770 :         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                 :          0 :       CLEAR_HARD_REG_SET (extra_clobbers);
     151                 :          0 :       for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
     152                 :            :         {
     153                 :          0 :           machine_mode mode = (machine_mode) i;
     154                 :          0 :           extra_clobbers |= (callee_abi.mode_clobbers (mode)
     155                 :          0 :                              & ~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                 :          0 :       result |= (extra_clobbers & m_abi_clobbers[abi_id]);
     161                 :            :     }
     162                 :     944096 :   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                 :   53928700 : call_clobbers_in_region (unsigned int abis, const_hard_reg_set mask,
     180                 :            :                          machine_mode mode)
     181                 :            : {
     182                 :   53928700 :   HARD_REG_SET result;
     183                 :   53928700 :   CLEAR_HARD_REG_SET (result);
     184                 :   90791500 :   for (unsigned int id = 0; abis; abis >>= 1, ++id)
     185                 :   36862800 :     if (abis & 1)
     186                 :   73725600 :       result |= function_abis[id].mode_clobbers (mode);
     187                 :  161786000 :   return result & mask;
     188                 :            : }
     189                 :            : 
     190                 :            : /* Return the predefined ABI used by functions with type TYPE.  */
     191                 :            : 
     192                 :            : const predefined_function_abi &
     193                 :  172033000 : fntype_abi (const_tree type)
     194                 :            : {
     195                 :  172033000 :   gcc_assert (FUNC_OR_METHOD_TYPE_P (type));
     196                 :  172033000 :   if (targetm.calls.fntype_abi)
     197                 :          0 :     return targetm.calls.fntype_abi (type);
     198                 :  172033000 :   return default_function_abi;
     199                 :            : }
     200                 :            : 
     201                 :            : /* Return the ABI of function decl FNDECL.  */
     202                 :            : 
     203                 :            : function_abi
     204                 :  130570000 : fndecl_abi (const_tree fndecl)
     205                 :            : {
     206                 :  130570000 :   gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
     207                 :  130570000 :   const predefined_function_abi &base_abi = fntype_abi (TREE_TYPE (fndecl));
     208                 :            : 
     209                 :  130570000 :   if (flag_ipa_ra && decl_binds_to_current_def_p (fndecl))
     210                 :   19797000 :     if (cgraph_rtl_info *info = cgraph_node::rtl_info (fndecl))
     211                 :   17712100 :       return function_abi (base_abi, info->function_used_regs);
     212                 :            : 
     213                 :  112857000 :   return base_abi;
     214                 :            : }
     215                 :            : 
     216                 :            : /* Return the ABI of the function called by INSN.  */
     217                 :            : 
     218                 :            : function_abi
     219                 :  186887000 : insn_callee_abi (const rtx_insn *insn)
     220                 :            : {
     221                 :  186887000 :   gcc_assert (insn && CALL_P (insn));
     222                 :            : 
     223                 :  186887000 :   if (flag_ipa_ra)
     224                 :  137847000 :     if (tree fndecl = get_call_fndecl (insn))
     225                 :  129620000 :       return fndecl_abi (fndecl);
     226                 :            : 
     227                 :   57266900 :   if (targetm.calls.insn_callee_abi)
     228                 :          0 :     return targetm.calls.insn_callee_abi (insn);
     229                 :            : 
     230                 :   57266900 :   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 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.