This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix pattern validation in genrecog


Thomas pointed out that, while I'd kept the code to validate patterns
for things like missing modes, the code wasn't being used.  Fixed with
the patch below.

I ended up reinstating the original code to create a single rtx
pattern for a define_peephole2 sequence, so that it could be
passed to validate_pattern as before.  One of the reasons I got
rid of the code originally was because I didn't like the idea of
a sequence of define_peephole2 instructions being put into a
PARALLEL -- there's nothing parallel about them, and it would be
easy to confuse the result with a "real" parallel in a define_insn
or define_split match.  I therefore changed it to use SEQUENCE instead.
(Not that it matters: nothing actually looks at the code.)

I also threw in a check for zero-length define_peephole2s while there.
This is enforced syntactically for other define_*s, but it's possible
to write a define_peephole2 that just asks for scratch registers and
doesn't actually match anything.

Tested on x86_64-linux-gnu.  OK to install?

Thanks,
Richard


gcc/
	* genrecog.c (match_pattern_1): Expect the pattern to be a SEQUENCE
	for define_peephole2s.
	(get_peephole2_pattern): New function.
	(main): Use it.  Call validate_pattern.

Index: gcc/genrecog.c
===================================================================
--- gcc/genrecog.c	2015-05-10 10:45:41.750134123 +0100
+++ gcc/genrecog.c	2015-05-10 10:45:41.746134173 +0100
@@ -4080,14 +4080,14 @@ match_pattern_2 (state *s, rtx top_patte
    (2) the rtx matches TOP_PATTERN and
    (3) C_TEST is true.
 
-   For peephole2, TOP_PATTERN is the DEFINE_PEEPHOLE2 itself, otherwise
-   it is the rtx pattern to match (PARALLEL, SET, etc.).  */
+   For peephole2, TOP_PATTERN is a SEQUENCE of the instruction patterns
+   to match, otherwise it is a single instruction pattern.  */
 
 static void
 match_pattern_1 (state *s, rtx top_pattern, const char *c_test,
 		 acceptance_type acceptance)
 {
-  if (GET_CODE (top_pattern) == DEFINE_PEEPHOLE2)
+  if (acceptance.type == PEEPHOLE2)
     {
       /* Match each individual instruction.  */
       position **subpos_ptr = &peep2_insn_pos_list;
@@ -4095,18 +4095,14 @@ match_pattern_1 (state *s, rtx top_patte
       for (int i = 0; i < XVECLEN (top_pattern, 0); ++i)
 	{
 	  rtx x = XVECEXP (top_pattern, 0, i);
-	  /* Ignore scratch register requirements.  */
-	  if (GET_CODE (x) != MATCH_SCRATCH && GET_CODE (x) != MATCH_DUP)
-	    {
-	      position *subpos = next_position (subpos_ptr, &root_pos,
-						POS_PEEP2_INSN, count);
-	      if (count > 0)
-		s = add_decision (s, rtx_test::peep2_count (count + 1),
-				  true, false);
-	      s = match_pattern_2 (s, top_pattern, subpos, x);
-	      subpos_ptr = &subpos->next;
-	      count += 1;
-	    }
+	  position *subpos = next_position (subpos_ptr, &root_pos,
+					    POS_PEEP2_INSN, count);
+	  if (count > 0)
+	    s = add_decision (s, rtx_test::peep2_count (count + 1),
+			      true, false);
+	  s = match_pattern_2 (s, top_pattern, subpos, x);
+	  subpos_ptr = &subpos->next;
+	  count += 1;
 	}
       acceptance.u.full.u.match_len = count - 1;
     }
@@ -5165,6 +5161,30 @@ add_implicit_parallel (rtvec vec)
     }
 }
 
+/* Return the rtx pattern for the list of rtxes in a define_peephole2.  */
+
+static rtx
+get_peephole2_pattern (rtvec vec)
+{
+  int i, j;
+  rtx pattern = rtx_alloc (SEQUENCE);
+  XVEC (pattern, 0) = rtvec_alloc (GET_NUM_ELEM (vec));
+  for (i = j = 0; i < GET_NUM_ELEM (vec); i++)
+    {
+      rtx x = RTVEC_ELT (vec, i);
+      /* Ignore scratch register requirements.  */
+      if (GET_CODE (x) != MATCH_SCRATCH && GET_CODE (x) != MATCH_DUP)
+	{
+	  XVECEXP (pattern, 0, j) = x;
+	  j++;
+	}
+    }
+  XVECLEN (pattern, 0) = j;
+  if (j == 0)
+    error_with_line (pattern_lineno, "empty define_peephole2");
+  return pattern;
+}
+
 /* Return true if *PATTERN_PTR is a PARALLEL in which at least one trailing
    rtx can be added automatically by add_clobbers.  If so, update
    *ACCEPTANCE_PTR so that its num_clobbers field contains the number
@@ -5231,20 +5251,20 @@ main (int argc, char **argv)
       if (desc == NULL)
 	break;
 
-      rtx pattern;
-
       acceptance_type acceptance;
       acceptance.partial_p = false;
       acceptance.u.full.code = next_insn_code;
 
+      rtx pattern;
       switch (GET_CODE (desc))
 	{
 	case DEFINE_INSN:
 	  {
 	    /* Match the instruction in the original .md form.  */
-	    pattern = add_implicit_parallel (XVEC (desc, 1));
 	    acceptance.type = RECOG;
 	    acceptance.u.full.u.num_clobbers = 0;
+	    pattern = add_implicit_parallel (XVEC (desc, 1));
+	    validate_pattern (pattern, desc, NULL_RTX, 0);
 	    match_pattern (&insn_root, pattern, XSTR (desc, 2), acceptance);
 
 	    /* If the pattern is a PARALLEL with trailing CLOBBERs,
@@ -5258,6 +5278,7 @@ main (int argc, char **argv)
 	case DEFINE_SPLIT:
 	  acceptance.type = SPLIT;
 	  pattern = add_implicit_parallel (XVEC (desc, 0));
+	  validate_pattern (pattern, desc, NULL_RTX, 0);
 	  match_pattern (&split_root, pattern, XSTR (desc, 1), acceptance);
 
 	  /* Declare the gen_split routine that we'll call if the
@@ -5268,7 +5289,9 @@ main (int argc, char **argv)
 
 	case DEFINE_PEEPHOLE2:
 	  acceptance.type = PEEPHOLE2;
-	  match_pattern (&peephole2_root, desc, XSTR (desc, 1), acceptance);
+	  pattern = get_peephole2_pattern (XVEC (desc, 0));
+	  validate_pattern (pattern, desc, NULL_RTX, 0);
+	  match_pattern (&peephole2_root, pattern, XSTR (desc, 1), acceptance);
 
 	  /* Declare the gen_peephole2 routine that we'll call if the
 	     pattern matches.  The definition comes from insn-emit.c.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]