This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[commit] Use SAL to improve mips skip_prologue
- From: Andrew Cagney <cagney at gnu dot org>
- To: gdb-patches at sources dot redhat dot com
- Date: Sat, 22 Nov 2003 16:17:25 -0500
- Subject: [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;