GCC Middle and Back End API Reference
genrecog.c File Reference

Data Structures

struct  position
struct  decision_head
struct  decision_test
struct  decision

Enumerations

enum  position_type { POS_PEEP2_INSN, POS_XEXP, POS_XVECEXP0 }
enum  decision_type {
  DT_num_insns, DT_mode, DT_code, DT_veclen,
  DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
  DT_const_int, DT_veclen_ge, DT_dup, DT_pred,
  DT_c_test, DT_accept_op, DT_accept_insn
}
enum  routine_type { RECOG, SPLIT, PEEPHOLE2 }

Functions

void debug_decision (struct decision *)
void debug_decision_list (struct decision *)
static struct positionnext_position (struct position **next_ptr, struct position *base, enum position_type type, int arg)
static int compare_positions ()
static struct decisionnew_decision ()
static struct decision_testnew_decision_test ()
static rtx find_operand ()
static rtx find_matching_operand ()
static void validate_pattern ()
static struct decisionadd_to_sequence (rtx pattern, struct decision_head *last, struct position *pos, enum routine_type insn_type, int top)
static int maybe_both_true_2 ()
static int maybe_both_true_1 ()
static int maybe_both_true (struct decision *d1, struct decision *d2, int toplevel)
static int nodes_identical_1 ()
static int nodes_identical ()
static void merge_accept_insn ()
static void merge_trees ()
static void factor_tests ()
static void simplify_tests ()
static int break_out_subroutines ()
static void find_afterward ()
static void change_state (struct position *oldpos, struct position *newpos, const char *indent)
static void print_code ()
static void write_afterward (struct decision *start, struct decision *afterward, const char *indent)
static void print_host_wide_int ()
static struct decisionwrite_switch ()
static void write_cond (struct decision_test *p, int depth, enum routine_type subroutine_type)
static void write_action (struct decision *p, struct decision_test *test, int depth, int uncond, struct decision *success, enum routine_type subroutine_type)
static int is_unconditional ()
static int write_node (struct decision *p, int depth, enum routine_type subroutine_type)
static void write_tree_1 (struct decision_head *head, int depth, enum routine_type subroutine_type)
static void write_tree (struct decision_head *head, struct position *prevpos, enum routine_type type, int initial)
static void write_subroutine ()
static void write_subroutines ()
static void write_header ()
static struct decision_head make_insn_sequence ()
static void process_tree ()
int main (int, char **)
int main ()
static void debug_decision_2 ()
static void debug_decision_1 ()
static void debug_decision_0 ()
DEBUG_FUNCTION void debug_decision ()
DEBUG_FUNCTION void debug_decision_list ()

Variables

static int next_subroutine_number
static int next_number
static int next_insn_code
static int max_depth
static int pattern_lineno
static struct position root_pos
static struct positionpeep2_insn_pos_list = &root_pos

Enumeration Type Documentation

These types are roughly in the order in which we'd like to test them.   
Enumerator:
DT_num_insns 
DT_mode 
DT_code 
DT_veclen 
DT_elt_zero_int 
DT_elt_one_int 
DT_elt_zero_wide 
DT_elt_zero_wide_safe 
DT_const_int 
DT_veclen_ge 
DT_dup 
DT_pred 
DT_c_test 
DT_accept_op 
DT_accept_insn 
Ways of obtaining an rtx to be tested.   
Enumerator:
POS_PEEP2_INSN 
POS_XEXP 
POS_XVECEXP0 
We can write three types of subroutines: One for insn recognition,
   one to split insns, and one for peephole-type optimizations.  This
   defines which type is being written.   
Enumerator:
RECOG 
SPLIT 
PEEPHOLE2 

Function Documentation

static struct decision* add_to_sequence ( rtx  pattern,
struct decision_head last,
struct position pos,
enum routine_type  insn_type,
int  top 
)
staticread
Create a chain of nodes to verify that an rtl expression matches
   PATTERN.

   LAST is a pointer to the listhead in the previous node in the chain (or
   in the calling function, for the first node).

   POSITION is the current position in the insn.

   INSN_TYPE is the type of insn for which we are emitting code.

   A pointer to the final node in the chain is returned.   

References decision_test::code, pred_data::codes, position::depth, DT_accept_op, DT_code, DT_dup, DT_elt_one_int, DT_elt_zero_int, DT_elt_zero_wide, DT_elt_zero_wide_safe, DT_mode, DT_num_insns, DT_pred, DT_veclen, DT_veclen_ge, decision_test::dup, decision_head::first, decision_test::intval, decision_head::last, len, lookup_predicate(), max_depth, message_with_line(), decision_test::mode, pred_data::name, new_decision(), new_decision_test(), position::next, next_position(), decision_test::num_insns, decision_test::opno, pattern_lineno, peep2_insn_pos_list, PEEPHOLE2, POS_PEEP2_INSN, POS_XEXP, POS_XVECEXP0, decision_test::pred, root_pos, pred_data::singleton, decision::success, decision::tests, decision_test::u, decision_test::veclen, position::xexps, and position::xvecexp0s.

