Commit 3beaff21 by Richard Sandiford Committed by Richard Sandiford

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
parent b25b4ed2
2015-06-14 Richard Sandiford <richard.sandiford@arm.com>
* 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 <ppalka@gcc.gnu.org>
* tree.c (make_vector_stat): Fix comment to state that the
......
......@@ -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. */
......
......@@ -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. */
......
......@@ -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);
}
......@@ -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 */
......@@ -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)
{
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment