Re: [PATCH, ARM] Fix line number data for PIC register setup code

2013-10-29 Thread Eric Botcazou
 Updated patch, re-bootstrapped on x86_64 and committed to trunk.
 
 Also applied to 4.7 and 4.8 branches, the same problem is present there.

You only asked for approval on trunk though, and I'm not sure we really care 
about the results of the GDB testsuite on the 4.7 branch at this point, so 
let's exclude the 4.7 branch here.

-- 
Eric Botcazou


Re: [PATCH, ARM] Fix line number data for PIC register setup code

2013-10-29 Thread Tom de Vries
On 29/10/13 09:12, Eric Botcazou wrote:
 Updated patch, re-bootstrapped on x86_64 and committed to trunk.

 Also applied to 4.7 and 4.8 branches, the same problem is present there.
 
 You only asked for approval on trunk though,

Eric,

Sorry about that.

 and I'm not sure we really care
 about the results of the GDB testsuite on the 4.7 branch at this point,

FWIW, I originally encountered the problem on 4.7.

 so let's exclude the 4.7 branch here.
 

Reverted on the 4.7 branch.

Thanks,
- Tom



Re: [PATCH, ARM] Fix line number data for PIC register setup code

2013-10-29 Thread Eric Botcazou
 Reverted on the 4.7 branch.

Thanks.

-- 
Eric Botcazou


Re: [PATCH, ARM] Fix line number data for PIC register setup code

2013-10-28 Thread Tom de Vries
On 27/10/13 17:04, Eric Botcazou wrote:
 The PIC register setup code is emitted after NOTE_INSNS_FUNCTION_BEG,
 because it uses the insert_insn_on_edge mechanism, and the corresponding
 insertion in cfgexpand.c:gimple_expand_cfg takes care to insert the code
 after the parm_birth_insn:
 ...
/* Avoid putting insns before parm_birth_insn.  */
if (e-src == ENTRY_BLOCK_PTR
 single_succ_p (ENTRY_BLOCK_PTR)
 parm_birth_insn)
  {
rtx insns = e-insns.r;
e-insns.r = NULL_RTX;
emit_insn_after_noloc (insns, parm_birth_insn, e-dest);
  }
 ...
 And in the case for this test-case, parm_birth_insn is the
 NOTE_INSNS_FUNCTION_BEG.
 
 So this means that parm_birth_insn can never be null, right?
 

Yes, AFAICT parm_birth_insn is never NULL at this point.

 2013-10-13  Tom de Vries  t...@codesourcery.com

  * cfgexpand.c (gimple_expand_cfg): Don't commit insertions after
  NOTE_INSN_FUNCTION_BEG.

  * gcc.target/arm/require-pic-register-loc.c: New test.
 
 OK if you also remove the test on parm_birth_insn.
 

Updated patch, re-bootstrapped on x86_64 and committed to trunk.

Also applied to 4.7 and 4.8 branches, the same problem is present there.

Thanks,
- Tom

2013-10-28  Tom de Vries  t...@codesourcery.com

* cfgexpand.c (gimple_expand_cfg): Remove test for parm_birth_insn.
Don't commit insertions after NOTE_INSN_FUNCTION_BEG.

* gcc.target/arm/require-pic-register-loc.c: New test.

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index ba4c0e6..9705036 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4789,14 +4789,18 @@ gimple_expand_cfg (void)
 	  if (e-insns.r)
 	{
 	  rebuild_jump_labels_chain (e-insns.r);
-	  /* Avoid putting insns before parm_birth_insn.  */
+	  /* Put insns after parm birth, but before
+		 NOTE_INSNS_FUNCTION_BEG.  */
 	  if (e-src == ENTRY_BLOCK_PTR
-		   single_succ_p (ENTRY_BLOCK_PTR)
-		   parm_birth_insn)
+		   single_succ_p (ENTRY_BLOCK_PTR))
 		{
 		  rtx insns = e-insns.r;
 		  e-insns.r = NULL_RTX;
-		  emit_insn_after_noloc (insns, parm_birth_insn, e-dest);
+		  if (NOTE_P (parm_birth_insn)
+		   NOTE_KIND (parm_birth_insn) == NOTE_INSN_FUNCTION_BEG)
+		emit_insn_before_noloc (insns, parm_birth_insn, e-dest);
+		  else
+		emit_insn_after_noloc (insns, parm_birth_insn, e-dest);
 		}
 	  else
 		commit_one_edge_insertion (e);
 2013-10-27  Tobias Burnus  bur...@net-b.de
 
 	PR other/33426
