This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

minor ld speedup


This turns some multiplies and divides into shifts, helping to speed up
the linker a bit.  Also removes lots of bfd_arch_mach_octets_per_byte
calls, and removes an unused parameter from another function.

ld/ChangeLog
	* ldexp.c (align_n): Make static.
	* ldexp.h (align_n): Delete declaration.
	* ldlang.h (lang_enter_output_section_statement): Remove
	block_value param.
	* ldlang.c (lang_enter_output_section_statement): Likewise.
	(TO_ADDR, TO_SIZE): Define.
	(opb): New var.
	(init_opb): New function.
	(print_input_section): Call init_opb and use TO_ADDR.
	(print_data_statement, print_reloc_statement): Likewise.
	(print_padding_statement): Likewise.
	(size_input_section): Use TO_SIZE and TO_ADDR, and global opb.
	(lang_check_section_addresses): Likewise.
	(lang_size_sections_1): Likewise.
	(lang_do_assignments_1): Likewise.
	(lang_set_startof): Likewise.
	(lang_one_common): Likewise.  Combine power_of_two and opb alignment.
	(lang_process): Call init_opb.
	(lang_abs_symbol_at_end_of): Use TO_ADDR and global opb.
	(lang_enter_overlay_section): Adjust
	lang_enter_output_section_statement call.
	* ldgram.y: Likewise.
	* mri.c (mri_draw_tree): Likewise.
	* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Likewise.
	* emultempl/mmo.em (mmo_place_orphan): Likewise.
	* emultempl/pe.em (gld${EMULATION_NAME}_place_orphan): Likewise.

Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.26
diff -u -p -r1.26 ldexp.c
--- ld/ldexp.c	11 Oct 2003 09:16:20 -0000	1.26
+++ ld/ldexp.c	3 Jan 2004 11:54:32 -0000
@@ -43,6 +43,8 @@ Software Foundation, 59 Temple Place - S
 
 static etree_value_type exp_fold_tree_no_dot
   (etree_type *, lang_output_section_statement_type *, lang_phase_type);
+static bfd_vma align_n
+  (bfd_vma, bfd_vma);
 
 struct exp_data_seg exp_data_seg;
 
@@ -1099,7 +1101,8 @@ exp_get_abs_int (etree_type *tree,
   return res.value;
 }
 
-bfd_vma align_n (bfd_vma value, bfd_vma align)
+static bfd_vma
+align_n (bfd_vma value, bfd_vma align)
 {
   if (align <= 1)
     return value;
Index: ld/ldexp.h
===================================================================
RCS file: /cvs/src/src/ld/ldexp.h,v
retrieving revision 1.10
diff -u -p -r1.10 ldexp.h
--- ld/ldexp.h	28 Jun 2003 05:28:54 -0000	1.10
+++ ld/ldexp.h	3 Jan 2004 11:54:32 -0000
@@ -138,7 +138,5 @@ fill_type *exp_get_fill
   (etree_type *, fill_type *, char *, lang_phase_type);
 bfd_vma exp_get_abs_int
   (etree_type *, int, char *, lang_phase_type);
-bfd_vma align_n
-  (bfd_vma, bfd_vma);
 
 #endif
Index: ld/ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.29
diff -u -p -r1.29 ldgram.y
--- ld/ldgram.y	3 Jan 2004 11:09:06 -0000	1.29
+++ ld/ldgram.y	3 Jan 2004 11:54:33 -0000
@@ -841,7 +841,7 @@ section:	NAME 		{ ldlex_expression(); }
 			{
 			  lang_enter_output_section_statement($1, $3,
 							      sectype,
-							      0, 0, $5, $4);
+							      0, $5, $4);
 			}
 		statement_list_opt
  		'}' { ldlex_popstate (); ldlex_expression (); }
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.131
diff -u -p -r1.131 ldlang.c
--- ld/ldlang.c	8 Dec 2003 03:43:33 -0000	1.131
+++ ld/ldlang.c	3 Jan 2004 11:54:35 -0000
@@ -1799,6 +1799,30 @@ ldlang_open_output (lang_statement_union
     }
 }
 
