This is the mail archive of the binutils@sourceware.org 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 optimization for Xtensa BFD


This patch avoids some redundant iteration over lists and generally cleans up a few bits of code. Committed on trunk.

2007-10-05  Bob Wilson  <bob.wilson@acm.org>
	
	* elf32-xtensa.c (removed_by_actions): New.
	(offset_with_removed_text): Reimplement using removed_by_actions.
	(offset_with_removed_text_before_fill): Delete.
	(relax_property_section): Use removed_by_actions.  Rearrange logic.
	(relax_section_symbols): Likewise.
	
Index: elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.96
diff -u -p -r1.96 elf32-xtensa.c
--- elf32-xtensa.c	4 Oct 2007 17:15:29 -0000	1.96
+++ elf32-xtensa.c	5 Oct 2007 18:04:28 -0000
@@ -4780,20 +4780,45 @@ text_action_add_literal (text_action_lis
 }
 
 
-static bfd_vma 
-offset_with_removed_text (text_action_list *action_list, bfd_vma offset)
+/* Find the total offset adjustment for the relaxations specified by
+   text_actions, beginning from a particular starting action.  This is
+   typically used from offset_with_removed_text to search an entire list of
+   actions, but it may also be called directly when adjusting adjacent offsets
+   so that each search may begin where the previous one left off.  */
+
+static int
+removed_by_actions (text_action **p_start_action,
+		    bfd_vma offset,
+		    bfd_boolean before_fill)
 {
   text_action *r;
   int removed = 0;
 
-  for (r = action_list->head; r && r->offset <= offset; r = r->next)
+  r = *p_start_action;
+  while (r)
     {
-      if (r->offset < offset
-	  || (r->action == ta_fill && r->removed_bytes < 0))
-	removed += r->removed_bytes;
+      if (r->offset > offset)
+	break;
+
+      if (r->offset == offset
+	  && (before_fill || r->action != ta_fill || r->removed_bytes >= 0))
+	break;
+
+      removed += r->removed_bytes;
+
+      r = r->next;
     }
 
-  return (offset - removed);
+  *p_start_action = r;
+  return removed;
+}
+
+
+static bfd_vma 
+offset_with_removed_text (text_action_list *action_list, bfd_vma offset)
+{
+  text_action *r = action_list->head;
+  return offset - removed_by_actions (&r, offset, FALSE);
 }
 
 
@@ -4810,20 +4835,6 @@ action_list_count (text_action_list *act
 }
 
 
-static bfd_vma
-offset_with_removed_text_before_fill (text_action_list *action_list,
-				      bfd_vma offset)
-{
-  text_action *r;
-  int removed = 0;
-
-  for (r = action_list->head; r && r->offset < offset; r = r->next)
-    removed += r->removed_bytes;
-
-  return (offset - removed);
-}
-
-
 /* The find_insn_action routine will only find non-fill actions.  */
 
 static text_action *
