LCOV - code coverage report
Current view: top level - gcc/config/i386 - x86-tune-sched-core.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 93 93
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 9 9
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Scheduler hooks for IA-32 which implement Core 2 specific logic.
       2              :    Copyright (C) 1988-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
       7              : it under the terms of the GNU General Public License as published by
       8              : the Free Software Foundation; either version 3, or (at your option)
       9              : any later version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful,
      12              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : GNU General Public License 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              : #define IN_TARGET_CODE 1
      21              : 
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "backend.h"
      26              : #include "rtl.h"
      27              : #include "tree.h"
      28              : #include "cfghooks.h"
      29              : #include "tm_p.h"
      30              : #include "insn-config.h"
      31              : #include "insn-attr.h"
      32              : #include "recog.h"
      33              : #include "target.h"
      34              : #include "rtl-iter.h"
      35              : #include "regset.h"
      36              : #include "sched-int.h"
      37              : 
      38              : 
      39              : /* Model decoder of Core 2/i7.
      40              :    Below hooks for multipass scheduling (see haifa-sched.cc:max_issue)
      41              :    track the instruction fetch block boundaries and make sure that long
      42              :    (9+ bytes) instructions are assigned to D0.  */
      43              : 
      44              : /* Maximum length of an insn that can be handled by
      45              :    a secondary decoder unit.  '8' for Core 2/i7.  */
      46              : static int core2i7_secondary_decoder_max_insn_size;
      47              : 
      48              : /* Ifetch block size, i.e., number of bytes decoder reads per cycle.
      49              :    '16' for Core 2/i7.  */
      50              : static int core2i7_ifetch_block_size;
      51              : 
      52              : /* Maximum number of instructions decoder can handle per cycle.
      53              :    '6' for Core 2/i7.  */
      54              : static int core2i7_ifetch_block_max_insns;
      55              : 
      56              : typedef struct ix86_first_cycle_multipass_data_ *
      57              :   ix86_first_cycle_multipass_data_t;
      58              : typedef const struct ix86_first_cycle_multipass_data_ *
      59              :   const_ix86_first_cycle_multipass_data_t;
      60              : 
      61              : /* A variable to store target state across calls to max_issue within
      62              :    one cycle.  */
      63              : static struct ix86_first_cycle_multipass_data_ _ix86_first_cycle_multipass_data,
      64              :   *ix86_first_cycle_multipass_data = &_ix86_first_cycle_multipass_data;
      65              : 
      66              : /* Initialize DATA.  */
      67              : static void
      68    118648174 : core2i7_first_cycle_multipass_init (void *_data)
      69              : {
      70    118648174 :   ix86_first_cycle_multipass_data_t data
      71              :     = (ix86_first_cycle_multipass_data_t) _data;
      72              : 
      73    118648174 :   data->ifetch_block_len = 0;
      74    118648174 :   data->ifetch_block_n_insns = 0;
      75    118648174 :   data->ready_try_change = NULL;
      76    118648174 :   data->ready_try_change_size = 0;
      77    118648174 : }
      78              : 
      79              : /* Advancing the cycle; reset ifetch block counts.  */
      80              : static void
      81     45774424 : core2i7_dfa_post_advance_cycle (void)
      82              : {
      83     45774424 :   ix86_first_cycle_multipass_data_t data = ix86_first_cycle_multipass_data;
      84              : 
      85     45774424 :   gcc_assert (data->ifetch_block_n_insns <= core2i7_ifetch_block_max_insns);
      86              : 
      87     45774424 :   data->ifetch_block_len = 0;
      88     45774424 :   data->ifetch_block_n_insns = 0;
      89     45774424 : }
      90              : 
      91              : /* Filter out insns from ready_try that the core will not be able to issue
      92              :    on current cycle due to decoder.  */
      93              : static void
      94    165835967 : core2i7_first_cycle_multipass_filter_ready_try
      95              : (const_ix86_first_cycle_multipass_data_t data,
      96              :  signed char *ready_try, int n_ready, bool first_cycle_insn_p)
      97              : {
      98    642455097 :   while (n_ready--)
      99              :     {
     100    476619130 :       rtx_insn *insn;
     101    476619130 :       int insn_size;
     102              : 
     103    476619130 :       if (ready_try[n_ready])
     104    208699780 :         continue;
     105              : 
     106    267919350 :       insn = get_ready_element (n_ready);
     107    267919350 :       insn_size = ix86_min_insn_size (insn);
     108              : 
     109    267919350 :       if (/* If this is a too long an insn for a secondary decoder ...  */
     110              :           (!first_cycle_insn_p
     111    211269552 :            && insn_size > core2i7_secondary_decoder_max_insn_size)
     112              :           /* ... or it would not fit into the ifetch block ...  */
     113    242908019 :           || data->ifetch_block_len + insn_size > core2i7_ifetch_block_size
     114              :           /* ... or the decoder is full already ...  */
     115    165438402 :           || data->ifetch_block_n_insns + 1 > core2i7_ifetch_block_max_insns)
     116              :         /* ... mask the insn out.  */
     117              :         {
     118    102481020 :           ready_try[n_ready] = 1;
     119              : 
     120    102481020 :           if (data->ready_try_change)
     121     94907696 :             bitmap_set_bit (data->ready_try_change, n_ready);
     122              :         }
     123              :     }
     124    165835967 : }
     125              : 
     126              : /* Prepare for a new round of multipass lookahead scheduling.  */
     127              : static void
     128     54903641 : core2i7_first_cycle_multipass_begin (void *_data,
     129              :                                      signed char *ready_try, int n_ready,
     130              :                                      bool first_cycle_insn_p)
     131              : {
     132     54903641 :   ix86_first_cycle_multipass_data_t data
     133              :     = (ix86_first_cycle_multipass_data_t) _data;
     134     54903641 :   const_ix86_first_cycle_multipass_data_t prev_data
     135              :     = ix86_first_cycle_multipass_data;
     136              : 
     137              :   /* Restore the state from the end of the previous round.  */
     138     54903641 :   data->ifetch_block_len = prev_data->ifetch_block_len;
     139     54903641 :   data->ifetch_block_n_insns = prev_data->ifetch_block_n_insns;
     140              : 
     141              :   /* Filter instructions that cannot be issued on current cycle due to
     142              :      decoder restrictions.  */
     143     54903641 :   core2i7_first_cycle_multipass_filter_ready_try (data, ready_try, n_ready,
     144              :                                                   first_cycle_insn_p);
     145     54903641 : }
     146              : 
     147              : /* INSN is being issued in current solution.  Account for its impact on
     148              :    the decoder model.  */
     149              : static void
     150    110932326 : core2i7_first_cycle_multipass_issue (void *_data,
     151              :                                      signed char *ready_try, int n_ready,
     152              :                                      rtx_insn *insn, const void *_prev_data)
     153              : {
     154    110932326 :   ix86_first_cycle_multipass_data_t data
     155              :     = (ix86_first_cycle_multipass_data_t) _data;
     156    110932326 :   const_ix86_first_cycle_multipass_data_t prev_data
     157              :     = (const_ix86_first_cycle_multipass_data_t) _prev_data;
     158              : 
     159    110932326 :   int insn_size = ix86_min_insn_size (insn);
     160              : 
     161    110932326 :   data->ifetch_block_len = prev_data->ifetch_block_len + insn_size;
     162    110932326 :   data->ifetch_block_n_insns = prev_data->ifetch_block_n_insns + 1;
     163    110932326 :   gcc_assert (data->ifetch_block_len <= core2i7_ifetch_block_size
     164              :               && data->ifetch_block_n_insns <= core2i7_ifetch_block_max_insns);
     165              : 
     166              :   /* Allocate or resize the bitmap for storing INSN's effect on ready_try.  */
     167    110932326 :   if (!data->ready_try_change)
     168              :     {
     169     16138300 :       data->ready_try_change = sbitmap_alloc (n_ready);
     170     16138300 :       data->ready_try_change_size = n_ready;
     171              :     }
     172     94794026 :   else if (data->ready_try_change_size < n_ready)
     173              :     {
     174      1060528 :       data->ready_try_change = sbitmap_resize (data->ready_try_change,
     175              :                                                n_ready, 0);
     176      1060528 :       data->ready_try_change_size = n_ready;
     177              :     }
     178    110932326 :   bitmap_clear (data->ready_try_change);
     179              : 
     180              :   /* Filter out insns from ready_try that the core will not be able to issue
     181              :      on current cycle due to decoder.  */
     182    110932326 :   core2i7_first_cycle_multipass_filter_ready_try (data, ready_try, n_ready,
     183              :                                                   false);
     184    110932326 : }
     185              : 
     186              : /* Revert the effect on ready_try.  */
     187              : static void
     188     56223098 : core2i7_first_cycle_multipass_backtrack (const void *_data,
     189              :                                          signed char *ready_try,
     190              :                                          int n_ready ATTRIBUTE_UNUSED)
     191              : {
     192     56223098 :   const_ix86_first_cycle_multipass_data_t data
     193              :     = (const_ix86_first_cycle_multipass_data_t) _data;
     194     56223098 :   unsigned int i = 0;
     195     56223098 :   sbitmap_iterator sbi;
     196              : 
     197     56223098 :   gcc_assert (bitmap_last_set_bit (data->ready_try_change) < n_ready);
     198    205903267 :   EXECUTE_IF_SET_IN_BITMAP (data->ready_try_change, 0, i, sbi)
     199              :     {
     200     93457071 :       ready_try[i] = 0;
     201              :     }
     202     56223098 : }
     203              : 
     204              : /* Save the result of multipass lookahead scheduling for the next round.  */
     205              : static void
     206     54903641 : core2i7_first_cycle_multipass_end (const void *_data)
     207              : {
     208     54903641 :   const_ix86_first_cycle_multipass_data_t data
     209              :     = (const_ix86_first_cycle_multipass_data_t) _data;
     210     54903641 :   ix86_first_cycle_multipass_data_t next_data
     211              :     = ix86_first_cycle_multipass_data;
     212              : 
     213     54903641 :   if (data != NULL)
     214              :     {
     215     52741298 :       next_data->ifetch_block_len = data->ifetch_block_len;
     216     52741298 :       next_data->ifetch_block_n_insns = data->ifetch_block_n_insns;
     217              :     }
     218     54903641 : }
     219              : 
     220              : /* Deallocate target data.  */
     221              : static void
     222    118648174 : core2i7_first_cycle_multipass_fini (void *_data)
     223              : {
     224    118648174 :   ix86_first_cycle_multipass_data_t data
     225              :     = (ix86_first_cycle_multipass_data_t) _data;
     226              : 
     227    118648174 :   if (data->ready_try_change)
     228              :     {
     229     16138300 :       sbitmap_free (data->ready_try_change);
     230     16138300 :       data->ready_try_change = NULL;
     231     16138300 :       data->ready_try_change_size = 0;
     232              :     }
     233    118648174 : }
     234              : 
     235              : void
     236       917458 : ix86_core2i7_init_hooks (void)
     237              : {
     238       917458 :   targetm.sched.dfa_post_advance_cycle
     239       917458 :     = core2i7_dfa_post_advance_cycle;
     240       917458 :   targetm.sched.first_cycle_multipass_init
     241       917458 :     = core2i7_first_cycle_multipass_init;
     242       917458 :   targetm.sched.first_cycle_multipass_begin
     243       917458 :     = core2i7_first_cycle_multipass_begin;
     244       917458 :   targetm.sched.first_cycle_multipass_issue
     245       917458 :     = core2i7_first_cycle_multipass_issue;
     246       917458 :   targetm.sched.first_cycle_multipass_backtrack
     247       917458 :     = core2i7_first_cycle_multipass_backtrack;
     248       917458 :   targetm.sched.first_cycle_multipass_end
     249       917458 :     = core2i7_first_cycle_multipass_end;
     250       917458 :   targetm.sched.first_cycle_multipass_fini
     251       917458 :     = core2i7_first_cycle_multipass_fini;
     252              : 
     253              :   /* Set decoder parameters.  */
     254       917458 :   core2i7_secondary_decoder_max_insn_size = 8;
     255       917458 :   core2i7_ifetch_block_size = 16;
     256       917458 :   core2i7_ifetch_block_max_insns = 6;
     257       917458 : }
        

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.