public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Rask Ingemann Lambertsen <rask@sygehus.dk>
To: "H. Peter Anvin" <hpa@zytor.com>
Cc: Uros Bizjak <ubizjak@gmail.com>,
	GCC Patches <gcc-patches@gcc.gnu.org>,
	        Jan Hubicka <jh@suse.cz>,
	Richard Kenner <kenner@vlsi1.ultra.nyu.edu>,
	        rridge@csclub.uwaterloo.ca
Subject: Real-mode i386 back end (Was: New back end ia16: 16-bit Intel x86)
Date: Tue, 21 Aug 2007 18:56:00 -0000	[thread overview]
Message-ID: <20070821185424.GP25795@sygehus.dk> (raw)
In-Reply-To: <46CB248E.4010000@zytor.com>

On Tue, Aug 21, 2007 at 10:44:46AM -0700, H. Peter Anvin wrote:
> The issue, rather, is the following error, which I haven't figured out
> the best way to address yet (mostly due to only running into it late
> last week):
> 
> /home/hpa/kernel/test-gcc16/arch/i386/boot/video.c:461: internal
> compiler error: in find_valid_class, at reload.c:699
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <URL:http://gcc.gnu.org/bugs.html> for instructions.
> 
> It happens mostly when compiling code which has previously been built
> with .code16gcc, so I'm using -mint32.
> 
> It looks like it calls find_valid_class with (outer=HImode,
> inner=SImode, n=1), however:
> 
> /* Find the largest class which has at least one register valid in
>    mode INNER, and which for every such register, that register number
>    plus N is also valid in OUTER (if in range) and is cheap to move
>    into REGNO.  Such a class must exist.  */
> 
> This does, however, cause trouble since we only allow SImode and HImode
> values in even registers; the odd registers being the upper half of a
> register.  Other than that, we're down to generating valid code for a
> fair number of the things I throw at it.

   This patch was once needed for my ia16 back end, but these days,
find_valid_class() isn't called any more. The problems with
find_valid_class() are still latent, though. The three problems I recall
being:

1) Assuming you can pass in a subreg_regno_offset and use it for any
register.
2) Not counting the number of registers in the class right.
3) Something about not checking HARD_REGNO_MODE_OK() enough.

   I'd like to know if the patch fixes your problem.

Index: reload.c
===================================================================
--- reload.c	(revision 126653)
+++ reload.c	(working copy)
@@ -252,7 +252,7 @@ static int push_secondary_reload (int, r
 				  enum machine_mode, enum reload_type,
 				  enum insn_code *, secondary_reload_info *);
 static enum reg_class find_valid_class (enum machine_mode, enum machine_mode,
-					int, unsigned int);
+					int, unsigned int, enum machine_mode);
 static int reload_inner_reg_of_subreg (rtx, enum machine_mode, int);
 static void push_replacement (rtx *, int, enum machine_mode);
 static void dup_replacements (rtx *, rtx *);
@@ -650,13 +650,15 @@ clear_secondary_mem (void)
 
 /* Find the largest class which has at least one register valid in
    mode INNER, and which for every such register, that register number
-   plus N is also valid in OUTER (if in range) and is cheap to move
-   into REGNO.  Such a class must exist.  */
+   plus subreg_regno_offset (regnum, INNER, OFFSET, OUTER2) is also valid
+   in OUTER (if in range) and is cheap to move into REGNO.
+   Such a class must exist.  */
 
 static enum reg_class
 find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
