GCC Middle and Back End API Reference
genrecog.cc File Reference
#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "read-md.h"
#include "gensupport.h"
#include "rtl.def"
Include dependency graph for genrecog.cc:

Data Structures

struct  position
 
class  list_head< T >
 
class  list_head< T >::range
 
struct  acceptance_type
 
class  parameter
 
class  pattern_routine
 
class  pattern_use
 
class  rtx_test
 
class  int_set
 
class  transition
 
class  decision
 
class  state
 
class  known_conditions
 
class  stats
 
class  merge_pattern_transition
 
class  merge_pattern_info
 
class  merge_state_result
 
class  merge_state_info
 
struct  test_pattern_hasher
 
struct  create_pattern_info
 
struct  state_size
 
class  pattern_pos
 
class  output_state
 

Macros

#define INCLUDE_ALGORITHM
 
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)
 
#define NUM_TRUE_RTX_CODE   ((int) FIRST_GENERATOR_RTX_CODE)
 
#define GENERATOR_FILE   1
 

Typedefs

typedef std::pair< transition *, state_sizesubroutine_candidate
 

Enumerations

enum  true_rtx_doe { FIRST_GENERATOR_RTX_CODE }
 
enum  position_type { POS_PEEP2_INSN , POS_XEXP , POS_XVECEXP0 }
 
enum  routine_type { SUBPATTERN , RECOG , SPLIT , PEEPHOLE2 }
 
enum  exit_state { ES_RETURNED , ES_FALLTHROUGH }
 

Functions

static struct positionnext_position (struct position **next_ptr, struct position *base, enum position_type type, int arg)
 
static int compare_positions (struct position *pos1, struct position *pos2)
 
static struct positioncommon_position (struct position *pos1, struct position *pos2)
 
static rtx find_operand (rtx pattern, int n, rtx stop)
 
static rtx find_matching_operand (rtx pattern, int n)
 
static bool constraints_supported_in_insn_p (rtx insn)
 
static const char * predicate_name (rtx match_rtx)
 
static bool special_predicate_operand_p (rtx operand)
 
static void validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
 
bool operator== (const acceptance_type &a, const acceptance_type &b)
 
bool operator!= (const acceptance_type &a, const acceptance_type &b)
 
bool operator== (const parameter &param1, const parameter &param2)
 
bool operator!= (const parameter &param1, const parameter &param2)
 
bool operator== (const rtx_test &a, const rtx_test &b)
 
bool operator!= (const rtx_test &a, const rtx_test &b)
 
bool operator== (const int_set &a, const int_set &b)
 
bool operator!= (const int_set &a, const int_set &b)
 
static void add_decision (state *from, const rtx_test &test, transition *trans)
 
static stateadd_decision (state *from, const rtx_test &test, int_set labels, bool optional)
 
static decisioninsert_decision_before (state::range r, const rtx_test &test, const int_set &labels, bool optional)
 
static void collapse_optional_decisions (state *s)
 
static void simplify_tests (state *s)
 
static bool common_test_p (decision *d, transition *common, vec< transition * > *where)
 
static bool safe_to_hoist_p (decision *d, const rtx_test &test, known_conditions *kc)
 
static decisionfind_common_test (decision *outer, bool with_position_p, position *pos, bool worthwhile_single_p, known_conditions *kc, vec< transition * > *where)
 
static void cse_tests (position *pos, state *s, known_conditions *kc)
 
parameter::type_enum transition_parameter_type (rtx_test::kind_enum kind)
 
static void find_operand_positions (state *s, vec< int > &operand_pos)
 
static stats get_stats (state *s)
 
static void optimize_subroutine_group (const char *type, state *root)
 
static bool useful_pattern_p (merge_pattern_info *pat)
 
static bool same_pattern_p (merge_pattern_info *pat1, merge_pattern_info *pat2)
 
static bool valid_result_p (merge_pattern_info *pat, merge_state_info *sinfo)
 
static void prune_invalid_results (merge_state_info *sinfo)
 
static bool complete_result_p (merge_pattern_info *pat, merge_state_info *sinfo)
 
static void update_parameters (vec< parameter > &to, const vec< parameter > &from)
 
static bool compatible_tests_p (const rtx_test &a, const rtx_test &b, parameter *parama, parameter *paramb)
 
static bool set_parameter (vec< parameter > &params, unsigned int id, const parameter &value)
 
static bool add_parameter (vec< parameter > &params1, vec< parameter > &params2, const parameter &param1, const parameter &param2, unsigned int start, unsigned int *res)
 
static bool merge_relative_positions (position **roota, position *a, position *rootb, position *b)
 
static bool merge_patterns (merge_state_info *sinfo1, merge_state_info *sinfo2)
 
static void populate_pattern_routine (create_pattern_info *, merge_state_info *, state *, const vec< parameter > &)
 
static decisioninit_pattern_use (create_pattern_info *cpi, merge_state_info *sinfo, const vec< parameter > &params)
 
static void add_pattern_acceptance (create_pattern_info *cpi, state *s)
 
static void populate_pattern_use (create_pattern_info *cpi, decision *use, merge_state_info *sinfo)
 
static void use_pattern (merge_state_info *sinfo)
 
static void split_out_patterns (vec< merge_state_info > &states)
 
static int subroutine_candidate_cmp (const void *a, const void *b)
 
static statecreate_subroutine (routine_type type, state *s, vec< state * > &procs)
 
static state_size find_subroutines (routine_type type, state *s, vec< state * > &procs)
 
static bool safe_predicate_mode (const struct pred_data *pred, machine_mode mode)
 
static void get_predicate_codes (const struct pred_data *pred, int_set *codes)
 
static bool has_same_test_p (decision *d1, decision *d2)
 
static bool mutually_exclusive_p (decision *d1, decision *d2)
 
static bool merge_into_decision (decision *d1, state *s2, const int_set *exclude, state **next_s1, state **next_s2, const int_set **next_exclude)
 
static bool merge_into_state_1 (state *s1, state *s2, const int_set *exclude, state **next_s1, state **next_s2, const int_set **next_exclude)
 
static void merge_into_state (state *s1, state *s2)
 
bool operator< (const pattern_pos &e1, const pattern_pos &e2)
 
static statematch_pattern_2 (state *s, md_rtx_info *info, position *pos, rtx pattern)
 
static void match_pattern_1 (state *s, md_rtx_info *info, rtx pattern, acceptance_type acceptance)
 
static void match_pattern (state *s, md_rtx_info *info, rtx pattern, acceptance_type acceptance)
 
static void write_header (FILE *f, const char *header_filename)
 
static const char * parameter_type_string (parameter::type_enum type)
 
static bool single_statement_p (const acceptance_type &acceptance)
 
static const char * get_failure_return (routine_type type)
 
static bool terminal_pattern_p (decision *d, unsigned int *base_out, unsigned int *count_out)
 
static bool test_position_available_p (output_state *os, const rtx_test &test)
 
static void ATTRIBUTE_PRINTF_3 printf_indent (FILE *f, unsigned int indent, const char *format,...)
 
static void change_state (FILE *f, output_state *os, position *pos, unsigned int indent)
 
static void print_code (FILE *f, enum rtx_code code)
 
static void print_host_wide_int (FILE *f, uint64_t val)
 
static void print_parameter_value (FILE *f, const parameter &param)
 
static void print_test_rtx (FILE *f, output_state *os, const rtx_test &test)
 
static void print_nonbool_test (FILE *f, output_state *os, const rtx_test &test)
 
static void print_label_value (FILE *f, const rtx_test &test, bool is_param, uint64_t value)
 
static void print_test (FILE *f, output_state *os, const rtx_test &test, bool is_param, uint64_t value, bool invert_p)
 
static exit_state print_decision (FILE *f, output_state *, decision *, unsigned int, bool)
 
static exit_state print_state (FILE *f, output_state *os, state *s, unsigned int indent, bool is_final)
 
static const char * print_subroutine_call (FILE *f, const acceptance_type &acceptance)
 
static exit_state print_acceptance (FILE *f, const acceptance_type &acceptance, unsigned int indent, bool is_final)
 
static void assign_position_var (output_state *os, position *pos, bool root_p)
 
static void assign_position_vars (output_state *os, state *s)
 
static void print_subroutine_start (FILE *f, output_state *os, state *s, position *root)
 
static void print_pattern (FILE *f, output_state *os, pattern_routine *routine, bool in_header=false)
 
static void print_subroutine (FILE *f, output_state *os, state *s, int proc_id, bool in_header=false)
 
static void print_subroutine_group (vec< FILE * > &vec, FILE *header, output_state *os, routine_type type, state *root)
 
static rtx get_peephole2_pattern (md_rtx_info *info)
 
static bool remove_clobbers (acceptance_type *acceptance_ptr, rtx *pattern_ptr)
 
static bool handle_arg (const char *arg)
 
int main (int argc, const char **argv)
 

Variables

static const bool merge_states_p = true
 
static const bool collapse_optional_decisions_p = true
 
static const bool cse_tests_p = true
 
static const bool simplify_tests_p = true
 
static const bool use_operand_variables_p = true
 
static const bool use_subroutines_p = true
 
static const bool use_pattern_routines_p = true
 
static const bool mark_optional_transitions_p = false
 
static const bool relative_patterns_p = false
 
