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().