@@ -8943,14 +8954,16 @@ relax_property_section (bfd *abfd,
 		  || target_relax_info->is_relaxable_asm_section ))
 	    {
 	      /* Translate the relocation's destination.  */
-	      bfd_vma new_offset, new_end_offset;
+	      bfd_vma old_offset = val.r_rel.target_offset;
+	      bfd_vma new_offset;
 	      long old_size, new_size;
-
-	      new_offset = offset_with_removed_text
-		(&target_relax_info->action_list, val.r_rel.target_offset);
+	      text_action *act = target_relax_info->action_list.head;
+	      new_offset = old_offset -
+		removed_by_actions (&act, old_offset, FALSE);
 
 	      /* Assert that we are not out of bounds.  */
 	      old_size = bfd_get_32 (abfd, size_p);
+	      new_size = old_size;
 
 	      if (old_size == 0)
 		{
@@ -8962,39 +8975,34 @@ relax_property_section (bfd *abfd,
 		     offset before or after the fill address depending
 		     on whether the expanding unreachable entry
 		     preceeds it.  */
-		  if (last_zfill_target_sec
-		      && last_zfill_target_sec == target_sec
-		      && last_zfill_target_offset == val.r_rel.target_offset)
-		    new_end_offset = new_offset;
-		  else
+		  if (last_zfill_target_sec == 0
+		      || last_zfill_target_sec != target_sec
+		      || last_zfill_target_offset != old_offset)
 		    {
-		      new_end_offset = new_offset;
-		      new_offset = offset_with_removed_text_before_fill
-			(&target_relax_info->action_list,
-			 val.r_rel.target_offset);
+		      bfd_vma new_end_offset = new_offset;
+
+		      /* Recompute the new_offset, but this time don't
+			 include any fill inserted by relaxation.  */
+		      act = target_relax_info->action_list.head;
+		      new_offset = old_offset -
+			removed_by_actions (&act, old_offset, TRUE);
 
 		      /* If it is not unreachable and we have not yet
 			 seen an unreachable at this address, place it
 			 before the fill address.  */
-		      if (!flags_p
-			  || (bfd_get_32 (abfd, flags_p)
-			      & XTENSA_PROP_UNREACHABLE) == 0)
-			new_end_offset = new_offset;
-		      else
+		      if (flags_p && (bfd_get_32 (abfd, flags_p)
+				      & XTENSA_PROP_UNREACHABLE) != 0)
 			{
+			  new_size = new_end_offset - new_offset;
+
 			  last_zfill_target_sec = target_sec;
-			  last_zfill_target_offset = val.r_rel.target_offset;
+			  last_zfill_target_offset = old_offset;
 			}
 		    }
 		}
 	      else
-		{
-		  new_end_offset = offset_with_removed_text_before_fill
-		    (&target_relax_info->action_list,
-		     val.r_rel.target_offset + old_size);
-		}
-
-	      new_size = new_end_offset - new_offset;
+		new_size -=
+		    removed_by_actions (&act, old_offset + old_size, TRUE);
 
 	      if (new_size != old_size)
 		{
@@ -9002,9 +9010,9 @@ relax_property_section (bfd *abfd,
 		  pin_contents (sec, contents);
 		}
 
-	      if (new_offset != val.r_rel.target_offset)
+	      if (new_offset != old_offset)
 		{
-		  bfd_vma diff = new_offset - val.r_rel.target_offset;
+		  bfd_vma diff = new_offset - old_offset;
 		  irel->r_addend += diff;
 		  pin_internal_relocs (sec, internal_relocs);
 		}
@@ -9257,19 +9265,14 @@ relax_section_symbols (bfd *abfd, asecti
 
       if (isym->st_shndx == sec_shndx)
 	{
-	  bfd_vma new_address = offset_with_removed_text
-	    (&relax_info->action_list, isym->st_value);
-	  bfd_vma new_size = isym->st_size;
+	  text_action *act = relax_info->action_list.head;
+	  bfd_vma orig_addr = isym->st_value;
 
-	  if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC)
-	    {
-	      bfd_vma new_end = offset_with_removed_text
-		(&relax_info->action_list, isym->st_value + isym->st_size);
-	      new_size = new_end - new_address;
-	    }
+	  isym->st_value -= removed_by_actions (&act, orig_addr, FALSE);
 
-	  isym->st_value = new_address;
-	  isym->st_size = new_size;
+	  if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC)
+	    isym->st_size -=
+	      removed_by_actions (&act, orig_addr + isym->st_size, FALSE);
 	}
     }
 
@@ -9287,20 +9290,15 @@ relax_section_symbols (bfd *abfd, asecti
 	   || sym_hash->root.type == bfd_link_hash_defweak)
 	  && sym_hash->root.u.def.section == sec)
 	{
-	  bfd_vma new_address = offset_with_removed_text
-	    (&relax_info->action_list, sym_hash->root.u.def.value);
-	  bfd_vma new_size = sym_hash->size;
+	  text_action *act = relax_info->action_list.head;
+	  bfd_vma orig_addr = sym_hash->root.u.def.value;
 
-	  if (sym_hash->type == STT_FUNC)
-	    {
-	      bfd_vma new_end = offset_with_removed_text
-		(&relax_info->action_list,
-		 sym_hash->root.u.def.value + sym_hash->size);
-	      new_size = new_end - new_address;
-	    }
+	  sym_hash->root.u.def.value -=
+	    removed_by_actions (&act, orig_addr, FALSE);
 
-	  sym_hash->root.u.def.value = new_address;
-	  sym_hash->size = new_size;
+	  if (sym_hash->type == STT_FUNC)
+	    sym_hash->size -=
+	      removed_by_actions (&act, orig_addr + sym_hash->size, FALSE);
 	}
     }
 

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