PATCH: Support more than 2 relaxation passes

H. J. Lu hjl@lucon.org
Wed Mar 8 19:38:00 GMT 2006


I need to run more than 2 relaxation passes. This patch allows a
backend to have more than 2 relaxation passes.


H.J.
----
bfd/

2006-03-08  H.J. Lu  <hongjiu.lu@intel.com>

	* elfxx-ia64.c (elfNN_ia64_relax_section): Check relax_pass
	instead of need_relax_finalize.

include/

2006-03-08  H.J. Lu  <hongjiu.lu@intel.com>

	* bfdlink.h (bfd_link_info): Replace need_relax_finalize with
	relax_pass.

ld/

2006-03-08  H.J. Lu  <hongjiu.lu@intel.com>

	* emultempl/ia64elf.em: Set link_info.relax_pass to 2. Remove
	link_info.need_relax_finalize.

	* ldlang.c (relax_sections): New.
	(lang_process): Use. Call relax_sections link_info.relax_pass
	times.

	* ldmain.c (main): Set link_info.relax_pass to 1. Remove
	link_info.need_relax_finalize.

--- binutils/bfd/elfxx-ia64.c.relax	2006-03-08 09:54:49.000000000 -0800
+++ binutils/bfd/elfxx-ia64.c	2006-03-08 10:55:34.000000000 -0800
@@ -894,7 +894,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
      the relax finalize pass.  */
   if ((sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
-      || (!link_info->need_relax_finalize
+      || (link_info->relax_pass == 1
 	  && sec->need_finalize_relax == 0))
     return TRUE;
 
@@ -938,7 +938,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
 	case R_IA64_PCREL21F:
 	  /* In the finalize pass, all br relaxations are done. We can
 	     skip it. */
-	  if (!link_info->need_relax_finalize)
+	  if (link_info->relax_pass == 1)
 	    continue;
 	  is_branch = TRUE;
 	  break;
@@ -947,7 +947,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
 	  /* We can't optimize brl to br before the finalize pass since
 	     br relaxations will increase the code size. Defer it to
 	     the finalize pass.  */
-	  if (link_info->need_relax_finalize)
+	  if (link_info->relax_pass == 0)
 	    {
 	      sec->need_finalize_relax = 1;
 	      continue;
@@ -960,7 +960,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
 	  /* We can't relax ldx/mov before the finalize pass since
 	     br relaxations will increase the code size. Defer it to
 	     the finalize pass.  */
-	  if (link_info->need_relax_finalize)
+	  if (link_info->relax_pass == 0)
 	    {
 	      sec->need_finalize_relax = 1;
 	      continue;
@@ -1352,7 +1352,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
 	}
     }
 
-  if (!link_info->need_relax_finalize)
+  if (link_info->relax_pass == 1)
     sec->need_finalize_relax = 0;
 
   *again = changed_contents || changed_relocs;
--- binutils/include/bfdlink.h.relax	2005-11-04 11:38:00.000000000 -0800
+++ binutils/include/bfdlink.h	2006-03-08 10:54:01.000000000 -0800
@@ -301,9 +301,6 @@ struct bfd_link_info
   /* TRUE if global symbols in discarded sections should be stripped.  */
   unsigned int strip_discarded: 1;
 
-  /* TRUE if the final relax pass is needed.  */
-  unsigned int need_relax_finalize: 1;
-
   /* TRUE if generating a position independent executable.  */
   unsigned int pie: 1;
 
@@ -398,6 +395,9 @@ struct bfd_link_info
      unloaded.  */
   const char *fini_function;
 
+  /* Number of relaxation passes.  */
+  int relax_pass;
+
   /* Non-zero if auto-import thunks for DATA items in pei386 DLLs
      should be generated/linked against.  Set to 1 if this feature
      is explicitly requested by the user, -1 if enabled by default.  */
--- binutils/ld/emultempl/ia64elf.em.relax	2005-05-16 11:04:41.000000000 -0700
+++ binutils/ld/emultempl/ia64elf.em	2006-03-08 10:54:09.000000000 -0800
@@ -32,7 +32,7 @@ static int itanium = 0;
 static void
 gld${EMULATION_NAME}_after_parse (void)
 {
-  link_info.need_relax_finalize = TRUE;
+  link_info.relax_pass = 2;
   bfd_elf${ELFSIZE}_ia64_after_parse (itanium);
 }
 
--- binutils/ld/ldlang.c.relax	2005-12-24 08:17:33.000000000 -0800
+++ binutils/ld/ldlang.c	2006-03-08 11:22:28.000000000 -0800
@@ -5384,6 +5384,35 @@ lang_gc_sections (void)
     bfd_gc_sections (output_bfd, &link_info);
 }
 
+static void
+relax_sections (void)
+{
+  /* Keep relaxing until bfd_relax_section gives up.  */
+  bfd_boolean relax_again;
+
+  do
+    {
+      relax_again = FALSE; 
+
+      /* Note: pe-dll.c does something like this also.  If you find
+	 you need to change this code, you probably need to change
+	 pe-dll.c also.  DJ  */
+
+      /* Do all the assignments with our current guesses as to
+	 section sizes.  */
+      lang_do_assignments ();
+
+      /* We must do this after lang_do_assignments, because it uses
+	 size.  */
+      lang_reset_memory_regions ();
+
+      /* Perform another relax pass - this time we know where the
+	 globals are, so can make a better guess.  */
+      lang_size_sections (&relax_again, FALSE);
+    }
+  while (relax_again);
+}
+
 void
 lang_process (void)
 {
@@ -5480,38 +5509,17 @@ lang_process (void)
   /* Now run around and relax if we can.  */
   if (command_line.relax)
     {
-      /* Keep relaxing until bfd_relax_section gives up.  */
-      bfd_boolean relax_again;
+      /* We may need more than one relaxation pass.  */
+      int i = link_info.relax_pass;
 
-      do
-	{
-	  relax_again = FALSE;
+      /* The backend can use it to determine the current pass.  */
+      link_info.relax_pass = 0;
 
-	  /* Note: pe-dll.c does something like this also.  If you find
-	     you need to change this code, you probably need to change
-	     pe-dll.c also.  DJ  */
-
-	  /* Do all the assignments with our current guesses as to
-	     section sizes.  */
-	  lang_do_assignments ();
-
-	  /* We must do this after lang_do_assignments, because it uses
-	     size.  */
-	  lang_reset_memory_regions ();
-
-	  /* Perform another relax pass - this time we know where the
-	     globals are, so can make a better guess.  */
-	  lang_size_sections (&relax_again, FALSE);
-
-	  /* If the normal relax is done and the relax finalize pass
-	     is not performed yet, we perform another relax pass.  */
-	  if (!relax_again && link_info.need_relax_finalize)
-	    {
-	      link_info.need_relax_finalize = FALSE;
-	      relax_again = TRUE;
-	    }
+      while (i--)
+	{
+	  relax_sections ();
+	  link_info.relax_pass++;
 	}
-      while (relax_again);
 
       /* Final extra sizing to report errors.  */
       lang_do_assignments ();
--- binutils/ld/ldmain.c.relax	2005-11-11 10:48:53.000000000 -0800
+++ binutils/ld/ldmain.c	2006-03-08 10:56:54.000000000 -0800
@@ -313,7 +313,7 @@ main (int argc, char **argv)
   link_info.spare_dynamic_tags = 5;
   link_info.flags = 0;
   link_info.flags_1 = 0;
-  link_info.need_relax_finalize = FALSE;
+  link_info.relax_pass = 1;
   link_info.warn_shared_textrel = FALSE;
   link_info.gc_sections = FALSE;
 



More information about the Binutils mailing list