+/* Convert between addresses in bytes and sizes in octets.
+   For currently supported targets, octets_per_byte is always a power
+   of two, so we can use shifts.  */
+#define TO_ADDR(X) ((X) >> opb_shift)
+#define TO_SIZE(X) ((X) << opb_shift)
+
+/* Support the above.  */
+static unsigned int opb_shift = 0;
+
+static void
+init_opb (void)
+{
+  unsigned x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
+					      ldfile_output_machine);
+  opb_shift = 0;
+  if (x > 1)
+    while ((x & 1) == 0)
+      {
+	x >>= 1;
+	++opb_shift;
+      }
+  ASSERT (x == 1);
+}
+
 /* Open all the input files.  */
 
 static void
@@ -2272,8 +2296,8 @@ print_input_section (lang_input_section_
 {
   asection *i = in->section;
   bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
-  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						ldfile_output_machine);
+
+  init_opb ();
   if (size != 0)
     {
       print_space ();
@@ -2297,7 +2321,7 @@ print_input_section (lang_input_section_
 	    }
 
 	  minfo ("0x%V %W %B\n",
-		 i->output_section->vma + i->output_offset, size / opb,
+		 i->output_section->vma + i->output_offset, TO_ADDR (size),
 		 i->owner);
 
 	  if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size)
@@ -2319,7 +2343,8 @@ print_input_section (lang_input_section_
 
 	  bfd_link_hash_traverse (link_info.hash, print_one_symbol, i);
 
-	  print_dot = i->output_section->vma + i->output_offset + size / opb;
+	  print_dot = (i->output_section->vma + i->output_offset
+		       + TO_ADDR (size));
 	}
     }
 }
@@ -2342,9 +2367,8 @@ print_data_statement (lang_data_statemen
   bfd_vma addr;
   bfd_size_type size;
   const char *name;
-  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						ldfile_output_machine);
 
+  init_opb ();
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
 
@@ -2388,8 +2412,7 @@ print_data_statement (lang_data_statemen
 
   print_nl ();
 
-  print_dot = addr + size / opb;
-
+  print_dot = addr + TO_ADDR (size);
 }
 
 /* Print an address statement.  These are generated by options like
@@ -2411,9 +2434,8 @@ print_reloc_statement (lang_reloc_statem
   int i;
   bfd_vma addr;
   bfd_size_type size;
-  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						ldfile_output_machine);
 
+  init_opb ();
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
 
@@ -2434,7 +2456,7 @@ print_reloc_statement (lang_reloc_statem
 
   print_nl ();
 
-  print_dot = addr + size / opb;
+  print_dot = addr + TO_ADDR (size);
 }
 
 static void
@@ -2442,9 +2464,8 @@ print_padding_statement (lang_padding_st
 {
   int len;
   bfd_vma addr;
-  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						ldfile_output_machine);
 
+  init_opb ();
   minfo (" *fill*");
 
   len = sizeof " *fill*" - 1;
@@ -2469,7 +2490,7 @@ print_padding_statement (lang_padding_st
 
   print_nl ();
 
-  print_dot = addr + s->size / opb;
+  print_dot = addr + TO_ADDR (s->size);
 }
 
 static void
@@ -2698,8 +2719,6 @@ size_input_section (lang_statement_union
 
   if (!is->ifile->just_syms_flag)
     {
-      unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						    ldfile_output_machine);
       unsigned int alignment_needed;
       asection *o;
 
@@ -2719,7 +2738,7 @@ size_input_section (lang_statement_union
 
       if (alignment_needed != 0)
 	{
-	  insert_pad (this_ptr, fill, alignment_needed * opb, o, dot);
+	  insert_pad (this_ptr, fill, TO_SIZE (alignment_needed), o, dot);
 	  dot += alignment_needed;
 	}
 
@@ -2729,10 +2748,10 @@ size_input_section (lang_statement_union
 
       /* Mark how big the output section must be to contain this now.  */
       if (i->_cooked_size != 0)
-	dot += i->_cooked_size / opb;
+	dot += TO_ADDR (i->_cooked_size);
       else
