LCOV - code coverage report
Current view: top level - gcc/config/i386 - x86-tune-sched-atom.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 60.7 % 112 68
Test Date: 2026-10-24 16:24:59 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Scheduler hooks for IA-32 which implement atom+ 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              : /* Try to reorder ready list to take advantage of Atom pipelined IMUL
      39              :    execution. It is applied if
      40              :    (1) IMUL instruction is on the top of list;
      41              :    (2) There exists the only producer of independent IMUL instruction in
      42              :        ready list.
      43              :    Return index of IMUL producer if it was found and -1 otherwise.  */
      44              : static int
      45         1088 : do_reorder_for_imul (rtx_insn **ready, int n_ready)
      46              : {
      47         1088 :   rtx_insn *insn;
      48         1088 :   rtx set, insn1, insn2;
      49         1088 :   sd_iterator_def sd_it;
      50         1088 :   dep_t dep;
      51         1088 :   int index = -1;
      52         1088 :   int i;
      53              : 
      54         1088 :   if (!TARGET_CPU_P (BONNELL))
      55              :     return index;
      56              : 
      57              :   /* Check that IMUL instruction is on the top of ready list.  */
      58          233 :   insn = ready[n_ready - 1];
      59          233 :   set = single_set (insn);
      60          233 :   if (!set)
      61              :     return index;
      62          232 :   if (!(GET_CODE (SET_SRC (set)) == MULT
      63            5 :       && GET_MODE (SET_SRC (set)) == SImode))
      64              :     return index;
      65              : 
      66              :   /* Search for producer of independent IMUL instruction.  */
      67            0 :   for (i = n_ready - 2; i >= 0; i--)
      68              :     {
      69            0 :       insn = ready[i];
      70            0 :       if (!NONDEBUG_INSN_P (insn))
      71            0 :         continue;
      72              :       /* Skip IMUL instruction.  */
      73            0 :       insn2 = PATTERN (insn);
      74            0 :       if (GET_CODE (insn2) == PARALLEL)
      75            0 :         insn2 = XVECEXP (insn2, 0, 0);
      76            0 :       if (GET_CODE (insn2) == SET
      77            0 :           && GET_CODE (SET_SRC (insn2)) == MULT
      78            0 :           && GET_MODE (SET_SRC (insn2)) == SImode)
      79            0 :         continue;
      80              : 
      81            0 :       FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
      82              :         {
      83            0 :           rtx_insn *con = DEP_CON (dep);
      84            0 :           if (!NONDEBUG_INSN_P (con))
      85            0 :             continue;
      86            0 :           insn1 = PATTERN (con);
      87            0 :           if (GET_CODE (insn1) == PARALLEL)
      88            0 :             insn1 = XVECEXP (insn1, 0, 0);
      89              : 
      90            0 :           if (GET_CODE (insn1) == SET
      91            0 :               && GET_CODE (SET_SRC (insn1)) == MULT
      92            0 :               && GET_MODE (SET_SRC (insn1)) == SImode)
      93              :             {
      94            0 :               sd_iterator_def sd_it1;
      95            0 :               dep_t dep1;
      96              :               /* Check if there is no other dependee for IMUL.  */
      97            0 :               index = i;
      98            0 :               FOR_EACH_DEP (con, SD_LIST_BACK, sd_it1, dep1)
      99              :                 {
     100            0 :                   rtx pro;
     101            0 :                   pro = DEP_PRO (dep1);
     102            0 :                   if (!NONDEBUG_INSN_P (pro))
     103            0 :                     continue;
     104            0 :                   if (pro != insn)
     105            0 :                     index = -1;
     106              :                 }
     107            0 :               if (index >= 0)
     108              :                 break;
     109              :             }
     110              :         }
     111            0 :       if (index >= 0)
     112              :         break;
     113              :     }
     114              :   return index;
     115              : }
     116              : 
     117              : /* Try to find the best candidate on the top of ready list if two insns
     118              :    have the same priority - candidate is best if its dependees were
     119              :    scheduled earlier. Applied for Silvermont only.
     120              :    Return true if top 2 insns must be interchanged.  */
     121              : static bool
     122          693 : swap_top_of_ready_list (rtx_insn **ready, int n_ready)
     123              : {
     124          693 :   rtx_insn *top = ready[n_ready - 1];
     125          693 :   rtx_insn *next = ready[n_ready - 2];
     126          693 :   rtx set;
     127          693 :   sd_iterator_def sd_it;
     128          693 :   dep_t dep;
     129          693 :   int clock1 = -1;
     130          693 :   int clock2 = -1;
     131              :   #define INSN_TICK(INSN) (HID (INSN)->tick)
     132              : 
     133          693 :   if (!TARGET_CPU_P (SILVERMONT) && !TARGET_CPU_P (INTEL))
     134              :     return false;
     135              : 
     136          576 :   if (!NONDEBUG_INSN_P (top))
     137              :     return false;
     138          576 :   if (!NONJUMP_INSN_P (top))
     139              :     return false;
     140          576 :   if (!NONDEBUG_INSN_P (next))
     141              :     return false;
     142          576 :   if (!NONJUMP_INSN_P (next))
     143              :     return false;
     144          576 :   set = single_set (top);
     145          576 :   if (!set)
     146              :     return false;
     147          575 :   set = single_set (next);
     148          575 :   if (!set)
     149              :     return false;
     150              : 
     151          567 :   if (INSN_PRIORITY_KNOWN (top) && INSN_PRIORITY_KNOWN (next))
     152              :     {
     153          567 :       if (INSN_PRIORITY (top) != INSN_PRIORITY (next))
     154              :         return false;
     155              :       /* Determine winner more precise.  */
     156          706 :       FOR_EACH_DEP (top, SD_LIST_RES_BACK, sd_it, dep)
     157              :         {
     158          343 :           rtx_insn *pro = DEP_PRO (dep);
     159          343 :           if (!NONDEBUG_INSN_P (pro))
     160            1 :             continue;
     161          342 :           if (INSN_TICK (pro) > clock1)
     162          343 :             clock1 = INSN_TICK (pro);
     163              :         }
     164          764 :       FOR_EACH_DEP (next, SD_LIST_RES_BACK, sd_it, dep)
     165              :         {
     166          401 :           rtx_insn *pro = DEP_PRO (dep);
     167          401 :           if (!NONDEBUG_INSN_P (pro))
     168            0 :             continue;
     169          401 :           if (INSN_TICK (pro) > clock2)
     170          401 :             clock2 = INSN_TICK (pro);
     171              :         }
     172              : 
     173          363 :       if (clock1 == clock2)
     174              :         {
     175              :           /* Determine winner - load must win. */
     176          288 :           enum attr_memory memory1, memory2;
     177          288 :           memory1 = get_attr_memory (top);
     178          288 :           memory2 = get_attr_memory (next);
     179          288 :           if (memory2 == MEMORY_LOAD && memory1 != MEMORY_LOAD)
     180              :             return true;
     181              :         }
     182          363 :         return (bool) (clock2 < clock1);
     183              :     }
     184              :   return false;
     185              :   #undef INSN_TICK
     186              : }
     187              : 
     188              : /* Perform possible reordering of ready list for Atom/Silvermont only.
     189              :    Return issue rate.  */
     190              : int
     191     35989938 : ix86_atom_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready,
     192              :                          int *pn_ready, int clock_var)
     193              : {
     194     35989938 :   int issue_rate = -1;
     195     35989938 :   int n_ready = *pn_ready;
     196     35989938 :   int i;
     197     35989938 :   rtx_insn *insn;
     198     35989938 :   int index = -1;
     199              : 
     200              :   /* Set up issue rate.  */
     201     35989938 :   issue_rate = ix86_issue_rate ();
     202              : 
     203              :   /* Do reordering for BONNELL/SILVERMONT only.  */
     204     35989938 :   if (!TARGET_CPU_P (BONNELL) && !TARGET_CPU_P (SILVERMONT)
     205     35987948 :       && !TARGET_CPU_P (INTEL))
     206              :     return issue_rate;
     207              : 
     208              :   /* Nothing to do if ready list contains only 1 instruction.  */
     209         3860 :   if (n_ready <= 1)
     210              :     return issue_rate;
     211              : 
     212              :   /* Do reordering for post-reload scheduler only.  */
     213         1091 :   if (!reload_completed)
     214              :     return issue_rate;
     215              : 
     216         1088 :   if ((index = do_reorder_for_imul (ready, n_ready)) >= 0)
     217              :     {
     218            0 :       if (sched_verbose > 1)
     219            0 :         fprintf (dump, ";;\tatom sched_reorder: put %d insn on top\n",
     220            0 :                  INSN_UID (ready[index]));
     221              : 
     222              :       /* Put IMUL producer (ready[index]) at the top of ready list.  */
     223            0 :       insn = ready[index];
     224            0 :       for (i = index; i < n_ready - 1; i++)
     225            0 :         ready[i] = ready[i + 1];
     226            0 :       ready[n_ready - 1] = insn;
     227            0 :       return issue_rate;
     228              :     }
     229              : 
     230              :   /* Skip selective scheduling since HID is not populated in it.  */
     231         1088 :   if (clock_var != 0
     232          702 :       && !sel_sched_p ()
     233         1781 :       && swap_top_of_ready_list (ready, n_ready))
     234              :     {
     235           43 :       if (sched_verbose > 1)
     236            0 :         fprintf (dump, ";;\tslm sched_reorder: swap %d and %d insns\n",
     237            0 :                  INSN_UID (ready[n_ready - 1]), INSN_UID (ready[n_ready - 2]));
     238              :       /* Swap 2 top elements of ready list.  */
     239           43 :       insn = ready[n_ready - 1];
     240           43 :       ready[n_ready - 1] = ready[n_ready - 2];
     241           43 :       ready[n_ready - 2] = insn;
     242              :     }
     243              :   return issue_rate;
     244              : }
        

Generated by: LCOV version 2.5.0-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.