static const bool pattern_have_num_clobbers_p = true
 
static const bool pattern_c_test_p = false
 
static const bool force_unique_params_p = true
 
static const unsigned int MAX_DEPTH = 6
 
static const unsigned int MIN_NUM_STATEMENTS = 5
 
static const unsigned int MAX_NUM_STATEMENTS = 200
 
static const unsigned int MIN_COMBINE_COST = 4
 
static const unsigned int MAX_PATTERN_PARAMS = 5
 
int num_operands
 
static struct position root_pos
 
static unsigned int num_positions = 1
 
static struct positionpeep2_insn_pos_list = &root_pos
 
static vec< pattern_routine * > patterns
 
const unsigned char TESTED_CODE = 1
 
const unsigned char TESTED_VECLEN = 2
 
static unsigned int pattern_use_states
 
static unsigned int pattern_def_states
 
auto_vec< FILE *, 10 > output_files
 
char header_name [255]
 
FILE * header = NULL
 

Macro Definition Documentation

◆ DEF_RTL_EXPR

#define DEF_RTL_EXPR ( ENUM,
NAME,
FORMAT,
CLASS )
Value:
TRUE_##ENUM,
@ ENUM
Definition gengtype.h:476

◆ GENERATOR_FILE

#define GENERATOR_FILE   1

Referenced by rtx_writer::rtx_writer().

◆ INCLUDE_ALGORITHM

#define INCLUDE_ALGORITHM
Generate code from machine description to recognize rtl as insns.
Copyright (C) 1987-2025 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
This program is used to produce insn-recog.cc, which contains a
function called `recog' plus its subroutines.  These functions
contain a decision tree that recognizes whether an rtx, the
argument given to recog, is a valid instruction.

recog returns -1 if the rtx is not valid.  If the rtx is valid,
recog returns a nonnegative number which is the insn code number
for the pattern that matched.  This is the same as the order in the
machine description of the entry that matched.  This number can be
used as an index into various insn_* tables, such as insn_template,
insn_outfun, and insn_n_operands (found in insn-output.cc).

The third argument to recog is an optional pointer to an int.  If
present, recog will accept a pattern if it matches except for
missing CLOBBER expressions at the end.  In that case, the value
pointed to by the optional pointer will be set to the number of
CLOBBERs that need to be added (it should be initialized to zero by
the caller).  If it is set nonzero, the caller should allocate a
PARALLEL of the appropriate size, copy the initial entries, and
call add_clobbers (found in insn-emit.cc) to fill in the CLOBBERs.

This program also generates the function `split_insns', which
returns 0 if the rtl could not be split, or it returns the split
rtl as an INSN list.