-	dot += i->_raw_size / opb;
-      o->_raw_size = (dot - o->vma) * opb;
+	dot += TO_ADDR (i->_raw_size);
+      o->_raw_size = TO_SIZE (dot - o->vma);
     }
   else
     {
@@ -2755,7 +2774,6 @@ static void
 lang_check_section_addresses (void)
 {
   asection *s;
-  unsigned opb = bfd_octets_per_byte (output_bfd);
 
   /* Scan all sections in the output list.  */
   for (s = output_bfd->sections; s != NULL; s = s->next)
@@ -2783,10 +2801,10 @@ lang_check_section_addresses (void)
 	  /* We must check the sections' LMA addresses not their
 	     VMA addresses because overlay sections can have
 	     overlapping VMAs but they must have distinct LMAs.  */
-	  s_start  = bfd_section_lma (output_bfd, s);
+	  s_start = bfd_section_lma (output_bfd, s);
 	  os_start = bfd_section_lma (output_bfd, os);
-	  s_end    = s_start  + bfd_section_size (output_bfd, s) / opb - 1;
-	  os_end   = os_start + bfd_section_size (output_bfd, os) / opb - 1;
+	  s_end = s_start + TO_ADDR (bfd_section_size (output_bfd, s)) - 1;
+	  os_end = os_start + TO_ADDR (bfd_section_size (output_bfd, os)) - 1;
 
 	  /* Look for an overlap.  */
 	  if ((s_end < os_start) || (s_start > os_end))
@@ -2851,9 +2869,6 @@ lang_size_sections_1
    bfd_boolean *relax,
    bfd_boolean check_regions)
 {
-  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						ldfile_output_machine);
-
   /* Size up the sections from their constituent parts.  */
   for (; s != NULL; s = s->header.next)
     {
@@ -2990,9 +3005,10 @@ lang_size_sections_1
 
 	    /* Put the section within the requested block size, or
 	       align at the block boundary.  */
-	    after = align_n (os->bfd_section->vma
-			     + os->bfd_section->_raw_size / opb,
-			     (bfd_vma) os->block_value);
+	    after = ((os->bfd_section->vma
+		      + TO_ADDR (os->bfd_section->_raw_size)
+		      + os->block_value - 1)
+		     & - (bfd_vma) os->block_value);
 
 	    if (bfd_is_abs_section (os->bfd_section))
 	      ASSERT (after == os->bfd_section->vma);
@@ -3001,10 +3017,10 @@ lang_size_sections_1
 		     && ! link_info.relocatable)
 	      os->bfd_section->_raw_size = 0;
 	    else
-	      os->bfd_section->_raw_size =
-		(after - os->bfd_section->vma) * opb;
+	      os->bfd_section->_raw_size
+		= TO_SIZE (after - os->bfd_section->vma);
 
-	    dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
+	    dot = os->bfd_section->vma + TO_ADDR (os->bfd_section->_raw_size);
 	    os->processed = TRUE;
 
 	    if (os->update_dot_tree != 0)
@@ -3042,7 +3058,7 @@ lang_size_sections_1
 		    /* Set load_base, which will be handled later.  */
 		    os->load_base = exp_intop (os->lma_region->current);
 		    os->lma_region->current +=
-		      os->bfd_section->_raw_size / opb;
+		      TO_ADDR (os->bfd_section->_raw_size);
 		    if (check_regions)
 		      os_region_check (os, os->lma_region, NULL,
 				       os->bfd_section->lma);
@@ -3085,9 +3101,9 @@ lang_size_sections_1
 		size = BYTE_SIZE;
 		break;
 	      }
-	    if (size < opb)
-	      size = opb;
-	    dot += size / opb;
+	    if (size < TO_SIZE ((unsigned) 1))
+	      size = TO_SIZE ((unsigned) 1);
+	    dot += TO_ADDR (size);
 	    output_section_statement->bfd_section->_raw_size += size;
 	    /* The output section gets contents, and then we inspect for
 	       any flags set in the input script which override any ALLOC.  */
@@ -3109,7 +3125,7 @@ lang_size_sections_1
 	    s->reloc_statement.output_section =
 	      output_section_statement->bfd_section;
 	    size = bfd_get_reloc_size (s->reloc_statement.howto);
-	    dot += size / opb;
+	    dot += TO_ADDR (size);
 	    output_section_statement->bfd_section->_raw_size += size;
 	  }
 	  break;
@@ -3184,7 +3200,7 @@ lang_size_sections_1
 		    /* Insert a pad after this statement.  We can't
 		       put the pad before when relaxing, in case the
 		       assignment references dot.  */
-		    insert_pad (&s->header.next, fill, (newdot - dot) * opb,
+		    insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot),
 				output_section_statement->bfd_section, dot);
 
 		    /* Don't neuter the pad below when relaxing.  */
@@ -3291,9 +3307,6 @@ lang_do_assignments_1
    fill_type *fill,
    bfd_vma dot)
 {
-  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						ldfile_output_machine);
-
   for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
