bfd/
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 6 Apr 2006 18:52:46 +0000 (18:52 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 6 Apr 2006 18:52:46 +0000 (18:52 +0000)
2006-04-06  H.J. Lu  <hongjiu.lu@intel.com>

* elfxx-ia64.c (elfNN_ia64_relax_section): Skip unneeded passes
with the skip_relax_pass_0 and skip_relax_pass_1 bits in the
section structure.

include/

2006-04-06  H.J. Lu  <hongjiu.lu@intel.com>

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

ld/

2006-04-06  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.

bfd/ChangeLog
bfd/elfxx-ia64.c
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/emultempl/ia64elf.em
ld/ldlang.c
ld/ldmain.c

index 97794afeb4be5a519b3a30f0beff38132366a27b..30fec772e6748f5050364f2385503235ffcb1135 100644 (file)
@@ -1,3 +1,9 @@
+2006-04-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * elfxx-ia64.c (elfNN_ia64_relax_section): Skip unneeded passes
+       with the skip_relax_pass_0 and skip_relax_pass_1 bits in the
+       section structure.
+
 2006-04-05  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * elf32-bfin.c (bfinfdpic_relocs_info_hash): Sprinkle casts to
index 8d3d5d7e53ee5d36e86abb916272bdcbd3a38a71..6b3257afdf133e75858c64d4c5b99628b7d26c58 100644 (file)
@@ -863,6 +863,12 @@ elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
   bfd_putl64 (t0, hit_addr);
   bfd_putl64 (t1, hit_addr + 8);
 }
+
+/* Rename some of the generic section flags to better document how they
+   are used here.  */
+#define skip_relax_pass_0 need_finalize_relax
+#define skip_relax_pass_1 has_gp_reloc
+
 \f
 /* These functions do relaxation for IA-64 ELF.  */
 
@@ -891,6 +897,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
   bfd_boolean changed_contents = FALSE;
   bfd_boolean changed_relocs = FALSE;
   bfd_boolean changed_got = FALSE;
+  bfd_boolean skip_relax_pass_0 = TRUE;
+  bfd_boolean skip_relax_pass_1 = TRUE;
   bfd_vma gp = 0;
 
   /* Assume we're not going to change any sizes, and we'll only need
@@ -902,11 +910,11 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
     return FALSE;
 
   /* Nothing to do if there are no relocations or there is no need for
-     the relax finalize pass.  */
+     the current pass.  */
   if ((sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
-      || (!link_info->need_relax_finalize
-         && sec->need_finalize_relax == 0))
+      || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
+      || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
     return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@@ -947,20 +955,19 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
        case R_IA64_PCREL21BI:
        case R_IA64_PCREL21M:
        case R_IA64_PCREL21F:
-         /* In the finalize pass, all br relaxations are done. We can
-            skip it. */
-         if (!link_info->need_relax_finalize)
+         /* In pass 1, all br relaxations are done. We can skip it. */
+         if (link_info->relax_pass == 1)
            continue;
+         skip_relax_pass_0 = FALSE;
          is_branch = TRUE;
          break;
 
        case R_IA64_PCREL60B:
-         /* 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)
+         /* We can't optimize brl to br in pass 0 since br relaxations
+            will increase the code size. Defer it to pass 1.  */
+         if (link_info->relax_pass == 0)
            {
-             sec->need_finalize_relax = 1;
+             skip_relax_pass_1 = FALSE;
              continue;
            }
          is_branch = TRUE;
@@ -968,12 +975,11 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
 
        case R_IA64_LTOFF22X:
        case R_IA64_LDXMOV:
-         /* 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)
+         /* We can't relax ldx/mov in pass 0 since br relaxations will
+            increase the code size. Defer it to pass 1.  */
+         if (link_info->relax_pass == 0)
            {
-             sec->need_finalize_relax = 1;
+             skip_relax_pass_1 = FALSE;
              continue;
            }
          is_branch = FALSE;
@@ -1363,8 +1369,12 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
        }
     }
 
-  if (!link_info->need_relax_finalize)
-    sec->need_finalize_relax = 0;
+  if (link_info->relax_pass == 0)
+    {
+      /* Pass 0 is only needed to relax br.  */
+      sec->skip_relax_pass_0 = skip_relax_pass_0;
+      sec->skip_relax_pass_1 = skip_relax_pass_1;
+    }
 
   *again = changed_contents || changed_relocs;
   return TRUE;
@@ -1380,6 +1390,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
     free (internal_relocs);
   return FALSE;
 }
+#undef skip_relax_pass_0
+#undef skip_relax_pass_1
 
 static void
 elfNN_ia64_relax_ldxmov (contents, off)
index 4af593fb88cd4c916f3029d614c9ade609fdbb80..af4eb6d7586290ec0f9b3ffb68322141a9014815 100644 (file)
@@ -1,3 +1,8 @@
+2006-04-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * bfdlink.h (bfd_link_info): Replace need_relax_finalize with
+       relax_pass.
+
 2006-03-25  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * elf/bfin.h (R_BFIN_GOT17M4, R_BFIN_GOTHI, R_BFIN_GOTLO,
index 3c978e80bfa978306e405de006a304ea0120bcb0..f4b7aa7cfa41b92070d8311570d68311963bc171 100644 (file)
@@ -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,12 @@ struct bfd_link_info
      unloaded.  */
   const char *fini_function;
 
+  /* Number of relaxation passes.  Usually only one relaxation pass
+     is needed.  But a backend can have as many relaxation passes as
+     necessary.  During bfd_relax_section call, it is set to the
+     current pass, starting from 0.  */
+  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.  */
index 300fb6b5ee296289fb96a210d039f6a780240121..f68e6a334ed1e0e4b698649226024925b6d599c4 100644 (file)
@@ -1,3 +1,15 @@
+2006-04-06  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.
+
 2006-04-05  Alan Modra  <amodra@bigpond.net.au>
 
        * Makefile.am (GENSCRIPTS): Pass prefix.
index d41fa00441a719ee659ea95e557188386ecdb5fa..ddc5370bfd99f1e168d624ba205153c88bf2923b 100644 (file)
@@ -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);
 }
 
index 66219f0bc3feddd2c2fce0ce5d2a8152c46094e5..8d4d9e9572b552644533878ef8cb5793801cedb6 100644 (file)
@@ -5411,6 +5411,37 @@ lang_gc_sections (void)
     bfd_gc_sections (output_bfd, &link_info);
 }
 
+/* Relax all sections until bfd_relax_section gives up.  */
+
+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)
 {
@@ -5507,38 +5538,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;
-
-      do
-       {
-         relax_again = FALSE;
+      /* We may need more than one relaxation pass.  */
+      int i = link_info.relax_pass;
 
-         /* 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  */
+      /* The backend can use it to determine the current pass.  */
+      link_info.relax_pass = 0;
 
-         /* 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 ();
index 3093bdb00c5ae50d6dff339f3aea7acc9039c2c3..db87a40b6aa74e5fb91d9270e0002735ed5f5b19 100644 (file)
@@ -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;