This program also generates the function `peephole2_insns', which
returns 0 if the rtl could not be matched.  If there was a match,
the new rtl is returned in an INSN list, and LAST_INSN will point
to the last recognized insn in the old sequence.


At a high level, the algorithm used in this file is as follows:

1. Build up a decision tree for each routine, using the following
   approach to matching an rtx:

   - First determine the "shape" of the rtx, based on GET_CODE,
     XVECLEN and XINT.  This phase examines SET_SRCs before SET_DESTs
     since SET_SRCs tend to be more distinctive.  It examines other
     operands in numerical order, since the canonicalization rules
     prefer putting complex operands of commutative operators first.

   - Next check modes and predicates.  This phase examines all
     operands in numerical order, even for SETs, since the mode of a
     SET_DEST is exact while the mode of a SET_SRC can be VOIDmode
     for constant integers.

   - Next check match_dups.

   - Finally check the C condition and (where appropriate) pnum_clobbers.

2. Try to optimize the tree by removing redundant tests, CSEing tests,
   folding tests together, etc.

3. Look for common subtrees and split them out into "pattern" routines.
   These common subtrees can be identical or they can differ in mode,
   code, or integer (usually an UNSPEC or UNSPEC_VOLATILE code).
   In the latter case the users of the pattern routine pass the
   appropriate mode, etc., as argument.  For example, if two patterns
   contain:

      (plus:SI (match_operand:SI 1 "register_operand")
               (match_operand:SI 2 "register_operand"))

   we can split the associated matching code out into a subroutine.
   If a pattern contains:

      (minus:DI (match_operand:DI 1 "register_operand")
                (match_operand:DI 2 "register_operand"))

   then we can consider using the same matching routine for both
   the plus and minus expressions, passing PLUS and SImode in the
   former case and MINUS and DImode in the latter case.

   The main aim of this phase is to reduce the compile time of the
   insn-recog.cc code and to reduce the amount of object code in
   insn-recog.o.

4. Split the matching trees into functions, trying to limit the
   size of each function to a sensible amount.

   Again, the main aim of this phase is to reduce the compile time
   of insn-recog.cc.  (It doesn't help with the size of insn-recog.o.)

5. Write out C++ code for each function.   

◆ NUM_TRUE_RTX_CODE

#define NUM_TRUE_RTX_CODE   ((int) FIRST_GENERATOR_RTX_CODE)

Referenced by get_predicate_codes().

Typedef Documentation

◆ subroutine_candidate

Pairs a transition with information about its target state.   

Enumeration Type Documentation

◆ exit_state

enum exit_state
Indicates whether a block of code always returns or whether it can fall
through.   
Enumerator
ES_RETURNED 
ES_FALLTHROUGH 

◆ position_type

Ways of obtaining an rtx to be tested.   
Enumerator
POS_PEEP2_INSN 
POS_XEXP 
POS_XVECEXP0 

◆ routine_type

Enumerator
SUBPATTERN 
RECOG 
SPLIT 
PEEPHOLE2 

◆ true_rtx_doe

Enumerator
FIRST_GENERATOR_RTX_CODE 
This file contains the definitions and documentation for the
   Register Transfer Expressions (rtx's) that make up the
   Register Transfer Language (rtl) used in the Back End of the GNU compiler.
   Copyright (C) 1987-2025 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
Expression definitions and descriptions for all targets are in this file.
Some will not be used for some targets.

The fields in the cpp macro call "DEF_RTL_EXPR()"
are used to create declarations in the C source of the compiler.

The fields are:

1.  The internal name of the rtx used in the C source.
It is a tag in the enumeration "enum rtx_code" defined in "rtl.h".
By convention these are in UPPER_CASE.

2.  The name of the rtx in the external ASCII format read by
read_rtx(), and printed by print_rtx().
These names are stored in rtx_name[].
By convention these are the internal (field 1) names in lower_case.

3.  The print format, and type of each rtx->u.fld[] (field) in this rtx.
These formats are stored in rtx_format[].
The meaning of the formats is documented in front of this array in rtl.cc

4.  The class of the rtx.  These are stored in rtx_class and are accessed
via the GET_RTX_CLASS macro.  They are defined as follows:

  RTX_CONST_OBJ
      an rtx code that can be used to represent a constant object
      (e.g, CONST_INT)
  RTX_OBJ
      an rtx code that can be used to represent an object (e.g, REG, MEM)
  RTX_COMPARE
      an rtx code for a comparison (e.g, LT, GT)
  RTX_COMM_COMPARE
      an rtx code for a commutative comparison (e.g, EQ, NE, ORDERED)
  RTX_UNARY
      an rtx code for a unary arithmetic expression (e.g, NEG, NOT)
  RTX_COMM_ARITH
      an rtx code for a commutative binary operation (e.g,, PLUS, MULT)
  RTX_TERNARY
      an rtx code for a non-bitfield three input operation (IF_THEN_ELSE)
  RTX_BIN_ARITH
      an rtx code for a non-commutative binary operation (e.g., MINUS, DIV)
  RTX_BITFIELD_OPS
      an rtx code for a bit-field operation (ZERO_EXTRACT, SIGN_EXTRACT)
  RTX_INSN
      an rtx code for a machine insn (INSN, JUMP_INSN, CALL_INSN) or
      data that will be output as assembly pseudo-ops (DEBUG_INSN)
  RTX_MATCH
      an rtx code for something that matches in insns (e.g, MATCH_DUP)
  RTX_AUTOINC
      an rtx code for autoincrement addressing modes (e.g. POST_DEC)
  RTX_EXTRA
      everything else

All of the expressions that appear only in machine descriptions,
not in RTL used by the compiler itself, are at the end of the file.   
Unknown, or no such operation; the enumeration constant should have
value zero.   
Used in the cselib routines to describe a value.  Objects of this
kind are only allocated in cselib.cc, in an alloc pool instead of in
GC memory.  The only operand of a VALUE is a cselib_val.
var-tracking requires this to have a distinct integral value from
DECL codes in trees.   
The RTL generated for a DEBUG_EXPR_DECL.  It links back to the
DEBUG_EXPR_DECL in the first operand.   
---------------------------------------------------------------------
Expressions used in constructing lists.
---------------------------------------------------------------------  
A linked list of expressions.   
A linked list of instructions.
The insns are represented in print by their uids.   
A linked list of integers.   
SEQUENCE is used in late passes of the compiler to group insns for
one reason or another.

For example, after delay slot filling, branch instructions with filled
delay slots are represented as a SEQUENCE of length 1 + n_delay_slots,
with the branch instruction in XEXPVEC(seq, 0, 0) and the instructions
occupying the delay slots in the remaining XEXPVEC slots.

Another place where a SEQUENCE may appear, is in REG_FRAME_RELATED_EXPR
notes, to express complex operations that are not obvious from the insn
to which the REG_FRAME_RELATED_EXPR note is attached.  In this usage of
SEQUENCE, the sequence vector slots do not hold real instructions but
only pseudo-instructions that can be translated to DWARF CFA expressions.

Some back ends also use SEQUENCE to group insns in bundles.

Much of the compiler infrastructure is not prepared to handle SEQUENCE
objects.  Only passes after pass_free_cfg are expected to handle them.   
Represents a non-global base address.  This is only used in alias.cc.   
----------------------------------------------------------------------
Expression types used for things in the instruction chain.

All formats must start with "uu" to handle the chain.
Each insn expression holds an rtl instruction and its semantics
during back-end processing.
See macros in "rtl.h" for the meaning of each rtx->u.fld[].

----------------------------------------------------------------------  
An annotation for variable assignment tracking.   
An instruction that cannot jump.   
An instruction that can possibly jump.
Fields ( rtx->u.fld[] ) have exact same meaning as INSN's.   
An instruction that can possibly call a subroutine
but which will not change which instruction comes next
in the current function.
Field ( rtx->u.fld[8] ) is CALL_INSN_FUNCTION_USAGE.
All other fields ( rtx->u.fld[] ) have exact same meaning as INSN's.   
Placeholder for tablejump JUMP_INSNs.  The pattern of this kind
of rtx is always either an ADDR_VEC or an ADDR_DIFF_VEC.  These
placeholders do not appear as real instructions inside a basic
block, but are considered active_insn_p instructions for historical
reasons, when jump table data was represented with JUMP_INSNs.   
A marker that indicates that control will not flow through.   
Holds a label that is followed by instructions.
Operand:
3: is used in jump.cc for the use-count of the label.
4: is used in the sh backend.
5: is a number that is unique in the entire compilation.
6: is the user-given name of the label, if any.   
Say where in the code a source line starts, for symbol table's sake.
Operand:
3: note-specific data
4: enum insn_note
5: unique number if insn_note == note_insn_deleted_label.   
----------------------------------------------------------------------
Top level constituents of INSN, JUMP_INSN and CALL_INSN.
----------------------------------------------------------------------  
Conditionally execute code.
Operand 0 is the condition that if true, the code is executed.
Operand 1 is the code to be executed (typically a SET).

Semantics are that there are no side effects if the condition
is false.  This pattern is created automatically by the if_convert
pass run after reload or by target-specific splitters.   
Several operations to be done in parallel (perhaps under COND_EXEC).   
A string that is passed through to the assembler as input.
 One can obviously pass comments through by using the
 assembler comment syntax.
 These occur in an insn all by themselves as the PATTERN.
 They also appear inside an ASM_OPERANDS
 as a convenient way to hold a string.   
An assembler instruction with operands.
1st operand is the instruction template.
2nd operand is the constraint for the output.
3rd operand is the number of the output this expression refers to.
  When an insn stores more than one value, a separate ASM_OPERANDS
  is made for each output; this integer distinguishes them.
4th is a vector of values of input operands.
5th is a vector of modes and constraints for the input operands.
  Each element is an ASM_INPUT containing a constraint string
  and whose mode indicates the mode of the input operand.
6th is a vector of labels that may be branched to by the asm.
7th is the source line number.   
A machine-specific operation.
1st operand is a vector of operands being used by the operation so that
  any needed reloads can be done.
2nd operand is a unique value saying which of a number of machine-specific
  operations is to be performed.
(Note that the vector must be the first operand because of the way that
genrecog.cc record positions within an insn.)

UNSPEC can occur all by itself in a PATTERN, as a component of a PARALLEL,
or inside an expression.
UNSPEC by itself or as a component of a PARALLEL
is currently considered not deletable.

FIXME: Replace all uses of UNSPEC that appears by itself or as a component
of a PARALLEL with USE.
Similar, but a volatile operation and one which may trap.   
----------------------------------------------------------------------
Table jump addresses.
----------------------------------------------------------------------  
Vector of addresses, stored as full words.
Each element is a LABEL_REF to a CODE_LABEL whose address we want.   
Vector of address differences X0 - BASE, X1 - BASE, ...
 First operand is BASE; the vector contains the X's.
 The machine mode of this rtx says how much space to leave
 for each difference and is adjusted by branch shortening if
 CASE_VECTOR_SHORTEN_MODE is defined.
 The third and fourth operands store the target labels with the
 minimum and maximum addresses respectively.
 The fifth operand stores flags for use by branch shortening.
Set at the start of shorten_branches:
 min_align: the minimum alignment for any of the target labels.
 base_after_vec: true iff BASE is after the ADDR_DIFF_VEC.
 min_after_vec: true iff minimum addr target label is after the ADDR_DIFF_VEC.
 max_after_vec: true iff maximum addr target label is after the ADDR_DIFF_VEC.
 min_after_base: true iff minimum address target label is after BASE.
 max_after_base: true iff maximum address target label is after BASE.
Set by the actual branch shortening process:
 offset_unsigned: true iff offsets have to be treated as unsigned.
 scale: scaling that is necessary to make offsets fit into the mode.

 The third, fourth and fifth operands are only valid when
 CASE_VECTOR_SHORTEN_MODE is defined, and only in an optimizing
 compilation.   
Memory prefetch, with attributes supported on some targets.
Operand 1 is the address of the memory to fetch.
Operand 2 is 1 for a write access, 0 otherwise.
Operand 3 is the level of temporal locality; 0 means there is no
temporal locality and 1, 2, and 3 are for increasing levels of temporal
locality.

The attributes specified by operands 2 and 3 are ignored for targets
whose prefetch instructions do not support them.   
----------------------------------------------------------------------
At the top level of an instruction (perhaps under PARALLEL).
----------------------------------------------------------------------  
Assignment.
Operand 1 is the location (REG, MEM, PC or whatever) assigned to.
Operand 2 is the value stored there.
ALL assignment must use SET.
Instructions that do multiple assignments must use multiple SET,
under PARALLEL.   
Indicate something is used in a way that we don't want to explain.
For example, subroutine calls will use the register
in which the static chain is passed.

USE cannot appear as an operand of other rtx except for PARALLEL.
USE is not deletable, as it indicates that the operand
is used in some unknown way.   
Indicate something is clobbered in a way that we don't want to explain.
For example, subroutine calls will clobber some physical registers
(the ones that are by convention not saved).

CLOBBER cannot appear as an operand of other rtx except for PARALLEL.
CLOBBER of a hard register appearing by itself (not within PARALLEL)
is considered undeletable before reload.   
Call a subroutine.
Operand 1 is the address to call.
Operand 2 is the number of arguments.   
Return from a subroutine.   
Like RETURN, but truly represents only a function return, while
RETURN may represent an insn that also performs other functions
of the function epilogue.  Like RETURN, this may also occur in
conditional jumps.   
Special for EH return from subroutine.   
Conditional trap.
Operand 1 is the condition.
Operand 2 is the trap code.
For an unconditional trap, make the condition (const_int 1).   
----------------------------------------------------------------------
Primitive values for use in expressions.
----------------------------------------------------------------------  
numeric integer constant  
numeric integer constant  
An rtx representation of a poly_wide_int.   
fixed-point constant  
numeric floating point or integer constant.  If the mode is
VOIDmode it is an int otherwise it has a floating point mode and a
floating point value.  Operands hold the value.  They are all 'w'
and there may be from 2 to 6; see real.h.   
Describes a vector constant.   
String constant.  Used for attributes in machine descriptions and
for special cases in DWARF2 debug output.  NOT used for source-
language string constants.   
This is used to encapsulate an expression whose value is constant
(such as the sum of a SYMBOL_REF and a CONST_INT) so that it will be
recognized as a constant operand rather than by arithmetic instructions.   
program counter.  Ordinary jumps are represented
by a SET whose first operand is (PC).   
A register.  The "operand" is the register number, accessed with
the REGNO macro.  If this number is less than FIRST_PSEUDO_REGISTER
then a hardware register is being referred to.  The second operand
points to a reg_attrs structure.
This rtx needs to have as many (or more) fields as a MEM, since we
can change REG rtx's into MEMs during reload.   
A scratch register.  This represents a register used only within a
single insn.  It will be replaced by a REG during register allocation
or reload unless the constraint indicates that the register won't be
needed, in which case it can remain a SCRATCH.   
A reference to a part of another value.  The first operand is the
complete value and the second is the byte offset of the selected part.    
This one-argument rtx is used for move instructions
that are guaranteed to alter only the low part of a destination.
Thus, (SET (SUBREG:HI (REG...)) (MEM:HI ...))
has an unspecified effect on the high part of REG,
but (SET (STRICT_LOW_PART (SUBREG:HI (REG...))) (MEM:HI ...))
is guaranteed to alter only the bits of REG that are in HImode.

The actual instruction used is probably the same in both cases,
but the register constraints may be tighter when STRICT_LOW_PART
is in use.   
(CONCAT a b) represents the virtual concatenation of a and b
to make a value that has as many bits as a and b put together.
This is used for complex values.  Normally it appears only
in DECL_RTLs and during RTL generation, but not in the insn chain.   
(CONCATN [a1 a2 ... an]) represents the virtual concatenation of
all An to make a value.  This is an extension of CONCAT to larger
number of components.  Like CONCAT, it should not appear in the
insn chain.  Every element of the CONCATN is the same size.   
A memory location; operand is the address.  The second operand is the
alias set to which this MEM belongs.  We use `0' instead of `w' for this
field so that the field need not be specified in machine descriptions.   
Reference to an assembler label in the code for this function.
The operand is a CODE_LABEL found in the insn chain.   
Reference to a named label:
Operand 0: label name
Operand 1: tree from which this symbol is derived, or null.
This is either a DECL node, or some kind of constant.   
----------------------------------------------------------------------
Expressions for operators in an rtl pattern
----------------------------------------------------------------------  
if_then_else.  This is used in representing ordinary
conditional jump instructions.
  Operand:
  0:  condition
  1:  then expr
  2:  else expr  