Referenced by make_insn_sequence().

static int break_out_subroutines ( )
static
Count the number of subnodes of HEAD.  If the number is high enough,
   make the first node in HEAD start a separate subroutine in the C code
   that is generated.   

References decision_head::first, decision::next, next_subroutine_number, decision::subroutine_number, and decision::success.

Referenced by process_tree().

static void change_state ( struct position oldpos,
struct position newpos,
const char *  indent 
)
static
Assuming that the state of argument is denoted by OLDPOS, take whatever
   actions are necessary to move to NEWPOS.  If we fail to move to the
   new state, branch to node AFTERWARD if nonzero, otherwise return.

   Failure to move to the new state can only occur if we are trying to
   match multiple insns and we try to step past the end of the stream.   

References position::arg, position::base, position::depth, POS_PEEP2_INSN, POS_XEXP, POS_XVECEXP0, and position::type.

Referenced by write_afterward(), and write_tree().

static int compare_positions ( )
static
Compare positions POS1 and POS2 lexicographically.   

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

Referenced by maybe_both_true().

void debug_decision ( struct decision )
DEBUG_FUNCTION void debug_decision ( )

References debug_decision_0().

static void debug_decision_0 ( )
static
static void debug_decision_1 ( )
static
void debug_decision_list ( struct decision )
DEBUG_FUNCTION void debug_decision_list ( )
static void factor_tests ( )
static
Walk the tree looking for sub-nodes that perform common tests.
   Factor out the common test into a new node.  This enables us
   (depending on the test type) to emit switch statements later.   

References DT_code, DT_elt_one_int, DT_elt_zero_int, DT_elt_zero_wide_safe, DT_mode, DT_veclen, decision_head::first, first, decision_head::last, merge_trees(), new_decision(), decision_test::next, decision::next, decision::position, decision::prev, decision::success, decision::tests, decision_test::type, and type().

Referenced by process_tree().

static void find_afterward ( )
static
For each node p, find the next alternative that might be true
   when p is true.   

References decision::afterward, decision_head::first, maybe_both_true(), decision::need_label, decision::next, decision::subroutine_number, and decision::success.

Referenced by process_tree().

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

References decision_test::code, and len.

Referenced by validate_pattern().

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

References decision_test::code, and len.

Referenced by validate_pattern().

static int is_unconditional ( )
static
Return 1 if the test is always true and has no fallthru path.  Return -1
   if the test does have a fallthru path, but requires that the condition be
   terminated.  Otherwise return 0 for a normal test.   
??? is_unconditional is a stupid name for a tri-state function.   

References DT_accept_insn, DT_accept_op, decision_test::insn, PEEPHOLE2, RECOG, SPLIT, decision_test::type, and decision_test::u.

Referenced by write_node().

int main ( int  ,
char **   
)
static struct decision_head make_insn_sequence ( )
staticread
static int maybe_both_true ( struct decision d1,
struct decision d2,
int  toplevel 
)
static
Return 0 if we can prove that there is no RTL that can match both
   D1 and D2.  Otherwise, return 1 (it may be that there is an RTL that
   can match both or just that we couldn't prove there wasn't such an RTL).

   TOPLEVEL is nonzero if we are to only look at the top level and not
   recursively descend.   

References compare_positions(), d1, d2, decision_head::first, maybe_both_true_1(), decision::next, decision::position, decision::success, and decision::tests.

Referenced by find_afterward(), and merge_trees().

static int maybe_both_true_1 ( )
static
A subroutine of maybe_both_true; examines all the tests for a given node.
   Returns > 0 for "definitely both true" and < 0 for "maybe both true".   

References DT_accept_op, maybe_both_true_2(), decision_test::next, and decision_test::type.

Referenced by maybe_both_true().

static int maybe_both_true_2 ( )
static
static void merge_accept_insn ( )
static
A subroutine of merge_trees; given two nodes that have been declared
   identical, cope with two insn accept states.  If they differ in the
   number of clobbers, then the conflict was created by make_insn_sequence
   and we can drop the with-clobbers version on the floor.  If both
   nodes have no additional clobbers, we have found an ambiguity in the
   source machine description.   

References DT_accept_insn, error_with_line(), get_insn_name(), decision_test::insn, message_with_line(), decision_test::next, decision::tests, decision_test::type, and decision_test::u.

Referenced by merge_trees().

static void merge_trees ( )
static
static struct decision* new_decision ( )
staticread
static struct decision_test* new_decision_test ( )
staticread
Create a new test and link it in at PLACE.   

References decision_test::next, decision_test::type, and type().

Referenced by add_to_sequence(), and make_insn_sequence().

static struct position* next_position ( struct position **  next_ptr,
struct position base,
enum position_type  type,
int  arg 
)
staticread
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::type, and type().

Referenced by add_to_sequence(), and make_insn_sequence().

static int nodes_identical ( )
static
True iff the two nodes are identical (on one level only).  Due
   to the way these lists are constructed, we shouldn't have to
   consider different orderings on the tests.   

