LCOV - code coverage report
Current view: top level - gcc - recog.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.4 % 58 53
Test Date: 2026-09-19 16:22:48 Functions: 60.0 % 5 3
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Declarations for interface to insn recognizer and insn-output.cc.
       2              :    Copyright (C) 1987-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 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              : #ifndef GCC_RECOG_H
      21              : #define GCC_RECOG_H
      22              : 
      23              : /* For enum tree_code ERROR_MARK.  */
      24              : #include "tree.h"
      25              : 
      26              : /* Random number that should be large enough for all purposes.  Also define
      27              :    a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra
      28              :    bit giving an invalid value that can be used to mean "uninitialized".  */
      29              : #define MAX_RECOG_ALTERNATIVES 35
      30              : typedef uint64_t alternative_mask;  /* Keep in sync with genattrtab.cc.  */
      31              : 
      32              : /* A mask of all alternatives.  */
      33              : #define ALL_ALTERNATIVES ((alternative_mask) -1)
      34              : 
      35              : /* A mask containing just alternative X.  */
      36              : #define ALTERNATIVE_BIT(X) ((alternative_mask) 1 << (X))
      37              : 
      38              : /* Types of operands.  */
      39              : enum op_type {
      40              :   OP_IN,
      41              :   OP_OUT,
      42              :   OP_INOUT
      43              : };
      44              : 
      45              : #ifndef GENERATOR_FILE
      46              : struct operand_alternative
      47              : {
      48              :   /* Pointer to the beginning of the constraint string for this alternative,
      49              :      for easier access by alternative number.  */
      50              :   const char *constraint;
      51              : 
      52              :   /* The register class valid for this alternative (possibly NO_REGS).  */
      53              :   enum reg_class cl : 16;
      54              : 
      55              :   /* "Badness" of this alternative, computed from number of '?' and '!'
      56              :      characters in the constraint string.  */
      57              :   unsigned int reject : 16;
      58              : 
      59              :   /* -1 if no matching constraint was found, or an operand number.  */
      60              :   int matches : 8;
      61              :   /* The same information, but reversed: -1 if this operand is not
      62              :      matched by any other, or the operand number of the operand that
      63              :      matches this one.  */
      64              :   int matched : 8;
      65              : 
      66              :   /* Bit ID is set if the constraint string includes a register constraint with
      67              :      register filter ID.  Use test_register_filters (REGISTER_FILTERS, REGNO)
      68              :      to test whether REGNO is a valid start register for the operand.  */
      69              :   unsigned int register_filters : MAX (NUM_REGISTER_FILTERS, 1);
      70              : 
      71              :   /* Bit ID is set if the constraint string includes a dependent
      72              :      register constraint with dependent-filter id ID.  */
      73              :   unsigned int dependent_filters : MAX (NUM_DEPENDENT_FILTERS, 1);
      74              : 
      75              :   /* Nonzero if '&' was found in the constraint string.  */
      76              :   unsigned int earlyclobber : 1;
      77              :   /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint
      78              :      string.  */
      79              :   unsigned int memory_ok : 1;
      80              :   /* Nonzero if 'p' was found in the constraint string.  */
      81              :   unsigned int is_address : 1;
      82              :   /* Nonzero if 'X' was found in the constraint string, or if the constraint
      83              :      string for this alternative was empty.  */
      84              :   unsigned int anything_ok : 1;
      85              : };
      86              : 
      87              : /* Return the class for operand I of alternative ALT, taking matching
      88              :    constraints into account.  */
      89              : 
      90              : inline enum reg_class
      91    186024595 : alternative_class (const operand_alternative *alt, int i)
      92              : {
      93    186024595 :   return alt[i].matches >= 0 ? alt[alt[i].matches].cl : alt[i].cl;
      94              : }
      95              : 
      96              : /* Return the mask of register filters that should be applied to operand I
      97              :    of alternative ALT, taking matching constraints into account.  */
      98              : 
      99              : inline unsigned int
     100     95856465 : alternative_register_filters (const operand_alternative *alt, int i)
     101              : {
     102     95856465 :   return (alt[i].matches >= 0
     103     95856465 :           ? alt[alt[i].matches].register_filters
     104     85531662 :           : alt[i].register_filters);
     105              : }
     106              : 
     107              : /* Return the mask of dynamic register filters that should be applied to
     108              :    operand I of alternative ALT, taking matching constraints into
     109              :    account.  */
     110              : 
     111              : inline unsigned int
     112              : alternative_dependent_filters (const operand_alternative *alt, int i)
     113              : {
     114            0 :   return (alt[i].matches >= 0
     115              :           ? alt[alt[i].matches].dependent_filters
     116              :           : alt[i].dependent_filters);
     117              : }
     118              : #endif
     119              : 
     120              : /* A class for substituting one rtx for another within an instruction,
     121              :    or for recursively simplifying the instruction as-is.  Derived classes
     122              :    can record or filter certain decisions.  */
     123              : 
     124              : class insn_propagation : public simplify_context
     125              : {
     126              : public:
     127              :   /* Assignments for RESULT_FLAGS.
     128              : 
     129              :      UNSIMPLIFIED is true if a substitution has been made inside an rtx
     130              :      X and if neither X nor its parent expressions could be simplified.
     131              : 
     132              :      FIRST_SPARE_RESULT is the first flag available for derived classes.  */
     133              :   static const uint16_t UNSIMPLIFIED = 1U << 0;
     134              :   static const uint16_t FIRST_SPARE_RESULT = 1U << 1;
     135              : 
     136              :   insn_propagation (rtx_insn *);
     137              :   insn_propagation (rtx_insn *, rtx, rtx, bool = true);
     138              :   bool apply_to_pattern (rtx *);
     139              :   bool apply_to_rvalue (rtx *);
     140              :   bool apply_to_note (rtx *);
     141              : 
     142              :   /* Return true if we should accept a substitution into the address of
     143              :      memory expression MEM.  Undoing changes OLD_NUM_CHANGES and up restores
     144              :      MEM's original address.  */
     145            0 :   virtual bool check_mem (int /*old_num_changes*/,
     146            0 :                           rtx /*mem*/) { return true; }
     147              : 
     148              :   /* Note that we've simplified OLD_RTX into NEW_RTX.  When substituting,
     149              :      this only happens if a substitution occurred within OLD_RTX.
     150              :      Undoing OLD_NUM_CHANGES and up will restore the old form of OLD_RTX.
     151              :      OLD_RESULT_FLAGS is the value that RESULT_FLAGS had before processing
     152              :      OLD_RTX.  */
     153            0 :   virtual void note_simplification (int /*old_num_changes*/,
     154              :                                     uint16_t /*old_result_flags*/,
     155            0 :                                     rtx /*old_rtx*/, rtx /*new_rtx*/) {}
     156              : 
     157              : private:
     158              :   bool apply_to_mem_1 (rtx);
     159              :   bool apply_to_lvalue_1 (rtx);
     160              :   bool apply_to_rvalue_1 (rtx *);
     161              :   bool apply_to_pattern_1 (rtx *);
     162              : 
     163              : public:
     164              :   /* The instruction that we are simplifying or propagating into.  */
     165              :   rtx_insn *insn;
     166              : 
     167              :   /* If FROM is nonnull, we're replacing FROM with TO, otherwise we're
     168              :      just doing a recursive simplification.  */
     169              :   rtx from;
     170              :   rtx to;
     171              : 
     172              :   /* The number of times that we have replaced FROM with TO.  */
     173              :   unsigned int num_replacements;
     174              : 
     175              :   /* A bitmask of flags that describe the result of the simplificiation;
     176              :      see above for details.  */
     177              :   uint16_t result_flags : 16;
     178              : 
     179              :   /* True if we should unshare TO when making the next substitution,
     180              :      false if we can use TO itself.  */
     181              :   uint16_t should_unshare : 1;
     182              : 
     183              :   /* True if we should call check_mem after substituting into a memory.  */
     184              :   uint16_t should_check_mems : 1;
     185              : 
     186              :   /* True if we should call note_simplification after each simplification.  */
     187              :   uint16_t should_note_simplifications : 1;
     188              : 
     189              :   /* For future expansion.  */
     190              :   uint16_t spare : 13;
     191              : 
     192              :   /* Gives the reason that a substitution failed, for debug purposes.  */
     193              :   const char *failure_reason;
     194              : };
     195              : 
     196              : /* Try to replace FROM with TO in INSN.  SHARED_P is true if TO is shared
     197              :    with other instructions, false if INSN can use TO directly.  */
     198              : 
     199     71004291 : inline insn_propagation::insn_propagation (rtx_insn *insn, rtx from, rtx to,
     200              :                                            bool shared_p)
     201     71004291 :   : insn (insn),
     202     71004291 :     from (from),
     203     71004291 :     to (to),
     204     71004291 :     num_replacements (0),
     205     71004291 :     result_flags (0),
     206     71004291 :     should_unshare (shared_p),
     207     71004291 :     should_check_mems (false),
     208     71004291 :     should_note_simplifications (false),
     209     71004291 :     spare (0),
     210     71004291 :     failure_reason (nullptr)
     211              : {
     212              : }
     213              : 
     214              : /* Try to simplify INSN without performing a substitution.  */
     215              : 
     216      3522231 : inline insn_propagation::insn_propagation (rtx_insn *insn)
     217      3522231 :   : insn_propagation (insn, NULL_RTX, NULL_RTX)
     218              : {
     219              : }
     220              : 
     221              : /* An RAII class that temporarily undoes part of the current change group.
     222              :    The sequence:
     223              : 
     224              :      {
     225              :        ...;
     226              :        undo_recog_changes undo (NUM);
     227              :        STMTS;
     228              :      }
     229              : 
     230              :    executes STMTS with all the changes numbered NUM and up temporarily
     231              :    reverted.  STMTS must not try to add to the current change group.
     232              : 
     233              :    Nested uses are supported, but each nested NUM must be no greater than
     234              :    outer NUMs.  */
     235              : 
     236              : class undo_recog_changes
     237              : {
     238              : public:
     239              :   undo_recog_changes (int);
     240              :   ~undo_recog_changes ();
     241              : 
     242   2795068779 :   static bool is_active () { return s_num_changes != 0; }
     243              : 
     244              : private:
     245              :   int m_old_num_changes;
     246              : 
     247              :   static int s_num_changes;
     248              : };
     249              : 
     250              : extern void init_recog (void);
     251              : extern void init_recog_no_volatile (void);
     252              : extern bool check_asm_operands (rtx);
     253              : extern int asm_operand_ok (rtx, const char *, const char **);
     254              : extern bool validate_change (rtx, rtx *, rtx, bool);
     255              : extern bool validate_unshare_change (rtx, rtx *, rtx, bool);
     256              : extern bool validate_change_xveclen (rtx, rtx *, int, bool);
     257              : extern bool canonicalize_change_group (rtx_insn *insn, rtx x);
     258              : extern bool insn_invalid_p (rtx_insn *, bool);
     259              : extern bool verify_changes (int);
     260              : extern void confirm_change_group (void);
     261              : extern bool apply_change_group (void);
     262              : extern int num_validated_changes (void);
     263              : extern void cancel_changes (int);
     264              : extern bool constrain_operands (int, alternative_mask);
     265              : extern bool constrain_operands_cached (rtx_insn *, int);
     266              : extern bool memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
     267              :                                          code_helper = ERROR_MARK);
     268              : #define memory_address_p(mode,addr) \
     269              :         memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
     270              : extern bool strict_memory_address_addr_space_p (machine_mode, rtx, addr_space_t,
     271              :                                                 code_helper = ERROR_MARK);
     272              : #define strict_memory_address_p(mode,addr) \
     273              :         strict_memory_address_addr_space_p ((mode), (addr), ADDR_SPACE_GENERIC)
     274              : extern bool validate_replace_rtx_subexp (rtx, rtx, rtx_insn *, rtx *);
     275              : extern bool validate_replace_rtx (rtx, rtx, rtx_insn *);
     276              : extern bool validate_replace_rtx_part (rtx, rtx, rtx *, rtx_insn *);
     277              : extern bool validate_replace_rtx_part_nosimplify (rtx, rtx, rtx *, rtx_insn *);
     278              : extern void validate_replace_rtx_group (rtx, rtx, rtx_insn *);
     279              : extern void validate_replace_src_group (rtx, rtx, rtx_insn *);
     280              : extern bool validate_simplify_insn (rtx_insn *insn);
     281              : extern int num_changes_pending (void);
     282              : extern bool reg_fits_class_p (const_rtx, reg_class_t, int, machine_mode);
     283              : extern bool valid_insn_p (rtx_insn *);
     284              : 
     285              : extern bool offsettable_memref_p (rtx);
     286              : extern bool offsettable_nonstrict_memref_p (rtx);
     287              : extern bool offsettable_address_addr_space_p (int, machine_mode, rtx,
     288              :                                              addr_space_t);
     289              : #define offsettable_address_p(strict,mode,addr) \
     290              :         offsettable_address_addr_space_p ((strict), (mode), (addr), \
     291              :                                           ADDR_SPACE_GENERIC)
     292              : extern bool mode_dependent_address_p (rtx, addr_space_t);
     293              : 
     294              : extern int recog (rtx, rtx_insn *, int *);
     295              : #ifndef GENERATOR_FILE
     296              : inline int recog_memoized (rtx_insn *insn);
     297              : #endif
     298              : extern void add_clobbers (rtx, int);
     299              : extern bool added_clobbers_hard_reg_p (int);
     300              : extern void insn_extract (rtx_insn *);
     301              : extern void extract_insn (rtx_insn *);
     302              : extern void extract_constrain_insn (rtx_insn *insn);
     303              : extern void extract_constrain_insn_cached (rtx_insn *);
     304              : extern void extract_insn_cached (rtx_insn *);
     305              : #ifndef GENERATOR_FILE
     306              : extern void preprocess_constraints (int, int, const char **,
     307              :                                     operand_alternative *, rtx **);
     308              : extern const operand_alternative *preprocess_insn_constraints (unsigned int);
     309              : #endif
     310              : extern void preprocess_constraints (rtx_insn *);
     311              : extern rtx_insn *peep2_next_insn (int);
     312              : extern bool peep2_regno_dead_p (int, int);
     313              : extern bool peep2_reg_dead_p (int, rtx);
     314              : #ifdef HARD_CONST
     315              : extern rtx peep2_find_free_register (int, int, const char *,
     316              :                                      machine_mode, HARD_REG_SET *);
     317              : #endif
     318              : extern rtx_insn *peephole2_insns (rtx, rtx_insn *, int *);
     319              : 
     320              : extern bool store_data_bypass_p (rtx_insn *, rtx_insn *);
     321              : extern bool if_test_bypass_p (rtx_insn *, rtx_insn *);
     322              : 
     323              : extern void copy_frame_info_to_split_insn (rtx_insn *, rtx_insn *);
     324              : 
     325              : #ifndef GENERATOR_FILE
     326              : /* Try recognizing the instruction INSN,
     327              :    and return the code number that results.
     328              :    Remember the code so that repeated calls do not
     329              :    need to spend the time for actual rerecognition.
     330              : 
     331              :    This function is the normal interface to instruction recognition.
     332              :    The automatically-generated function `recog' is normally called
     333              :    through this one.  */
     334              : 
     335              : inline int
     336  17696860416 : recog_memoized (rtx_insn *insn)
     337              : {
     338  17696860416 :   if (INSN_CODE (insn) < 0)
     339    751026865 :     INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
     340  17696860416 :   return INSN_CODE (insn);
     341              : }
     342              : #endif
     343              : 
     344              : /* Skip chars until the next ',' or the end of the string.  This is
     345              :    useful to skip alternatives in a constraint string.  */
     346              : inline const char *
     347   3306328853 : skip_alternative (const char *p)
     348              : {
     349   3306328853 :   const char *r = p;
     350  10252425455 :   while (*r != '\0' && *r != ',')
     351   6946096602 :     r++;
     352   3306328853 :   if (*r == ',')
     353   3073977411 :     r++;
     354   3306328853 :   return r;
     355              : }
     356              : 
     357              : /* Nonzero means volatile operands are recognized.  */
     358              : extern int volatile_ok;
     359              : 
     360              : /* RAII class for temporarily setting volatile_ok.  */
     361              : 
     362              : class temporary_volatile_ok
     363              : {
     364              : public:
     365      4654253 :   temporary_volatile_ok (int value) : save_volatile_ok (volatile_ok)
     366              :   {
     367      4654253 :     volatile_ok = value;
     368              :   }
     369              : 
     370      4654253 :   ~temporary_volatile_ok () { volatile_ok = save_volatile_ok; }
     371              : 
     372              : private:
     373              :   temporary_volatile_ok (const temporary_volatile_ok &);
     374              :   int save_volatile_ok;
     375              : };
     376              : 
     377              : /* Set by constrain_operands to the number of the alternative that
     378              :    matched.  */
     379              : extern int which_alternative;
     380              : 
     381              : /* True for inline asm operands with - constraint modifier.  */
     382              : extern bool raw_constraint_p;
     383              : 
     384              : /* The following vectors hold the results from insn_extract.  */
     385              : 
     386              : struct recog_data_d
     387              : {
     388              :   recog_data_d () = default;
     389              :   recog_data_d (const recog_data_d &) = delete;
     390              :   recog_data_d (const recog_data_d &&) = delete;
     391              : 
     392              :   /* It is very tempting to make the 5 operand related arrays into a
     393              :      structure and index on that.  However, to be source compatible
     394              :      with all of the existing md file insn constraints and output
     395              :      templates, we need `operand' as a flat array.  Without that
     396              :      member, making an array for the rest seems pointless.  */
     397              : 
     398              :   /* Gives value of operand N.  */
     399              :   rtx operand[MAX_RECOG_OPERANDS];
     400              : 
     401              :   /* Gives location where operand N was found.  */
     402              :   rtx *operand_loc[MAX_RECOG_OPERANDS];
     403              : 
     404              :   /* Gives the constraint string for operand N.  */
     405              :   const char *constraints[MAX_RECOG_OPERANDS];
     406              : 
     407              :   /* Nonzero if operand N is a match_operator or a match_parallel.  */
     408              :   char is_operator[MAX_RECOG_OPERANDS];
     409              : 
     410              :   /* Gives the mode of operand N.  */
     411              :   machine_mode operand_mode[MAX_RECOG_OPERANDS];
     412              : 
     413              :   /* Gives the type (in, out, inout) for operand N.  */
     414              :   enum op_type operand_type[MAX_RECOG_OPERANDS];
     415              : 
     416              :   /* Gives location where the Nth duplicate-appearance of an operand
     417              :      was found.  This is something that matched MATCH_DUP.  */
     418              :   rtx *dup_loc[MAX_DUP_OPERANDS];
     419              : 
     420              :   /* Gives the operand number that was duplicated in the Nth
     421              :      duplicate-appearance of an operand.  */
     422              :   char dup_num[MAX_DUP_OPERANDS];
     423              : 
     424              :   /* ??? Note that these are `char' instead of `unsigned char' to (try to)
     425              :      avoid certain lossage from K&R C, wherein `unsigned char' default
     426              :      promotes to `unsigned int' instead of `int' as in ISO C.  As of 1999,
     427              :      the most common places to bootstrap from K&R C are SunOS and HPUX,
     428              :      both of which have signed characters by default.  The only other
     429              :      supported natives that have both K&R C and unsigned characters are
     430              :      ROMP and Irix 3, and neither have been seen for a while, but do
     431              :      continue to consider unsignedness when performing arithmetic inside
     432              :      a comparison.  */
     433              : 
     434              :   /* The number of operands of the insn.  */
     435              :   char n_operands;
     436              : 
     437              :   /* The number of MATCH_DUPs in the insn.  */
     438              :   char n_dups;
     439              : 
     440              :   /* The number of alternatives in the constraints for the insn.  */
     441              :   char n_alternatives;
     442              : 
     443              :   /* True if insn is ASM_OPERANDS.  */
     444              :   bool is_asm;
     445              : 
     446              :   /* In case we are caching, hold insn data was generated for.  */
     447              :   rtx_insn *insn;
     448              : };
     449              : 
     450              : extern struct recog_data_d *recog_data_ptr;
     451              : #define recog_data (*recog_data_ptr)
     452              : 
     453              : #ifndef GENERATOR_FILE
     454              : /* RAII class for saving/restoring recog_data.  */
     455              : 
     456              : class recog_state_saver
     457              : {
     458              :   recog_data_d m_tmp_recog_data;
     459              : public:
     460              :   recog_state_saver ();
     461              :   ~recog_state_saver ();
     462              : 
     463              :   recog_data_d *saved_recog_data_ptr;
     464              :   int saved_alternative;
     465              : };
     466              : 
     467     74139424 : inline recog_state_saver::recog_state_saver ()
     468     74139424 :   : saved_recog_data_ptr (recog_data_ptr),
     469     74139424 :     saved_alternative (which_alternative)
     470              : {
     471     74139424 :   m_tmp_recog_data.insn = nullptr;
     472     74139424 :   recog_data_ptr = &m_tmp_recog_data;
     473              : }
     474              : 
     475     74139424 : inline recog_state_saver::~recog_state_saver ()
     476              : {
     477     74139424 :   recog_data_ptr = saved_recog_data_ptr;
     478     74139424 :   which_alternative = saved_alternative;
     479              : }
     480              : 
     481              : extern const operand_alternative *recog_op_alt;
     482              : 
     483              : /* Return a pointer to an array in which index OP describes the constraints
     484              :    on operand OP of the current instruction alternative (which_alternative).
     485              :    Only valid after calling preprocess_constraints and constrain_operands.  */
     486              : 
     487              : inline const operand_alternative *
     488    106408035 : which_op_alt ()
     489              : {
     490    106408035 :   gcc_checking_assert (IN_RANGE (which_alternative, 0,
     491              :                                  recog_data.n_alternatives - 1));
     492    106408035 :   return &recog_op_alt[which_alternative * recog_data.n_operands];
     493              : }
     494              : #endif
     495              : 
     496              : /* A table defined in insn-output.cc that give information about
     497              :    each insn-code value.  */
     498              : 
     499              : typedef bool (*insn_operand_predicate_fn) (rtx, machine_mode);
     500              : typedef const char * (*insn_output_fn) (rtx *, rtx_insn *);
     501              : 
     502              : struct insn_gen_fn
     503              : {
     504              :   typedef void (*stored_funcptr) (void);
     505              : 
     506              :   template<typename ...Ts>
     507    108293829 :   rtx_insn *operator() (Ts... args) const
     508              :   {
     509              :     typedef rtx_insn *(*funcptr) (decltype ((void) args, NULL_RTX)...);
     510    108293829 :     return ((funcptr) func) (args...);
     511              :   }
     512              : 
     513              :   // This is for compatibility of code that invokes functions like
     514              :   //   (*funcptr) (arg)
     515              :   insn_gen_fn operator * (void) const { return *this; }
     516              : 
     517              :   // The wrapped function pointer must be public and there must not be any
     518              :   // constructors.  Otherwise the insn_data_d struct initializers generated
     519              :   // by genoutput.cc will result in static initializer functions, which defeats
     520              :   // the purpose of the generated insn_data_d array.
     521              :   stored_funcptr func;
     522              : };
     523              : 
     524              : struct insn_operand_data
     525              : {
     526              :   const insn_operand_predicate_fn predicate;
     527              : 
     528              :   const char *const constraint;
     529              : 
     530              :   machine_mode const mode : 16;
     531              : 
     532              :   const char strict_low;
     533              : 
     534              :   const char is_operator;
     535              : 
     536              :   const char eliminable;
     537              : 
     538              :   const char allows_mem;
     539              : };
     540              : 
     541              : /* Legal values for insn_data.output_format.  Indicate what type of data
     542              :    is stored in insn_data.output.  */
     543              : #define INSN_OUTPUT_FORMAT_NONE         0       /* abort */
     544              : #define INSN_OUTPUT_FORMAT_SINGLE       1       /* const char * */
     545              : #define INSN_OUTPUT_FORMAT_MULTI        2       /* const char * const * */
     546              : #define INSN_OUTPUT_FORMAT_FUNCTION     3       /* const char * (*)(...) */
     547              : 
     548              : struct insn_data_d
     549              : {
     550              :   const char *const name;
     551              : 
     552              :   /* How to print the insn.  OUTPUT_FORMAT says which member is live.  The
     553              :      constructors let genoutput write the member's value directly, and pick
     554              :      the member from its type.  */
     555              :   union insn_output_u
     556              :   {
     557              :     const char *single;
     558              :     const char *const *multi;
     559              :     insn_output_fn function;
     560              : 
     561              :     constexpr insn_output_u () : single (nullptr) {}
     562              :     constexpr insn_output_u (const char *s) : single (s) {}
     563              :     constexpr insn_output_u (const char *const *m) : multi (m) {}
     564              :     constexpr insn_output_u (insn_output_fn f) : function (f) {}
     565              :   } output;
     566              :   const insn_gen_fn genfun;
     567              :   const struct insn_operand_data *const operand;
     568              : 
     569              :   const char n_generator_args;
     570              :   const char n_operands;
     571              :   const char n_dups;
     572              :   const char n_alternatives;
     573              :   const char output_format;
     574              : };
     575              : 
     576              : extern const struct insn_data_d insn_data[];
     577              : extern int peep2_current_count;
     578              : 
     579              : #ifndef GENERATOR_FILE
     580              : #include "insn-codes.h"
     581              : 
     582              : /* An enum of boolean attributes that may only depend on the current
     583              :    subtarget, not on things like operands or compiler phase.  */
     584              : enum bool_attr {
     585              :   BA_ENABLED,
     586              :   BA_PREFERRED_FOR_SPEED,
     587              :   BA_PREFERRED_FOR_SIZE,
     588              :   BA_LAST = BA_PREFERRED_FOR_SIZE
     589              : };
     590              : 
     591              : /* Target-dependent globals.  */
     592              : struct target_recog {
     593              :   bool x_initialized;
     594              :   alternative_mask x_bool_attr_masks[NUM_INSN_CODES][BA_LAST + 1];
     595              :   operand_alternative *x_op_alt[NUM_INSN_CODES];
     596              : };
     597              : 
     598              : extern struct target_recog default_target_recog;
     599              : #if SWITCHABLE_TARGET
     600              : extern struct target_recog *this_target_recog;
     601              : #else
     602              : #define this_target_recog (&default_target_recog)
     603              : #endif
     604              : 
     605              : alternative_mask get_enabled_alternatives (rtx_insn *);
     606              : alternative_mask get_preferred_alternatives (rtx_insn *);
     607              : alternative_mask get_preferred_alternatives (rtx_insn *, basic_block);
     608              : bool check_bool_attrs (rtx_insn *);
     609              : 
     610              : void recog_init ();
     611              : 
     612              : /* This RAII class can help to undo tentative insn changes on failure.
     613              :    When an object of the class goes out of scope, it undoes all group
     614              :    changes that have been made via the validate_change machinery and
     615              :    not yet confirmed via confirm_change_group.
     616              : 
     617              :    For example:
     618              : 
     619              :       insn_change_watermark watermark;
     620              :       validate_change (..., true); // A
     621              :       ...
     622              :       if (test)
     623              :         // Undoes change A.
     624              :         return false;
     625              :       ...
     626              :       validate_change (..., true); // B
     627              :       ...
     628              :       if (test)
     629              :         // Undoes changes A and B.
     630              :         return false;
     631              :       ...
     632              :       confirm_change_group ();
     633              : 
     634              :    Code that wants to avoid this behavior can use keep ():
     635              : 
     636              :       insn_change_watermark watermark;
     637              :       validate_change (..., true); // A
     638              :       ...
     639              :       if (test)
     640              :         // Undoes change A.
     641              :         return false;
     642              :       ...
     643              :       watermark.keep ();
     644              :       validate_change (..., true); // B
     645              :       ...
     646              :       if (test)
     647              :         // Undoes change B, but not A.
     648              :         return false;
     649              :       ...
     650              :       confirm_change_group ();  */
     651              : class insn_change_watermark
     652              : {
     653              : public:
     654    113617061 :   insn_change_watermark () : m_old_num_changes (num_validated_changes ()) {}
     655              :   ~insn_change_watermark ();
     656     15671076 :   void keep () { m_old_num_changes = num_validated_changes (); }
     657              : 
     658              : private:
     659              :   int m_old_num_changes;
     660              : };
     661              : 
     662    113617061 : inline insn_change_watermark::~insn_change_watermark ()
     663              : {
     664    113617061 :   if (m_old_num_changes < num_validated_changes ())
     665     45482653 :     cancel_changes (m_old_num_changes);
     666    113617061 : }
     667              : 
     668              : #endif
     669              : 
     670              : #endif /* GCC_RECOG_H */
        

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.