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

[commit] Use SAL to improve mips skip_prologue


Hello,

The attached modifies the MIPS so that it uses the SAL to bound the prologue analyzer (used when skipping the function prologue). See refine_prologue_limit (variants found in both ia64 and ppc) for the origins of the idea.

structs.exp before:

# of expected passes            468
# of unexpected failures        111
# of known failures             30

after:

# of expected passes            602
# of unexpected failures        7

say no more,
Andrew
2003-11-22  Andrew Cagney  <cagney@redhat.com>

	* mips-tdep.c (skip_prologue_using_sal): New function.
	(mips32_skip_prologue, mips16_skip_prologue): Use
	skip_prologue_using_sal to get an upper bound on the search.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.255
diff -u -r1.255 mips-tdep.c
--- mips-tdep.c	22 Nov 2003 14:04:39 -0000	1.255
+++ mips-tdep.c	22 Nov 2003 20:54:15 -0000
@@ -4307,6 +4307,61 @@
 }
 
 
+/* Given PC at the function's start address, attempt to find the
+   prologue end using SAL information.  Return zero if the skip fails.
+
+   A non-optimized prologue traditionally has one SAL for the function
+   and a second for the function body.  A single line function has
+   them both pointing at the same line.
+
+   An optimized prologue is similar but the prologue may contain
+   instructions (SALs) from the instruction body.  Need to skip those
+   while not getting into the function body.
+
+   The functions end point and an increasing SAL line are used as
+   indicators of the prologue's endpoint.
+
+   This code is based on the function refine_prologue_limit (versions
+   found in both ia64 and ppc).  */
+
+static CORE_ADDR
+skip_prologue_using_sal (CORE_ADDR func_addr)
+{
+  struct symtab_and_line prologue_sal;
+  CORE_ADDR start_pc;
+  CORE_ADDR end_pc;
+
+  /* Get an initial range for the function.  */
+  find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
+  start_pc += FUNCTION_START_OFFSET;
+
+  prologue_sal = find_pc_line (start_pc, 0);
+  if (prologue_sal.line != 0)
+    {
+      while (prologue_sal.end < end_pc)
+	{
+	  struct symtab_and_line sal;
+
+	  sal = find_pc_line (prologue_sal.end, 0);
+	  if (sal.line == 0)
+	    break;
+	  /* Assume that a consecutive SAL for the same (or larger)
+             line mark the prologue -> body transition.  */
+	  if (sal.line >= prologue_sal.line)
+	    break;
+	  /* The case in which compiler's optimizer/scheduler has
+	     moved instructions into the prologue.  We look ahead in
+	     the function looking for address ranges whose
+	     corresponding line number is less the first one that we
+	     found for the function.  This is more conservative then
+	     refine_prologue_limit which scans a large number of SALs
+	     looking for any in the prologue */
+	  prologue_sal = sal;
+	}
+    }
+  return prologue_sal.end;
+}
+
 /* Skip the PC past function prologue instructions (32-bit version).
    This is a helper function for mips_skip_prologue.  */
 
@@ -4318,10 +4373,15 @@
   int seen_sp_adjust = 0;
   int load_immediate_bytes = 0;
 
+  /* Find an upper bound on the prologue.  */
+  end_pc = skip_prologue_using_sal (pc);
+  if (end_pc == 0)
+    end_pc = pc + 100; /* Magic.  */
+
   /* Skip the typical prologue instructions. These are the stack adjustment
      instruction and the instructions that save registers on the stack
      or in the gcc frame.  */
-  for (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN)
+  for (; pc < end_pc; pc += MIPS_INSTLEN)
     {
       unsigned long high_word;
 
@@ -4463,10 +4523,15 @@
     }				/* end of table marker */
   };
 
+  /* Find an upper bound on the prologue.  */
+  end_pc = skip_prologue_using_sal (pc);
+  if (end_pc == 0)
+    end_pc = pc + 100; /* Magic.  */
+
   /* Skip the typical prologue instructions. These are the stack adjustment
      instruction and the instructions that save registers on the stack
      or in the gcc frame.  */
-  for (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN)
+  for (; pc < end_pc; pc += MIPS16_INSTLEN)
     {
       unsigned short inst;
       int i;

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