-		  enum machine_mode inner ATTRIBUTE_UNUSED, int n,
-		  unsigned int dest_regno ATTRIBUTE_UNUSED)
+		  enum machine_mode inner ATTRIBUTE_UNUSED, int offset,
+		  unsigned int dest_regno ATTRIBUTE_UNUSED,
+		  enum machine_mode outer2)
 {
   int best_cost = -1;
   int class;
@@ -666,16 +668,30 @@ find_valid_class (enum machine_mode oute
   unsigned int best_size = 0;
   int cost;
 
+  gcc_assert (outer2 == outer);
+
   for (class = 1; class < N_REG_CLASSES; class++)
     {
       int bad = 0;
       int good = 0;
-      for (regno = 0; regno < FIRST_PSEUDO_REGISTER - n && ! bad; regno++)
+      unsigned int nregs;
+      unsigned int class_size = 0;
+
+      for (regno = 0, nregs = hard_regno_nregs[0][inner];
+	   ((!HARD_REGNO_MODE_OK (regno, inner) && regno < FIRST_PSEUDO_REGISTER)
+	      || regno + nregs - 1 < FIRST_PSEUDO_REGISTER)
+	   && !bad;
+	   nregs = hard_regno_nregs[++regno][inner])
 	if (TEST_HARD_REG_BIT (reg_class_contents[class], regno))
 	  {
-	    if (HARD_REGNO_MODE_OK (regno, inner))
+	    /* We ought to check all registers [regno; regno + nregs - 1]. */
+	    /* nregs is bogus if ! HARD_REGNO_MODE_OK(). */
+	    if (HARD_REGNO_MODE_OK (regno, inner)
+	        && TEST_HARD_REG_BIT (reg_class_contents[class], regno + nregs - 1))
 	      {
+		int n = subreg_regno_offset (regno, inner, offset, outer);
 		good = 1;
+		class_size ++;
 		if (! TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
 		    || ! HARD_REGNO_MODE_OK (regno + n, outer))
 		  bad = 1;
@@ -686,18 +703,25 @@ find_valid_class (enum machine_mode oute
 	continue;
       cost = REGISTER_MOVE_COST (outer, class, dest_class);
 
-      if ((reg_class_size[class] > best_size
+      if ((class_size > best_size
 	   && (best_cost < 0 || best_cost >= cost))
 	  || best_cost > cost)
 	{
 	  best_class = class;
-	  best_size = reg_class_size[class];
+	  best_size = class_size;
 	  best_cost = REGISTER_MOVE_COST (outer, class, dest_class);
 	}
     }
 
   gcc_assert (best_size != 0);
 
+  {
+    FILE *log;
+    log = fopen ("/tmp/find_valid_class_log", "a");
+    fprintf (log, "(%s, %s, %d, %d) = %s\n", GET_MODE_NAME (outer),
+	     GET_MODE_NAME (inner), offset, dest_regno, reg_class_names[best_class]);
+    fclose (log);
+  }
   return best_class;
 }
 \f
@@ -1079,11 +1103,8 @@ push_reload (rtx in, rtx out, rtx *inloc
       if (REG_P (SUBREG_REG (in)))
 	in_class
 	  = find_valid_class (inmode, GET_MODE (SUBREG_REG (in)),
-			      subreg_regno_offset (REGNO (SUBREG_REG (in)),
-						   GET_MODE (SUBREG_REG (in)),
-						   SUBREG_BYTE (in),
-						   GET_MODE (in)),
-			      REGNO (SUBREG_REG (in)));
+			      SUBREG_BYTE (in), REGNO (SUBREG_REG (in)),
+			      GET_MODE (in));
 
       /* This relies on the fact that emit_reload_insns outputs the
 	 instructions for input reloads of type RELOAD_OTHER in the same
@@ -1173,11 +1194,8 @@ push_reload (rtx in, rtx out, rtx *inloc
       push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
 		   &SUBREG_REG (out),
 		   find_valid_class (outmode, GET_MODE (SUBREG_REG (out)),
-				     subreg_regno_offset (REGNO (SUBREG_REG (out)),
-							  GET_MODE (SUBREG_REG (out)),
-							  SUBREG_BYTE (out),
-							  GET_MODE (out)),
-				     REGNO (SUBREG_REG (out))),
+				     SUBREG_BYTE (out),
+				     REGNO (SUBREG_REG (out)), GET_MODE (out)),
 		   VOIDmode, VOIDmode, 0, 0,
 		   opnum, RELOAD_OTHER);
     }

-- 
Rask Ingemann Lambertsen

  reply	other threads:[~2007-08-21 18:54 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-06 14:23 New back end ia16: 16-bit Intel x86 Uros Bizjak
2007-08-07  1:29 ` Rask Ingemann Lambertsen
2007-08-07 17:37   ` Daniel Jacobowitz
2007-08-07 20:03   ` Uros Bizjak
2007-08-08 12:21     ` Jan Hubicka
2007-08-08 17:30       ` Mark Mitchell
2007-08-08 23:22         ` Richard Kenner
2007-08-08 18:52       ` Rask Ingemann Lambertsen
2007-08-08 20:24         ` Michael Matz
2007-08-08 20:59         ` H.J. Lu
2007-08-08 22:46           ` DJ Delorie
2007-08-09  9:33         ` Jan Hubicka
2007-08-09 14:01           ` Rask Ingemann Lambertsen
2007-08-09 15:43           ` DJ Delorie
2007-08-08 15:28     ` Rask Ingemann Lambertsen
2007-08-17 22:38       ` H. Peter Anvin
2007-08-18  2:34         ` Rask Ingemann Lambertsen
2007-08-18  5:33           ` H. Peter Anvin
2007-08-18 17:36             ` Rask Ingemann Lambertsen
2007-08-18 17:50               ` H. Peter Anvin
2007-08-18 20:39                 ` Rask Ingemann Lambertsen
2007-08-19  2:11                   ` H. Peter Anvin
2007-08-19 12:25                     ` Rask Ingemann Lambertsen
2007-08-19 20:07                       ` H. Peter Anvin
2007-08-21  8:48                       ` H. Peter Anvin
2007-08-21 14:35                         ` Rask Ingemann Lambertsen
2007-08-21 17:46                           ` H. Peter Anvin
2007-08-21 18:56                             ` Rask Ingemann Lambertsen [this message]
2007-08-19  7:29                   ` H. Peter Anvin
2007-08-19 10:56                     ` Rask Ingemann Lambertsen
2007-08-19 21:40                       ` H. Peter Anvin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070821185424.GP25795@sygehus.dk \
    --to=rask@sygehus.dk \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hpa@zytor.com \
    --cc=jh@suse.cz \
    --cc=kenner@vlsi1.ultra.nyu.edu \
    --cc=rridge@csclub.uwaterloo.ca \
    --cc=ubizjak@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).