From 3beaff21f346c7f34bf45f7b56f2c1c880a91e31 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 14 Jun 2015 20:25:40 +0000 Subject: [PATCH] rtl.h (classify_insn): Declare. gcc/ * rtl.h (classify_insn): Declare. * emit-rtl.c (classify_insn): Move to... * rtl.c: ...here and add generator support. * gensupport.h (get_emit_function, needs_barrier_p): Declare. * gensupport.c (get_emit_function, needs_barrier_p): New functions. * genemit.c (gen_emit_seq): New function. (gen_expand, gen_split): Use it. From-SVN: r224470 --- gcc/ChangeLog | 10 +++++ gcc/emit-rtl.c | 37 ------------------ gcc/genemit.c | 99 ++++++++++-------------------------------------- gcc/gensupport.c | 34 +++++++++++++++++ gcc/gensupport.h | 2 + gcc/rtl.c | 48 +++++++++++++++++++++++ gcc/rtl.h | 1 + 7 files changed, 114 insertions(+), 117 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f7eb1f631e..c9b156f2e8d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-06-14 Richard Sandiford + + * rtl.h (classify_insn): Declare. + * emit-rtl.c (classify_insn): Move to... + * rtl.c: ...here and add generator support. + * gensupport.h (get_emit_function, needs_barrier_p): Declare. + * gensupport.c (get_emit_function, needs_barrier_p): New functions. + * genemit.c (gen_emit_seq): New function. + (gen_expand, gen_split): Use it. + 2015-06-13 Patrick Palka * tree.c (make_vector_stat): Fix comment to state that the diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index e064d4ece10..e64ca4ceb4c 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -5304,43 +5304,6 @@ set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst) return NULL_RTX; } -/* Return an indication of which type of insn should have X as a body. - The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN. */ - -static enum rtx_code -classify_insn (rtx x) -{ - if (LABEL_P (x)) - return CODE_LABEL; - if (GET_CODE (x) == CALL) - return CALL_INSN; - if (ANY_RETURN_P (x)) - return JUMP_INSN; - if (GET_CODE (x) == SET) - { - if (SET_DEST (x) == pc_rtx) - return JUMP_INSN; - else if (GET_CODE (SET_SRC (x)) == CALL) - return CALL_INSN; - else - return INSN; - } - if (GET_CODE (x) == PARALLEL) - { - int j; - for (j = XVECLEN (x, 0) - 1; j >= 0; j--) - if (GET_CODE (XVECEXP (x, 0, j)) == CALL) - return CALL_INSN; - else if (GET_CODE (XVECEXP (x, 0, j)) == SET - && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx) - return JUMP_INSN; - else if (GET_CODE (XVECEXP (x, 0, j)) == SET - && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL) - return CALL_INSN; - } - return INSN; -} - /* Emit the rtl pattern X as an appropriate kind of insn. If X is a label, it is simply added into the insn chain. */ diff --git a/gcc/genemit.c b/gcc/genemit.c index b6df49cd959..15ec08192ba 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -268,6 +268,23 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used) } printf (")"); } + +/* Output code to emit the instruction patterns in VEC, with each element + becoming a separate instruction. USED is as for gen_exp. */ + +static void +gen_emit_seq (rtvec vec, char *used) +{ + for (int i = 0, len = GET_NUM_ELEM (vec); i < len; ++i) + { + rtx next = RTVEC_ELT (vec, i); + printf (" %s (", get_emit_function (next)); + gen_exp (next, DEFINE_EXPAND, used); + printf (");\n"); + if (needs_barrier_p (next)) + printf (" emit_barrier ();"); + } +} /* Generate the `gen_...' function for a DEFINE_INSN. */ @@ -475,49 +492,8 @@ gen_expand (rtx expand) printf (" }\n"); } - /* Output code to construct the rtl for the instruction bodies. - Use emit_insn to add them to the sequence being accumulated. - But don't do this if the user's code has set `no_more' nonzero. */ - used = XCNEWVEC (char, stats.num_operand_vars); - - for (i = 0; i < XVECLEN (expand, 1); i++) - { - rtx next = XVECEXP (expand, 1, i); - if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC) - || (GET_CODE (next) == PARALLEL - && ((GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC) - || ANY_RETURN_P (XVECEXP (next, 0, 0)))) - || ANY_RETURN_P (next)) - printf (" emit_jump_insn ("); - else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL) - || GET_CODE (next) == CALL - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL) - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == CALL)) - printf (" emit_call_insn ("); - else if (LABEL_P (next)) - printf (" emit_label ("); - else if (GET_CODE (next) == MATCH_OPERAND - || GET_CODE (next) == MATCH_DUP - || GET_CODE (next) == MATCH_OPERATOR - || GET_CODE (next) == MATCH_OP_DUP - || GET_CODE (next) == MATCH_PARALLEL - || GET_CODE (next) == MATCH_PAR_DUP - || GET_CODE (next) == PARALLEL) - printf (" emit ("); - else - printf (" emit_insn ("); - gen_exp (next, DEFINE_EXPAND, used); - printf (");\n"); - if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC - && GET_CODE (SET_SRC (next)) == LABEL_REF) - printf (" emit_barrier ();"); - } - + gen_emit_seq (XVEC (expand, 1), used); XDELETEVEC (used); /* Call `get_insns' to extract the list of all the @@ -601,44 +577,7 @@ gen_split (rtx split) printf (" (void) operand%d;\n", i); } - /* Output code to construct the rtl for the instruction bodies. - Use emit_insn to add them to the sequence being accumulated. - But don't do this if the user's code has set `no_more' nonzero. */ - - for (i = 0; i < XVECLEN (split, 2); i++) - { - rtx next = XVECEXP (split, 2, i); - if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC) - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC) - || ANY_RETURN_P (next)) - printf (" emit_jump_insn ("); - else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL) - || GET_CODE (next) == CALL - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == SET - && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL) - || (GET_CODE (next) == PARALLEL - && GET_CODE (XVECEXP (next, 0, 0)) == CALL)) - printf (" emit_call_insn ("); - else if (LABEL_P (next)) - printf (" emit_label ("); - else if (GET_CODE (next) == MATCH_OPERAND - || GET_CODE (next) == MATCH_OPERATOR - || GET_CODE (next) == MATCH_PARALLEL - || GET_CODE (next) == MATCH_OP_DUP - || GET_CODE (next) == MATCH_DUP - || GET_CODE (next) == PARALLEL) - printf (" emit ("); - else - printf (" emit_insn ("); - gen_exp (next, GET_CODE (split), used); - printf (");\n"); - if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC - && GET_CODE (SET_SRC (next)) == LABEL_REF) - printf (" emit_barrier ();"); - } + gen_emit_seq (XVEC (split, 2), used); /* Call `get_insns' to make a list of all the insns emitted within this gen_... function. */ diff --git a/gcc/gensupport.c b/gcc/gensupport.c index dc73cf9ae17..916fbc10b92 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -2982,3 +2982,37 @@ get_pattern_stats (struct pattern_stats *stats, rtvec pattern) MAX (stats->max_dup_opno, stats->max_scratch_opno)) + 1; } + +/* Return the emit_* function that should be used for pattern X. */ + +const char * +get_emit_function (rtx x) +{ + switch (classify_insn (x)) + { + case INSN: + return "emit_insn"; + + case CALL_INSN: + return "emit_call_insn"; + + case JUMP_INSN: + return "emit_jump_insn"; + + case UNKNOWN: + return "emit"; + + default: + gcc_unreachable (); + } +} + +/* Return true if we must emit a barrier after pattern X. */ + +bool +needs_barrier_p (rtx x) +{ + return (GET_CODE (x) == SET + && GET_CODE (SET_DEST (x)) == PC + && GET_CODE (SET_SRC (x)) == LABEL_REF); +} diff --git a/gcc/gensupport.h b/gcc/gensupport.h index e2544353d93..97f9a72b100 100644 --- a/gcc/gensupport.h +++ b/gcc/gensupport.h @@ -111,5 +111,7 @@ struct pattern_stats extern void get_pattern_stats (struct pattern_stats *ranges, rtvec vec); extern void compute_test_codes (rtx, int, char *); +extern const char *get_emit_function (rtx); +extern bool needs_barrier_p (rtx); #endif /* GCC_GENSUPPORT_H */ diff --git a/gcc/rtl.c b/gcc/rtl.c index 6341b69c60d..346155e9faf 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -657,6 +657,54 @@ rtx_equal_p (const_rtx x, const_rtx y) return 1; } +/* Return an indication of which type of insn should have X as a body. + In generator files, this can be UNKNOWN if the answer is only known + at (GCC) runtime. Otherwise the value is CODE_LABEL, INSN, CALL_INSN + or JUMP_INSN. */ + +enum rtx_code +classify_insn (rtx x) +{ + if (LABEL_P (x)) + return CODE_LABEL; + if (GET_CODE (x) == CALL) + return CALL_INSN; + if (ANY_RETURN_P (x)) + return JUMP_INSN; + if (GET_CODE (x) == SET) + { + if (GET_CODE (SET_DEST (x)) == PC) + return JUMP_INSN; + else if (GET_CODE (SET_SRC (x)) == CALL) + return CALL_INSN; + else + return INSN; + } + if (GET_CODE (x) == PARALLEL) + { + int j; + for (j = XVECLEN (x, 0) - 1; j >= 0; j--) + if (GET_CODE (XVECEXP (x, 0, j)) == CALL) + return CALL_INSN; + else if (GET_CODE (XVECEXP (x, 0, j)) == SET + && GET_CODE (SET_DEST (XVECEXP (x, 0, j))) == PC) + return JUMP_INSN; + else if (GET_CODE (XVECEXP (x, 0, j)) == SET + && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL) + return CALL_INSN; + } +#ifdef GENERATOR_FILE + if (GET_CODE (x) == MATCH_OPERAND + || GET_CODE (x) == MATCH_OPERATOR + || GET_CODE (x) == MATCH_PARALLEL + || GET_CODE (x) == MATCH_OP_DUP + || GET_CODE (x) == MATCH_DUP + || GET_CODE (x) == PARALLEL) + return UNKNOWN; +#endif + return INSN; +} + void dump_rtx_statistics (void) { diff --git a/gcc/rtl.h b/gcc/rtl.h index 394513ea8a4..967175cd6e6 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2666,6 +2666,7 @@ extern rtvec rtvec_alloc (int); extern rtvec shallow_copy_rtvec (rtvec); extern bool shared_const_p (const_rtx); extern rtx copy_rtx (rtx); +extern enum rtx_code classify_insn (rtx); extern void dump_rtx_statistics (void); /* In emit-rtl.c */ -- 2.30.2