Comparison, produces a condition code result.   
plus  
Operand 0 minus operand 1.   
Minus operand 0.   
Multiplication with signed saturation  
Multiplication with unsigned saturation  
Signed high-part multiplication.   
Unsigned high-part multiplication.   
Operand 0 divided by operand 1.   
Division with signed saturation  
Division with unsigned saturation  
Remainder of operand 0 divided by operand 1.   
Unsigned divide and remainder.   
Bitwise operations.   
Operand:
 0:  value to be shifted.
 1:  number of bits.   
Minimum and maximum values of two operands.  We need both signed and
unsigned forms.  (We cannot use MIN for SMIN because it conflicts
with a macro of the same name.)   The signed variants should be used
with floating point.  Further, if both operands are zeros, or if either
operand is NaN, then it is unspecified which of the two operands is
returned as the result.   
These unary operations are used to represent incrementation
and decrementation as they occur in memory addresses.
The amount of increment or decrement are not represented
because they can be understood from the machine-mode of the
containing MEM.  These operations exist in only two cases:
1. pushes onto the stack.
2. created automatically by the auto-inc-dec pass.   
These binary operations are used to represent generic address
side-effects in memory addresses, except for simple incrementation
or decrementation which use the above operations.  They are
created automatically by the life_analysis pass in flow.c.
The first operand is a REG which is used as the address.
The second operand is an expression that is assigned to the
register, either before (PRE_MODIFY) or after (POST_MODIFY)
evaluating the address.
Currently, the compiler can only handle second operands of the
form (plus (reg) (reg)) and (plus (reg) (const_int)), where
the first operand of the PLUS has to be the same register as
the first operand of the *_MODIFY.   
Comparison operations.  The first 6 are allowed only for integral,
floating-point and vector modes.  LTGT is only allowed for floating-point
modes.  The last 4 are allowed only for integral and vector modes.
For floating-point operations, if either operand is a NaN, then NE returns
true and the remaining operations return false.  The operations other than
EQ and NE may generate an exception on quiet NaNs.   
Additional floating-point unordered comparison flavors.   
These are equivalent to unordered or ...   
Represents the result of sign-extending the sole operand.
The machine modes of the operand and of the SIGN_EXTEND expression
determine how much sign-extension is going on.   
Similar for zero-extension (such as unsigned short to int).   
Similar but here the operand has a wider mode.   
Similar for extending floating-point values (such as SFmode to DFmode).   
Conversion of fixed point operand to floating point value.   
With fixed-point machine mode:
Conversion of floating point operand to fixed point value.
Value is defined only when the operand's value is an integer.
With floating-point machine mode (and operand with same mode):
Operand is rounded toward zero to produce an integer value
represented in floating point.   
Conversion of unsigned fixed point operand to floating point value.   
With fixed-point machine mode:
Conversion of floating point operand to *unsigned* fixed point value.
Value is defined only when the operand's value is an integer.   
Conversions involving fractional fixed-point types without saturation,
including:
  fractional to fractional (of different precision),
  signed integer to fractional,
  fractional to signed integer,
  floating point to fractional,
  fractional to floating point.
NOTE: fractional can be either signed or unsigned for conversions.   
Conversions involving fractional fixed-point types and unsigned integer
without saturation, including:
  unsigned integer to fractional,
  fractional to unsigned integer.
NOTE: fractional can be either signed or unsigned for conversions.   
Conversions involving fractional fixed-point types with saturation,
including:
  fractional to fractional (of different precision),
  signed integer to fractional,
  floating point to fractional.
NOTE: fractional can be either signed or unsigned for conversions.   
Conversions involving fractional fixed-point types and unsigned integer
with saturation, including:
  unsigned integer to fractional.
NOTE: fractional can be either signed or unsigned for conversions.   
Absolute value  
Square root  
Swap bytes.   
Find first bit that is set.
Value is 1 + number of trailing zeros in the arg.,
or 0 if arg is 0.   
Count number of leading redundant sign bits (number of leading
sign bits minus one).   
Count leading zeros.   
Count trailing zeros.   
Population count (number of 1 bits).   
Population parity (number of 1 bits modulo 2).   
Reverse bits.   
Reference to a signed bit-field of specified size and position.
Operand 0 is the memory unit (usually SImode or QImode) which
contains the field's first bit.  Operand 1 is the width, in bits.
Operand 2 is the number of bits in the memory unit before the
first bit of this field.
If BITS_BIG_ENDIAN is defined, the first bit is the msb and
operand 2 counts from the msb of the memory unit.
Otherwise, the first bit is the lsb and operand 2 counts from
the lsb of the memory unit.
This kind of expression cannot appear as an lvalue in RTL.   
Similar for unsigned bit-field.
But note!  This kind of expression _can_ appear as an lvalue.   
For RISC machines.  These save memory when splitting insns.   
HIGH are the high-order bits of a constant expression.   
LO_SUM is the sum of a register and the low-order bits
of a constant expression.   
Describes a merge operation between two vector values.
Operands 0 and 1 are the vectors to be merged, operand 2 is a bitmask
that specifies where the parts of the result are taken from.  Set bits
indicate operand 0, clear bits indicate operand 1.  The parts are defined
by the mode of the vectors.   
Describes an operation that selects parts of a vector.
Operands 0 is the source vector, operand 1 is a PARALLEL that contains
a CONST_INT for each of the subparts of the result vector, giving the
number of the source subpart that should be stored into it.   
Describes a vector concat operation.  Operands 0 and 1 are the source
vectors, the result is a vector that is as long as operands 0 and 1
combined and is the concatenation of the two source vectors.   
Describes an operation that converts a small vector into a larger one by
duplicating the input values.  The output vector mode must have the same
submodes as the input vector mode, and the number of output parts must be
an integer multiple of the number of input parts.   
Creation of a vector in which element I has the value BASE + I * STEP,
where BASE is the first operand and STEP is the second.  The result
must have a vector integer mode.   
Addition with signed saturation  
Addition with unsigned saturation  
Operand 0 minus operand 1, with signed saturation.   
Negation with signed saturation.   
Negation with unsigned saturation.   
Absolute value with signed saturation.   
Shift left with signed saturation.   
Shift left with unsigned saturation.   
Operand 0 minus operand 1, with unsigned saturation.   
Signed saturating truncate.   
Unsigned saturating truncate.   
Floating point multiply/add combined instruction.   
Floating point copysign.  Operand 0 with the sign of operand 1.   
Information about the variable and its location.   
Used in VAR_LOCATION for a pointer to a decl that is no longer
addressable.   
Represents value that argument had on function entry.  The
single argument is the DECL_INCOMING_RTL of the corresponding
parameter.   
Used in VAR_LOCATION for a reference to a parameter that has
been optimized away completely.   
Used in marker DEBUG_INSNs to avoid being recognized as an insn.   
All expressions from this point forward appear only in machine
descriptions.   

Function Documentation

◆ add_decision() [1/2]

static state * add_decision ( state * from,
const rtx_test & test,
int_set labels,
bool optional )
static
Add a transition from FROM to a new, empty state that is taken
when TEST == LABELS.  OPTIONAL says whether the new transition
should be optional.  Return the new state.   

References add_decision().

◆ add_decision() [2/2]

static void add_decision ( state * from,
const rtx_test & test,
transition * trans )
static
Add to FROM a decision that performs TEST and has a single transition
TRANS.   

References list_head< T >::push_back().

Referenced by add_decision(), add_pattern_acceptance(), create_subroutine(), match_pattern_1(), and match_pattern_2().

◆ add_parameter()

static bool add_parameter ( vec< parameter > & params1,
vec< parameter > & params2,
const parameter & param1,
const parameter & param2,
unsigned int start,
unsigned int * res )
static
PARAMS2 is the "params" array for a pattern and PARAMS1 is the
set of parameters that a particular state is going to pass to
that pattern.

Try to extend PARAMS1 and PARAMS2 so that there is a parameter
that is equal to PARAM1 for the state and has a default value of
PARAM2.  Parameters beginning at START were added as part of the
same match and so may be reused.   

References force_unique_params_p, gcc_assert, i, parameter::is_param, and MAX_PATTERN_PARAMS.

Referenced by merge_patterns().

◆ add_pattern_acceptance()

static void add_pattern_acceptance ( create_pattern_info * cpi,
state * s )
static

◆ assign_position_var()