diff --git a/gcc/testsuite/gcc.target/arm/require-pic-register-loc.c b/gcc/testsuite/gcc.target/arm/require-pic-register-loc.c
new file mode 100644
index 000..bd85e86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/require-pic-register-loc.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options -g -fPIC } */
+
+void *v;
+void a (void *x) { }
+void b (void) { }
+   /* line 7.  */
+int/* line 8.  */
+main (int argc)/* line 9.  */
+{  /* line 10.  */
+  if (argc == 12345)   /* line 11.  */
+{
+  a (v);
+  return 1;
+}
+  b ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not \.loc 1 7 0 } } */
+/* { dg-final { scan-assembler-not \.loc 1 8 0 } } */
+/* { dg-final { scan-assembler-not \.loc 1 9 0 } } */
+
+/* The loc at the start of the prologue.  */
+/* { dg-final { scan-assembler-times \.loc 1 10 0 1 } } */
+
+/* The loc at the end of the prologue, with the first user line.  */
+/* { dg-final { scan-assembler-times \.loc 1 11 0 1 } } */


[PING] [PATCH, ARM] Fix line number data for PIC register setup code

2013-10-27 Thread Tom de Vries
Ping.

Original submission at http://gcc.gnu.org/ml/gcc-patches/2013-10/msg00903.html .

This patch fixes a regression of 174 tests in the gdb testsuite for
arm-linux-gnueabi with -fPIC (or arm-linux-androideabi) caused by the fix for
PR47028.

The fix for PR47028 made sure that insertions on the single edge from
ENTRY_BLOCK_PTR to the entry bb are committed after the parameters are 
available.

However, the fix had as side-effect that the insertions could be committed both
before and after NOTE_INSN_FUNCTION_BEG. Before the fix, the insertions were
always committed before NOTE_INSN_FUNCTION_BEG.

NOTE_INSN_FUNCTION_BEG has significance with respect to line number info, and
insertions after the note caused wrong .loc info to be generated in the assembly
in some cases, which caused the gdb test failures.

This patch makes sure the insertions are committed before 
NOTE_INSN_FUNCTION_BEG.

Thanks,
- Tom


Re: [PATCH, ARM] Fix line number data for PIC register setup code

2013-10-27 Thread Eric Botcazou
 The PIC register setup code is emitted after NOTE_INSNS_FUNCTION_BEG,
 because it uses the insert_insn_on_edge mechanism, and the corresponding
 insertion in cfgexpand.c:gimple_expand_cfg takes care to insert the code
 after the parm_birth_insn:
 ...
 /* Avoid putting insns before parm_birth_insn.  */
 if (e-src == ENTRY_BLOCK_PTR
  single_succ_p (ENTRY_BLOCK_PTR)
  parm_birth_insn)
   {
 rtx insns = e-insns.r;
 e-insns.r = NULL_RTX;
 emit_insn_after_noloc (insns, parm_birth_insn, e-dest);
   }
 ...
 And in the case for this test-case, parm_birth_insn is the
 NOTE_INSNS_FUNCTION_BEG.

So this means that parm_birth_insn can never be null, right?

 2013-10-13  Tom de Vries  t...@codesourcery.com
 
   * cfgexpand.c (gimple_expand_cfg): Don't commit insertions after
   NOTE_INSN_FUNCTION_BEG.
 
   * gcc.target/arm/require-pic-register-loc.c: New test.

OK if you also remove the test on parm_birth_insn.

-- 
Eric Botcazou


Re: [PATCH, ARM] Fix line number data for PIC register setup code

2013-10-14 Thread Tom de Vries
On 14/10/13 00:17, Tom de Vries wrote:
 This patch makes sure we emit insertions scheduled for the first real BB 
 before
 NOTE_INSN_FUNCTION_BEG. As a consequence, it moves the PIC register setup code
 to before the NOTE_INSN_FUNCTION_BEG. This removes the second .loc, and the
 breakpoint of main ends up at line 8.
 
 Bootstrapped and regtested on x86_64 (ada inclusive), no issues found.
 
 Tested gdb with target arm-none-linux-gnueabi and CFLAGS_FOR_TARGET=-fPIC. The
 patch removes 174 FAILs.
 
 Re-testing gcc with target arm-none-linux-gnueabi atm.
 