@@ -3315,7 +3328,8 @@ lang_do_assignments_1
 		dot = os->bfd_section->vma;
 		(void) lang_do_assignments_1 (os->children.head, os,
 					      os->fill, dot);
-		dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
+		dot = (os->bfd_section->vma
+		       + TO_ADDR (os->bfd_section->_raw_size));
 
 	      }
 	    if (os->load_base)
@@ -3377,9 +3391,9 @@ lang_do_assignments_1
 		size = BYTE_SIZE;
 		break;
 	      }
-	    if (size < opb)
-	      size = opb;
-	    dot += size / opb;
+	    if (size < TO_SIZE ((unsigned) 1))
+	      size = TO_SIZE ((unsigned) 1);
+	    dot += TO_ADDR (size);
 	  }
 	  break;
 
@@ -3394,7 +3408,7 @@ lang_do_assignments_1
 	    if (!value.valid_p)
 	      einfo (_("%F%P: invalid reloc statement\n"));
 	  }
-	  dot += bfd_get_reloc_size (s->reloc_statement.howto) / opb;
+	  dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto));
 	  break;
 
 	case lang_input_section_enum:
@@ -3402,9 +3416,9 @@ lang_do_assignments_1
 	    asection *in = s->input_section.section;
 
 	    if (in->_cooked_size != 0)
-	      dot += in->_cooked_size / opb;
+	      dot += TO_ADDR (in->_cooked_size);
 	    else
-	      dot += in->_raw_size / opb;
+	      dot += TO_ADDR (in->_raw_size);
 	  }
 	  break;
 
@@ -3424,7 +3438,7 @@ lang_do_assignments_1
 
 	  break;
 	case lang_padding_statement_enum:
-	  dot += s->padding_statement.size / opb;
+	  dot += TO_ADDR (s->padding_statement.size);
 	  break;
 
 	case lang_group_statement_enum:
@@ -3447,8 +3461,7 @@ lang_do_assignments_1
 
 void
 lang_do_assignments (lang_statement_union_type *s,
-		     lang_output_section_statement_type
-		     *output_section_statement,
+		     lang_output_section_statement_type *output_section_statement,
 		     fill_type *fill,
 		     bfd_vma dot)
 {
@@ -3494,15 +3507,11 @@ lang_set_startof (void)
       h = bfd_link_hash_lookup (link_info.hash, buf, FALSE, FALSE, TRUE);
       if (h != NULL && h->type == bfd_link_hash_undefined)
 	{
-	  unsigned opb;
-
-	  opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-					       ldfile_output_machine);
 	  h->type = bfd_link_hash_defined;
 	  if (s->_cooked_size != 0)
-	    h->u.def.value = s->_cooked_size / opb;
+	    h->u.def.value = TO_ADDR (s->_cooked_size);
 	  else
-	    h->u.def.value = s->_raw_size / opb;
+	    h->u.def.value = TO_ADDR (s->_raw_size);
 	  h->u.def.section = bfd_abs_section_ptr;
 	}
 
@@ -3696,8 +3705,6 @@ lang_one_common (struct bfd_link_hash_en
   unsigned int power_of_two;
   bfd_vma size;
   asection *section;
-  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture,
-						ldfile_output_machine);
 
   if (h->type != bfd_link_hash_common)
     return TRUE;
@@ -3711,9 +3718,9 @@ lang_one_common (struct bfd_link_hash_en
 
   section = h->u.c.p->section;
 
-  /* Increase the size of the section.  */
-  section->_cooked_size = align_n ((section->_cooked_size + opb - 1) / opb,
-				   (bfd_vma) 1 << power_of_two) * opb;
+  /* Increase the size of the section to align the common sym.  */
+  section->_cooked_size += ((bfd_vma) 1 << (power_of_two + opb_shift)) - 1;
+  section->_cooked_size &= (- (bfd_vma) 1 << (power_of_two + opb_shift));
 
   /* Adjust the alignment if necessary.  */
   if (power_of_two > section->alignment_power)
@@ -3994,7 +4001,6 @@ lang_output_section_statement_type *
 lang_enter_output_section_statement (const char *output_section_statement_name,
 				     etree_type *address_exp,
 				     enum section_type sectype,
-				     bfd_vma block_value,
 				     etree_type *align,
 				     etree_type *subalign,
 				     etree_type *ebase)
@@ -4021,7 +4027,7 @@ lang_enter_output_section_statement (con
     os->flags = SEC_NO_FLAGS;
   else
     os->flags = SEC_NEVER_LOAD;
-  os->block_value = block_value ? block_value : 1;
+  os->block_value = 1;
   stat_ptr = &os->children;
 
   os->subsection_alignment =
@@ -4147,6 +4153,7 @@ lang_process (void)
 
   /* Open the output file.  */
   lang_for_each_statement (ldlang_open_output);
+  init_opb ();
 
   ldemul_create_output_section_statements ();
 
@@ -4582,8 +4589,7 @@ lang_abs_symbol_at_end_of (const char *s
 	h->u.def.value = 0;
       else
 	h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
-			  + bfd_section_size (output_bfd, sec) /
-                          bfd_octets_per_byte (output_bfd));
+			  + TO_ADDR (bfd_section_size (output_bfd, sec)));
 
       h->u.def.section = bfd_abs_section_ptr;
     }