static void assign_position_var ( output_state * os,
position * pos,
bool root_p )
static
Make sure that OS has a position variable for POS.  ROOT_P is true if
POS is the root position for the routine.   

References assign_position_var(), position::base, position::id, output_state::id_to_var, POS_PEEP2_INSN, position::type, and output_state::var_to_id.

Referenced by assign_position_var(), assign_position_vars(), and print_subroutine_start().

◆ assign_position_vars()

static void assign_position_vars ( output_state * os,
state * s )
static
Make sure that OS has the position variables required by S.   

References assign_position_var(), assign_position_vars(), list_head< T >::first, decision::next, and transition::next.

Referenced by assign_position_vars(), and print_subroutine_start().

◆ change_state()

static void change_state ( FILE * f,
output_state * os,
position * pos,
unsigned int indent )
static
Emit code to initialize the variable associated with POS, if it isn't
already valid in state OS.  Indent each line by INDENT spaces.  Update
OS with the new state.   

References position::arg, position::base, change_state(), gcc_assert, position::id, output_state::id_to_var, POS_PEEP2_INSN, POS_XEXP, POS_XVECEXP0, printf_indent(), output_state::seen_vars, position::type, and output_state::var_to_id.

Referenced by change_state(), and print_decision().

◆ collapse_optional_decisions()

static void collapse_optional_decisions ( state * s)
static

◆ common_position()

static struct position * common_position ( struct position * pos1,
struct position * pos2 )
static
Return the most deeply-nested position that is common to both
POS1 and POS2.  If the positions are from different instructions,
return the one with the lowest insn_id.   

References position::base, position::depth, and position::insn_id.

Referenced by populate_pattern_routine(), and split_out_patterns().

◆ common_test_p()

static bool common_test_p ( decision * d,
transition * common,
vec< transition * > * where )
static
Return true if all successful returns passing through D require the
condition tested by COMMON to be true.

When returning true, add all transitions like COMMON in D to WHERE.
WHERE may contain a partial result on failure.   

References rtx_test::ACCEPT, common_test_p(), list_head< T >::first, transition::from, rtx_test::kind, transition::labels, transition::next, transition::optional, list_head< T >::singleton(), and decision::test.

Referenced by common_test_p(), and find_common_test().

◆ compare_positions()

static int compare_positions ( struct position * pos1,
struct position * pos2 )
static
Compare positions POS1 and POS2 lexicographically.   

References position::arg, position::base, position::depth, and position::type.

Referenced by operator<().

◆ compatible_tests_p()

static bool compatible_tests_p ( const rtx_test & a,
const rtx_test & b,
parameter * parama,
parameter * paramb )
static
Return true if A and B can be tested by a single test.  If the test
can be parameterised, store the parameter value for A in *PARAMA and
the parameter value for B in *PARAMB, otherwise leave PARAMA and
PARAMB alone.   

References a, b, parameter::INT, parameter::MODE, rtx_test::PREDICATE, and rtx_test::SAVED_CONST_INT.

Referenced by test_pattern_hasher::equal(), and merge_patterns().

◆ complete_result_p()

static bool complete_result_p ( merge_pattern_info * pat,
merge_state_info * sinfo )
static
Return true if PAT represents the biggest posssible match for SINFO;
that is, if the next action of SINFO's state on return from PAT will
be something that cannot be merged with any other state.   

References merge_pattern_info::transitions.

Referenced by split_out_patterns().

◆ constraints_supported_in_insn_p()

static bool constraints_supported_in_insn_p ( rtx insn)
static
In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
don't use the MATCH_OPERAND constraint, only the predicate.
This is confusing to folks doing new ports, so help them
not make the mistake.   

References GET_CODE.

Referenced by validate_pattern().

◆ create_subroutine()

static state * create_subroutine ( routine_type type,
state * s,
vec< state * > & procs )
static
Turn S into a subroutine of type TYPE and add it to PROCS.  Return a new
state that performs a subroutine call to S.   

References rtx_test::accept(), add_decision(), acceptance_type::partial_p, acceptance_type::subroutine_id, acceptance_type::type, and acceptance_type::u.

Referenced by find_subroutines().

◆ cse_tests()

◆ find_common_test()

static decision * find_common_test ( decision * outer,
bool with_position_p,
position * pos,
bool worthwhile_single_p,
known_conditions * kc,
vec< transition * > * where )
static
Look for a transition that is taken by all successful returns from a range
of decisions starting at OUTER and that would be better performed by
OUTER's state instead.  On success, store all instances of that transition
in WHERE and return the last decision in the range.  The range could
just be OUTER, or it could include later decisions as well.

WITH_POSITION_P is true if only tests with position POS should be tried,
false if any test should be tried.  WORTHWHILE_SINGLE_P is true if the
result is useful even when the range contains just a single decision
with a single transition.  KC are the conditions that are known to
hold at OUTER.   

References common_test_p(), list_head< T >::first, decision::next, safe_to_hoist_p(), list_head< T >::singleton(), decision::test, and transition::to.

Referenced by cse_tests().

◆ find_matching_operand()

static rtx find_matching_operand ( rtx pattern,
int n )
static
Search for and return operand M, such that it has a matching
constraint for operand N.   

References find_matching_operand(), gcc_unreachable, GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, NULL, r, RTX_CODE, XEXP, XSTR, XVEC, XVECEXP, and XVECLEN.

Referenced by find_matching_operand(), and validate_pattern().

◆ find_operand()

static rtx find_operand ( rtx pattern,
int n,
rtx stop )
static
Search for and return operand N, stop when reaching node STOP.   

References find_operand(), gcc_unreachable, GET_CODE, GET_RTX_FORMAT, GET_RTX_LENGTH, i, NULL, NULL_RTX, r, RTX_CODE, XEXP, XINT, XVEC, XVECEXP, and XVECLEN.

Referenced by find_operand(), match_pattern_2(), and validate_pattern().

◆ find_operand_positions()

static void find_operand_positions ( state * s,
vec< int > & operand_pos )
static
Initialize the pos_operand fields of each state reachable from S.
If OPERAND_POS[ID] >= 0, the position with id ID is stored in
operands[OPERAND_POS[ID]] on entry to S.   

References find_operand_positions(), list_head< T >::first, decision::next, transition::next, and rtx_test::SET_OP.

Referenced by find_operand_positions(), and optimize_subroutine_group().

◆ find_subroutines()

static state_size find_subroutines ( routine_type type,
state * s,
vec< state * > & procs )
static
Walk state tree S, of type TYPE, and look for subtrees that would be
better split into subroutines.  Accumulate all such subroutines in PROCS.
Return the size of the new state tree (excluding subroutines).   

References rtx_test::ACCEPT, candidates, create_subroutine(), state_size::depth, find_subroutines(), list_head< T >::first, i, decision::if_statement_p(), rtx_test::kind, MAX, MAX_DEPTH, MAX_NUM_STATEMENTS, MIN_NUM_STATEMENTS, decision::next, transition::next, state_size::num_statements, rtx_test::pos, rtx_test::pos_operand, rtx_test::SET_OP, rtx_test::single_outcome_p(), list_head< T >::singleton(), subroutine_candidate_cmp(), and decision::test.

Referenced by find_subroutines(), and print_subroutine_group().

◆ get_failure_return()

static const char * get_failure_return ( routine_type type)
static
Return the C failure value for a routine of type TYPE.   

References gcc_unreachable, PEEPHOLE2, RECOG, SPLIT, and SUBPATTERN.

Referenced by print_decision(), and print_state().

◆ get_peephole2_pattern()

static rtx get_peephole2_pattern ( md_rtx_info * info)
static
Return the rtx pattern for the list of rtxes in a define_peephole2.   

References md_rtx_info::def, error_at(), GET_CODE, GET_NUM_ELEM, i, md_rtx_info::loc, rtvec_alloc(), RTVEC_ELT, rtx_alloc(), XVEC, XVECEXP, and XVECLEN.

Referenced by main().

◆ get_predicate_codes()

static void get_predicate_codes ( const struct pred_data * pred,
int_set * codes )
static
Fill CODES with the set of codes that could be matched by PRED.   

References pred_data::codes, i, and NUM_TRUE_RTX_CODE.

Referenced by match_pattern_2().

◆ get_stats()

◆ handle_arg()

static bool handle_arg ( const char * arg)
static

References fopen, header, header_name, and output_files.

◆ has_same_test_p()

static bool has_same_test_p ( decision * d1,
decision * d2 )
static
Return true if the first path through D1 tests the same thing as D2.   

References d1, and d2.

Referenced by mutually_exclusive_p().

◆ init_pattern_use()

static decision * init_pattern_use ( create_pattern_info * cpi,
merge_state_info * sinfo,
const vec< parameter > & params )
static
SINFO matches a pattern for which we've decided to create a C routine.
Return a decision that performs a call to the pattern routine,
but leave the caller to add the transitions to it.  Initialize CPI
for this purpose.  Also create a definition for the pattern routine,
if it doesn't already have one.

PARAMS are the parameters that SINFO passes to its pattern.   

