LCOV - code coverage report
Current view: top level - gcc - recog.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.8 % 53 46
Test Date: 2026-07-11 15:47:05 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_BITFIELD (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    183869986 : alternative_class (const operand_alternative *alt, int i)
      92              : {
      93    183869986 :   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     94848812 : alternative_register_filters (const operand_alternative *alt, int i)
     101              : {
     102     94848812 :   return (alt[i].matches >= 0
     103     94848812 :           ? alt[alt[i].matches].register_filters
     104     84650772 :           : 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     70254141 : inline insn_propagation::insn_propagation (rtx_insn *insn, rtx from, rtx to,
     200     70254141 :                                            bool shared_p)
     201     70254141 :   : insn (insn),
     202     70254141 :     from (from),
     203     70254141 :     to (to),
     204     70254141 :     num_replacements (0),
     205     70254141 :     result_flags (0),
     206     70254141 :     should_unshare (shared_p),
     207     70254141 :     should_check_mems (false),
     208     70254141 :     should_note_simplifications (false),
     209     70254141 :     spare (0),
     210     70254141 :     failure_reason (nullptr)
     211              : {
     212              : }
     213              : 
     214              : /* Try to simplify INSN without performing a substitution.  */
     215              : 
     216      3555461 : inline insn_propagation::insn_propagation (rtx_insn *insn)
     217      3555461 :   : 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   2760134772 :   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  17389017819 : recog_memoized (rtx_insn *insn)
     337              : {
     338  17389017819 :   if (INSN_CODE (insn) < 0)
     339    727062098 :     INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
     340  17389017819 :   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   3271771466 : skip_alternative (const char *p)
     348              : {
     349   3271771466 :   const char *r = p;
     350  10146168540 :   while (*r != '\0' && *r != ',')
     351   6874397074 :     r++;
     352   3271771466 :   if (*r == ',')
     353   3040901226 :     r++;
     354   3271771466 :   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      4521539 :   temporary_volatile_ok (int value) : save_volatile_ok (volatile_ok)
     366              :   {
     367      4521539 :     volatile_ok = value;
     368              :   }
     369              : 
     370      4521539 :   ~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              :   /* It is very tempting to make the 5 operand related arrays into a
     389              :      structure and index on that.  However, to be source compatible
     390              :      with all of the existing md file insn constraints and output
     391              :      templates, we need `operand' as a flat array.  Without that
     392              :      member, making an array for the rest seems pointless.  */
     393              : 
     394              :   /* Gives value of operand N.  */
     395              :   rtx operand[MAX_RECOG_OPERANDS];
     396              : 
     397              :   /* Gives location where operand N was found.  */
     398              :   rtx *operand_loc[MAX_RECOG_OPERANDS];
     399              : 
     400              :   /* Gives the constraint string for operand N.  */
     401              :   const char *constraints[MAX_RECOG_OPERANDS];
     402              : 
     403              :   /* Nonzero if operand N is a match_operator or a match_parallel.  */
     404              :   char is_operator[MAX_RECOG_OPERANDS];
     405              : 
     406              :   /* Gives the mode of operand N.  */
     407              :   machine_mode operand_mode[MAX_RECOG_OPERANDS];
     408              : 
     409              :   /* Gives the type (in, out, inout) for operand N.  */
     410              :   enum op_type operand_type[MAX_RECOG_OPERANDS];
     411              : 
     412              :   /* Gives location where the Nth duplicate-appearance of an operand
     413              :      was found.  This is something that matched MATCH_DUP.  */
     414              :   rtx *dup_loc[MAX_DUP_OPERANDS];
     415              : 
     416              :   /* Gives the operand number that was duplicated in the Nth
     417              :      duplicate-appearance of an operand.  */
     418              :   char dup_num[MAX_DUP_OPERANDS];
     419              : 
     420              :   /* ??? Note that these are `char' instead of `unsigned char' to (try to)
     421              :      avoid certain lossage from K&R C, wherein `unsigned char' default
     422              :      promotes to `unsigned int' instead of `int' as in ISO C.  As of 1999,
     423              :      the most common places to bootstrap from K&R C are SunOS and HPUX,
     424              :      both of which have signed characters by default.  The only other
     425              :      supported natives that have both K&R C and unsigned characters are
     426              :      ROMP and Irix 3, and neither have been seen for a while, but do
     427              :      continue to consider unsignedness when performing arithmetic inside
     428              :      a comparison.  */
     429              : 
     430              :   /* The number of operands of the insn.  */
     431              :   char n_operands;
     432              : 
     433              :   /* The number of MATCH_DUPs in the insn.  */
     434              :   char n_dups;
     435              : 
     436              :   /* The number of alternatives in the constraints for the insn.  */
     437              :   char n_alternatives;
     438              : 
     439              :   /* True if insn is ASM_OPERANDS.  */
     440              :   bool is_asm;
     441              : 
     442              :   /* In case we are caching, hold insn data was generated for.  */
     443              :   rtx_insn *insn;
     444              : };
     445              : 
     446              : extern struct recog_data_d recog_data;
     447              : 
     448              : /* RAII class for saving/restoring recog_data.  */
     449              : 
     450              : class recog_data_saver
     451              : {
     452              :   recog_data_d m_saved_data;
     453              : public:
     454            0 :   recog_data_saver () : m_saved_data (recog_data) {}
     455            0 :   ~recog_data_saver () { recog_data = m_saved_data; }
     456              : };
     457              : 
     458              : #ifndef GENERATOR_FILE
     459              : extern const operand_alternative *recog_op_alt;
     460              : 
     461              : /* Return a pointer to an array in which index OP describes the constraints
     462              :    on operand OP of the current instruction alternative (which_alternative).
     463              :    Only valid after calling preprocess_constraints and constrain_operands.  */
     464              : 
     465              : inline const operand_alternative *
     466    104978414 : which_op_alt ()
     467              : {
     468    104978414 :   gcc_checking_assert (IN_RANGE (which_alternative, 0,
     469              :                                  recog_data.n_alternatives - 1));
     470    104978414 :   return &recog_op_alt[which_alternative * recog_data.n_operands];
     471              : }
     472              : #endif
     473              : 
     474              : /* A table defined in insn-output.cc that give information about
     475              :    each insn-code value.  */
     476              : 
     477              : typedef bool (*insn_operand_predicate_fn) (rtx, machine_mode);
     478              : typedef const char * (*insn_output_fn) (rtx *, rtx_insn *);
     479              : 
     480              : struct insn_gen_fn
     481              : {
     482              :   typedef void (*stored_funcptr) (void);
     483              : 
     484              :   template<typename ...Ts>
     485    107119312 :   rtx_insn *operator() (Ts... args) const
     486              :   {
     487              :     typedef rtx_insn *(*funcptr) (decltype ((void) args, NULL_RTX)...);
     488    107119312 :     return ((funcptr) func) (args...);
     489              :   }
     490              : 
     491              :   // This is for compatibility of code that invokes functions like
     492              :   //   (*funcptr) (arg)
     493              :   insn_gen_fn operator * (void) const { return *this; }
     494              : 
     495              :   // The wrapped function pointer must be public and there must not be any
     496              :   // constructors.  Otherwise the insn_data_d struct initializers generated
     497              :   // by genoutput.cc will result in static initializer functions, which defeats
     498              :   // the purpose of the generated insn_data_d array.
     499              :   stored_funcptr func;
     500              : };
     501              : 
     502              : struct insn_operand_data
     503              : {
     504              :   const insn_operand_predicate_fn predicate;
     505              : 
     506              :   const char *const constraint;
     507              : 
     508              :   ENUM_BITFIELD(machine_mode) const mode : 16;
     509              : 
     510              :   const char strict_low;
     511              : 
     512              :   const char is_operator;
     513              : 
     514              :   const char eliminable;
     515              : 
     516              :   const char allows_mem;
     517              : };
     518              : 
     519              : /* Legal values for insn_data.output_format.  Indicate what type of data
     520              :    is stored in insn_data.output.  */
     521              : #define INSN_OUTPUT_FORMAT_NONE         0       /* abort */
     522              : #define INSN_OUTPUT_FORMAT_SINGLE       1       /* const char * */
     523              : #define INSN_OUTPUT_FORMAT_MULTI        2       /* const char * const * */
     524              : #define INSN_OUTPUT_FORMAT_FUNCTION     3       /* const char * (*)(...) */
     525              : 
     526              : struct insn_data_d
     527              : {
     528              :   const char *const name;
     529              : #if HAVE_DESIGNATED_UNION_INITIALIZERS
     530              :   union {
     531              :     const char *single;
     532              :     const char *const *multi;
     533              :     insn_output_fn function;
     534              :   } output;
     535              : #else
     536              :   struct {
     537              :     const char *single;
     538              :     const char *const *multi;
     539              :     insn_output_fn function;
     540              :   } output;
     541              : #endif
     542              :   const insn_gen_fn genfun;
     543              :   const struct insn_operand_data *const operand;
     544              : 
     545              :   const char n_generator_args;
     546              :   const char n_operands;
     547              :   const char n_dups;
     548              :   const char n_alternatives;
     549              :   const char output_format;
     550              : };
     551              : 
     552              : extern const struct insn_data_d insn_data[];
     553              : extern int peep2_current_count;
     554              : 
     555              : #ifndef GENERATOR_FILE
     556              : #include "insn-codes.h"
     557              : 
     558              : /* An enum of boolean attributes that may only depend on the current
     559              :    subtarget, not on things like operands or compiler phase.  */
     560              : enum bool_attr {
     561              :   BA_ENABLED,
     562              :   BA_PREFERRED_FOR_SPEED,
     563              :   BA_PREFERRED_FOR_SIZE,
     564              :   BA_LAST = BA_PREFERRED_FOR_SIZE
     565              : };
     566              : 
     567              : /* Target-dependent globals.  */
     568              : struct target_recog {
     569              :   bool x_initialized;
     570              :   alternative_mask x_bool_attr_masks[NUM_INSN_CODES][BA_LAST + 1];
     571              :   operand_alternative *x_op_alt[NUM_INSN_CODES];
     572              : };
     573              : 
     574              : extern struct target_recog default_target_recog;
     575              : #if SWITCHABLE_TARGET
     576              : extern struct target_recog *this_target_recog;
     577              : #else
     578              : #define this_target_recog (&default_target_recog)
     579              : #endif
     580              : 
     581              : alternative_mask get_enabled_alternatives (rtx_insn *);
     582              : alternative_mask get_preferred_alternatives (rtx_insn *);
     583              : alternative_mask get_preferred_alternatives (rtx_insn *, basic_block);
     584              : bool check_bool_attrs (rtx_insn *);
     585              : 
     586              : void recog_init ();
     587              : 
     588              : /* This RAII class can help to undo tentative insn changes on failure.
     589              :    When an object of the class goes out of scope, it undoes all group
     590              :    changes that have been made via the validate_change machinery and
     591              :    not yet confirmed via confirm_change_group.
     592              : 
     593              :    For example:
     594              : 
     595              :       insn_change_watermark watermark;
     596              :       validate_change (..., true); // A
     597              :       ...
     598              :       if (test)
     599              :         // Undoes change A.
     600              :         return false;
     601              :       ...
     602              :       validate_change (..., true); // B
     603              :       ...
     604              :       if (test)
     605              :         // Undoes changes A and B.
     606              :         return false;
     607              :       ...
     608              :       confirm_change_group ();
     609              : 
     610              :    Code that wants to avoid this behavior can use keep ():
     611              : 
     612              :       insn_change_watermark watermark;
     613              :       validate_change (..., true); // A
     614              :       ...
     615              :       if (test)
     616              :         // Undoes change A.
     617              :         return false;
     618              :       ...
     619              :       watermark.keep ();
     620              :       validate_change (..., true); // B
     621              :       ...
     622              :       if (test)
     623              :         // Undoes change B, but not A.
     624              :         return false;
     625              :       ...
     626              :       confirm_change_group ();  */
     627              : class insn_change_watermark
     628              : {
     629              : public:
     630    112461534 :   insn_change_watermark () : m_old_num_changes (num_validated_changes ()) {}
     631              :   ~insn_change_watermark ();
     632     15463103 :   void keep () { m_old_num_changes = num_validated_changes (); }
     633              : 
     634              : private:
     635              :   int m_old_num_changes;
     636              : };
     637              : 
     638    112461534 : inline insn_change_watermark::~insn_change_watermark ()
     639              : {
     640    112461534 :   if (m_old_num_changes < num_validated_changes ())
     641     45029322 :     cancel_changes (m_old_num_changes);
     642    112461534 : }
     643              : 
     644              : #endif
     645              : 
     646              : #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.