@@ -4832,7 +4838,7 @@ lang_enter_overlay_section (const char *
   etree_type *size;
 
   lang_enter_output_section_statement (name, overlay_vma, normal_section,
-				       0, 0, overlay_subalign, 0);
+				       0, overlay_subalign, 0);
 
   /* If this is the first section, then base the VMA of future
      sections on this one.  This will work correctly even if `.' is
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.32
diff -u -p -r1.32 ldlang.h
--- ld/ldlang.h	4 Dec 2003 12:09:25 -0000	1.32
+++ ld/ldlang.h	3 Jan 2004 11:54:36 -0000
@@ -403,7 +403,6 @@ extern lang_output_section_statement_typ
   (const char *output_section_statement_name,
    etree_type *address_exp,
    enum section_type sectype,
-   bfd_vma block_value,
    etree_type *align,
    etree_type *subalign,
    etree_type *);
Index: ld/mri.c
===================================================================
RCS file: /cvs/src/src/ld/mri.c,v
retrieving revision 1.13
diff -u -p -r1.13 mri.c
--- ld/mri.c	28 Jun 2003 05:28:54 -0000	1.13
+++ ld/mri.c	3 Jan 2004 11:54:36 -0000
@@ -220,7 +220,7 @@ mri_draw_tree (void)
 
 	  lang_enter_output_section_statement (p->name, base,
 					       p->ok_to_load ? 0 : noload_section,
-					       1, align, subalign, NULL);
+					       align, subalign, NULL);
 	  base = 0;
 	  tmp = xmalloc (sizeof *tmp);
 	  tmp->next = NULL;
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.107
diff -u -p -r1.107 elf32.em
--- ld/emultempl/elf32.em	3 Jan 2004 11:09:07 -0000	1.107
+++ ld/emultempl/elf32.em	3 Jan 2004 11:54:37 -0000
@@ -1256,7 +1256,6 @@ gld${EMULATION_NAME}_place_orphan (lang_
 
   os_tail = lang_output_section_statement.tail;
   os = lang_enter_output_section_statement (secname, address, 0,
-					    (bfd_vma) 0,
 					    (etree_type *) NULL,
 					    (etree_type *) NULL,
 					    load_base);
Index: ld/emultempl/mmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmo.em,v
retrieving revision 1.11
diff -u -p -r1.11 mmo.em
--- ld/emultempl/mmo.em	27 Jun 2003 00:38:25 -0000	1.11
+++ ld/emultempl/mmo.em	3 Jan 2004 11:54:37 -0000
@@ -127,7 +127,6 @@ mmo_place_orphan (lang_input_statement_t
   os = lang_enter_output_section_statement (bfd_get_section_name (s->owner,
 								  s),
 					    NULL, 0,
-					    (bfd_vma) 0,
 					    (etree_type *) NULL,
 					    (etree_type *) NULL,
 					    (etree_type *) NULL);
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.86
diff -u -p -r1.86 pe.em
--- ld/emultempl/pe.em	3 Jan 2004 11:09:07 -0000	1.86
+++ ld/emultempl/pe.em	3 Jan 2004 11:54:38 -0000
@@ -1647,7 +1647,6 @@ gld_${EMULATION_NAME}_place_orphan (lang
 	}
 
       os = lang_enter_output_section_statement (outsecname, address, 0,
-						(bfd_vma) 0,
 						(etree_type *) NULL,
 						(etree_type *) NULL,
 						(etree_type *) NULL);

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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