References list_head< T >::first, gcc_assert, i, pattern_routine::insn_p, create_pattern_info::next_result, merge_pattern_info::num_results, pattern_routine::param_types, merge_pattern_info::params, merge_state_result::pattern, rtx_test::pattern, pattern_routine::pattern_id, patterns, pattern_routine::pnum_clobbers_p, populate_pattern_routine(), pattern_routine::pos, rtx_test::pos, rtx_test::pos_operand, merge_state_result::root, create_pattern_info::routine, merge_pattern_info::routine, pattern_routine::s, sinfo::s, and decision::test.

Referenced by populate_pattern_routine(), and use_pattern().

◆ insert_decision_before()

static decision * insert_decision_before ( state::range r,
const rtx_test & test,
const int_set & labels,
bool optional )
static
Insert a decision before decisions R to make them dependent on
TEST == LABELS.  OPTIONAL says whether the new transition should be
optional.   

References list_head< T >::push_back(), and r.

Referenced by cse_tests().

◆ main()

◆ match_pattern()

static void match_pattern ( state * s,
md_rtx_info * info,
rtx pattern,
acceptance_type acceptance )
static
Like match_pattern_1, but (if merge_states_p) try to merge the
decisions with what's already in S, to reduce the amount of
backtracking.   

References match_pattern_1(), merge_into_state(), and merge_states_p.

Referenced by find_optab(), and main().

◆ match_pattern_1()

static void match_pattern_1 ( state * s,
md_rtx_info * info,
rtx pattern,
acceptance_type acceptance )
static
Add new decisions to S that make it return ACCEPTANCE if:

(1) the rtx doesn't match anything already matched by S
(2) the rtx matches TOP_PATTERN and
(3) the C test required by INFO->def is true

For peephole2, TOP_PATTERN is a SEQUENCE of the instruction patterns
to match, otherwise it is a single instruction pattern.   

References rtx_test::accept(), add_decision(), rtx_test::c_test(), count, md_rtx_info::def, acceptance_type::full, get_c_test(), rtx_test::have_num_clobbers(), i, acceptance_type::match_len, match_pattern_2(), maybe_eval_c_test(), position::next, next_position(), acceptance_type::num_clobbers, rtx_test::peep2_count(), peep2_insn_pos_list, PEEPHOLE2, POS_PEEP2_INSN, RECOG, root_pos, acceptance_type::type, acceptance_type::u, XVECEXP, and XVECLEN.

Referenced by match_pattern().

◆ match_pattern_2()

◆ merge_into_decision()

static bool merge_into_decision ( decision * d1,
state * s2,
const int_set * exclude,
state ** next_s1,
state ** next_s2,
const int_set ** next_exclude )
static
Try to merge S2's decision into D1, given that they have the same test.
Fail only if EXCLUDE is nonnull and the new transition would have the
same labels as *EXCLUDE.  When returning true, set *NEXT_S1, *NEXT_S2
and *NEXT_EXCLUDE as for merge_into_state_1, or set *NEXT_S2 to null
if the merge is complete.   

References int_set::begin(), d1, d2, end(), int_set::end(), list_head< T >::first, gcc_assert, i, i1, i2, transition::labels, transition::optional, list_head< T >::push_back(), r, list_head< T >::replace(), list_head< T >::singleton(), and transition::to.

Referenced by merge_into_state_1().

◆ merge_into_state()

static void merge_into_state ( state * s1,
state * s2 )
static
Merge S2 into S1.  If they both match a particular rtx, give
priority to S1.  Each state in S2 has a single decision.   

References merge_into_state_1().

Referenced by match_pattern().

◆ merge_into_state_1()

static bool merge_into_state_1 ( state * s1,
state * s2,
const int_set * exclude,
state ** next_s1,
state ** next_s2,
const int_set ** next_exclude )
static
Make progress in merging S2 into S1, given that each state in S2
has a single decision.  If EXCLUDE is nonnull, avoid creating a new
transition with the same test as S2's decision and with the labels
in *EXCLUDE.

Return true if there is still work to do.  When returning true,
set *NEXT_S1, *NEXT_S2 and *NEXT_EXCLUDE to the values that
S1, S2 and EXCLUDE should have next time round.

If S1 and S2 both match a particular rtx, give priority to S1.   

References d1, d2, list_head< T >::last, merge_into_decision(), mutually_exclusive_p(), transition::optional, list_head< T >::push_back(), list_head< T >::release(), list_head< T >::singleton(), decision::test, and transition::to.

Referenced by merge_into_state().

◆ merge_patterns()

◆ merge_relative_positions()

static bool merge_relative_positions ( position ** roota,
position * a,
position * rootb,
position * b )
static
If *ROOTA is nonnull, return true if the same sequence of steps are
required to reach A from *ROOTA as to reach B from ROOTB.  If *ROOTA
is null, update it if necessary in order to make the condition hold.   

References a, b, position::insn_id, and relative_patterns_p.

Referenced by merge_patterns().

◆ mutually_exclusive_p()

static bool mutually_exclusive_p ( decision * d1,
decision * d2 )
static
Return true if D1 and D2 cannot match the same rtx.  All states reachable
from D2 have single decisions and all those decisions have single
transitions.   

References int_set::begin(), d1, d2, int_set::end(), list_head< T >::first, has_same_test_p(), i1, i2, transition::labels, mutually_exclusive_p(), and transition::next.

Referenced by merge_into_state_1(), and mutually_exclusive_p().

◆ next_position()

static struct position * next_position ( struct position ** next_ptr,
struct position * base,
enum position_type type,
int arg )
static
Return a position with the given BASE, TYPE and ARG.  NEXT_PTR
points to where the unique object that represents the position
should be stored.  Create the object if it doesn't already exist,
otherwise reuse the object that is already there.   

References position::arg, position::base, position::depth, position::id, position::insn_id, num_positions, POS_PEEP2_INSN, and position::type.

Referenced by match_pattern_1(), and match_pattern_2().

◆ operator!=() [1/4]

bool operator!= ( const acceptance_type & a,
const acceptance_type & b )

References a, b, and operator==().

◆ operator!=() [2/4]

bool operator!= ( const int_set & a,
const int_set & b )

References a, b, and operator==().

◆ operator!=() [3/4]

bool operator!= ( const parameter & param1,
const parameter & param2 )

References operator==().

◆ operator!=() [4/4]

bool operator!= ( const rtx_test & a,
const rtx_test & b )

References a, b, and operator==().

◆ operator<()

bool operator< ( const pattern_pos & e1,
const pattern_pos & e2 )
Compare entries according to their depth-first order.  There shouldn't
be two entries at the same position.   

References compare_positions(), gcc_assert, pattern_pos::pattern, and pattern_pos::pos.

◆ operator==() [1/4]

bool operator== ( const acceptance_type & a,
const acceptance_type & b )

References a, and b.

Referenced by operator!=(), operator!=(), operator!=(), and operator!=().

◆ operator==() [2/4]

bool operator== ( const int_set & a,
const int_set & b )

References a, b, and i.

◆ operator==() [3/4]

bool operator== ( const parameter & param1,
const parameter & param2 )

◆ operator==() [4/4]

◆ optimize_subroutine_group()

◆ parameter_type_string()

static const char * parameter_type_string ( parameter::type_enum type)
static
Return the C type of a parameter with type TYPE.   

References parameter::CODE, gcc_unreachable, parameter::INT, parameter::MODE, parameter::UINT, parameter::UNSET, and parameter::WIDE_INT.

Referenced by print_pattern().

◆ populate_pattern_routine()

static void populate_pattern_routine ( create_pattern_info * cpi,
merge_state_info * sinfo,
state * news,
const vec< parameter > & params )
static
Initialize new empty state NEWS so that it implements SINFO's pattern
(here referred to as "P").  P may be the top level of a pattern routine
or a subpattern that should be inlined into its parent pattern's routine
(as per same_pattern_p).  The choice of SINFO for a top-level pattern is
arbitrary; it could be any of the states that use P.  The choice for
subpatterns follows the choice for the parent pattern.

PARAMS gives the value of each parameter to P in terms of the parameters
to the top-level pattern.  If P itself is the top level pattern, PARAMS[I]
is always "parameter (TYPE, true, I)".   

References add_pattern_acceptance(), rtx_test::C_TEST, common_position(), list_head< T >::first, gcc_assert, gcc_unreachable, rtx_test::HAVE_NUM_CLOBBERS, i, init_pattern_use(), pattern_routine::insn_p, rtx_test::integer, parameter::is_param, rtx_test::is_param, transition::is_param, rtx_test::kind, transition::labels, rtx_test::mode, rtx_test::mode_is_param, transition::next, merge_pattern_info::num_results, merge_pattern_info::param_test, merge_pattern_info::param_test_p, merge_pattern_info::param_transition, merge_pattern_info::param_transition_p, merge_pattern_info::params, merge_state_result::pattern, pattern_def_states, pattern_routine::pnum_clobbers_p, populate_pattern_routine(), pattern_routine::pos, rtx_test::pos, rtx_test::pos_operand, rtx_test::PREDICATE, rtx_test::predicate, list_head< T >::push_back(), merge_state_info::res, create_pattern_info::routine, sinfo::s, same_pattern_p(), rtx_test::SAVED_CONST_INT, decision::test, merge_pattern_info::transitions, rtx_test::u, parameter::value, and rtx_test::value.

Referenced by init_pattern_use(), and populate_pattern_routine().

◆ populate_pattern_use()

