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]

SPU stack analysis and function splitting


Currently the SPU stack analysis code assumes that there are at most
two code sections per function (hot/cold function partitioning).  That
may be true at the moment, but won't be when spu-gcc starts splitting
functions into multiple sections.

	* elf32-spu.c (mark_functions_via_relocs): Don't assume that
	the "->start" pointer reaches to function origin, so that we
	can handle functions split over more than two sections.
	(build_call_tree): Likewise.
	(pasted_function): Don't attempt to set fun->start back to the
	function origin, just go back one section.

Index: bfd/elf32-spu.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-spu.c,v
retrieving revision 1.29
diff -u -p -r1.29 elf32-spu.c
--- bfd/elf32-spu.c	7 Feb 2008 01:26:56 -0000	1.29
+++ bfd/elf32-spu.c	27 Feb 2008 22:21:43 -0000
@@ -1997,14 +1997,29 @@ mark_functions_via_relocs (asection *sec
 	     destination has been called by some other function then
 	     it is a separate function.  We also assume that functions
 	     are not split across input files.  */
-	  if (callee->fun->start != NULL
-	      || sec->owner != sym_sec->owner)
+	  if (sec->owner != sym_sec->owner)
 	    {
 	      callee->fun->start = NULL;
 	      callee->fun->is_func = TRUE;
 	    }
-	  else
+	  else if (callee->fun->start == NULL)
 	    callee->fun->start = caller;
+	  else
+	    {
+	      struct function_info *callee_start;
+	      struct function_info *caller_start;
+	      callee_start = callee->fun;
+	      while (callee_start->start)
+		callee_start = callee_start->start;
+	      caller_start = caller;
+	      while (caller_start->start)
+		caller_start = caller_start->start;
+	      if (caller_start != callee_start)
+		{
+		  callee->fun->start = NULL;
+		  callee->fun->is_func = TRUE;
+		}
+	    }
 	}
     }
 
@@ -2041,11 +2056,7 @@ pasted_function (asection *sec, struct b
       if (l->u.indirect.section == sec)
 	{
 	  if (fun_start != NULL)
-	    {
-	      if (fun_start->start)
-		fun_start = fun_start->start;
-	      fun->start = fun_start;
-	    }
+	    fun->start = fun_start;
 	  return TRUE;
 	}
       if (l->type == bfd_indirect_link_order
@@ -2382,14 +2393,19 @@ build_call_tree (bfd *output_bfd, struct
 	      int i;
 	      for (i = 0; i < sinfo->num_fun; ++i)
 		{
-		  if (sinfo->fun[i].start != NULL)
+		  struct function_info *start = sinfo->fun[i].start;
+
+		  if (start != NULL)
 		    {
-		      struct call_info *call = sinfo->fun[i].call_list;
+		      struct call_info *call;
 
+		      while (start->start != NULL)
+			start = start->start;
+		      call = sinfo->fun[i].call_list;
 		      while (call != NULL)
 			{
 			  struct call_info *call_next = call->next;
-			  if (!insert_callee (sinfo->fun[i].start, call))
+			  if (!insert_callee (start, call))
 			    free (call);
 			  call = call_next;
 			}

-- 
Alan Modra
Australia Development Lab, IBM


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