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