References decision_head::first, decision_test::next, nodes_identical_1(), decision::position, decision::success, decision::tests, and decision_test::type.

Referenced by merge_trees().

static void print_code ( )
static
Print the enumerator constant for CODE -- the upcase version of
   the name.   

Referenced by write_cond(), and write_switch().

static void print_host_wide_int ( )
static
Emit a HOST_WIDE_INT 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, HOST_WIDE_INT, and HOST_WIDE_INT_PRINT_DEC_C.

Referenced by write_cond(), and write_switch().

static void simplify_tests ( )
static
After factoring, try to simplify the tests on any one node.
   Tests that are useful for switch statements are recognizable
   by having only a single test on a node -- we'll be manipulating
   nodes with multiple tests:

   If we have mode tests or code tests that are redundant with
   predicates, remove them.   

References DT_code, DT_mode, DT_pred, decision_head::first, decision_test::next, decision::next, decision::success, decision::tests, and decision_test::type.

Referenced by process_tree().

static void validate_pattern ( )
static
Check for various errors in patterns.  SET is nonnull for a destination,
   and is the complete set pattern.  SET_CODE is '=' for normal sets, and
   '+' within a context that requires in-out constraints.   

References pred_data::allows_non_const, pred_data::allows_non_lvalue, decision_test::code, error_with_line(), find_matching_operand(), find_operand(), len, lookup_predicate(), message_with_line(), pattern_lineno, rtx_name, SET, pred_data::special, and strstr().

Referenced by make_insn_sequence().

static void write_action ( struct decision p,
struct decision_test test,
int  depth,
int  uncond,
struct decision success,
enum routine_type  subroutine_type 
)
static
Emit code for one action.  The previous tests have succeeded;
   TEST is the last of the chain.  In the normal case we simply
   perform a state change.  For the `accept' tests we must do more work.   

References position::arg, position::base, DT_accept_insn, DT_accept_op, get_insn_name(), indent, decision_test::insn, decision::need_label, decision_test::next, decision::number, decision_test::opno, PEEPHOLE2, POS_PEEP2_INSN, decision::position, RECOG, SPLIT, position::type, decision_test::type, and decision_test::u.

Referenced by write_node().

static void write_afterward ( struct decision start,
struct decision afterward,
const char *  indent 
)
static
Emit code to cross an afterward link -- change state and branch.   

References change_state(), decision::number, decision::position, and decision::subroutine_number.

Referenced by write_switch(), and write_tree_1().

static void write_header ( void  )
static
Begin the output file.   

Referenced by main().

static int write_node ( struct decision p,
int  depth,
enum routine_type  subroutine_type 
)
static
Emit code for one node -- the conditional and the accompanying action.
   Return true if there is no fallthru path.   

References decision_test::code, DT_code, DT_const_int, DT_elt_zero_wide_safe, decision_head::first, decision_test::intval, is_unconditional(), decision_test::next, decision::success, decision::tests, decision_test::type, decision_test::u, write_action(), and write_cond().

Referenced by write_tree_1().

static void write_subroutine ( )
static
Write out a subroutine of type TYPE to do comparisons starting at
   node TREE.   

References decision_head::first, max_depth, PEEPHOLE2, RECOG, root_pos, SPLIT, decision::subroutine_number, and write_tree().

Referenced by process_tree(), and write_subroutines().

static void write_subroutines ( )
static
In break_out_subroutines, we discovered the boundaries for the
   subroutines, but did not write them out.  Do so now.   

References decision_head::first, decision::next, decision::subroutine_number, decision::success, and write_subroutine().

Referenced by process_tree().

static void write_tree ( struct decision_head head,
struct position prevpos,
enum routine_type  type,
int  initial 
)
static
Write out the decision tree starting at HEAD.  PREVPOS is the
   position at the node that branched to this node.   

References decision::afterward, change_state(), position::depth, decision_head::first, decision::need_label, decision::next, decision::number, decision::position, decision::subroutine_number, decision::success, and write_tree_1().

Referenced by write_subroutine().

static void write_tree_1 ( struct decision_head head,
int  depth,
enum routine_type  subroutine_type 
)
static

Variable Documentation

int max_depth
static
Record the highest depth we ever have so we know how many variables to
   allocate in each subroutine we make.   

Referenced by add_to_sequence(), want_inline_self_recursive_call_p(), and write_subroutine().

int next_insn_code
static
Next number to use as an insn_code.   

Referenced by main(), and make_insn_sequence().

int next_number
static
Next available node number for tree nodes.   

Referenced by new_decision().

int next_subroutine_number
static
int pattern_lineno
static
The line number of the start of the pattern currently being processed.   

Referenced by add_to_sequence(), main(), make_insn_sequence(), and validate_pattern().

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 add_to_sequence(), and make_insn_sequence().

struct position root_pos
static
The root position (x0).   

Referenced by add_to_sequence(), make_insn_sequence(), and write_subroutine().