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]

[Xtensa Patch] Improve peformance when assembling Exception Table Entries


When the Xtensa port of gas encounters an expression that takes the difference of two symbols, it walks the frags between those two symbols.

C++ exception tables as produced by GCC have a lot of these expressions, and they are of the form a - b, a - c, a - d. This results in n-squared performance in the length of the C++ function, which in turn prevents certain G++ torture tests from completing in a reasonable amount of time.

This patch caches the second frag, allowing the traversal to continue from where it left off, resulting in linear performance and allowing the GCC torture tests to complete in reasonable time.

Sterling

2009-08-19  Sterling Augustine  <sterling@tensilica.com>
	* config/tc-xtensa.h (xtensa_frag_data): Rename unused field
        fr_prev to no_transform_end.
	* config/tc-xtensa.c (xtensa_mark_difference_of_two_symbols):
        Set and use no_transform_end.


Index: tc-xtensa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.c,v
retrieving revision 1.112
diff -u -p -r1.112 tc-xtensa.c
--- tc-xtensa.c	18 Aug 2009 16:42:15 -0000	1.112
+++ tc-xtensa.c	19 Aug 2009 16:00:02 -0000
@@ -7460,6 +7460,7 @@ xtensa_mark_difference_of_two_symbols (v
 	    {
 	      fragS *start;
 	      fragS *end;
+	      fragS *walk;
 
 	      if (symbol_get_frag (left)->fr_address 
 		  <= symbol_get_frag (right)->fr_address)
@@ -7472,12 +7473,19 @@ xtensa_mark_difference_of_two_symbols (v
 		  start = symbol_get_frag (right);
 		  end = symbol_get_frag (left);
 		}
+
+	      if (start->tc_frag_data.no_transform_end != NULL)
+		walk = start->tc_frag_data.no_transform_end;
+	      else
+		walk = start;
 	      do 
 		{
-		  start->tc_frag_data.is_no_transform = 1;
-		  start = start->fr_next;
+		  walk->tc_frag_data.is_no_transform = 1;
+		  walk = walk->fr_next;
 		}
-	      while (start && start->fr_address < end->fr_address);
+	      while (walk && walk->fr_address < end->fr_address);
+
+	      start->tc_frag_data.no_transform_end = walk;
 	    }
 	}
     }
Index: tc-xtensa.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.h,v
retrieving revision 1.32
diff -u -p -r1.32 tc-xtensa.h
--- tc-xtensa.h	4 Nov 2008 23:11:02 -0000	1.32
+++ tc-xtensa.h	19 Aug 2009 16:00:02 -0000
@@ -263,9 +263,10 @@ struct xtensa_frag_type
   symbolS *slot_symbols[MAX_SLOTS];
   offsetT slot_offsets[MAX_SLOTS];
 
-  /* The global aligner needs to walk backward through the list of
-     frags.  This field is only valid after xtensa_end.  */
-  fragS *fr_prev;
+  /* When marking frags after this one in the chain as no transform,
+     cache the last one in the chain, so that we can skip to the
+     end of the chain.  */
+  fragS *no_transform_end;
 };
 
 

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