static void populate_pattern_use ( create_pattern_info * cpi,
decision * use,
merge_state_info * sinfo )
static
USE is a decision that calls a pattern routine and SINFO is part of the
original state tree that the call is supposed to replace.  Add the
transitions for SINFO and its substates to USE.   

References list_head< T >::first, gcc_assert, i, transition::next, create_pattern_info::next_result, merge_state_result::pattern, pattern_use_states, populate_pattern_use(), sinfo::s, and merge_pattern_info::transitions.

Referenced by populate_pattern_use(), and use_pattern().

◆ predicate_name()

static const char * predicate_name ( rtx match_rtx)
static
Return the name of the predicate matched by MATCH_RTX.   

References GET_CODE, match_rtx(), and XSTR.

Referenced by match_pattern_2(), and special_predicate_operand_p().

◆ print_acceptance()

static exit_state print_acceptance ( FILE * f,
const acceptance_type & acceptance,
unsigned int indent,
bool is_final )
static

◆ print_code()

static void print_code ( FILE * f,
enum rtx_code code )
static
Print the enumerator constant for CODE -- the upcase version of
the name.   

References GET_RTX_NAME.

Referenced by print_parameter_value().

◆ print_decision()

◆ print_host_wide_int()

static void print_host_wide_int ( FILE * f,
uint64_t val )
static
Emit a uint64_t as an integer constant expression.  We need to take
special care to avoid "decimal constant is so large that it is unsigned"
warnings in the resulting code.   

References HOST_BITS_PER_WIDE_INT, and HOST_WIDE_INT_PRINT_DEC_C.

Referenced by print_parameter_value().

◆ print_label_value()

static void print_label_value ( FILE * f,
const rtx_test & test,
bool is_param,
uint64_t value )
static
IS_PARAM and LABEL are taken from a transition whose source
decision performs TEST.  Print the C code for the label.   

References rtx_test::kind, print_parameter_value(), and transition_parameter_type().

Referenced by print_decision(), and print_test().

◆ print_nonbool_test()

◆ print_parameter_value()

static void print_parameter_value ( FILE * f,
const parameter & param )
static

◆ print_pattern()

static void print_pattern ( FILE * f,
output_state * os,
pattern_routine * routine,
bool in_header = false )
static

◆ print_state()

static exit_state print_state ( FILE * f,
output_state * os,
state * s,
unsigned int indent,
bool is_final )
static
Print code to perform S, indent each line by INDENT spaces.
IS_FINAL is true if there are no fallback decisions to test on failure;
if the state fails then the entire routine fails.   

References ES_FALLTHROUGH, ES_RETURNED, list_head< T >::first, get_failure_return(), decision::next, print_decision(), printf_indent(), and output_state::type.

Referenced by print_decision(), print_filtered_help(), print_pattern(), and print_subroutine().

◆ print_subroutine()

static void print_subroutine ( FILE * f,
output_state * os,
state * s,
int proc_id,
bool in_header = false )
static
Output a routine of type TYPE that implements S.  PROC_ID is the
number of the subroutine associated with S, or 0 if S is the main
routine.   

References end(), gcc_unreachable, PEEPHOLE2, print_state(), print_subroutine_start(), RECOG, root_pos, SPLIT, SUBPATTERN, and output_state::type.

Referenced by print_subroutine_group().

◆ print_subroutine_call()

static const char * print_subroutine_call ( FILE * f,
const acceptance_type & acceptance )
static
Print the code for subroutine call ACCEPTANCE (for which partial_p
is known to be true).  Return the C condition that indicates a successful
match.   

References gcc_unreachable, PEEPHOLE2, RECOG, SPLIT, SUBPATTERN, acceptance_type::subroutine_id, acceptance_type::type, and acceptance_type::u.

Referenced by print_acceptance().

◆ print_subroutine_group()

static void print_subroutine_group ( vec< FILE * > & vec,
FILE * header,
output_state * os,
routine_type type,
state * root )
static
Print out a routine of type TYPE that performs ROOT.   

References choose_output(), find_subroutines(), FOR_EACH_VEC_ELT, header, i, print_subroutine(), output_state::type, and use_subroutines_p.

Referenced by main().

◆ print_subroutine_start()

static void print_subroutine_start ( FILE * f,
output_state * os,
state * s,
position * root )
static
Print the open brace and variable definitions for a routine that
implements S.  ROOT is the deepest rtx from which S can access all
relevant parts of the first instruction it matches.  Initialize OS
so that every relevant position has an rtx variable xN and so that
only ROOT's variable has a valid value.   

References assign_position_var(), assign_position_vars(), i, num_positions, RECOG, output_state::seen_vars, SUBPATTERN, output_state::type, and output_state::var_to_id.

Referenced by print_pattern(), and print_subroutine().

◆ print_test()

◆ print_test_rtx()

static void print_test_rtx ( FILE * f,
output_state * os,
const rtx_test & test )
static
Print the C expression for the rtx tested by TEST.   

References position::id, output_state::id_to_var, rtx_test::pos, and rtx_test::pos_operand.

Referenced by print_decision(), print_nonbool_test(), and print_test().

◆ printf_indent()

static void ATTRIBUTE_PRINTF_3 printf_indent ( FILE * f,
unsigned int indent,
const char * format,
... )
static
Like printf, but print INDENT spaces at the beginning.   

References ap, and vfprintf().

Referenced by change_state(), print_acceptance(), print_decision(), and print_state().

◆ prune_invalid_results()

static void prune_invalid_results ( merge_state_info * sinfo)
static
Remove any matches that are no longer valid from the head of SINFO's
list of matches.   

References gcc_assert, and valid_result_p().

Referenced by split_out_patterns().

◆ remove_clobbers()

static bool remove_clobbers ( acceptance_type * acceptance_ptr,
rtx * pattern_ptr )
static
Return true if *PATTERN_PTR is a PARALLEL in which at least one trailing
rtx can be added automatically by add_clobbers.  If so, update
*ACCEPTANCE_PTR so that its num_clobbers field contains the number
of such trailing rtxes and update *PATTERN_PTR so that it contains
the pattern without those rtxes.   

References acceptance_type::full, GET_CODE, i, acceptance_type::num_clobbers, REG_P, rtvec_alloc(), rtx_alloc(), acceptance_type::u, XEXP, XVEC, XVECEXP, and XVECLEN.

Referenced by main().

◆ safe_predicate_mode()

static bool safe_predicate_mode ( const struct pred_data * pred,
machine_mode mode )
static
Return true if, for all X, PRED (X, MODE) implies that X has mode MODE.   

References pred_data::codes, GET_MODE_CLASS, and pred_data::special.

Referenced by match_pattern_2().

◆ safe_to_hoist_p()

static bool safe_to_hoist_p ( decision * d,
const rtx_test & test,
known_conditions * kc )
static
Return true if TEST can safely be performed at D, where
the conditions in KC hold.  TEST is known to occur along the
first path from D (i.e. always following the first transition
of the first decision).  Any intervening tests can be used as
negative proof that hoisting isn't safe, but only KC can be used
as positive proof.   

References rtx_test::ACCEPT, position::arg, position::base, rtx_test::C_TEST, rtx_test::CODE, rtx_test::DUPLICATE, gcc_unreachable, rtx_test::HAVE_NUM_CLOBBERS, position::id, rtx_test::INT_FIELD, rtx_test::kind, rtx_test::MODE, rtx_test::opno, rtx_test::PATTERN, rtx_test::PEEP2_COUNT, known_conditions::peep2_count, rtx_test::pos, POS_PEEP2_INSN, POS_XEXP, POS_XVECEXP0, known_conditions::position_tests, rtx_test::PREDICATE, rtx_test::REGNO_FIELD, rtx_test::SAVED_CONST_INT, rtx_test::SET_OP, known_conditions::set_operands, rtx_test::SUBREG_FIELD, decision::test, TESTED_CODE, TESTED_VECLEN, position::type, rtx_test::u, rtx_test::VECLEN, rtx_test::VECLEN_GE, and rtx_test::WIDE_INT_FIELD.

Referenced by cse_tests(), and find_common_test().

◆ same_pattern_p()

static bool same_pattern_p ( merge_pattern_info * pat1,
merge_pattern_info * pat2 )
static
PAT2 is a subpattern of PAT1.  Return true if PAT2 should be inlined
into PAT1's C routine.   

References merge_pattern_info::num_users, and useful_pattern_p().

Referenced by populate_pattern_routine(), and split_out_patterns().

◆ set_parameter()

static bool set_parameter ( vec< parameter > & params,
unsigned int id,
const parameter & value )
static
PARAMS is an array of the parameters that a state is going to pass
to a pattern routine.  It is still incomplete; index I has a kind of
parameter::UNSET if we don't yet know what the state will pass
as parameter I.  Try to make parameter ID equal VALUE, returning
true on success.   

References force_unique_params_p, i, and parameter::UNSET.

Referenced by merge_patterns().

◆ simplify_tests()

◆ single_statement_p()

static bool single_statement_p ( const acceptance_type & acceptance)
static
Return true if ACCEPTANCE requires only a single C statement even in
a backtracking context.   

References acceptance_type::full, gcc_unreachable, acceptance_type::num_clobbers, acceptance_type::partial_p, PEEPHOLE2, RECOG, SPLIT, SUBPATTERN, acceptance_type::type, and acceptance_type::u.

