aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2015-06-14 20:25:40 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2015-06-14 20:25:40 +0000
commit3beaff21f346c7f34bf45f7b56f2c1c880a91e31 (patch)
tree5c9473ab1cc9660cc825b2a8b95569ab4d1e7cc6 /gcc
parentb25b4ed2b7010c0d36474b4caf3f7fe1a094095c (diff)
downloadgcc-3beaff21f346c7f34bf45f7b56f2c1c880a91e31.zip
gcc-3beaff21f346c7f34bf45f7b56f2c1c880a91e31.tar.gz
gcc-3beaff21f346c7f34bf45f7b56f2c1c880a91e31.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/emit-rtl.c37
-rw-r--r--gcc/genemit.c99
-rw-r--r--gcc/gensupport.c34
-rw-r--r--gcc/gensupport.h2
-rw-r--r--gcc/rtl.c48
-rw-r--r--gcc/rtl.h1
7 files changed, 114 insertions, 117 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0f7eb1f..c9b156f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index e064d4e..e64ca4c 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 b6df49c..15ec081 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 dc73cf9..916fbc1 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 e254435..97f9a72 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 6341b69..346155e 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 394513e..967175c 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 */