LCOV - code coverage report
Current view: top level - gcc - rtlanal.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 100.0 % 46 46
Test Date: 2024-11-30 13:30:02 Functions: 100.0 % 2 2
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Analyze RTL for GNU compiler.
       2                 :             :    Copyright (C) 2020-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                 :             : /* Note that for historical reasons, many rtlanal.cc functions are
      21                 :             :    declared in rtl.h rather than here.  */
      22                 :             : 
      23                 :             : #ifndef GCC_RTLANAL_H
      24                 :             : #define GCC_RTLANAL_H
      25                 :             : 
      26                 :             : /* A dummy register value that represents the whole of variable memory.
      27                 :             :    Using ~0U means that arrays that track both registers and memory can
      28                 :             :    be indexed by regno + 1.  */
      29                 :             : const unsigned int MEM_REGNO = ~0U;
      30                 :             : 
      31                 :             : /* Bitmasks of flags describing an rtx_obj_reference.  See the accessors
      32                 :             :    in the class for details.  */
      33                 :             : namespace rtx_obj_flags
      34                 :             : {
      35                 :             :   const uint16_t IS_READ = 1U << 0;
      36                 :             :   const uint16_t IS_WRITE = 1U << 1;
      37                 :             :   const uint16_t IS_CLOBBER = 1U << 2;
      38                 :             :   const uint16_t IS_PRE_POST_MODIFY = 1U << 3;
      39                 :             :   const uint16_t IS_MULTIREG = 1U << 4;
      40                 :             :   const uint16_t IN_MEM_LOAD = 1U << 5;
      41                 :             :   const uint16_t IN_MEM_STORE = 1U << 6;
      42                 :             :   const uint16_t IN_SUBREG = 1U << 7;
      43                 :             :   const uint16_t IN_NOTE = 1U << 8;
      44                 :             : 
      45                 :             :   /* Flags that apply to all subrtxes of the rtx they were originally
      46                 :             :      added for.  */
      47                 :             :   static const uint16_t STICKY_FLAGS = IN_NOTE;
      48                 :             : }
      49                 :             : 
      50                 :             : /* Contains information about a reference to a register or variable memory.  */
      51                 :             : class rtx_obj_reference
      52                 :             : {
      53                 :             : public:
      54                 :             :   rtx_obj_reference () = default;
      55                 :             :   rtx_obj_reference (unsigned int regno, uint16_t flags,
      56                 :             :                      machine_mode mode, unsigned int multireg_offset = 0);
      57                 :             : 
      58                 :             :   bool is_reg () const { return regno != MEM_REGNO; }
      59                 :    37730107 :   bool is_mem () const { return regno == MEM_REGNO; }
      60                 :             : 
      61                 :             :   /* True if the reference is a read or a write respectively.
      62                 :             :      Both flags are set in a read-modify-write context, such as
      63                 :             :      for read_modify_subreg_p.  */
      64                 :   877655268 :   bool is_read () const { return flags & rtx_obj_flags::IS_READ; }
      65                 :  1014628744 :   bool is_write () const { return flags & rtx_obj_flags::IS_WRITE; }
      66                 :             : 
      67                 :             :   /* True if IS_WRITE and if the write is a clobber rather than a set.  */
      68                 :        4612 :   bool is_clobber () const { return flags & rtx_obj_flags::IS_CLOBBER; }
      69                 :             : 
      70                 :             :   /* True if the reference is updated by an RTX_AUTOINC.  Both IS_READ
      71                 :             :      and IS_WRITE are also true if so.  */
      72                 :   257005288 :   bool is_pre_post_modify () const
      73                 :             :   {
      74                 :   257005288 :     return flags & rtx_obj_flags::IS_PRE_POST_MODIFY;
      75                 :             :   }
      76                 :             : 
      77                 :             :   /* True if the register is part of a multi-register hard REG.  */
      78                 :   650984052 :   bool is_multireg () const { return flags & rtx_obj_flags::IS_MULTIREG; }
      79                 :             : 
      80                 :             :   /* True if the reference occurs in the address of a load MEM.  */
      81                 :   359298469 :   bool in_mem_load () const { return flags & rtx_obj_flags::IN_MEM_LOAD; }
      82                 :             : 
      83                 :             :   /* True if the reference occurs in the address of a store MEM.  */
      84                 :             :   bool in_mem_store () const { return flags & rtx_obj_flags::IN_MEM_STORE; }
      85                 :             : 
      86                 :             :   /* True if the reference occurs in any kind of MEM address.  */
      87                 :   393978764 :   bool in_address () const { return in_mem_load () || in_mem_store (); }
      88                 :             : 
      89                 :             :   /* True if the reference occurs in a SUBREG.  */
      90                 :   650984052 :   bool in_subreg () const { return flags & rtx_obj_flags::IN_SUBREG; }
      91                 :             : 
      92                 :             :   /* True if the reference occurs in a REG_EQUAL or REG_EQUIV note.  */
      93                 :   393978764 :   bool in_note () const { return flags & rtx_obj_flags::IN_NOTE; }
      94                 :             : 
      95                 :             :   /* The referenced register, or MEM_REGNO for variable memory.  */
      96                 :             :   unsigned int regno;
      97                 :             : 
      98                 :             :   /* A bitmask of rtx_obj_flags.  */
      99                 :             :   unsigned int flags : 16;
     100                 :             : 
     101                 :             :   /* The mode of the reference.  If IS_MULTIREG, this is the mode of
     102                 :             :      REGNO - MULTIREG_OFFSET.  */
     103                 :             :   machine_mode mode : MACHINE_MODE_BITSIZE;
     104                 :             : 
     105                 :             :   /* If IS_MULTIREG, the offset of REGNO from the start of the register.  */
     106                 :             :   unsigned int multireg_offset : 8;
     107                 :             : };
     108                 :             : 
     109                 :             : /* Construct a reference with the given fields.  */
     110                 :             : 
     111                 :   112459544 : inline rtx_obj_reference::rtx_obj_reference (unsigned int regno, uint16_t flags,
     112                 :             :                                              machine_mode mode,
     113                 :             :                                              unsigned int multireg_offset)
     114                 :             :   : regno (regno),
     115                 :             :     flags (flags),
     116                 :       12616 :     mode (mode),
     117                 :   508622577 :     multireg_offset (multireg_offset)
     118                 :             : {
     119                 :             : }
     120                 :             : 
     121                 :             : /* Contains information about an rtx or an instruction, including a
     122                 :             :    list of rtx_obj_references.  The storage backing the list needs
     123                 :             :    to be filled in by assigning to REF_BEGIN and REF_END.  */
     124                 :             : 
     125                 :             : class rtx_properties
     126                 :             : {
     127                 :             : public:
     128                 :             :   rtx_properties ();
     129                 :             : 
     130                 :             :   void try_to_add_reg (const_rtx x, unsigned int flags = 0);
     131                 :             :   void try_to_add_dest (const_rtx x, unsigned int flags = 0);
     132                 :             :   void try_to_add_src (const_rtx x, unsigned int flags = 0);
     133                 :             :   void try_to_add_pattern (const_rtx pat);
     134                 :             :   void try_to_add_note (const_rtx x);
     135                 :             :   void try_to_add_insn (const rtx_insn *insn, bool include_notes);
     136                 :             : 
     137                 :             :   iterator_range<rtx_obj_reference *> refs () const;
     138                 :             : 
     139                 :             :   /* Return the number of rtx_obj_references that have been recorded.  */
     140                 :   392553267 :   size_t num_refs () const { return ref_iter - ref_begin; }
     141                 :             : 
     142                 :             :   bool has_side_effects () const;
     143                 :             : 
     144                 :             :   /* [REF_BEGIN, REF_END) is the maximum extent of the memory available
     145                 :             :      for recording references.  REG_ITER is the first unused entry.  */
     146                 :             :   rtx_obj_reference *ref_begin;
     147                 :             :   rtx_obj_reference *ref_iter;
     148                 :             :   rtx_obj_reference *ref_end;
     149                 :             : 
     150                 :             :   /* True if the rtx includes an asm.  */
     151                 :             :   unsigned int has_asm : 1;
     152                 :             : 
     153                 :             :   /* True if the rtx includes a call.  */
     154                 :             :   unsigned int has_call : 1;
     155                 :             : 
     156                 :             :   /* True if the rtx includes an RTX_AUTOINC expression.  */
     157                 :             :   unsigned int has_pre_post_modify : 1;
     158                 :             : 
     159                 :             :   /* True if the rtx contains volatile references, in the sense of
     160                 :             :      volatile_refs_p.  */
     161                 :             :   unsigned int has_volatile_refs : 1;
     162                 :             : 
     163                 :             :   /* For future expansion.  */
     164                 :             :   unsigned int spare : 28;
     165                 :             : };
     166                 :             : 
     167                 :   392553267 : inline rtx_properties::rtx_properties ()
     168                 :             :   : ref_begin (nullptr),
     169                 :             :     ref_iter (nullptr),
     170                 :             :     ref_end (nullptr),
     171                 :   392553267 :     has_asm (false),
     172                 :   392553267 :     has_call (false),
     173                 :   392553267 :     has_pre_post_modify (false),
     174                 :   392553267 :     has_volatile_refs (false),
     175                 :   392553267 :     spare (0)
     176                 :             : {
     177                 :             : }
     178                 :             : 
     179                 :             : /* Like add_src, but treat X has being part of a REG_EQUAL or
     180                 :             :    REG_EQUIV note.  */
     181                 :             : 
     182                 :             : inline void
     183                 :    15689276 : rtx_properties::try_to_add_note (const_rtx x)
     184                 :             : {
     185                 :    15689276 :   try_to_add_src (x, rtx_obj_flags::IN_NOTE);
     186                 :    15689276 : }
     187                 :             : 
     188                 :             : /* Return true if the rtx has side effects, in the sense of
     189                 :             :    side_effects_p (except for side_effects_p's special handling
     190                 :             :    of combine.cc clobbers).  */
     191                 :             : 
     192                 :             : inline bool
     193                 :          39 : rtx_properties::has_side_effects () const
     194                 :             : {
     195                 :          39 :   return has_volatile_refs || has_pre_post_modify || has_call;
     196                 :             : }
     197                 :             : 
     198                 :             : /* Return an iterator range for all the references, suitable for
     199                 :             :    range-based for loops.  */
     200                 :             : 
     201                 :             : inline iterator_range<rtx_obj_reference *>
     202                 :   785106481 : rtx_properties::refs () const
     203                 :             : {
     204                 :   785106481 :   return { ref_begin, ref_iter };
     205                 :             : }
     206                 :             : 
     207                 :             : /* BASE is derived from rtx_properties and provides backing storage
     208                 :             :    for REF_BEGIN.  It has a grow () method that increases the amount
     209                 :             :    of memory available if the initial allocation was too small.  */
     210                 :             : 
     211                 :             : template<typename Base>
     212                 :   785106488 : class growing_rtx_properties : public Base
     213                 :             : {
     214                 :             : public:
     215                 :             :   template<typename... Args>
     216                 :             :   growing_rtx_properties (Args...);
     217                 :             : 
     218                 :             :   template<typename AddFn>
     219                 :             :   void repeat (AddFn add);
     220                 :             : 
     221                 :             :   /* Wrappers around the try_to_* functions that always succeed.  */
     222                 :             :   void add_dest (const_rtx x, unsigned int flags = 0);
     223                 :             :   void add_src (const_rtx x, unsigned int flags = 0);
     224                 :             :   void add_pattern (const_rtx pat);
     225                 :             :   void add_note (const_rtx x);
     226                 :             :   void add_insn (const rtx_insn *insn, bool include_notes);
     227                 :             : };
     228                 :             : 
     229                 :             : template<typename Base>
     230                 :             : template<typename... Args>
     231                 :   392553267 : growing_rtx_properties<Base>::growing_rtx_properties (Args... args)
     232                 :   392553267 :   : Base (std::forward<Args> (args)...)
     233                 :             : {
     234                 :             : }
     235                 :             : 
     236                 :             : /* Perform ADD until there is enough room to hold the result.  */
     237                 :             : 
     238                 :             : template<typename Base>
     239                 :             : template<typename AddFn>
     240                 :             : inline void
     241                 :   392553267 : growing_rtx_properties<Base>::repeat (AddFn add)
     242                 :             : {
     243                 :   392553267 :   ptrdiff_t count = this->num_refs ();
     244                 :       12573 :   for (;;)
     245                 :             :     {
     246                 :   392565840 :       add ();
     247                 :             :       /* This retries if the storage happened to be exactly the right size,
     248                 :             :          but that's expected to be a rare case and so isn't worth
     249                 :             :          optimizing for.  */
     250                 :   392565840 :       if (LIKELY (this->ref_iter != this->ref_end))
     251                 :             :         break;
     252                 :       12573 :       this->grow (count);
     253                 :             :     }
     254                 :   392553267 : }
     255                 :             : 
     256                 :             : template<typename Base>
     257                 :             : inline void
     258                 :             : growing_rtx_properties<Base>::add_dest (const_rtx x, unsigned int flags)
     259                 :             : {
     260                 :             :   repeat ([&]() { this->try_to_add_dest (x, flags); });
     261                 :             : }
     262                 :             : 
     263                 :             : template<typename Base>
     264                 :             : inline void
     265                 :             : growing_rtx_properties<Base>::add_src (const_rtx x, unsigned int flags)
     266                 :             : {
     267                 :             :   repeat ([&]() { this->try_to_add_src (x, flags); });
     268                 :             : }
     269                 :             : 
     270                 :             : template<typename Base>
     271                 :             : inline void
     272                 :             : growing_rtx_properties<Base>::add_pattern (const_rtx pat)
     273                 :             : {
     274                 :             :   repeat ([&]() { this->try_to_add_pattern (pat); });
     275                 :             : }
     276                 :             : 
     277                 :             : template<typename Base>
     278                 :             : inline void
     279                 :             : growing_rtx_properties<Base>::add_note (const_rtx x)
     280                 :             : {
     281                 :             :   repeat ([&]() { this->try_to_add_note (x); });
     282                 :             : }
     283                 :             : 
     284                 :             : template<typename Base>
     285                 :             : inline void
     286                 :   392553267 : growing_rtx_properties<Base>::add_insn (const rtx_insn *insn, bool include_notes)
     287                 :             : {
     288                 :   785119107 :   repeat ([&]() { this->try_to_add_insn (insn, include_notes); });
     289                 :             : }
     290                 :             : 
     291                 :             : /* A base class for vec_rtx_properties; see there for details.  */
     292                 :             : 
     293                 :             : class vec_rtx_properties_base : public rtx_properties
     294                 :             : {
     295                 :             :   static const size_t SIZE = 32;
     296                 :             : 
     297                 :             : public:
     298                 :             :   vec_rtx_properties_base ();
     299                 :             :   ~vec_rtx_properties_base ();
     300                 :             : 
     301                 :             : protected:
     302                 :             :   void grow (ptrdiff_t);
     303                 :             : 
     304                 :             : private:
     305                 :             :   rtx_obj_reference m_storage[SIZE];
     306                 :             : };
     307                 :             : 
     308                 :   392553267 : inline vec_rtx_properties_base::vec_rtx_properties_base ()
     309                 :             : {
     310                 :   392553267 :   ref_begin = ref_iter = m_storage;
     311                 :   392553267 :   ref_end = m_storage + SIZE;
     312                 :             : }
     313                 :             : 
     314                 :   392553267 : inline vec_rtx_properties_base::~vec_rtx_properties_base ()
     315                 :             : {
     316                 :   392553267 :   if (UNLIKELY (ref_begin != m_storage))
     317                 :       10284 :     free (ref_begin);
     318                 :             : }
     319                 :             : 
     320                 :             : /* A rtx_properties that stores its references in a temporary array.
     321                 :             :    Like auto_vec, the array is initially on the stack, but can switch
     322                 :             :    to the heap if necessary.
     323                 :             : 
     324                 :             :    The reason for implementing this as a derived class is that the
     325                 :             :    default on-stack size should be enough for the vast majority of
     326                 :             :    expressions and instructions.  It's therefore not worth paying
     327                 :             :    the cost of conditionally calling grow code at every site that
     328                 :             :    records a new reference.  Instead, the rtx_properties code can use
     329                 :             :    trivial iterator updates for the common case, and in the rare case
     330                 :             :    that the vector needs to be resized, we can pay the cost of
     331                 :             :    collecting the references a second time.  */
     332                 :             : using vec_rtx_properties = growing_rtx_properties<vec_rtx_properties_base>;
     333                 :             : 
     334                 :             : bool
     335                 :             : vec_series_highpart_p (machine_mode result_mode, machine_mode op_mode,
     336                 :             :                        rtx sel);
     337                 :             : 
     338                 :             : bool
     339                 :             : vec_series_lowpart_p (machine_mode result_mode, machine_mode op_mode, rtx sel);
     340                 :             : 
     341                 :             : bool
     342                 :             : contains_paradoxical_subreg_p (rtx x);
     343                 :             : #endif
        

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