No issues found.

OK for trunk?

Thanks,
- Tom



Re: Fix line number data for PIC register setup code

2013-10-13 Thread Tom de Vries
On 03/10/13 17:17, Tom de Vries wrote:
 we need to emit it before the FUNCTION_BEG insn-note
 (rough proof-of-concept patch attached), such that no .loc will be generated 
 for
 it.

I investigated further, and now I think it's a regression caused by the fix for
PR47028.

Attached patch works for the testcase. I'll test the patch, and if successful do
a write-up and submit to gcc-patches.

Thanks,
- Tom

2013-10-13  Tom de Vries  t...@codesourcery.com

* cfgexpand.c (gimple_expand_cfg): Don't commit insertions after
NOTE_INSN_FUNCTION_BEG.

* gcc.target/arm/require-pic-register-loc.c: New test.

Index: gcc/cfgexpand.c
===
--- gcc/cfgexpand.c (revision 421892)
+++ gcc/cfgexpand.c (working copy)
@@ -4618,14 +4618,19 @@ gimple_expand_cfg (void)
 	  if (e-insns.r)
 	{
 	  rebuild_jump_labels_chain (e-insns.r);
-	  /* Avoid putting insns before parm_birth_insn.  */
+	  /* Put insns after parm birth, but before
+		 NOTE_INSNS_FUNCTION_BEG.  */
 	  if (e-src == ENTRY_BLOCK_PTR
 		   single_succ_p (ENTRY_BLOCK_PTR)
 		   parm_birth_insn)
 		{
 		  rtx insns = e-insns.r;
 		  e-insns.r = NULL_RTX;
-		  emit_insn_after_noloc (insns, parm_birth_insn, e-dest);
+		  if (NOTE_P (parm_birth_insn)
+		   NOTE_KIND (parm_birth_insn) == NOTE_INSN_FUNCTION_BEG)
+		emit_insn_before_noloc (insns, parm_birth_insn, e-dest);
+		  else
+		emit_insn_after_noloc (insns, parm_birth_insn, e-dest);
 		}
 	  else
 		commit_one_edge_insertion (e);
Index: gcc/testsuite/gcc.target/arm/require-pic-register-loc.c
===
--- /dev/null (new file)
+++ gcc/testsuite/gcc.target/arm/require-pic-register-loc.c (revision 0)
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options -g -fPIC } */
+
+void *v;
+void a (void *x) { }
+void b (void) { }
+   /* line 7.  */
+int/* line 8.  */
+main (int argc)/* line 9.  */
+{  /* line 10.  */
+  if (argc == 12345)   /* line 11.  */
+{
+  a (v);
+  return 1;
+}
+  b ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not \.loc 1 7 0 } } */
+/* { dg-final { scan-assembler-not \.loc 1 8 0 } } */
+/* { dg-final { scan-assembler-not \.loc 1 9 0 } } */
+
+/* The loc at the start of the prologue.  */
+/* { dg-final { scan-assembler-times \.loc 1 10 0 1 } } */
+
+/* The loc at the end of the prologue, with the first user line.  */
+/* { dg-final { scan-assembler-times \.loc 1 11 0 1 } } */


[PATCH, ARM] Fix line number data for PIC register setup code

2013-10-13 Thread Tom de Vries
Richard,

This patch fixes line number data for the PIC register setup code for ARM,
resulting in 174 removed FAILs for the gdb testsuite with -fPIC.

Consider break.c (minimized from gdb/testsuite/gdb.base/break.c):
...
 1  void *v;
 2  void a (void *x) { }
 3  void b (void) { }
 4  
 5  int
 6  main (int argc)
 7  {
 8if (argc == 12345)
 9  {
10a (v);
11return 1;
12  }
13b ();
14  
15return 0;
16  }
...

We compile like this with -fPIC:
...
$ arm-none-linux-gnueabi-gcc break.c -g -fPIC
...

and run to a breakpoint in main:
...
(gdb) b main
Breakpoint 1 at 0x8410: file break.c, line 7.
(gdb) c
Continuing.