Referenced by print_decision().

◆ special_predicate_operand_p()

static bool special_predicate_operand_p ( rtx operand)
static
Return true if OPERAND is a MATCH_OPERAND using a special predicate
function.   

References GET_CODE, lookup_predicate(), NULL, predicate_name(), and pred_data::special.

Referenced by validate_pattern().

◆ split_out_patterns()

◆ subroutine_candidate_cmp()

static int subroutine_candidate_cmp ( const void * a,
const void * b )
static
Sort two subroutine_candidates so that the one with the largest
number of statements comes last.   

References a, and b.

Referenced by find_subroutines().

◆ terminal_pattern_p()

static bool terminal_pattern_p ( decision * d,
unsigned int * base_out,
unsigned int * count_out )
static
Return true if D is a call to a pattern routine and if there is some X
such that the transition for pattern result N goes to a successful return
with code X+N.  When returning true, set *BASE_OUT to this X and *COUNT_OUT
to the number of return values.  (We know that every PATTERN decision has
a transition for every successful return.)   

References rtx_test::ACCEPT, rtx_test::acceptance, acceptance_type::code, count, list_head< T >::first, acceptance_type::full, rtx_test::kind, transition::next, rtx_test::PATTERN, list_head< T >::singleton(), decision::test, acceptance_type::u, and rtx_test::u.

Referenced by print_decision().

◆ test_position_available_p()

static bool test_position_available_p ( output_state * os,
const rtx_test & test )
static
Return true if TEST doesn't test an rtx or if the rtx it tests is
already available in state OS.   

References position::id, output_state::id_to_var, rtx_test::pos, rtx_test::pos_operand, and output_state::seen_vars.

Referenced by print_decision().

◆ transition_parameter_type()

◆ update_parameters()

static void update_parameters ( vec< parameter > & to,
const vec< parameter > & from )
static
Update TO for any parameters that have been added to FROM since TO
was last set.  The extra parameters in FROM will be constants or
instructions to duplicate earlier parameters.   

References i.

Referenced by merge_patterns(), split_out_patterns(), and use_pattern().

◆ use_pattern()

static void use_pattern ( merge_state_info * sinfo)
static
We have decided to replace SINFO's state with a call to a pattern
routine.  Make the change, creating a definition of the pattern routine
if it doesn't have one already.   

References init_pattern_use(), merge_pattern_info::params, merge_state_result::params, merge_state_result::pattern, populate_pattern_use(), list_head< T >::push_back(), list_head< T >::release(), sinfo::s, and update_parameters().

Referenced by split_out_patterns().

◆ useful_pattern_p()

static bool useful_pattern_p ( merge_pattern_info * pat)
static
True if PAT would be useful as a subroutine.   

References MIN_COMBINE_COST, and merge_pattern_info::num_statements.

Referenced by same_pattern_p(), and split_out_patterns().

◆ valid_result_p()

static bool valid_result_p ( merge_pattern_info * pat,
merge_state_info * sinfo )
static
PAT was previously matched against SINFO based on tentative matches
for the target states of SINFO's state.  Return true if the match
still holds; that is, if the target states of SINFO's state still
match the corresponding transitions of PAT.   

References merge_state_result::pattern, and merge_pattern_info::transitions.

Referenced by prune_invalid_results(), and split_out_patterns().

◆ validate_pattern()

static void validate_pattern ( rtx pattern,
md_rtx_info * info,
rtx set,
int set_code )
static

◆ write_header()

static void write_header ( FILE * f,
const char * header_filename )
static
Begin the output file.   

Variable Documentation

◆ collapse_optional_decisions_p

const bool collapse_optional_decisions_p = true
static

◆ cse_tests_p

const bool cse_tests_p = true
static

◆ force_unique_params_p

const bool force_unique_params_p = true
static
Whether to require each parameter passed to a pattern routine to be
unique.  Disabling this check for example allows unary operators with
matching modes (like NEG) and unary operators with mismatched modes
(like ZERO_EXTEND) to be matched by a single pattern.  However, we then
often have cases where the same value is passed too many times.   

Referenced by add_parameter(), and set_parameter().

◆ header

◆ header_name

char header_name[255]

Referenced by handle_arg(), and main().

◆ mark_optional_transitions_p

const bool mark_optional_transitions_p = false
static
Whether to add comments for optional tests that we decided to keep.
Can be useful when debugging the generator itself but is noise when
debugging the generated code.   

Referenced by print_decision().

◆ MAX_DEPTH

const unsigned int MAX_DEPTH = 6
static
The maximum (approximate) depth of block nesting that an individual
routine or subroutine should have.  This limit is about keeping the
output readable rather than reducing compile time.   

Referenced by find_subroutines().

◆ MAX_NUM_STATEMENTS

const unsigned int MAX_NUM_STATEMENTS = 200
static
The number of pseudo-statements a state can have before we consider
splitting out substates into subroutines.  This limit is about avoiding
compile-time problems with very big functions (and also about keeping
functions within --param optimization limits, etc.).   

Referenced by find_subroutines().

◆ MAX_PATTERN_PARAMS

const unsigned int MAX_PATTERN_PARAMS = 5
static
The maximum number of arguments that a pattern routine can have.
The idea is to prevent one pattern getting a ridiculous number of
arguments when it would be more beneficial to have a separate pattern
routine instead.   

Referenced by add_parameter().

◆ merge_states_p

const bool merge_states_p = true
static
Debugging variables to control which optimizations are performed.
Note that disabling merge_states_p leads to very large output.   

Referenced by match_pattern().

◆ MIN_COMBINE_COST

const unsigned int MIN_COMBINE_COST = 4
static
The minimum number of pseudo-statements that can be used in a pattern
routine.   

Referenced by useful_pattern_p().

◆ MIN_NUM_STATEMENTS

const unsigned int MIN_NUM_STATEMENTS = 5
static
The minimum number of pseudo-statements that a state must have before
we split it out into a subroutine.   

Referenced by find_subroutines().

◆ num_operands

static int num_operands
The maximum operand number plus one.   

Referenced by gen_proto(), match_pattern_2(), and optimize_subroutine_group().

◆ num_positions

unsigned int num_positions = 1
static
The number of positions created.  Also one higher than the maximum
position id.   

Referenced by main(), next_position(), optimize_subroutine_group(), and print_subroutine_start().

◆ output_files

auto_vec<FILE *, 10> output_files
The list of output files.   
Process source files and output type information.
Copyright (C) 2002-2025 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
Data types, macros, etc. used only in this file.   
The list of output files.   

◆ pattern_c_test_p

const bool pattern_c_test_p = false
static
Whether pattern routines should be allowed to test .md file C conditions.
This requires passing insn around as a parameter, in case the C
condition refers to it.  In practice this tends to lead to bigger
object files.   

Referenced by split_out_patterns().

◆ pattern_def_states

unsigned int pattern_def_states
static
The number of states used while defining pattern routines.   

Referenced by populate_pattern_routine(), and split_out_patterns().

◆ pattern_have_num_clobbers_p

const bool pattern_have_num_clobbers_p = true
static
Whether pattern routines should be allowed to test whether pnum_clobbers
is null.  This requires passing pnum_clobbers around as a parameter.   

Referenced by split_out_patterns().

◆ pattern_use_states

unsigned int pattern_use_states
static
The number of states that were removed by calling pattern routines.   

Referenced by populate_pattern_use(), and split_out_patterns().

◆ patterns

vec<pattern_routine *> patterns
static
All defined patterns.   

◆ peep2_insn_pos_list

struct position* peep2_insn_pos_list = &root_pos
static
A list of all POS_PEEP2_INSNs.  The entry for insn 0 is the root position,
since we are given that instruction's pattern as x0.   

Referenced by match_pattern_1().

◆ relative_patterns_p

const bool relative_patterns_p = false
static
Whether pattern routines should calculate positions relative to their
rtx parameter rather than use absolute positions.  This e.g. allows
a pattern routine to be shared between a plain SET and a PARALLEL
that includes a SET.

In principle it sounds like this should be useful, especially for
recog_for_combine, where the plain SET form is generated automatically
from a PARALLEL of a single SET and some CLOBBERs.  In practice it doesn't
seem to help much and leads to slightly bigger object files.   

Referenced by test_pattern_hasher::equal(), test_pattern_hasher::hash(), and merge_relative_positions().

◆ root_pos

struct position root_pos
static
The root position (x0).   

Referenced by match_pattern_1(), optimize_subroutine_group(), and print_subroutine().

◆ simplify_tests_p

const bool simplify_tests_p = true
static

◆ TESTED_CODE

const unsigned char TESTED_CODE = 1
Indicates that we have tested GET_CODE (X) for a particular rtx X.   

Referenced by cse_tests(), and safe_to_hoist_p().

◆ TESTED_VECLEN

const unsigned char TESTED_VECLEN = 2
Indicates that we have tested XVECLEN (X, 0) for a particular rtx X.   

Referenced by cse_tests(), and safe_to_hoist_p().

◆ use_operand_variables_p

const bool use_operand_variables_p = true
static

◆ use_pattern_routines_p

const bool use_pattern_routines_p = true
static

Referenced by main().

◆ use_subroutines_p

const bool use_subroutines_p = true
static

Referenced by print_subroutine_group().