GCC Middle and Back End API 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 position * | next_position (struct position **next_ptr, struct position *base, enum position_type type, int arg) |
static int | compare_positions () |
static struct decision * | new_decision () |
static struct decision_test * | new_decision_test () |
static rtx | find_operand () |
static rtx | find_matching_operand () |
static void | validate_pattern () |
static struct decision * | add_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 decision * | write_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 position * | peep2_insn_pos_list = &root_pos |
enum decision_type |
enum position_type |
enum routine_type |
|
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 |
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 |
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 |
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 |
References debug_decision_1(), decision_head::first, indent, decision::next, and decision::success.
Referenced by debug_decision(), and debug_decision_list().
|
static |
References decision::afterward, debug_decision_2(), indent, decision_test::next, decision::next, decision::number, and decision::tests.
Referenced by debug_decision_0().
|
static |
References decision_test::c_test, decision_test::code, DT_accept_insn, DT_accept_op, DT_c_test, 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, HOST_WIDE_INT_PRINT_DEC, decision_test::insn, decision_test::intval, memcpy(), decision_test::mode, decision_test::num_insns, decision_test::opno, decision_test::pred, decision_test::type, decision_test::u, and decision_test::veclen.
Referenced by debug_decision_1().
void debug_decision_list | ( | struct decision * | ) |
DEBUG_FUNCTION void debug_decision_list | ( | ) |
References debug_decision_0(), and decision::next.
|
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 |
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 |
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 |
Search for and return operand N, stop when reaching node STOP.
References decision_test::code, and len.
Referenced by validate_pattern().
|
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 ** | |||
) |
int main | ( | ) |
|
staticread |
Construct and return a sequence of decisions that will recognize INSN. TYPE says what type of routine we are recognizing (RECOG or SPLIT).
References add_to_sequence(), DT_accept_insn, DT_accept_op, DT_c_test, decision_head::last, maybe_eval_c_test(), memset(), merge_trees(), new_decision(), new_decision_test(), decision_test::next, next_insn_code, next_position(), pattern_lineno, peep2_insn_pos_list, PEEPHOLE2, POS_PEEP2_INSN, RECOG, root_pos, rtvec_alloc(), SPLIT, decision::success, decision::tests, and validate_pattern().
Referenced by main().
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 |
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 |
A subroutine of maybe_both_true; examines only one test. Returns > 0 for "definitely both true" and < 0 for "maybe both true".
References decision_test::code, d1, d2, DT_code, 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::intval, decision_test::mode, decision_test::num_insns, NUM_RTX_CODE, decision_test::pred, decision_test::type, decision_test::u, and decision_test::veclen.
Referenced by maybe_both_true_1().
|
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 |
Merge two decision trees OLDH and ADDH, modifying OLDH destructively.
References decision_head::first, decision_head::last, maybe_both_true(), merge_accept_insn(), decision::next, nodes_identical(), decision::position, decision::prev, decision::success, decision::tests, and decision_test::type.
Referenced by factor_tests(), main(), and make_insn_sequence().
|
staticread |
Create a new node in sequence after LAST.
References decision_head::first, last, decision_head::last, next_number, decision::number, decision::position, and decision::success.
Referenced by add_to_sequence(), factor_tests(), and make_insn_sequence().
|
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().
|
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 |
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 |
A subroutine of nodes_identical. Examine two tests for equivalence.
References decision_test::c_test, decision_test::code, DT_accept_insn, DT_accept_op, DT_c_test, 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_test::intval, decision_test::mode, decision_test::num_insns, decision_test::opno, decision_test::pred, decision_test::type, decision_test::u, and decision_test::veclen.
Referenced by nodes_identical(), and write_switch().
|
static |
Print the enumerator constant for CODE -- the upcase version of the name.
Referenced by write_cond(), and write_switch().
|
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 |
References break_out_subroutines(), factor_tests(), find_afterward(), decision_head::first, next_subroutine_number, PEEPHOLE2, simplify_tests(), write_subroutine(), and write_subroutines().
Referenced by main().
|
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 |
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 |
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 |
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 |
Emit code for one test.
References decision_test::c_test, decision_test::code, DT_accept_insn, DT_c_test, DT_code, DT_const_int, 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_test::insn, decision_test::intval, decision_test::mode, decision_test::num_insns, decision_test::pred, print_c_condition(), print_code(), print_host_wide_int(), RECOG, decision_test::type, decision_test::u, and decision_test::veclen.
Referenced by write_node().
|
static |
Begin the output file.
Referenced by main().
|
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 |
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 |
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().
|
staticread |
Emit a switch statement, if possible, for an initial sequence of nodes at START. Return the first node yet untested.
References decision::afterward, decision_test::code, pred_data::codes, DT_code, DT_elt_one_int, DT_elt_zero_int, DT_elt_zero_wide, DT_elt_zero_wide_safe, DT_mode, DT_pred, DT_veclen, decision_head::first, indent, decision_test::intval, memset(), decision_test::mode, decision::need_label, decision_test::next, decision::next, nodes_identical_1(), NUM_RTX_CODE, decision::number, decision_test::pred, print_code(), print_host_wide_int(), decision::success, decision::tests, decision_test::type, decision_test::u, decision_test::veclen, and write_afterward().
Referenced by write_tree_1().
|
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 |
Emit code for all of the sibling nodes of HEAD.
References decision::afterward, decision_head::first, decision_head::last, decision::need_label, decision::next, decision::number, write_afterward(), write_node(), and write_switch().
Referenced by write_tree().
|
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().
|
static |
Next number to use as an insn_code.
Referenced by main(), and make_insn_sequence().
|
static |
Next available node number for tree nodes.
Referenced by new_decision().
|
static |
Referenced by break_out_subroutines(), and process_tree().
|
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().
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().
|
static |
The root position (x0).
Referenced by add_to_sequence(), make_insn_sequence(), and write_subroutine().