Breakpoint 1, main (argc=1) at break.c:7
7   {
...

The breakpoint should be at line number 8, the first line with user code.

The assembly for the start of main looks like this:
...
main:
.LFB2:
.loc 1 7 0
.cfi_startproc
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
stmfd   sp!, {fp, lr}
.cfi_def_cfa_offset 8
.cfi_offset 11, -8
.cfi_offset 14, -4
add fp, sp, #4
.cfi_def_cfa 11, 4
sub sp, sp, #8
str r0, [fp, #-8]
.loc 1 7 0
ldr r2, .L6
.LPIC0:
add r2, pc, r2
.loc 1 8 0
ldr r1, [fp, #-8]
ldr r3, .L6+4
cmp r1, r3
bne .L4
.loc 1 10 0
...

From the point of view of the debugger, in the presence of .loc info, the
prologue is the code in between the 2 first .loc markers. See this comment in
gdb/arm-tdep.c:arm_skip_prologue:
...
  /* GCC always emits a line note before the prologue and another
 one after, even if the two are at the same address or on the
 same line.  Take advantage of this so that we do not need to
 know every instruction that might appear in the prologue.
...

So gdb breaks at line 7, because it considers the prologue the code between the
first 2 .locs, and the user code for main to start at the second .loc, which has
line number 7.

The code at the second .loc is the PIC register setup code, generated by
require_pic_register:
...
.loc 1 7 0
ldr r2, .L6
.LPIC0:
add r2, pc, r2
...

The second .loc is emitted by gcc, because it's the first insn after
NOTE_INSNS_FUNCTION_BEG (which sets final.c:force_source_line in
final.c:final_scan_insn).

The PIC register setup code is emitted after NOTE_INSNS_FUNCTION_BEG, because it
uses the insert_insn_on_edge mechanism, and the corresponding insertion in
cfgexpand.c:gimple_expand_cfg takes care to insert the code after the
parm_birth_insn:
...
  /* Avoid putting insns before parm_birth_insn.  */
  if (e-src == ENTRY_BLOCK_PTR
   single_succ_p (ENTRY_BLOCK_PTR)
   parm_birth_insn)
{
  rtx insns = e-insns.r;
  e-insns.r = NULL_RTX;
  emit_insn_after_noloc (insns, parm_birth_insn, e-dest);
}
...
And in the case for this test-case, parm_birth_insn is the 
NOTE_INSNS_FUNCTION_BEG.

In summary, the problem seems to be caused by a discrepancy between:
- the line number of the PIC register setup code (prologue_location), and
- the location of the PIC register setup code (after NOTE_INSN_FUNCTION_BEG).

The problem can be reproduced using Ulrich's example here (
http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01570.html ), but though related
it's not the same problem as explained there. There the wrong line number of the
breakpoint was after the first user line. Here the wrong line number of the
breakpoint is before the first user line.

We can see from that email that this problem was not present after the fix. The
problem was introduced by Jakub's fix for PR47028 (Insert entry edge insertions
after parm_birth_insn instead of at the beginning of first bb), 12 days after
Ulrich's fix.

This patch makes sure we emit insertions scheduled for the first real BB before
NOTE_INSN_FUNCTION_BEG. As a consequence, it moves the PIC register setup code
to before the NOTE_INSN_FUNCTION_BEG. This removes the second .loc, and the
breakpoint of main ends up at line 8.

Bootstrapped and regtested on x86_64 (ada inclusive), no issues found.

Tested gdb with target arm-none-linux-gnueabi and CFLAGS_FOR_TARGET=-fPIC. The
patch removes 174 FAILs.

Re-testing gcc with target arm-none-linux-gnueabi atm.

OK for trunk?

Thanks,
- Tom

2013-10-13  Tom de Vries  t...@codesourcery.com

* cfgexpand.c (gimple_expand_cfg): Don't commit insertions after
NOTE_INSN_FUNCTION_BEG.

* gcc.target/arm/require-pic-register-loc.c: New test.
Index: gcc/cfgexpand.c
===
--- gcc/cfgexpand.c (revision 421892)
+++ gcc/cfgexpand.c (working copy)
@@ -4618,14 +4618,19 @@ gimple_expand_cfg (void)
 	  

Fix line number data for PIC register setup code

2013-10-03 Thread Tom de Vries
Richard,

( see also related discussion
http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01570.html )

Consider break.c (minimized from gdb/testsuite/gdb.base/break.c):
...
void *v;
void a (void *x) { }
void b (void) { }

int
main (int argc)
{
  if (argc == 12345)
{
  a (v);
  return 1;
}
  b ();

  return 0;
}
...

We compile like this with -fPIC:
...
$ arm-none-linux-gnueabi-gcc break.c -g -fPIC
...

and run to a breakpoint in main:
...
(gdb) b main
Breakpoint 1 at 0x8410: file break.c, line 7.
(gdb) c
Continuing.

Breakpoint 1, main (argc=1) at break.c:7
7   {
...

When we compile with -fno-PIC, we break at another line:
...
(gdb) b main
Breakpoint 1 at 0x83f8: file break.c, line 8.
(gdb) continue
Continuing.

Breakpoint 1, main (argc=1) at break.c:8
8 if (argc == 12345)
...

AFAIU, the correct line number is 8, so the case with -fPIC needs to be fixed.


The assembly looks like this:
...
main:
.LFB0:
.file 1 break.c
.loc 1 88 0
.cfi_startproc
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
stmfd   sp!, {fp, lr}
.cfi_def_cfa_offset 8
.cfi_offset 11, -8
.cfi_offset 14, -4
add fp, sp, #4
.cfi_def_cfa 11, 4
sub sp, sp, #8
str r0, [fp, #-8]
.loc 1 88 0
ldr r2, .L4
.LPIC0:
add r2, pc, r2
.loc 1 89 0
ldr r1, [fp, #-8]
ldr r3, .L4+4
cmp r1, r3
bne .L2
.loc 1 91 0
...

From the point of view of the debugger, in the presence of .loc info, the
prologue is the code in between the 2 first .loc markers. See this comment in
gdb/arm-tdep.c:arm_skip_prologue:
...
  /* GCC always emits a line note before the prologue and another
 one after, even if the two are at the same address or on the
 same line.  Take advantage of this so that we do not need to
 know every instruction that might appear in the prologue.
...

Manually removing the second '.loc 1 88 0' (in the pic register setup generated
by require_pic_register) from the assembly gives us the required behaviour.

An easy way to achieve this in the compiler is this patch:
...
Index: config/arm/arm.c
===
--- config/arm/arm.c(revision 202646)
+++ config/arm/arm.c(working copy)
@@ -5542,9 +5542,12 @@ require_pic_register (void)
  seq = get_insns ();
  end_sequence ();

  for (insn = seq; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
- INSN_LOCATION (insn) = prologue_location;
+ INSN_LOCATION (insn) = UNKNOWN_LOCATION;

  /* We can be called during expansion of PHI nodes, where
 we can't yet emit instructions directly in the final
...

However, it looks to me somewhat contradictory that when we mark this code as
UNKNOWN_LOCATION gdb recognized it as part of the prologue, and when we mark it
with prologue_location, gdb doesn't recognize it as part of the prologue.


Looking in more detail why we're emitting the .loc, it's because the pic
register setup follows the FUNCTION_BEG insn-note, which forces a .loc on the
next insn using the final.c:force_source_line variable.

According to this comment in dwarf2out_source_line:
...
 ... NOTE_INSN_FUNCTION_BEG, i.e. the first
 insn that corresponds to something the user wrote.
...
NOTE_INSN_FUNCTION_BEG marks the beginning of user code. To me it seems that we
have to make a choice here: Either the pic register setup code generated by
require_pic_register is user code, or it is prologue code.

If it's prologue code, we need to emit it before the FUNCTION_BEG insn-note
(rough proof-of-concept patch attached), such that no .loc will be generated for
it. Gdb will recognize it as part of the prologue, and the breakpoint will have
the correct line number.

It it's user code, we need to mark it with the first user line, such that a .loc
with the first user line will be generated. Gdb then won't count it as part of
the prologue, and the breakpoint will have the correct line number.


My preference would be to mark it as prologue code, since that's the case for
other uses of arm_load_pic_register.

What is the proper way to fix this?

Thanks,
- Tom

2013-09-15  Tom de Vries  t...@codesourcery.com

gcc/
* cfgexpand.c (gimple_expand_cfg): Emit insns_before_parm_birth_insn.
* function.h (struct rtl_data): Add x_insns_before_parm_birth_insn
field.
(insns_before_parm_birth_insn): Define new macro.
* config/arm/arm.c (require_pic_register): Use
insns_before_parm_birth_insn.
Index: gcc/cfgexpand.c
===
--- gcc/cfgexpand.c (revision 418548)
+++ gcc/cfgexpand.c (working copy)
@@ -4609,6 +4609,10 @@ gimple_expand_cfg (void)
  split edges which