Re: PATCH: Check ia32 in GCC tests

2011-07-09 Thread H.J. Lu
On Sat, Jul 09, 2011 at 07:22:18PM -0700, H.J. Lu wrote:
> On Thu, Jul 07, 2011 at 10:29:53AM -0700, H.J. Lu wrote:
> > Hi,
> > 
> > On Linux/x86-64, when we pass
> > 
> > RUNTESTFLAGS="--target_board='unix{-mx32}'"
> > 
> > to GCC tests, we can't check lp64/ilp32 for availability of 64bit x86
> > instructions.  This patch adds ia32 and x32 effetive targets.  OK for
> > trunk?
> > 
> 
> Here is a followup patch to use ia32 effetive target.  OK for trunk?
> 
> Thanks.
> 
> 
> H.J.
> --
> 2011-07-09  H.J. Lu  
> 
>   * gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp: Check
>   ia32.
>   * go.test/go-test.exp (go-set-goarch): Likewise.
> 

A small update.

H.J.

2011-07-09  H.J. Lu  

* gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp: Check
ia32.
* go.test/go-test.exp (go-set-goarch): Likewise.

diff --git 
a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp 
b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp
index a11aa3b..1a22e7d 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp
@@ -22,7 +22,7 @@ load_lib gcc-dg.exp
 
 # Exit immediately if this isn't a x86 target.
 if { (![istarget x86_64-*-*] && ![istarget i?86-*-*])
- || (![is-effective-target x32] && ![is-effective-target lp64]) } then {
+ || [is-effective-target ia32] } then {
   return
 }
 
diff --git a/gcc/testsuite/go.test/go-test.exp 
b/gcc/testsuite/go.test/go-test.exp
index f0285a2..f5f2e60 100644
--- a/gcc/testsuite/go.test/go-test.exp
+++ b/gcc/testsuite/go.test/go-test.exp
@@ -134,7 +134,7 @@ proc go-set-goarch { } {
}
"i?86-*-*" -
"x86_64-*-*" {
-   if [check_effective_target_ilp32] {
+   if [check_effective_target_ia32] {
set goarch "386"
} else {
set goarch "amd64"


PATCH: Check ia32 in GCC tests

2011-07-09 Thread H.J. Lu
On Thu, Jul 07, 2011 at 10:29:53AM -0700, H.J. Lu wrote:
> Hi,
> 
> On Linux/x86-64, when we pass
> 
> RUNTESTFLAGS="--target_board='unix{-mx32}'"
> 
> to GCC tests, we can't check lp64/ilp32 for availability of 64bit x86
> instructions.  This patch adds ia32 and x32 effetive targets.  OK for
> trunk?
> 

Here is a followup patch to use ia32 effetive target.  OK for trunk?

Thanks.


H.J.
--
2011-07-09  H.J. Lu  

* gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp: Check
ia32.
* go.test/go-test.exp (go-set-goarch): Likewise.

diff --git 
a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp 
b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp
index a11aa3b..1a22e7d 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp
@@ -22,7 +22,7 @@ load_lib gcc-dg.exp
 
 # Exit immediately if this isn't a x86 target.
 if { (![istarget x86_64-*-*] && ![istarget i?86-*-*])
- || (![is-effective-target x32] && ![is-effective-target lp64]) } then {
+ || [is-effective-target ia32] } then {
   return
 }
 
diff --git a/gcc/testsuite/go.test/go-test.exp 
b/gcc/testsuite/go.test/go-test.exp
index f0285a2..5057dee 100644
--- a/gcc/testsuite/go.test/go-test.exp
+++ b/gcc/testsuite/go.test/go-test.exp
@@ -134,7 +134,7 @@ proc go-set-goarch { } {
}
"i?86-*-*" -
"x86_64-*-*" {
-   if [check_effective_target_ilp32] {
+   if { [check_effective_target_ia32] } {
set goarch "386"
} else {
set goarch "amd64"


Re: [rfc, i386] Convert output_mi_thunk to rtl

2011-07-09 Thread H.J. Lu
On Sat, Jul 9, 2011 at 6:43 PM, Richard Henderson  wrote:
> On 07/09/2011 06:42 PM, H.J. Lu wrote:
>> On Sat, Jul 9, 2011 at 6:34 PM, Richard Henderson  wrote:
>>> I developed this patch while working on the dwarf2 pass series.
>>> This was before I bypassed the entire problem by removing the
>>> !deep branch prediction paths.
>>>
>>> Ideally, we'd do this generically from gimple.  Less ideally,
>>> but still better, is to always emit rtl, and support that in
>>> the middle end without so many hacks in the back end.
>>>
>>> I think this cleans things up a bit over emitting text.
>>> Particularly if we then include HJ's x32 stuff.
>>>
>>> Thoughts?
>>
>> For TARGET_64BIT, please use ptr_mode instead of DImode
>> to load thunk into a register.
>
> That's not quite good enough.  For Correctness you need a
> zero-extension into Pmode.
>

Sure and i386.md has

(define_expand "zero_extendsidi2"
  [(set (match_operand:DI 0 "nonimmediate_operand" "")
(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
  ""
{
  if (!TARGET_64BIT)
{
  emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
  DONE;
}
})

(define_insn "*zero_extendsidi2_rex64"
  [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*Y2")
(zero_extend:DI
 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
  "TARGET_64BIT"
  "@
   mov\t{%k1, %k0|%k0, %k1}
   #
   movd\t{%1, %0|%0, %1}
   movd\t{%1, %0|%0, %1}
   %vmovd\t{%1, %0|%0, %1}
   %vmovd\t{%1, %0|%0, %1}"
  [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
   (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
   (set_attr "prefix_0f" "0,*,*,*,*,*")
   (set_attr "mode" "SI,DI,DI,DI,TI,TI")])



-- 
H.J.


Re: [rfc, i386] Convert output_mi_thunk to rtl

2011-07-09 Thread Richard Henderson
On 07/09/2011 06:42 PM, H.J. Lu wrote:
> On Sat, Jul 9, 2011 at 6:34 PM, Richard Henderson  wrote:
>> I developed this patch while working on the dwarf2 pass series.
>> This was before I bypassed the entire problem by removing the
>> !deep branch prediction paths.
>>
>> Ideally, we'd do this generically from gimple.  Less ideally,
>> but still better, is to always emit rtl, and support that in
>> the middle end without so many hacks in the back end.
>>
>> I think this cleans things up a bit over emitting text.
>> Particularly if we then include HJ's x32 stuff.
>>
>> Thoughts?
> 
> For TARGET_64BIT, please use ptr_mode instead of DImode
> to load thunk into a register.

That's not quite good enough.  For Correctness you need a
zero-extension into Pmode.


r~


Re: [rfc, i386] Convert output_mi_thunk to rtl

2011-07-09 Thread H.J. Lu
On Sat, Jul 9, 2011 at 6:34 PM, Richard Henderson  wrote:
> I developed this patch while working on the dwarf2 pass series.
> This was before I bypassed the entire problem by removing the
> !deep branch prediction paths.
>
> Ideally, we'd do this generically from gimple.  Less ideally,
> but still better, is to always emit rtl, and support that in
> the middle end without so many hacks in the back end.
>
> I think this cleans things up a bit over emitting text.
> Particularly if we then include HJ's x32 stuff.
>
> Thoughts?

For TARGET_64BIT, please use ptr_mode instead of DImode
to load thunk into a register.

Thanks.

-- 
H.J.


[rfc, i386] Convert output_mi_thunk to rtl

2011-07-09 Thread Richard Henderson
I developed this patch while working on the dwarf2 pass series.
This was before I bypassed the entire problem by removing the
!deep branch prediction paths.

Ideally, we'd do this generically from gimple.  Less ideally,
but still better, is to always emit rtl, and support that in
the middle end without so many hacks in the back end.

I think this cleans things up a bit over emitting text.
Particularly if we then include HJ's x32 stuff.

Thoughts?


r~
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 04cb07d..003941a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -29287,12 +29287,13 @@ x86_output_mi_thunk (FILE *file,
 tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
 HOST_WIDE_INT vcall_offset, tree function)
 {
-  rtx xops[3];
   rtx this_param = x86_this_parameter (function);
-  rtx this_reg, tmp;
+  rtx this_reg, tmp, fnaddr;
+
+  reload_completed = 1;
+  epilogue_completed = 1;
 
-  /* Make sure unwind info is emitted for the thunk if needed.  */
-  final_start_function (emit_barrier (), file, 1);
+  emit_note (NOTE_INSN_PROLOGUE_END);
 
   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
  pull it in now and let DELTA benefit.  */
@@ -29301,9 +29302,8 @@ x86_output_mi_thunk (FILE *file,
   else if (vcall_offset)
 {
   /* Put the this parameter into %eax.  */
-  xops[0] = this_param;
-  xops[1] = this_reg = gen_rtx_REG (Pmode, AX_REG);
-  output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
+  this_reg = gen_rtx_REG (Pmode, AX_REG);
+  emit_move_insn (this_reg, this_param);
 }
   else
 this_reg = NULL_RTX;
@@ -29311,117 +29311,124 @@ x86_output_mi_thunk (FILE *file,
   /* Adjust the this parameter by a fixed constant.  */
   if (delta)
 {
-  xops[0] = GEN_INT (delta);
-  xops[1] = this_reg ? this_reg : this_param;
+  rtx delta_rtx = GEN_INT (delta);
+  rtx delta_dst = this_reg ? this_reg : this_param;
+
   if (TARGET_64BIT)
{
- if (!x86_64_general_operand (xops[0], DImode))
+ if (!x86_64_general_operand (delta_rtx, Pmode))
{
- tmp = gen_rtx_REG (DImode, R10_REG);
- xops[1] = tmp;
- output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", xops);
- xops[0] = tmp;
- xops[1] = this_param;
+ tmp = gen_rtx_REG (Pmode, R10_REG);
+ emit_move_insn (tmp, delta_rtx);
+ delta_rtx = tmp;
}
- if (x86_maybe_negate_const_int (&xops[0], DImode))
-   output_asm_insn ("sub{q}\t{%0, %1|%1, %0}", xops);
- else
-   output_asm_insn ("add{q}\t{%0, %1|%1, %0}", xops);
}
-  else if (x86_maybe_negate_const_int (&xops[0], SImode))
-   output_asm_insn ("sub{l}\t{%0, %1|%1, %0}", xops);
-  else
-   output_asm_insn ("add{l}\t{%0, %1|%1, %0}", xops);
+
+  emit_insn (ix86_gen_add3 (delta_dst, delta_dst, delta_rtx));
 }
 
   /* Adjust the this parameter by a value stored in the vtable.  */
   if (vcall_offset)
 {
+  rtx vcall_addr, vcall_mem;
+  unsigned int tmp_regno;
+
   if (TARGET_64BIT)
-   tmp = gen_rtx_REG (DImode, R10_REG);
+   tmp_regno = R10_REG;
   else
{
- int tmp_regno = CX_REG;
  unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
+ tmp_regno = CX_REG;
  if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) != 0)
tmp_regno = AX_REG;
- tmp = gen_rtx_REG (SImode, tmp_regno);
}
+  tmp = gen_rtx_REG (Pmode, tmp_regno);
 
-  xops[0] = gen_rtx_MEM (Pmode, this_reg);
-  xops[1] = tmp;
-  output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
+  emit_move_insn (tmp, gen_rtx_MEM (ptr_mode, this_reg));
 
   /* Adjust the this parameter.  */
-  xops[0] = gen_rtx_MEM (Pmode, plus_constant (tmp, vcall_offset));
-  if (TARGET_64BIT && !memory_operand (xops[0], Pmode))
+  vcall_addr = plus_constant (tmp, vcall_offset);
+  if (TARGET_64BIT
+ && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
{
- rtx tmp2 = gen_rtx_REG (DImode, R11_REG);
- xops[0] = GEN_INT (vcall_offset);
- xops[1] = tmp2;
- output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
- xops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tmp, tmp2));
+ rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
+ emit_move_insn (tmp2, GEN_INT (vcall_offset));
+ vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
}
-  xops[1] = this_reg;
-  output_asm_insn ("add%z1\t{%0, %1|%1, %0}", xops);
+
+  vcall_mem = gen_rtx_MEM (Pmode, vcall_addr);
+  emit_insn (ix86_gen_add3 (this_reg, this_reg, vcall_mem));
 }
 
   /* If necessary, drop THIS back to its stack slot.  */
   if (this_reg && this_reg != this_param)
-{
-  xops[0] = this_reg;
-  xops[1] = this_param;
-  output_asm_insn ("mov%z1\t{

Re: PATCH [5/n] X32: Fix x32 trampoline

2011-07-09 Thread H.J. Lu
On Sat, Jul 9, 2011 at 4:12 PM, Richard Henderson  wrote:
> On 07/09/2011 04:05 PM, H.J. Lu wrote:
>>> Is this change actually necessary?  I would think that the
>>> predicate has already been adjusted...
>>>
>>
>> Since we always use short version for x32, there is no need to call.
>> x86_64_zext_immediate_operand.
>
> Yes, but using the shorter condition, i.e. always calling
> x86_64_zext_immediate_operand and letting it return true for
> all x32 symbols, is easier to maintain.

I always updated x86_64_zext_immediate_operand for x32.
I will remove TARGET_X32.

Thanks.

-- 
H.J.


Committed, cris-elf: Don't compile crtstuff.c with debug info

2011-07-09 Thread Hans-Peter Nilsson
The $(LIBGCC2_CFLAGS) removed in the patch is prehistoric
(before first commit in the FSF repo) but was once needed or at
least seemed like a good idea; I can't recall which.  These
days, its major effect is to add "-g", which with the recent
dwarf2 changes is lethal, if you're unlucky.  With the default
CRT_CALL_STATIC_FUNCTION it might add, in a dwarf2 frame info
debug section:

  .byte   0x4 ;# DW_CFA_advance_loc4
  .dword  .LCFI4-.LCFI3

where .LCFI4 and .LCFI3 are in different sections due to the
switching-sections-with-asm hack.  That kind of expression is
not supported.  There have to be a few unlucky circumstances:
the assembler has to not support CFI directives (the gcc
configure-test failing) and the stack frame for
 void call_foo(void) { asm(".section .init"); foo(); asm(".text"); }
has to be non-empty; call_foo has to explicitly store its
return-address (as with call insns in RISC ISAs).

Committed after testing that it works as good as defining
CRT_CALL_STATIC_FUNCTION, which would be needed in several
flavors due to PIC and ISA variation.

PR target/49684
* config/cris/t-elfmulti (CRTSTUFF_T_CFLAGS): Don't include
$(LIBGCC2_CFLAGS).

Index: config/cris/t-elfmulti
===
--- config/cris/t-elfmulti  (revision 175272)
+++ config/cris/t-elfmulti  (working copy)
@@ -1,4 +1,4 @@
-# Copyright (C) 2001, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2007, 2011 Free Software Foundation, Inc.
 #
 # This file is part of GCC.
 #
@@ -31,4 +31,4 @@ MULTILIB_MATCHES = \
 MULTILIB_EXTRA_OPTS = mbest-lib-options
 INSTALL_LIBGCC = install-multilib
 LIBGCC = stmp-multilib
-CRTSTUFF_T_CFLAGS = $(LIBGCC2_CFLAGS) -moverride-best-lib-options
+CRTSTUFF_T_CFLAGS = -moverride-best-lib-options

brgds, H-P


Re: PATCH [5/n] X32: Fix x32 trampoline

2011-07-09 Thread Richard Henderson
On 07/09/2011 04:05 PM, H.J. Lu wrote:
>> Is this change actually necessary?  I would think that the
>> predicate has already been adjusted...
>>
> 
> Since we always use short version for x32, there is no need to call.
> x86_64_zext_immediate_operand.

Yes, but using the shorter condition, i.e. always calling
x86_64_zext_immediate_operand and letting it return true for
all x32 symbols, is easier to maintain.

>> > Have I forgotten x86 encoding?  I thought movl imm,reg was 5 bytes...
>> >
>> >
> You forgot the REX prefix:

Ah, right.  I forgot what the chain register was.


r~


Re: PATCH [5/n] X32: Fix x32 trampoline

2011-07-09 Thread H.J. Lu
On Sat, Jul 9, 2011 at 3:46 PM, Richard Henderson  wrote:
> On 07/09/2011 02:41 PM, H.J. Lu wrote:
>> Hi,
>>
>> X32 uses movl instead of movabs for trampoline.  OK for trunk?
>>
>> Thanks.
>>
>> H.J.
>> ---
>> 2011-07-09  H.J. Lu  
>>
>>       * config/i386/i386.c (ix86_trampoline_init): Use movl instead
>>       of movabs for x32.
>>
>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>> index 04cb07d..c852719 100644
>> --- a/gcc/config/i386/i386.c
>> +++ b/gcc/config/i386/i386.c
>> @@ -22721,13 +23030,14 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, 
>> rtx chain_value)
>>      }
>>    else
>>      {
>> -      int offset = 0;
>> +      int offset = 0, size;
>>
>>        /* Load the function address to r11.  Try to load address using
>>        the shorter movl instead of movabs.  We may want to support
>>        movq for kernel mode, but kernel does not use trampolines at
>>        the moment.  */
>> -      if (x86_64_zext_immediate_operand (fnaddr, VOIDmode))
>> +      if (TARGET_X32
>> +       || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
>
> Is this change actually necessary?  I would think that the
> predicate has already been adjusted...
>

Since we always use short version for x32, there is no need to call.
x86_64_zext_immediate_operand.


-- 
H.J.


[PATCH] libtool -- don't print warnings with --silent

2011-07-09 Thread John David Anglin
The attached patch fixes the boehm-gc testsuite on hppa2.0w-hp-hpux11.11.
Without it, libtool always generates an informational warning when linking
causing the entire boehm-gc testsuite to fail.

Ok?  Ralf would you please install in libtool tree if ok.

2011-07-09  John David Anglin  

PR boehm-gc/48494
* ltmain.sh (func_warning): Don't print warnings if opt_silent is true.

Index: ltmain.sh
===
--- ltmain.sh   (revision 176045)
+++ ltmain.sh   (working copy)
@@ -437,7 +437,9 @@
 # Echo program name prefixed warning message to standard error.
 func_warning ()
 {
-$opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+${opt_silent-false} || {
+  $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+}
 
 # bash bug again:
 :

Dave
-- 
J. David Anglin  dave.ang...@nrc-cnrc.gc.ca
National Research Council of Canada  (613) 990-0752 (FAX: 952-6602)


Re: PATCH [5/n] X32: Fix x32 trampoline

2011-07-09 Thread H.J. Lu
On Sat, Jul 9, 2011 at 3:46 PM, Richard Henderson  wrote:
> On 07/09/2011 02:41 PM, H.J. Lu wrote:
>> Hi,
>>
>> X32 uses movl instead of movabs for trampoline.  OK for trunk?
>>
>> Thanks.
>>
>> H.J.
>> ---
>> 2011-07-09  H.J. Lu  
>>
>>       * config/i386/i386.c (ix86_trampoline_init): Use movl instead
>>       of movabs for x32.
>>
>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>> index 04cb07d..c852719 100644
>> --- a/gcc/config/i386/i386.c
>> +++ b/gcc/config/i386/i386.c
>> @@ -22721,13 +23030,14 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, 
>> rtx chain_value)
>>      }
>>    else
>>      {
>> -      int offset = 0;
>> +      int offset = 0, size;
>>
>>        /* Load the function address to r11.  Try to load address using
>>        the shorter movl instead of movabs.  We may want to support
>>        movq for kernel mode, but kernel does not use trampolines at
>>        the moment.  */
>> -      if (x86_64_zext_immediate_operand (fnaddr, VOIDmode))
>> +      if (TARGET_X32
>> +       || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
>
> Is this change actually necessary?  I would think that the
> predicate has already been adjusted...
>
>> -      emit_move_insn (mem, gen_int_mode (0xba49, HImode));
>> +      /* Use the shorter movl instead of movabs for x32.  */
>> +      if (TARGET_X32)
>> +     {
>> +       size = 6;
>> +       emit_move_insn (mem, gen_int_mode (0xba41, HImode));
>
> Have I forgotten x86 encoding?  I thought movl imm,reg was 5 bytes...
>
>

You forgot the REX prefix:

[hjl@gnu-6 tmp]$ cat x.s
mov $0x1234, %r11d
[hjl@gnu-6 tmp]$ gcc -c x.s
[hjl@gnu-6 tmp]$ objdump -dw x.o

x.o: file format elf64-x86-64


Disassembly of section .text:

 <.text>:
   0:   41 bb 00 00 34 12   mov$0x1234,%r11d
[hjl@gnu-6 tmp]$




-- 
H.J.


Re: PATCH [4/n] X32: Use ptr_mode for vtable adjustment

2011-07-09 Thread H.J. Lu
On Sat, Jul 9, 2011 at 3:43 PM, Richard Henderson  wrote:
> On 07/09/2011 02:36 PM, H.J. Lu wrote:
>>
>> Hi,
>>
>> Thunk is in ptr_mode, not Pmode.  OK for trunk?
>>
>> Thanks.
>>
>> H.J.
>> ---
>> 2011-07-09  H.J. Lu  
>>
>>       * config/i386/i386.c (x86_output_mi_thunk): Use ptr_mode instead
>>       of Pmode for vtable adjustment.
>>
>> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
>> index 04cb07d..c852719 100644
>> --- a/gcc/config/i386/i386.c
>> +++ b/gcc/config/i386/i386.c
>> @@ -29338,7 +29681,7 @@ x86_output_mi_thunk (FILE *file,
>>    if (vcall_offset)
>>      {
>>        if (TARGET_64BIT)
>> -     tmp = gen_rtx_REG (DImode, R10_REG);
>> +     tmp = gen_rtx_REG (ptr_mode, R10_REG);
>>        else
>>       {
>>         int tmp_regno = CX_REG;
>> @@ -29348,7 +29691,7 @@ x86_output_mi_thunk (FILE *file,
>>         tmp = gen_rtx_REG (SImode, tmp_regno);
>>       }
>>
>> -      xops[0] = gen_rtx_MEM (Pmode, this_reg);
>> +      xops[0] = gen_rtx_MEM (ptr_mode, this_reg);
>>        xops[1] = tmp;
>>        output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
>>
>> @@ -29360,9 +29703,10 @@ x86_output_mi_thunk (FILE *file,
>>         xops[0] = GEN_INT (vcall_offset);
>>         xops[1] = tmp2;
>>         output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
>> -       xops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tmp, tmp2));
>> +       xops[0] = gen_rtx_MEM (ptr_mode,
>> +                              gen_rtx_PLUS (Pmode, tmp, tmp2));
>>       }
>> -      xops[1] = this_reg;
>> +      xops[1] = gen_rtx_REG (ptr_mode, REGNO (this_reg));
>
> Not ok.  This is incoherent in its treatment of Pmode vs ptr_mode.
> You're creating an addition
>
>        (plus:P (reg:ptr tmp) (reg:P tmp2))

It is because thunk is stored in ptr_mode, not Pmode.

>
> I have a queued patch that replaces all of this with rtl.  I will
> post it later today.
>

I will update it for x32 after your change is checked in.

Thanks.

-- 
H.J.


Committed: robustify CRIS ASM_OUTPUT_CASE_END

2011-07-09 Thread Hans-Peter Nilsson
The recent dwarf2 changes caused notes to be emitted between the
CRIS (casesi expanded to sort-of) tablejump and the jump-table.
I know RTH solved that particular problem another way (thanks!),
but the documented adjacency promise is about of instructions,
not notes, so it seems appropriate to also commit this tested
solution hopefully avoiding some future surprises.  And if
something happens, we have a chance to catch it as an internal
error rather than hoping for a SEGV.

PR bootstrap/49680
* config/cris/cris.c (cris_asm_output_case_end): Robustify against
stray notes and debug insns by using prev_nonnote_nondebug_insn
instead of PREV_INSN.

Index: config/cris/cris.c
===
--- config/cris/cris.c  (revision 175272)
+++ config/cris/cris.c  (working copy)
@@ -2275,12 +2275,22 @@ cris_legitimate_pic_operand (rtx x)
 void
 cris_asm_output_case_end (FILE *stream, int num, rtx table)
 {
+  /* Step back, over the label for the table, to the actual casejump and
+ assert that we find only what's expected.  */
+  rtx whole_jump_insn = prev_nonnote_nondebug_insn (table);
+  gcc_assert (whole_jump_insn != NULL_RTX && LABEL_P (whole_jump_insn));
+  whole_jump_insn = prev_nonnote_nondebug_insn (whole_jump_insn);
+  gcc_assert (whole_jump_insn != NULL_RTX
+ && (JUMP_P (whole_jump_insn)
+ || (TARGET_V32 && INSN_P (whole_jump_insn)
+ && GET_CODE (PATTERN (whole_jump_insn)) == SEQUENCE)));
+  /* Get the pattern of the casejump, so we can extract the default label.  */
+  whole_jump_insn = PATTERN (whole_jump_insn);
+
   if (TARGET_V32)
 {
-  rtx whole_jump_insn = PATTERN (PREV_INSN (PREV_INSN (table)));
-
   /* This can be a SEQUENCE, meaning the delay-slot of the jump is
-filled.  */
+filled.  We also output the offset word a little differently.  */
   rtx parallel_jump
= (GET_CODE (whole_jump_insn) == SEQUENCE
   ? PATTERN (XVECEXP (whole_jump_insn, 0, 0)) : whole_jump_insn);
@@ -2298,11 +2308,7 @@ cris_asm_output_case_end (FILE *stream, 
   "\t.word %LL%d-%LL%d%s\n",
   CODE_LABEL_NUMBER (XEXP
  (XEXP
-  (XEXP
-   (XVECEXP
-(PATTERN
- (PREV_INSN
-  (PREV_INSN (table))), 0, 0), 1),
+  (XEXP (XVECEXP (whole_jump_insn, 0, 0), 1), 
2), 0)),
   num,
   (TARGET_PDEBUG ? "; default" : ""));

brgds, H-P


Re: PATCH [5/n] X32: Fix x32 trampoline

2011-07-09 Thread Richard Henderson
On 07/09/2011 02:41 PM, H.J. Lu wrote:
> Hi,
> 
> X32 uses movl instead of movabs for trampoline.  OK for trunk?
> 
> Thanks.
> 
> H.J.
> ---
> 2011-07-09  H.J. Lu  
> 
>   * config/i386/i386.c (ix86_trampoline_init): Use movl instead
>   of movabs for x32.
> 
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 04cb07d..c852719 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -22721,13 +23030,14 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx 
> chain_value)
>  }
>else
>  {
> -  int offset = 0;
> +  int offset = 0, size;
>  
>/* Load the function address to r11.  Try to load address using
>the shorter movl instead of movabs.  We may want to support
>movq for kernel mode, but kernel does not use trampolines at
>the moment.  */
> -  if (x86_64_zext_immediate_operand (fnaddr, VOIDmode))
> +  if (TARGET_X32
> +   || x86_64_zext_immediate_operand (fnaddr, VOIDmode))

Is this change actually necessary?  I would think that the 
predicate has already been adjusted...

> -  emit_move_insn (mem, gen_int_mode (0xba49, HImode));
> +  /* Use the shorter movl instead of movabs for x32.  */
> +  if (TARGET_X32)
> + {
> +   size = 6;
> +   emit_move_insn (mem, gen_int_mode (0xba41, HImode));

Have I forgotten x86 encoding?  I thought movl imm,reg was 5 bytes...


r~


Re: PATCH [4/n] X32: Use ptr_mode for vtable adjustment

2011-07-09 Thread Richard Henderson
On 07/09/2011 02:36 PM, H.J. Lu wrote:
> 
> Hi,
> 
> Thunk is in ptr_mode, not Pmode.  OK for trunk?
> 
> Thanks.
> 
> H.J.
> ---
> 2011-07-09  H.J. Lu  
> 
>   * config/i386/i386.c (x86_output_mi_thunk): Use ptr_mode instead
>   of Pmode for vtable adjustment.
> 
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 04cb07d..c852719 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -29338,7 +29681,7 @@ x86_output_mi_thunk (FILE *file,
>if (vcall_offset)
>  {
>if (TARGET_64BIT)
> - tmp = gen_rtx_REG (DImode, R10_REG);
> + tmp = gen_rtx_REG (ptr_mode, R10_REG);
>else
>   {
> int tmp_regno = CX_REG;
> @@ -29348,7 +29691,7 @@ x86_output_mi_thunk (FILE *file,
> tmp = gen_rtx_REG (SImode, tmp_regno);
>   }
>  
> -  xops[0] = gen_rtx_MEM (Pmode, this_reg);
> +  xops[0] = gen_rtx_MEM (ptr_mode, this_reg);
>xops[1] = tmp;
>output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
>  
> @@ -29360,9 +29703,10 @@ x86_output_mi_thunk (FILE *file,
> xops[0] = GEN_INT (vcall_offset);
> xops[1] = tmp2;
> output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
> -   xops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tmp, tmp2));
> +   xops[0] = gen_rtx_MEM (ptr_mode,
> +  gen_rtx_PLUS (Pmode, tmp, tmp2));
>   }
> -  xops[1] = this_reg;
> +  xops[1] = gen_rtx_REG (ptr_mode, REGNO (this_reg));

Not ok.  This is incoherent in its treatment of Pmode vs ptr_mode.
You're creating an addition

(plus:P (reg:ptr tmp) (reg:P tmp2))

I have a queued patch that replaces all of this with rtl.  I will
post it later today.


r~


PATCH [5/n] X32: Supprot 32bit address

2011-07-09 Thread H.J. Lu
Hi,

TARGET_MEM_REF only works on ptr_mode.  That means base and index parts
of x86 address operand in x32 mode may be in ptr_mode.  This patch
supports 32bit base and index parts in x32 mode.  OK for trunk?

Thanks.


H.J.
---
2011-07-09  H.J. Lu  

* config/i386/i386.c (ix86_simplify_base_index_disp): New.
(ix86_decompose_address): Support 32bit address in x32 mode.
(ix86_legitimate_address_p): Likewise.
(ix86_fixup_binary_operands): Likewise.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 04cb07d..c852719 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10984,6 +11010,190 @@ ix86_live_on_entry (bitmap regs)
 }
 }
 
+/* For TARGET_X32, IRA may generate
+
+   (set (reg:SI 40 r11)
+(plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
+  (const_int 8))
+ (subreg:SI (plus:DI (reg/f:DI 7 sp)
+ (const_int CONST1)) 0))
+(const_int CONST2)))
+
+   We translate it into
+
+   (set (reg:SI 40 r11)
+(plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
+  (const_int 8))
+ (reg/f:SI 7 sp))
+(const_int [CONST1 + CONST2])))
+
+   We also translate
+
+   (plus:DI (zero_extend:DI (plus:SI (plus:SI (reg:SI 4 si [70])
+ (reg:SI 2 cx [86]))
+(const_int CONST1)))
+   (const_int CONST2))
+
+   into
+
+   (plus:DI (zero_extend:DI (plus:SI (reg:SI 4 si [70])
+(reg:SI 2 cx [86]))
+   (const_int [CONST1 + CONST2])))
+
+   We also translate
+
+   (plus:SI (plus:SI (plus:SI (reg:SI 4 si [70])
+ (reg:SI 2 cx [86]))
+(symbol_ref:SI ("A.193.2210")))
+   (const_int CONST))
+
+   into
+
+   (plus:SI (plus:SI (reg:SI 4 si [70])
+(reg:SI 2 cx [86]))
+   (const (plus:SI (symbol_ref:SI ("A.193.2210"))
+   (const_int CONST
+
+   We also translate
+
+   (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+   (subreg:SI (plus:DI (reg/f:DI 7 sp)
+   (const_int 64 [0x40])) 0))
+
+   into
+
+   (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+   (plus:SI (reg/f:SI 7 sp) (const_int 64 [0x40])))
+
+   If PLUS is true, we also translate
+
+   (set (reg:SI 40 r11)
+(plus:SI (plus:SI (reg:SI 1 dx)
+ (subreg:SI (plus:DI (reg/f:DI 7 sp)
+ (const_int CONST1)) 0))
+(const_int CONST2)))
+
+   into
+
+   (set (reg:SI 40 r11)
+(plus:SI (plus:SI (reg:SI 1 dx)
+ (reg/f:SI 7 sp))
+(const_int [CONST1 + CONST2])))
+
+ */
+
+static void
+ix86_simplify_base_index_disp (rtx *base_p, rtx *index_p, rtx *disp_p,
+  bool plus)
+{
+  rtx base = *base_p;
+  rtx disp, index, op0, op1;
+
+  if (!base || GET_MODE (base) != ptr_mode)
+return;
+
+  disp = *disp_p;
+  if (disp != NULL_RTX
+  && disp != const0_rtx
+  && !CONST_INT_P (disp))
+return;
+
+  if (GET_CODE (base) == SUBREG)
+base = SUBREG_REG (base);
+
+  if (GET_CODE (base) == PLUS)
+{
+  rtx addend;
+
+  op0 = XEXP (base, 0);
+  op1 = XEXP (base, 1);
+
+  if ((REG_P (op0)
+  || (!plus
+  && GET_CODE (op0) == PLUS
+  && GET_MODE (op0) == ptr_mode
+  && REG_P (XEXP (op0, 0))
+  && REG_P (XEXP (op0, 1
+ && (CONST_INT_P (op1)
+ || GET_CODE (op1) == SYMBOL_REF
+ || GET_CODE (op1) == LABEL_REF))
+   {
+ base = op0;
+ addend = op1;
+   }
+  else if (REG_P (op1)
+  && (CONST_INT_P (op0)
+  || GET_CODE (op0) == SYMBOL_REF
+  || GET_CODE (op0) == LABEL_REF))
+   {
+ base = op1;
+ addend = op0;
+   }
+  else if (plus
+  && GET_CODE (op1) == SUBREG
+  && GET_MODE (op1) == ptr_mode)
+   {
+ op1 = SUBREG_REG (op1);
+ if (GET_CODE (op1) == PLUS)
+   {
+ addend = XEXP (op1, 1);
+ op1 = XEXP (op1, 0);
+ if (REG_P (op1) && CONST_INT_P (addend))
+   {
+ op1 = gen_rtx_REG (ptr_mode, REGNO (op1));
+ *base_p = gen_rtx_PLUS (ptr_mode, op0, op1);
+   }
+ else
+   return;
+   }
+ else
+   return;
+   }
+  else
+   return;
+
+  if (disp == NULL_RTX || disp == const0_rtx)
+   *disp_p = addend;
+  else
+   {
+ if (CONST_INT_P (addend))
+   *disp_p = GEN_INT (INTVAL (disp) + INTVAL (addend));
+ else
+   {
+ disp = gen_rtx_PLUS (ptr_mode, addend, disp);
+ 

PATCH [5/n] X32: Fix x32 trampoline

2011-07-09 Thread H.J. Lu
Hi,

X32 uses movl instead of movabs for trampoline.  OK for trunk?

Thanks.

H.J.
---
2011-07-09  H.J. Lu  

* config/i386/i386.c (ix86_trampoline_init): Use movl instead
of movabs for x32.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 04cb07d..c852719 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -22721,13 +23030,14 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
 }
   else
 {
-  int offset = 0;
+  int offset = 0, size;
 
   /* Load the function address to r11.  Try to load address using
 the shorter movl instead of movabs.  We may want to support
 movq for kernel mode, but kernel does not use trampolines at
 the moment.  */
-  if (x86_64_zext_immediate_operand (fnaddr, VOIDmode))
+  if (TARGET_X32
+ || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
{
  fnaddr = copy_to_mode_reg (DImode, fnaddr);
 
@@ -22750,11 +23060,21 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
 
   /* Load static chain using movabs to r10.  */
   mem = adjust_address (m_tramp, HImode, offset);
-  emit_move_insn (mem, gen_int_mode (0xba49, HImode));
+  /* Use the shorter movl instead of movabs for x32.  */
+  if (TARGET_X32)
+   {
+ size = 6;
+ emit_move_insn (mem, gen_int_mode (0xba41, HImode));
+   }
+  else
+   {
+ size = 10;
+ emit_move_insn (mem, gen_int_mode (0xba49, HImode));
+   }
 
-  mem = adjust_address (m_tramp, DImode, offset + 2);
+  mem = adjust_address (m_tramp, ptr_mode, offset + 2);
   emit_move_insn (mem, chain_value);
-  offset += 10;
+  offset += size;
 
   /* Jump to r11; the last (unused) byte is a nop, only there to
 pad the write out to a single 32-bit store.  */


PATCH [4/n] X32: Use ptr_mode for vtable adjustment

2011-07-09 Thread H.J. Lu

Hi,

Thunk is in ptr_mode, not Pmode.  OK for trunk?

Thanks.

H.J.
---
2011-07-09  H.J. Lu  

* config/i386/i386.c (x86_output_mi_thunk): Use ptr_mode instead
of Pmode for vtable adjustment.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 04cb07d..c852719 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -29338,7 +29681,7 @@ x86_output_mi_thunk (FILE *file,
   if (vcall_offset)
 {
   if (TARGET_64BIT)
-   tmp = gen_rtx_REG (DImode, R10_REG);
+   tmp = gen_rtx_REG (ptr_mode, R10_REG);
   else
{
  int tmp_regno = CX_REG;
@@ -29348,7 +29691,7 @@ x86_output_mi_thunk (FILE *file,
  tmp = gen_rtx_REG (SImode, tmp_regno);
}
 
-  xops[0] = gen_rtx_MEM (Pmode, this_reg);
+  xops[0] = gen_rtx_MEM (ptr_mode, this_reg);
   xops[1] = tmp;
   output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
 
@@ -29360,9 +29703,10 @@ x86_output_mi_thunk (FILE *file,
  xops[0] = GEN_INT (vcall_offset);
  xops[1] = tmp2;
  output_asm_insn ("mov{q}\t{%0, %1|%1, %0}", xops);
- xops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tmp, tmp2));
+ xops[0] = gen_rtx_MEM (ptr_mode,
+gen_rtx_PLUS (Pmode, tmp, tmp2));
}
-  xops[1] = this_reg;
+  xops[1] = gen_rtx_REG (ptr_mode, REGNO (this_reg));
   output_asm_insn ("add%z1\t{%0, %1|%1, %0}", xops);
 }
 


Re: PING: PATCH [4/n]: Prepare x32: Permute the conversion and addition if one operand is a constant

2011-07-09 Thread H.J. Lu
On Sat, Jul 9, 2011 at 2:18 PM, Paolo Bonzini  wrote:
> On 07/05/2011 04:27 PM, H.J. Lu wrote:
>>>
>>>  diff --git a/gcc/explow.c b/gcc/explow.c
>>>  index 7387dad..b343bf8 100644
>>>  --- a/gcc/explow.c
>>>  +++ b/gcc/explow.c
>>>  @@ -383,18 +383,13 @@ convert_memory_address_addr_space (enum
>>> machine_mode to_mode ATTRIBUTE_UNUSED,
>>>
>>>      case PLUS:
>>>      case MULT:
>>>  -      /* For addition we can safely permute the conversion and addition
>>>  -        operation if one operand is a constant and converting the
>>> constant
>>>  -        does not change it or if one operand is a constant and we are
>>>  -        using a ptr_extend instruction  (POINTERS_EXTEND_UNSIGNED<  0).
>>>  -        We can always safely permute them if we are making the address
>>>  -        narrower.  */
>>>  +      /* For addition we safely permute the conversion and addition
>>>  +        operation if one operand is a constant since we can't generate
>>>  +        new instructions.  We can always safely permute them if we are
>>>  +        making the address narrower.  */
>>>        if (GET_MODE_SIZE (to_mode)<  GET_MODE_SIZE (from_mode)
>>>           || (GET_CODE (x) == PLUS
>>>  -&&  CONST_INT_P (XEXP (x, 1))
>>>  -&&  (XEXP (x, 1) == convert_memory_address_addr_space
>>>  -                                  (to_mode, XEXP (x, 1), as)
>>>  -                 || POINTERS_EXTEND_UNSIGNED<  0)))
>>>  +&&  CONST_INT_P (XEXP (x, 1
>>>         return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
>>>                                convert_memory_address_addr_space
>>>                                  (to_mode, XEXP (x, 0), as),
>
> This does not seem safe to me.
>
> Paolo
>

The current code is broken for x32.  See:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47727

We can't generate any new instructions.  Do you have any suggestions.

Thanks.

-- 
H.J.


PATCH [3/n] X32: Promote pointers to Pmode

2011-07-09 Thread H.J. Lu
Hi,

X32 psABI requires promoting pointers to Pmode when passing/returning
in registers.  OK for trunk?

Thanks.

H.J.
--
2011-07-09  H.J. Lu  

* config/i386/i386.c (ix86_promote_function_mode): New.
(TARGET_PROMOTE_FUNCTION_MODE): Likewise.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 04cb07d..c852719 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7052,6 +7061,23 @@ ix86_function_value (const_tree valtype, const_tree 
fntype_or_decl,
   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
 }
 
+/* Pointer function arguments and return values are promoted to
+   Pmode.  */
+
+static enum machine_mode
+ix86_promote_function_mode (const_tree type, enum machine_mode mode,
+   int *punsignedp, const_tree fntype,
+   int for_return)
+{
+  if (for_return != 1 && type != NULL_TREE && POINTER_TYPE_P (type))
+{
+  *punsignedp = POINTERS_EXTEND_UNSIGNED;
+  return Pmode;
+}
+  return default_promote_function_mode (type, mode, punsignedp, fntype,
+   for_return);
+}
+
 rtx
 ix86_libcall_value (enum machine_mode mode)
 {
@@ -34810,6 +35154,9 @@ ix86_autovectorize_vector_sizes (void)
 #undef TARGET_FUNCTION_VALUE_REGNO_P
 #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
 
+#undef TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
+
 #undef TARGET_SECONDARY_RELOAD
 #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
 


[Patch, Fortran, committed] Fix -Wold-style-definition warning in libgfortran

2011-07-09 Thread Tobias Burnus
When looking at the build log, I saw a -Wold-style-definition warning in 
libgfortran.


I have committed fix as obvious (Rev. 176109).

Tobias
Index: libgfortran/runtime/error.c
===
--- libgfortran/runtime/error.c	(Revision 176108)
+++ libgfortran/runtime/error.c	(Arbeitskopie)
@@ -164,7 +164,7 @@ st_printf (const char * format, ...)
core.  */
 
 void
-sys_abort ()
+sys_abort (void)
 {
   /* If backtracing is enabled, print backtrace and disable signal
  handler for ABRT.  */
Index: libgfortran/ChangeLog
===
--- libgfortran/ChangeLog	(Revision 176108)
+++ libgfortran/ChangeLog	(Arbeitskopie)
@@ -1,4 +1,9 @@
 2011-07-09  Tobias Burnus  
+
+	* runtime/error.c (sys_abort): Change argument list
+	from "()" to "(void)".
+
+2011-07-09  Tobias Burnus  
 	Daniel Carrera  
 
 	* caf/mpi.c (runtime_error): New function.


PATCH [2/n] X32: Turn on 64bit and check models for x32

2011-07-09 Thread H.J. Lu
Hi,

This patch turns on 64bit and check models for x32.  OK for trunk?

Thanks.

H.J.
---
2011-07-09  H.J. Lu  

* config/i386/i386.c (ix86_option_override_internal): Turn on
OPTION_MASK_ISA_64BIT for TARGET_X32.  Only allow small and
small PIC models for TARGET_X32.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 04cb07d..c852719 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2973,6 +2973,9 @@ ix86_option_override_internal (bool main_args_p)
   SUBSUBTARGET_OVERRIDE_OPTIONS;
 #endif
 
+  if (TARGET_X32)
+ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+
   /* -fPIC is the default for x86_64.  */
   if (TARGET_MACHO && TARGET_64BIT)
 flag_pic = 2;
@@ -3064,6 +3067,9 @@ ix86_option_override_internal (bool main_args_p)
  if (!TARGET_64BIT)
error ("code model %qs not supported in the %s bit mode",
   "medium", "32");
+ else if (TARGET_X32)
+   error ("code model %qs not supported in x32 mode",
+  "medium");
  break;
 
case CM_LARGE:
@@ -3073,6 +3079,9 @@ ix86_option_override_internal (bool main_args_p)
  if (!TARGET_64BIT)
error ("code model %qs not supported in the %s bit mode",
   "large", "32");
+ else if (TARGET_X32)
+   error ("code model %qs not supported in x32 mode",
+  "medium");
  break;
 
case CM_32:


Re: PING: PATCH [4/n]: Prepare x32: Permute the conversion and addition if one operand is a constant

2011-07-09 Thread Paolo Bonzini

On 07/05/2011 04:27 PM, H.J. Lu wrote:

 diff --git a/gcc/explow.c b/gcc/explow.c
 index 7387dad..b343bf8 100644
 --- a/gcc/explow.c
 +++ b/gcc/explow.c
 @@ -383,18 +383,13 @@ convert_memory_address_addr_space (enum machine_mode 
to_mode ATTRIBUTE_UNUSED,

  case PLUS:
  case MULT:
 -  /* For addition we can safely permute the conversion and addition
 -operation if one operand is a constant and converting the constant
 -does not change it or if one operand is a constant and we are
 -using a ptr_extend instruction  (POINTERS_EXTEND_UNSIGNED<  0).
 -We can always safely permute them if we are making the address
 -narrower.  */
 +  /* For addition we safely permute the conversion and addition
 +operation if one operand is a constant since we can't generate
 +new instructions.  We can always safely permute them if we are
 +making the address narrower.  */
if (GET_MODE_SIZE (to_mode)<  GET_MODE_SIZE (from_mode)
   || (GET_CODE (x) == PLUS
 -&&  CONST_INT_P (XEXP (x, 1))
 -&&  (XEXP (x, 1) == convert_memory_address_addr_space
 -  (to_mode, XEXP (x, 1), as)
 - || POINTERS_EXTEND_UNSIGNED<  0)))
 +&&  CONST_INT_P (XEXP (x, 1
 return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
convert_memory_address_addr_space
  (to_mode, XEXP (x, 0), as),


This does not seem safe to me.

Paolo


Re: PING: PATCH [4/n]: Prepare x32: Permute the conversion and addition if one operand is a constant

2011-07-09 Thread H.J. Lu
Hi Jeff,

Can you take a look at this?

Thanks.

H.J.
On Tue, Jul 5, 2011 at 7:27 AM, H.J. Lu  wrote:
> Ping.
>
> On Sat, Jun 11, 2011 at 8:58 AM, H.J. Lu  wrote:
>> Hi,
>>
>> convert_memory_address_addr_space has a special PLUS/MULT case for
>> POINTERS_EXTEND_UNSIGNED < 0.  It turns out that it is also needed
>> for all Pmode != ptr_mode cases.  OK for trunk?
>>
>> Thanks.
>>
>>
>> H.J.
>> ---
>> 2011-06-11  H.J. Lu  
>>
>>        PR middle-end/47727
>>        * explow.c (convert_memory_address_addr_space): Permute the
>>        conversion and addition if one operand is a constant.
>>
>> diff --git a/gcc/explow.c b/gcc/explow.c
>> index 7387dad..b343bf8 100644
>> --- a/gcc/explow.c
>> +++ b/gcc/explow.c
>> @@ -383,18 +383,13 @@ convert_memory_address_addr_space (enum machine_mode 
>> to_mode ATTRIBUTE_UNUSED,
>>
>>     case PLUS:
>>     case MULT:
>> -      /* For addition we can safely permute the conversion and addition
>> -        operation if one operand is a constant and converting the constant
>> -        does not change it or if one operand is a constant and we are
>> -        using a ptr_extend instruction  (POINTERS_EXTEND_UNSIGNED < 0).
>> -        We can always safely permute them if we are making the address
>> -        narrower.  */
>> +      /* For addition we safely permute the conversion and addition
>> +        operation if one operand is a constant since we can't generate
>> +        new instructions.  We can always safely permute them if we are
>> +        making the address narrower.  */
>>       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
>>          || (GET_CODE (x) == PLUS
>> -             && CONST_INT_P (XEXP (x, 1))
>> -             && (XEXP (x, 1) == convert_memory_address_addr_space
>> -                                  (to_mode, XEXP (x, 1), as)
>> -                 || POINTERS_EXTEND_UNSIGNED < 0)))
>> +             && CONST_INT_P (XEXP (x, 1
>>        return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
>>                               convert_memory_address_addr_space
>>                                 (to_mode, XEXP (x, 0), as),
>>
>
>
>
> --
> H.J.
>



-- 
H.J.


[x32] PATCH: Add comments to *movsi_internal

2011-07-09 Thread H.J. Lu
Hi,

I checked in this patch to add comments to *movsi_internal.

H.J.
---
commit 3c92ec7ad8591d3b2e3c3bc3c6b25e2bf38335cf
Author: H.J. Lu 
Date:   Sat Jul 9 08:03:46 2011 -0700

Add comments to *movsi_internal.

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index fdff5af..57ecbe4 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,5 +1,9 @@
 2011-07-09  H.J. Lu  
 
+   * config/i386/i386.md (*movsi_internal): Add comments.
+
+2011-07-09  H.J. Lu  
+
* config/i386/i386.c (ix86_simplify_base_disp): Renamed to ...
(ix86_simplify_base_index_disp): This.  Handle index.
(ix86_simplify_base_disp): Updated.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 4230c8f..f00c73b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2197,9 +2197,11 @@
   [(const_int 0)]
   "ix86_split_long_move (operands); DONE;")
 
+;; Use "Ys" constraint to disallow store with X32 PIC operand as
+;; immediate.
 (define_insn "*movsi_internal"
   [(set (match_operand:SI 0 "nonimmediate_operand"
-   "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
+   "=r,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
(match_operand:SI 1 "general_operand"
"g ,rYs,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"


[x32] PATCH: Add x32 LEA zero-extend split

2011-07-09 Thread H.J. Lu
Hi,

I checked in this patch to add x32 LEA zero-extend split.

H.J.
---
commit a57ad5f219b8aa7cc67c18fb3a217517c2a461f4
Author: H.J. Lu 
Date:   Sat Jul 9 08:00:56 2011 -0700

Support x32 LEA zero-extend split.

diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index a610f23..fdff5af 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,3 +1,14 @@
+2011-07-09  H.J. Lu  
+
+   * config/i386/i386.c (ix86_simplify_base_disp): Renamed to ...
+   (ix86_simplify_base_index_disp): This.  Handle index.
+   (ix86_simplify_base_disp): Updated.
+
+   * config/i386/i386.md (*lea_1_x32): Renamed to ...
+   (*lea_2_x32): This.
+   (*lea_2_zext_x32): New.
+   (X32 LEA zero-extend split): Likewise.
+
 2011-07-06  H.J. Lu  
 
* config.gcc: Check with_multilib_list instead of enable_x32.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b0112b9..c852719 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11054,6 +11054,17 @@ ix86_live_on_entry (bitmap regs)
(const (plus:SI (symbol_ref:SI ("A.193.2210"))
(const_int CONST
 
+   We also translate
+
+   (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+   (subreg:SI (plus:DI (reg/f:DI 7 sp)
+   (const_int 64 [0x40])) 0))
+
+   into
+
+   (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+   (plus:SI (reg/f:SI 7 sp) (const_int 64 [0x40])))
+
If PLUS is true, we also translate
 
(set (reg:SI 40 r11)
@@ -11072,10 +11083,11 @@ ix86_live_on_entry (bitmap regs)
  */
 
 static void
-ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus)
+ix86_simplify_base_index_disp (rtx *base_p, rtx *index_p, rtx *disp_p,
+  bool plus)
 {
   rtx base = *base_p;
-  rtx disp;
+  rtx disp, index, op0, op1;
 
   if (!base || GET_MODE (base) != ptr_mode)
 return;
@@ -11091,10 +11103,11 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, 
bool plus)
 
   if (GET_CODE (base) == PLUS)
 {
-  rtx op0 = XEXP (base, 0);
-  rtx op1 = XEXP (base, 1);
   rtx addend;
 
+  op0 = XEXP (base, 0);
+  op1 = XEXP (base, 1);
+
   if ((REG_P (op0)
   || (!plus
   && GET_CODE (op0) == PLUS
@@ -11160,6 +11173,25 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, 
bool plus)
*base_p = base;
}
 }
+  else if (!plus
+  && (disp == NULL_RTX || disp == const0_rtx)
+  && index_p
+  && (index = *index_p) != NULL_RTX
+  && GET_CODE (index) == SUBREG
+  && GET_MODE (index) == ptr_mode)
+{
+  index = SUBREG_REG (index);
+  if (GET_CODE (index) == PLUS && GET_MODE (index) == Pmode)
+   {
+ op0 = XEXP (index, 0);
+ op1 = XEXP (index, 1);
+ if (REG_P (op0) && CONST_INT_P (op1))
+   {
+ *index_p = gen_rtx_REG (ptr_mode, REGNO (op0));
+ *disp_p = op1;
+   }
+   }
+}
 }
 
 /* Extract the parts of an RTL expression that is a valid memory address
@@ -11208,12 +11240,14 @@ ix86_decompose_address (rtx addr, struct ix86_address 
*out)
{
  op = XEXP (op, 0);
  if (n == 1)
-   ix86_simplify_base_disp (&op, &addends[0], false);
+   ix86_simplify_base_index_disp (&op, NULL,
+  &addends[0], false);
}
  else if (n == 1
   && GET_CODE (op) == PLUS
   && GET_MODE (op) == ptr_mode)
-   ix86_simplify_base_disp (&op, &addends[0], true);
+   ix86_simplify_base_index_disp (&op, NULL, &addends[0],
+  true);
}
}
   while (GET_CODE (op) == PLUS);
@@ -11308,14 +11342,14 @@ ix86_decompose_address (rtx addr, struct ix86_address 
*out)
   scale = INTVAL (scale_rtx);
 }
 
-  index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
+  if (TARGET_X32 && reload_completed)
+ix86_simplify_base_index_disp (&base, &index, &disp, false);
 
   /* Avoid useless 0 displacement.  */
   if (disp == const0_rtx && (base || index))
 disp = NULL_RTX;
 
-  if (TARGET_X32 && reload_completed)
-ix86_simplify_base_disp (&base, &disp, false);
+  index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
 
   base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
 
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index fe4b6be..4230c8f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -5477,18 +5477,20 @@
   [(set_attr "type" "lea")
(set_attr "mode" "")])
 
-(define_insn "*lea_1_x32"
+(define_insn "*lea_2"
   [(set (match_operand:SI 0 "register_operand" "=r")
-   (match_operand:SI 1 "no_seg_address_operand" "p"))]
-  "TARGET_X32"
+   (subreg:SI (match_operand:DI 1 "no_seg_addre

[PATCH 6/6] dwarf2: Move CFI output routines to dwarf2cfi.c.

2011-07-09 Thread Richard Henderson
---
 gcc/defaults.h  |   22 ++
 gcc/dwarf2cfi.c |  567 
 gcc/dwarf2out.c |  638 +--
 gcc/dwarf2out.h |7 +
 4 files changed, 604 insertions(+), 630 deletions(-)

diff --git a/gcc/defaults.h b/gcc/defaults.h
index 6bacb3c..70c63ce 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -453,6 +453,28 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 #define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
 #endif
 
+/* The size of addresses as they appear in the Dwarf 2 data.
+   Some architectures use word addresses to refer to code locations,
+   but Dwarf 2 info always uses byte addresses.  On such machines,
+   Dwarf 2 addresses need to be larger than the architecture's
+   pointers.  */
+#ifndef DWARF2_ADDR_SIZE
+#define DWARF2_ADDR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
+#endif
+
+/* The size in bytes of a DWARF field indicating an offset or length
+   relative to a debug info section, specified to be 4 bytes in the
+   DWARF-2 specification.  The SGI/MIPS ABI defines it to be the same
+   as PTR_SIZE.  */
+#ifndef DWARF_OFFSET_SIZE
+#define DWARF_OFFSET_SIZE 4
+#endif
+
+/* The size in bytes of a DWARF 4 type signature.  */
+#ifndef DWARF_TYPE_SIGNATURE_SIZE
+#define DWARF_TYPE_SIGNATURE_SIZE 8
+#endif
+
 /* Default sizes for base C types.  If the sizes are different for
your target, you should override these values by defining the
appropriate symbols in your tm.h file.  */
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 28f9b93..5b8420e 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -2553,6 +2553,573 @@ execute_dwarf2_frame (void)
   return 0;
 }
 
+/* Convert a DWARF call frame info. operation to its string name */
+
+static const char *
+dwarf_cfi_name (unsigned int cfi_opc)
+{
+  switch (cfi_opc)
+{
+case DW_CFA_advance_loc:
+  return "DW_CFA_advance_loc";
+case DW_CFA_offset:
+  return "DW_CFA_offset";
+case DW_CFA_restore:
+  return "DW_CFA_restore";
+case DW_CFA_nop:
+  return "DW_CFA_nop";
+case DW_CFA_set_loc:
+  return "DW_CFA_set_loc";
+case DW_CFA_advance_loc1:
+  return "DW_CFA_advance_loc1";
+case DW_CFA_advance_loc2:
+  return "DW_CFA_advance_loc2";
+case DW_CFA_advance_loc4:
+  return "DW_CFA_advance_loc4";
+case DW_CFA_offset_extended:
+  return "DW_CFA_offset_extended";
+case DW_CFA_restore_extended:
+  return "DW_CFA_restore_extended";
+case DW_CFA_undefined:
+  return "DW_CFA_undefined";
+case DW_CFA_same_value:
+  return "DW_CFA_same_value";
+case DW_CFA_register:
+  return "DW_CFA_register";
+case DW_CFA_remember_state:
+  return "DW_CFA_remember_state";
+case DW_CFA_restore_state:
+  return "DW_CFA_restore_state";
+case DW_CFA_def_cfa:
+  return "DW_CFA_def_cfa";
+case DW_CFA_def_cfa_register:
+  return "DW_CFA_def_cfa_register";
+case DW_CFA_def_cfa_offset:
+  return "DW_CFA_def_cfa_offset";
+
+/* DWARF 3 */
+case DW_CFA_def_cfa_expression:
+  return "DW_CFA_def_cfa_expression";
+case DW_CFA_expression:
+  return "DW_CFA_expression";
+case DW_CFA_offset_extended_sf:
+  return "DW_CFA_offset_extended_sf";
+case DW_CFA_def_cfa_sf:
+  return "DW_CFA_def_cfa_sf";
+case DW_CFA_def_cfa_offset_sf:
+  return "DW_CFA_def_cfa_offset_sf";
+
+/* SGI/MIPS specific */
+case DW_CFA_MIPS_advance_loc8:
+  return "DW_CFA_MIPS_advance_loc8";
+
+/* GNU extensions */
+case DW_CFA_GNU_window_save:
+  return "DW_CFA_GNU_window_save";
+case DW_CFA_GNU_args_size:
+  return "DW_CFA_GNU_args_size";
+case DW_CFA_GNU_negative_offset_extended:
+  return "DW_CFA_GNU_negative_offset_extended";
+
+default:
+  return "DW_CFA_";
+}
+}
+
+/* This routine will generate the correct assembly data for a location
+   description based on a cfi entry with a complex address.  */
+
+static void
+output_cfa_loc (dw_cfi_ref cfi, int for_eh)
+{
+  dw_loc_descr_ref loc;
+  unsigned long size;
+
+  if (cfi->dw_cfi_opc == DW_CFA_expression)
+{
+  unsigned r = 
+   DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+  dw2_asm_output_data (1, r, NULL);
+  loc = cfi->dw_cfi_oprnd2.dw_cfi_loc;
+}
+  else
+loc = cfi->dw_cfi_oprnd1.dw_cfi_loc;
+
+  /* Output the size of the block.  */
+  size = size_of_locs (loc);
+  dw2_asm_output_data_uleb128 (size, NULL);
+
+  /* Now output the operations themselves.  */
+  output_loc_sequence (loc, for_eh);
+}
+
+/* Similar, but used for .cfi_escape.  */
+
+static void
+output_cfa_loc_raw (dw_cfi_ref cfi)
+{
+  dw_loc_descr_ref loc;
+  unsigned long size;
+
+  if (cfi->dw_cfi_opc == DW_CFA_expression)
+{
+  unsigned r = 
+   DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
+  fprintf (asm_out_file, "%#x,", r);
+  loc = cfi->dw_cfi_oprnd2.dw_cfi_lo

[PATCH 2/6] dwarf2cfi: Unify add_fde_cfi and add_cie_cfi.

2011-07-09 Thread Richard Henderson
---
 gcc/dwarf2cfi.c |   82 ---
 gcc/dwarf2out.c |8 +++---
 2 files changed, 40 insertions(+), 50 deletions(-)

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index d96aa70..ca9b503 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -146,6 +146,9 @@ static GTY(()) unsigned long dwarf2out_cfi_label_num;
 /* The insn after which a new CFI note should be emitted.  */
 static rtx cfi_insn;
 
+/* When non-null, add_cfi will add the CFI to this vector.  */
+static cfi_vec *add_cfi_vec;
+
 /* True if remember_state should be emitted before following CFI directive.  */
 static bool emit_cfa_remember;
 
@@ -270,10 +273,10 @@ dwarf2out_cfi_label (void)
   return xstrdup (label);
 }
 
-/* Add CFI to the current fde.  */
+/* Add CFI either to the current insn stream or to a vector, or both.  */
 
 static void
-add_fde_cfi (dw_cfi_ref cfi)
+add_cfi (dw_cfi_ref cfi)
 {
   if (emit_cfa_remember)
 {
@@ -283,7 +286,7 @@ add_fde_cfi (dw_cfi_ref cfi)
   emit_cfa_remember = false;
   cfi_remember = new_cfi ();
   cfi_remember->dw_cfi_opc = DW_CFA_remember_state;
-  add_fde_cfi (cfi_remember);
+  add_cfi (cfi_remember);
 }
 
   any_cfis_emitted = true;
@@ -292,18 +295,8 @@ add_fde_cfi (dw_cfi_ref cfi)
   cfi_insn = emit_note_after (NOTE_INSN_CFI, cfi_insn);
   NOTE_CFI (cfi_insn) = cfi;
 }
-  else
-{
-  dw_fde_ref fde = cfun->fde;
-  VEC_safe_push (dw_cfi_ref, gc, fde->dw_fde_cfi, cfi);
-  dwarf2out_emit_cfi (cfi);
-}
-}
-
-static void
-add_cie_cfi (dw_cfi_ref cfi)
-{
-  VEC_safe_push (dw_cfi_ref, gc, cie_cfi_vec, cfi);
+  if (add_cfi_vec != NULL)
+VEC_safe_push (dw_cfi_ref, gc, *add_cfi_vec, cfi);
 }
 
 /* This function fills in aa dw_cfa_location structure from a dwarf location
@@ -512,7 +505,7 @@ cfa_equal_p (const dw_cfa_location *loc1, const 
dw_cfa_location *loc2)
the dw_cfa_location structure.  */
 
 static void
-def_cfa_1 (bool for_cie, dw_cfa_location *loc_p)
+def_cfa_1 (dw_cfa_location *loc_p)
 {
   dw_cfi_ref cfi;
   dw_cfa_location loc;
@@ -584,10 +577,7 @@ def_cfa_1 (bool for_cie, dw_cfa_location *loc_p)
   cfi->dw_cfi_oprnd1.dw_cfi_loc = loc_list;
 }
 
-  if (for_cie)
-add_cie_cfi (cfi);
-  else
-add_fde_cfi (cfi);
+  add_cfi (cfi);
   old_cfa = loc;
 }
 
@@ -596,10 +586,9 @@ def_cfa_1 (bool for_cie, dw_cfa_location *loc_p)
otherwise it is saved in SREG.  */
 
 static void
-reg_save (bool for_cie, unsigned int reg, unsigned int sreg,
-  HOST_WIDE_INT offset)
+reg_save (unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
 {
-  dw_fde_ref fde = for_cie ? NULL : cfun->fde;
+  dw_fde_ref fde = cfun ? cfun->fde : NULL;
   dw_cfi_ref cfi = new_cfi ();
 
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
@@ -632,10 +621,7 @@ reg_save (bool for_cie, unsigned int reg, unsigned int 
sreg,
   cfi->dw_cfi_oprnd2.dw_cfi_reg_num = sreg;
 }
 
-  if (for_cie)
-add_cie_cfi (cfi);
-  else
-add_fde_cfi (cfi);
+  add_cfi (cfi);
 }
 
 /* Record the initial position of the return address.  RTL is
@@ -693,7 +679,7 @@ initial_return_save (rtx rtl)
 }
 
   if (reg != DWARF_FRAME_RETURN_COLUMN)
-reg_save (true, DWARF_FRAME_RETURN_COLUMN, reg, offset - cfa.offset);
+reg_save (DWARF_FRAME_RETURN_COLUMN, reg, offset - cfa.offset);
 }
 
 /* Given a SET, calculate the amount of stack adjustment it
@@ -975,7 +961,7 @@ dwarf2out_args_size (HOST_WIDE_INT size)
   cfi = new_cfi ();
   cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
   cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
-  add_fde_cfi (cfi);
+  add_cfi (cfi);
 }
 
 /* Record a stack adjustment of OFFSET bytes.  */
@@ -1000,7 +986,7 @@ dwarf2out_stack_adjust (HOST_WIDE_INT offset)
   if (args_size < 0)
 args_size = 0;
 
-  def_cfa_1 (false, &cfa);
+  def_cfa_1 (&cfa);
   if (flag_asynchronous_unwind_tables)
 dwarf2out_args_size (args_size);
 }
@@ -1205,7 +1191,7 @@ dwarf2out_flush_queued_reg_saves (void)
sreg = DWARF_FRAME_REGNUM (REGNO (q->saved_reg));
   else
sreg = INVALID_REGNUM;
-  reg_save (false, reg, sreg, q->cfa_offset);
+  reg_save (reg, sreg, q->cfa_offset);
 }
 
   queued_reg_saves = NULL;
@@ -1299,7 +1285,7 @@ dwarf2out_frame_debug_def_cfa (rtx pat)
   gcc_unreachable ();
 }
 
-  def_cfa_1 (false, &cfa);
+  def_cfa_1 (&cfa);
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_ADJUST_CFA note.  */
@@ -1330,7 +1316,7 @@ dwarf2out_frame_debug_adjust_cfa (rtx pat)
   cfa.reg = REGNO (dest);
   gcc_assert (cfa.indirect == 0);
 
-  def_cfa_1 (false, &cfa);
+  def_cfa_1 (&cfa);
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_OFFSET note.  */
@@ -1376,7 +1362,7 @@ dwarf2out_frame_debug_cfa_offset (rtx set)
   /* ??? We'd like to use queue_reg_save, but we need to come up with
  a different flushing heuristic for epilogues.  */
   if (!span)
-reg_save (false, sregno, INVALID_REGNUM, offset);
+reg_save (sregno, INVALID_REGNUM, offse

[PATCH 4/6] dwarf2cfi: Handle return column save from CIE.

2011-07-09 Thread Richard Henderson
When we record a save of the return column in the CIE, remember
that while processing the FDE.  This requires propagating the
handling of PC_RTX as a representative of the return column to
more locations.

MIPS had been handling this case by hand, and is no longer required.
---
 gcc/config/mips/mips.c |7 --
 gcc/dwarf2cfi.c|  222 +++-
 2 files changed, 126 insertions(+), 103 deletions(-)

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index f4010da..ee71c40 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -8203,13 +8203,6 @@ mips_frame_set (rtx mem, rtx reg)
 {
   rtx set;
 
-  /* If we're saving the return address register and the DWARF return
- address column differs from the hard register number, adjust the
- note reg to refer to the former.  */
-  if (REGNO (reg) == RETURN_ADDR_REGNUM
-  && DWARF_FRAME_RETURN_COLUMN != RETURN_ADDR_REGNUM)
-reg = gen_rtx_REG (GET_MODE (reg), DWARF_FRAME_RETURN_COLUMN);
-
   set = gen_rtx_SET (VOIDmode, mem, reg);
   RTX_FRAME_RELATED_P (set) = 1;
 
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index b4b035d..5b76df3 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -603,64 +603,6 @@ reg_save (unsigned int reg, unsigned int sreg, 
HOST_WIDE_INT offset)
   add_cfi (cfi);
 }
 
-/* Record the initial position of the return address.  RTL is
-   INCOMING_RETURN_ADDR_RTX.  */
-
-static void
-initial_return_save (rtx rtl)
-{
-  unsigned int reg = INVALID_REGNUM;
-  HOST_WIDE_INT offset = 0;
-
-  switch (GET_CODE (rtl))
-{
-case REG:
-  /* RA is in a register.  */
-  reg = DWARF_FRAME_REGNUM (REGNO (rtl));
-  break;
-
-case MEM:
-  /* RA is on the stack.  */
-  rtl = XEXP (rtl, 0);
-  switch (GET_CODE (rtl))
-   {
-   case REG:
- gcc_assert (REGNO (rtl) == STACK_POINTER_REGNUM);
- offset = 0;
- break;
-
-   case PLUS:
- gcc_assert (REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM);
- offset = INTVAL (XEXP (rtl, 1));
- break;
-
-   case MINUS:
- gcc_assert (REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM);
- offset = -INTVAL (XEXP (rtl, 1));
- break;
-
-   default:
- gcc_unreachable ();
-   }
-
-  break;
-
-case PLUS:
-  /* The return address is at some offset from any value we can
-actually load.  For instance, on the SPARC it is in %i7+8. Just
-ignore the offset for now; it doesn't matter for unwinding frames.  */
-  gcc_assert (CONST_INT_P (XEXP (rtl, 1)));
-  initial_return_save (XEXP (rtl, 0));
-  return;
-
-default:
-  gcc_unreachable ();
-}
-
-  if (reg != DWARF_FRAME_RETURN_COLUMN)
-reg_save (DWARF_FRAME_RETURN_COLUMN, reg, offset - cfa.offset);
-}
-
 /* Given a SET, calculate the amount of stack adjustment it
contains.  */
 
@@ -1088,6 +1030,8 @@ DEF_VEC_ALLOC_O (reg_saved_in_data, gc);
5 entries.  */
 static GTY(()) VEC(reg_saved_in_data, gc) *regs_saved_in_regs;
 
+static GTY(()) reg_saved_in_data *cie_return_save;
+
 /* Compare X and Y for equivalence.  The inputs may be REGs or PC_RTX.  */
 
 static bool
@@ -1134,10 +1078,9 @@ queue_reg_save (rtx reg, rtx sreg, HOST_WIDE_INT offset)
   struct queued_reg_save *q;
 
   /* Duplicates waste space, but it's also necessary to remove them
- for correctness, since the queue gets output in reverse
- order.  */
+ for correctness, since the queue gets output in reverse order.  */
   for (q = queued_reg_saves; q != NULL; q = q->next)
-if (REGNO (q->reg) == REGNO (reg))
+if (compare_reg_or_pc (q->reg, reg))
   break;
 
   if (q == NULL)
@@ -1165,7 +1108,10 @@ dwarf2out_flush_queued_reg_saves (void)
 
   record_reg_saved_in_reg (q->saved_reg, q->reg);
 
-  reg = DWARF_FRAME_REGNUM (REGNO (q->reg));
+  if (q->reg == pc_rtx)
+   reg = DWARF_FRAME_RETURN_COLUMN;
+  else
+reg = DWARF_FRAME_REGNUM (REGNO (q->reg));
   if (q->saved_reg)
sreg = DWARF_FRAME_REGNUM (REGNO (q->saved_reg));
   else
@@ -1375,13 +1321,11 @@ dwarf2out_frame_debug_cfa_register (rtx set)
   src = XEXP (set, 1);
   dest = XEXP (set, 0);
 
+  record_reg_saved_in_reg (dest, src);
   if (src == pc_rtx)
 sregno = DWARF_FRAME_RETURN_COLUMN;
   else
-{
-  record_reg_saved_in_reg (dest, src);
-  sregno = DWARF_FRAME_REGNUM (REGNO (src));
-}
+sregno = DWARF_FRAME_REGNUM (REGNO (src));
 
   dregno = DWARF_FRAME_REGNUM (REGNO (dest));
 
@@ -2031,14 +1975,14 @@ dwarf2out_frame_debug_expr (rtx expr)
  gcc_unreachable ();
}
 
-/* Rule 17 */
-/* If the source operand of this MEM operation is not a
-  register, basically the source is return address.  Here
-  we only care how much stack grew and we don't save it.  */
-  if (!REG_P (src))
+  /* Rule 17 */
+  /* If the source operand of this MEM operation is a memory,
+w

[PATCH 5/6] dwarf2: Reduce some redundant definitions.

2011-07-09 Thread Richard Henderson
Move some definitions to defaults.h; some simply aren't needed
anymore in the respective dwarf2{cfi,out}.c files.
---
 gcc/defaults.h  |   33 ++
 gcc/dwarf2cfi.c |   80 ---
 gcc/dwarf2out.c |   37 -
 3 files changed, 33 insertions(+), 117 deletions(-)

diff --git a/gcc/defaults.h b/gcc/defaults.h
index 118cb1c..6bacb3c 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -413,6 +413,26 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 #define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
 #endif
 
+/* Offsets recorded in opcodes are a multiple of this alignment factor.  */
+#ifndef DWARF_CIE_DATA_ALIGNMENT
+#ifdef STACK_GROWS_DOWNWARD
+#define DWARF_CIE_DATA_ALIGNMENT (-((int) UNITS_PER_WORD))
+#else
+#define DWARF_CIE_DATA_ALIGNMENT ((int) UNITS_PER_WORD)
+#endif
+#endif
+
+/* The DWARF 2 CFA column which tracks the return address.  Normally this
+   is the column for PC, or the first column after all of the hard
+   registers.  */
+#ifndef DWARF_FRAME_RETURN_COLUMN
+#ifdef PC_REGNUM
+#define DWARF_FRAME_RETURN_COLUMN  DWARF_FRAME_REGNUM (PC_REGNUM)
+#else
+#define DWARF_FRAME_RETURN_COLUMN  DWARF_FRAME_REGISTERS
+#endif
+#endif
+
 /* How to renumber registers for dbx and gdb.  If not defined, assume
no renumbering is necessary.  */
 
@@ -420,6 +440,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
 #endif
 
+/* The mapping from gcc register number to DWARF 2 CFA column number.
+   By default, we just provide columns for all registers.  */
+#ifndef DWARF_FRAME_REGNUM
+#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
+#endif
+
+/* Map register numbers held in the call frame info that gcc has
+   collected using DWARF_FRAME_REGNUM to those that should be output in
+   .debug_frame and .eh_frame.  */
+#ifndef DWARF2_FRAME_REG_OUT
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
+#endif
+
 /* Default sizes for base C types.  If the sizes are different for
your target, you should override these values by defining the
appropriate symbols in your tm.h file.  */
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 5b76df3..28f9b93 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -55,88 +55,8 @@ along with GCC; see the file COPYING3.  If not see
 #define INCOMING_RETURN_ADDR_RTX  (gcc_unreachable (), NULL_RTX)
 #endif
 
-/* The size of the target's pointer type.  */
-#ifndef PTR_SIZE
-#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
-#endif
-
 /* Maximum size (in bytes) of an artificially generated label.  */
 #define MAX_ARTIFICIAL_LABEL_BYTES 30
-
-/* The size of addresses as they appear in the Dwarf 2 data.
-   Some architectures use word addresses to refer to code locations,
-   but Dwarf 2 info always uses byte addresses.  On such machines,
-   Dwarf 2 addresses need to be larger than the architecture's
-   pointers.  */
-#ifndef DWARF2_ADDR_SIZE
-#define DWARF2_ADDR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
-#endif
-
-/* The size in bytes of a DWARF field indicating an offset or length
-   relative to a debug info section, specified to be 4 bytes in the
-   DWARF-2 specification.  The SGI/MIPS ABI defines it to be the same
-   as PTR_SIZE.  */
-
-#ifndef DWARF_OFFSET_SIZE
-#define DWARF_OFFSET_SIZE 4
-#endif
-
-/* According to the (draft) DWARF 3 specification, the initial length
-   should either be 4 or 12 bytes.  When it's 12 bytes, the first 4
-   bytes are 0x, followed by the length stored in the next 8
-   bytes.
-
-   However, the SGI/MIPS ABI uses an initial length which is equal to
-   DWARF_OFFSET_SIZE.  It is defined (elsewhere) accordingly.  */
-
-#ifndef DWARF_INITIAL_LENGTH_SIZE
-#define DWARF_INITIAL_LENGTH_SIZE (DWARF_OFFSET_SIZE == 4 ? 4 : 12)
-#endif
-
-/* Round SIZE up to the nearest BOUNDARY.  */
-#define DWARF_ROUND(SIZE,BOUNDARY) \
-  SIZE) + (BOUNDARY) - 1) / (BOUNDARY)) * (BOUNDARY))
-
-/* Offsets recorded in opcodes are a multiple of this alignment factor.  */
-#ifndef DWARF_CIE_DATA_ALIGNMENT
-#ifdef STACK_GROWS_DOWNWARD
-#define DWARF_CIE_DATA_ALIGNMENT (-((int) UNITS_PER_WORD))
-#else
-#define DWARF_CIE_DATA_ALIGNMENT ((int) UNITS_PER_WORD)
-#endif
-#endif
-
-/* CIE identifier.  */
-#if HOST_BITS_PER_WIDE_INT >= 64
-#define DWARF_CIE_ID \
-  (unsigned HOST_WIDE_INT) (DWARF_OFFSET_SIZE == 4 ? DW_CIE_ID : DW64_CIE_ID)
-#else
-#define DWARF_CIE_ID DW_CIE_ID
-#endif
-
-/* The DWARF 2 CFA column which tracks the return address.  Normally this
-   is the column for PC, or the first column after all of the hard
-   registers.  */
-#ifndef DWARF_FRAME_RETURN_COLUMN
-#ifdef PC_REGNUM
-#define DWARF_FRAME_RETURN_COLUMN  DWARF_FRAME_REGNUM (PC_REGNUM)
-#else
-#define DWARF_FRAME_RETURN_COLUMN  DWARF_FRAME_REGISTERS
-#endif
-#endif
-
-/* The mapping from gcc register number to DWARF 2 CFA column number.  By
-   default, we just provide columns for all r

[PATCH 1/6] Move ASM_COMMENT_START to defaults.h.

2011-07-09 Thread Richard Henderson
Note the extreme silliness in dwarf2out.c with 3 (three) copies.
---
 gcc/defaults.h  |5 +
 gcc/dwarf2asm.c |6 --
 gcc/dwarf2out.c |   15 ---
 gcc/final.c |5 -
 gcc/toplev.c|4 
 gcc/varasm.c|4 
 gcc/vmsdbgout.c |5 -
 7 files changed, 5 insertions(+), 39 deletions(-)

diff --git a/gcc/defaults.h b/gcc/defaults.h
index 5f83b18..118cb1c 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -28,6 +28,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #ifndef GCC_DEFAULTS_H
 #define GCC_DEFAULTS_H
 
+/* How to start an assembler comment.  */
+#ifndef ASM_COMMENT_START
+#define ASM_COMMENT_START ";#"
+#endif
+
 /* Store in OUTPUT a string (made with alloca) containing an
assembler-name for a local static variable or function named NAME.
LABELNO is an integer which is different for each call.  */
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index 4c1b6d4..0b7480b 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -34,12 +34,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "ggc.h"
 #include "tm_p.h"
 
-
-/* How to start an assembler comment.  */
-#ifndef ASM_COMMENT_START
-#define ASM_COMMENT_START ";#"
-#endif
-
 
 /* Output an unaligned integer with the given value and size.  Prefer not
to print a newline, since the caller may want to add a comment.  */
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index bad0b2d..211f270 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -168,11 +168,6 @@ static GTY(()) section *debug_str_section;
 static GTY(()) section *debug_ranges_section;
 static GTY(()) section *debug_frame_section;
 
-/* How to start an assembler comment.  */
-#ifndef ASM_COMMENT_START
-#define ASM_COMMENT_START ";#"
-#endif
-
 /* Maximum size (in bytes) of an artificially generated label.  */
 #define MAX_ARTIFICIAL_LABEL_BYTES 30
 
@@ -277,11 +272,6 @@ static void output_cfa_loc_raw (dw_cfi_ref);
personality CFI.  */
 static GTY(()) rtx current_unit_personality;
 
-/* How to start an assembler comment.  */
-#ifndef ASM_COMMENT_START
-#define ASM_COMMENT_START ";#"
-#endif
-
 /* Data and reference forms for relocatable data.  */
 #define DW_FORM_data (DWARF_OFFSET_SIZE == 8 ? DW_FORM_data8 : DW_FORM_data4)
 #define DW_FORM_ref (DWARF_OFFSET_SIZE == 8 ? DW_FORM_ref8 : DW_FORM_ref4)
@@ -3479,11 +3469,6 @@ typedef struct skeleton_chain_struct
 }
 skeleton_chain_node;
 
-/* How to start an assembler comment.  */
-#ifndef ASM_COMMENT_START
-#define ASM_COMMENT_START ";#"
-#endif
-
 /* Define a macro which returns nonzero for a TYPE_DECL which was
implicitly generated for a type.
 
diff --git a/gcc/final.c b/gcc/final.c
index 483a645..3416955 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -106,11 +106,6 @@ along with GCC; see the file COPYING3.  If not see
 #define CC_STATUS_INIT
 #endif
 
-/* How to start an assembler comment.  */
-#ifndef ASM_COMMENT_START
-#define ASM_COMMENT_START ";#"
-#endif
-
 /* Is the given character a logical line separator for the assembler?  */
 #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
 #define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';')
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 4591c30..109325c 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -722,7 +722,6 @@ print_version (FILE *file, const char *indent)
   print_plugins_versions (file, indent);
 }
 
-#ifdef ASM_COMMENT_START
 static int
 print_to_asm_out_file (print_switch_type type, const char * text)
 {
@@ -755,7 +754,6 @@ print_to_asm_out_file (print_switch_type type, const char * 
text)
   return -1;
 }
 }
-#endif
 
 static int
 print_to_stderr (print_switch_type type, const char * text)
@@ -921,7 +919,6 @@ init_asm_output (const char *name)
inform (input_location, "-frecord-gcc-switches is not supported by 
the current target");
}
 
-#ifdef ASM_COMMENT_START
   if (flag_verbose_asm)
{
  /* Print the list of switches in effect
@@ -930,7 +927,6 @@ init_asm_output (const char *name)
  print_switch_values (print_to_asm_out_file);
  putc ('\n', asm_out_file);
}
-#endif
 }
 }
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index cfdf8d7..b0690f50 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -5062,14 +5062,12 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT 
size,
   else if (TREE_CODE (local.type) == ARRAY_TYPE)
local.index = ce->index;
 
-#ifdef ASM_COMMENT_START
   if (local.field && flag_verbose_asm)
fprintf (asm_out_file, "%s %s:\n",
 ASM_COMMENT_START,
 DECL_NAME (local.field)
 ? IDENTIFIER_POINTER (DECL_NAME (local.field))
 : "");
-#endif
 
   /* Eliminate the marker that makes a cast not be an lvalue.  */
   if (local.val != NULL_TREE)
@@ -6180,12 +6178,10 @@ default_elf_asm_named_section (const char *name, 
unsigned int flags,
type = "progbits";
 
   format = ",@%s";
-#ifdef ASM_COMME

[PATCH 3/6] dwarf2cfi: Simplify re-initialization for each function.

2011-07-09 Thread Richard Henderson
There's no point calling lookup_cfa to re-create the CFA
we initialized just a few lines above.
---
 gcc/dwarf2cfi.c |   45 +
 1 files changed, 13 insertions(+), 32 deletions(-)

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index ca9b503..b4b035d 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -405,7 +405,9 @@ get_cfa_from_loc_descr (dw_cfa_location *cfa, struct 
dw_loc_descr_struct *loc)
 }
 }
 
-/* Subroutine of lookup_cfa.  */
+/* Find the previous value for the CFA, iteratively.  CFI is the opcode
+   to interpret, *LOC will be updated as necessary, *REMEMBER is used for
+   one level of remember/restore state processing.  */
 
 void
 lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc, dw_cfa_location *remember)
@@ -444,29 +446,6 @@ lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc, 
dw_cfa_location *remember)
 }
 }
 
-/* Find the previous value for the CFA.  */
-
-static void
-lookup_cfa (dw_cfa_location *loc)
-{
-  int ix;
-  dw_cfi_ref cfi;
-  dw_fde_ref fde;
-  dw_cfa_location remember;
-
-  memset (loc, 0, sizeof (*loc));
-  loc->reg = INVALID_REGNUM;
-  remember = *loc;
-
-  FOR_EACH_VEC_ELT (dw_cfi_ref, cie_cfi_vec, ix, cfi)
-lookup_cfa_1 (cfi, loc, &remember);
-
-  fde = cfun->fde;
-  if (fde)
-FOR_EACH_VEC_ELT (dw_cfi_ref, fde->dw_fde_cfi, ix, cfi)
-  lookup_cfa_1 (cfi, loc, &remember);
-}
-
 /* The current rule for calculating the DWARF2 canonical frame address.  */
 static dw_cfa_location cfa;
 
@@ -2301,7 +2280,7 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
 
 /* Examine CFI and return true if a cfi label and set_loc is needed
beforehand.  Even when generating CFI assembler instructions, we
-   still have to add the cfi to the list so that lookup_cfa works
+   still have to add the cfi to the list so that lookup_cfa_1 works
later on.  When -g2 and above we even need to force emitting of
CFI labels and add to list a DW_CFA_set_loc for convert_cfa_to_fb_loc_list
purposes.  If we're generating DWARF3 output we use DW_OP_call_frame_cfa
@@ -2596,15 +2575,18 @@ execute_dwarf2_frame (void)
 }
 
   /* Set up state for generating call frame debug info.  */
-  lookup_cfa (&cfa);
-  gcc_assert (cfa.reg
- == (unsigned long)DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM));
+  gcc_checking_assert (queued_reg_saves == NULL);
+  gcc_checking_assert (regs_saved_in_regs == NULL);
 
-  old_cfa = cfa;
+  memset (&cfa, 0, sizeof(cfa));
   cfa.reg = STACK_POINTER_REGNUM;
+  cfa.offset = INCOMING_FRAME_SP_OFFSET;
+
+  old_cfa = cfa;
   cfa_store = cfa;
-  cfa_temp.reg = -1;
-  cfa_temp.offset = 0;
+
+  memset (&cfa_temp, 0, sizeof(cfa_temp));
+  cfa_temp.reg = INVALID_REGNUM;
 
   dwarf2out_alloc_current_fde ();
 
@@ -2617,7 +2599,6 @@ execute_dwarf2_frame (void)
   barrier_args_size = NULL;
   regs_saved_in_regs = NULL;
   queued_reg_saves = NULL;
-  args_size = old_args_size = 0;
 
   return 0;
 }
-- 
1.7.6



[PATCH 0/6] dwarf2{cfi,out} cleanups

2011-07-09 Thread Richard Henderson
Tidies up the split between the two files.
Tested on x86_64-linux.


r~


Richard Henderson (6):
  Move ASM_COMMENT_START to defaults.h.
  dwarf2cfi: Unify add_fde_cfi and add_cie_cfi.
  dwarf2cfi: Simplify re-initialization for each function.
  dwarf2cfi: Handle return column save from CIE.
  dwarf2: Reduce some redundant definitions.
  dwarf2: Move CFI output routines to dwarf2cfi.c.

 gcc/config/mips/mips.c |7 -
 gcc/defaults.h |   60 +++
 gcc/dwarf2asm.c|6 -
 gcc/dwarf2cfi.c|  994 
 gcc/dwarf2out.c|  690 +-
 gcc/dwarf2out.h|7 +
 gcc/final.c|5 -
 gcc/toplev.c   |4 -
 gcc/varasm.c   |4 -
 gcc/vmsdbgout.c|5 -
 10 files changed, 816 insertions(+), 966 deletions(-)

-- 
1.7.6



[dwarf2cfi] Fix debug/49686

2011-07-09 Thread Richard Henderson
We were dropping the CFI notes inside the sequence
instead of in front of it.

Tested with sh-sim.

r~
PR debug/49686
* dwarf2cfi.c (dwarf2out_frame_debug): Don't set cfi_insn here...
(create_cfi_notes): ... do it here instead.



diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 2625067..d96aa70 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -2180,17 +2180,6 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
   bool handled_one = false;
   bool need_flush = false;
 
-  /* Remember where we are to insert notes.  Do not separate tablejump
- insns from their ADDR_DIFF_VEC.  Putting the note after the VEC
- should be ok.  */
-  if (after_p)
-{
-  if (!tablejump_p (insn, NULL, &cfi_insn))
-   cfi_insn = insn;
-}
-  else
-cfi_insn = PREV_INSN (insn);
-
   if (!NONJUMP_INSN_P (insn) || clobbers_queued_reg_save (insn))
 dwarf2out_flush_queued_reg_saves ();
 
@@ -2201,7 +2190,6 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
 is still used to save registers.  */
   if (!ACCUMULATE_OUTGOING_ARGS)
dwarf2out_notice_stack_adjust (insn, after_p);
-  cfi_insn = NULL;
   return;
 }
 
@@ -2323,7 +2311,6 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
 
   if (need_flush)
 dwarf2out_flush_queued_reg_saves ();
-  cfi_insn = NULL;
 }
 
 /* Examine CFI and return true if a cfi label and set_loc is needed
@@ -2432,6 +2419,8 @@ create_cfi_notes (void)
 {
   rtx pat;
 
+  cfi_insn = PREV_INSN (insn);
+
   if (BARRIER_P (insn))
{
  dwarf2out_frame_debug (insn, false);
@@ -2443,9 +2432,7 @@ create_cfi_notes (void)
  switch (NOTE_KIND (insn))
{
case NOTE_INSN_PROLOGUE_END:
- cfi_insn = PREV_INSN (insn);
  dwarf2out_flush_queued_reg_saves ();
- cfi_insn = NULL;
  break;
 
case NOTE_INSN_EPILOGUE_BEG:
@@ -2457,7 +2444,6 @@ create_cfi_notes (void)
case NOTE_INSN_CFA_RESTORE_STATE:
  cfi_insn = insn;
  dwarf2out_frame_debug_restore_state ();
- cfi_insn = NULL;
  break;
}
  continue;
@@ -2484,8 +2470,15 @@ create_cfi_notes (void)
  || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
dwarf2out_frame_debug (insn, false);
 
+  /* Do not separate tablejump insns from their ADDR_DIFF_VEC.
+Putting the note after the VEC should be ok.  */
+  if (!tablejump_p (insn, NULL, &cfi_insn))
+   cfi_insn = insn;
+
   dwarf2out_frame_debug (insn, true);
 }
+
+  cfi_insn = NULL;
 }
 
 /* Determine if we need to save and restore CFI information around this


[Patch, Fortran] PR - fix SIGNAL intrinsic (4.6/4.7 Regression)

2011-07-09 Thread Tobias Burnus

The regression seems to be a side effect of the -fwhole-file effort.

The BT_UNKNOWN of the second argument of SIGNAL(NUMBER,HANDLER) triggers 
an ICE in trans-types.c, when generating the decl for the external 
function "signal" (or rather for __gfortran_signal_func{,_int}).


As both handler ==  and handler == proc-pointer> are pointers, it seems to be simplest to translate the 
second argument as "void *" (BT_VOID).


Build and regtested on x86-64-linux.
OK for the trunk and the 4.6 branch?

Tobias
2011-07-09  Tobias Burnus  

	PR fortran/49690
	* intrinsic.c (add_functions): Use BT_VOID for 2nd argument of SIGNAL.

2011-07-09  Tobias Burnus  

	PR fortran/49690
	* gfortran.dg/intrinsic_signal.f90: New.

diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index a72da91..5946ddd 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -2594,7 +2594,7 @@ add_functions (void)
 
   add_sym_2 ("signal", GFC_ISYM_SIGNAL, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
 	 di, GFC_STD_GNU, gfc_check_signal, NULL, gfc_resolve_signal,
-	 num, BT_INTEGER, di, REQUIRED, han, BT_UNKNOWN, 0, REQUIRED);
+	 num, BT_INTEGER, di, REQUIRED, han, BT_VOID, 0, REQUIRED);
 
   make_generic ("signal", GFC_ISYM_SIGNAL, GFC_STD_GNU);
 
--- /dev/null	2011-07-09 08:27:50.727884038 +0200
+++ gcc/gcc/testsuite/gfortran.dg/intrinsic_signal.f90	2011-07-09 20:19:35.0 +0200
@@ -0,0 +1,21 @@
+! { dg-do compile }
+!
+! PR fortran/49690
+!
+! Reduced test case, based on the one of Debian bug #631204
+!
+
+subroutine ctrlc_ast
+   common /xinterrupt/ interrupted
+   logical interrupted
+   interrupted = .true.
+end subroutine ctrlc_ast  
+
+subroutine set_ctrl_c(ctrlc_ast)
+   external ctrlc_ast
+   intrinsic signal
+   integer old_handle
+   common /xinterrupt/ interrupted
+   logical interrupted
+   old_handler = signal(2, ctrlc_ast)
+end subroutine set_ctrl_c


[PATCH, fortran]: Fix PR 48926, gfortran.dg/coarray/image_index_1.f90 -fcoarray=single -O2 (test for excess errors)

2011-07-09 Thread Uros Bizjak
Hello!

gfc_get_corank returns integer value, not bool.  This problem was
triggered by --enable-build-with-cxx configured build.

2011-07-09  Uros Bizjak  

PR fortran/48926
* expr.c (gfc_get_corank): Change return value to int.
* gfortran.h (gfc_get_corank): Update function prototype.

Patch was regression tested on x86_64-pc-linux-gnu {,-m32} with
--enable-build-with-cxx.

Approved by Tobias Burnus in the PR. Patch was committed to mainline,
will be committed to 4.6 branch soon.

Uros.
Index: expr.c
===
--- expr.c  (revision 176083)
+++ expr.c  (working copy)
@@ -4143,7 +4143,7 @@
 }
 
 
-bool
+int
 gfc_get_corank (gfc_expr *e)
 {
   int corank;
Index: gfortran.h
===
--- gfortran.h  (revision 176083)
+++ gfortran.h  (working copy)
@@ -2734,7 +2734,7 @@
 bool gfc_is_proc_ptr_comp (gfc_expr *, gfc_component **);
 
 bool gfc_is_coindexed (gfc_expr *);
-bool gfc_get_corank (gfc_expr *);
+int gfc_get_corank (gfc_expr *);
 bool gfc_has_ultimate_allocatable (gfc_expr *);
 bool gfc_has_ultimate_pointer (gfc_expr *);
 


C++ PATCH to build_vec_init_elt to strip TARGET_EXPR

2011-07-09 Thread Jason Merrill
My patch for 49528 broke this testcase because build_vec_init_elt was 
returning what looks like a temporary of non-literal type.  There isn't 
actually a temporary, so let's not return something that looks like one.


Tested x86_64-pc-linux-gnu, applying to trunk and 4.6.
commit 3f54d9656d3e65b396940d2f1227126d61bab91f
Author: Jason Merrill 
Date:   Sat Jul 9 00:23:17 2011 -0400

	* tree.c (build_vec_init_elt): Strip TARGET_EXPR.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index dcd85e4..4ef89c4 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -511,6 +511,11 @@ build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
 complain);
   release_tree_vector (argvec);
 
+  /* For a trivial constructor, build_over_call creates a TARGET_EXPR.  But
+ we don't want one here because we aren't creating a temporary.  */
+  if (TREE_CODE (init) == TARGET_EXPR)
+init = TARGET_EXPR_INITIAL (init);
+
   return init;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/regress5.C b/gcc/testsuite/g++.dg/cpp0x/regress/regress5.C
new file mode 100644
index 000..b193591
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/regress/regress5.C
@@ -0,0 +1,16 @@
+// { dg-options -std=c++0x }
+
+struct A
+{
+  int i;
+  A(int);
+};
+
+struct B
+{
+  virtual void f();
+  A ar[3];
+};
+
+extern B b;
+B b2(b);


Re: [Patch,testsuite]: Skip AVR if .text overflows

2011-07-09 Thread Mike Stump
On Jul 8, 2011, at 7:57 AM, Georg-Johann Lay wrote:
> These tests are too big for AVR: .text (128 KiB) overflows and ld
> complains.
> 
> Ok to commit?

Ok.  If people feel they have a nice design for `too big', let us know...  I 
think it would have to be ld message scan based, to allow things that are just 
small enough, and correctly identify those that are just a hair too big.  I'd 
preapprove work in that direction.  :-)


Re: [Patch,testsuite]: Skip -fschedule-insns if no scheduling available.

2011-07-09 Thread Mike Stump

On Jul 8, 2011, at 7:25 AM, Georg-Johann Lay wrote:

> There are tests in suite that set -fschedule-insns[2] and FAIL because of
> 
> warning: instruction scheduling not supported on this target machine
> [enabled by default]
> 
> As there is no individual switch do disable the warning, the patch
> disables some test cases so reduce the overall "noise of false test
> fails".
> 
> There is no proc for that yet, so I wrote one. Lightly tested with my
> testsuite: get now UNSUPPORTED instead of FAIL.
> 
> Ok to commit?

Awesome, thanks; oops, I mean, Ok.


Re: [pdp11] Emit prologue as rtl

2011-07-09 Thread Richard Henderson
On 07/09/2011 06:30 AM, Paul Koning wrote:
> 
> On Jul 8, 2011, at 6:13 PM, Richard Henderson wrote:
> 
>> This appears to do the right thing.  I didn't bother with
>> markers for unwind info, since pdp11 is limited to a.out
>> and thus will never use dwarf2.
>>
>> There are improvements that could be made.  I added some
>> comments to that effect but did not otherwise change the
>> code generation.
>>
>> Note that the existence of the epilogue and return patterns
>> will by themselves cause changes.  In particular, basic block
>> re-ordering will likely move the epilogue into the middle of
>> the function, placing unlikely code paths later; something
>> that was not possible with a text-based epilogue.
> 
> Thanks, that looks good.

Committed.  HAVE_prologue and HAVE_epilogue are now
universally true.  Yaye!


r~


Re: [patch] Disable static build for libjava

2011-07-09 Thread Matthias Klose
On 07/07/2011 10:35 PM, Ralf Wildenhues wrote:
> Hi Matthias,
> 
> On Thu, Jul 07, 2011 at 10:26:59PM +0200, Jakub Jelinek wrote:
>> On Thu, Jul 07, 2011 at 10:22:37PM +0200, Matthias Klose wrote:
>>> +AC_PROG_LIBTOOL
> 
> This tests the wrong compiler and toolchain.  The compiler you want
> to test doesn't exist yet at the time this configure script is run.
> So you might as well deduce the switch you need from a fixed set or
> other GCC configure data.
> 
> Or you put AC_PROG_LIBTOOL in libjava/ but pass down the value of
> enable_static_libjava as --en/disable-static there.

here is the updated patch. AC_PROG_LIBTOOL is already called in libjava/

ok to install?

  Matthias



2011-07-09  Matthias Klose  

* Makefile.tpl (EXTRA_CONFIGARGS_LIBJAVA): Define.
* Makefile.def (target_modules/libjava): Pass
$(EXTRA_CONFIGARGS_LIBJAVA).
* configure.ac: Pass --disable-static in EXTRA_CONFIGARGS_LIBJAVA,
if not configured with --enable-static-libjava.
* Makefile.in: Regenerate.
* configure: Likewise.

 
gcc/

2011-07-09  Matthias Klose  

* doc/install.texi: Document --enable-static-libjava.

 
Index: Makefile.tpl
===
--- Makefile.tpl(revision 176072)
+++ Makefile.tpl(working copy)
@@ -319,6 +319,8 @@
 HOST_LIBELFLIBS = @libelflibs@
 HOST_LIBELFINC = @libelfinc@
 
+EXTRA_CONFIGARGS_LIBJAVA = @EXTRA_CONFIGARGS_LIBJAVA@
+
 # --
 # Programs producing files for the BUILD machine
 # --
Index: Makefile.def
===
--- Makefile.def(revision 176072)
+++ Makefile.def(working copy)
@@ -132,7 +132,8 @@
 target_modules = { module= winsup; };
 target_modules = { module= libgloss; no_check=true; };
 target_modules = { module= libffi; };
-target_modules = { module= libjava; raw_cxx=true; };
+target_modules = { module= libjava; raw_cxx=true;
+   extra_configure_flags="$(EXTRA_CONFIGARGS_LIBJAVA)"; };
 target_modules = { module= zlib; };
 target_modules = { module= boehm-gc; };
 target_modules = { module= rda; };
Index: configure.ac
===
--- configure.ac(revision 176072)
+++ configure.ac(working copy)
@@ -443,7 +443,21 @@
   ;;
 esac
 
+AC_ARG_ENABLE(static-libjava,
+[AS_HELP_STRING([[--enable-static-libjava[=ARG]]],
+   [build static libjava @<:@default=no@:>@])],
+ENABLE_STATIC_LIBJAVA=$enableval,
+ENABLE_STATIC_LIBJAVA=no)
+enable_static_libjava=
+if test "${ENABLE_STATIC_LIBJAVA}" = "yes" ; then
+  enable_static_libjava=yes
+fi
 
+if test x$enable_static_libjava != xyes ; then
+  EXTRA_CONFIGARGS_LIBJAVA=--disable-static
+fi
+AC_SUBST(EXTRA_CONFIGARGS_LIBJAVA)
+
 # Disable libmudflap on some systems.
 if test x$enable_libmudflap = x ; then
 case "${target}" in
Index: gcc/doc/install.texi
===
--- gcc/doc/install.texi(revision 176072)
+++ gcc/doc/install.texi(working copy)
@@ -1968,6 +1968,10 @@
 @item --enable-browser-plugin
 Build the gcjwebplugin web browser plugin.
 
+@item --enable-static-libjava
+Build static libraries in libjava. The default is to only build shared
+libraries.
+
 @table @code
 @item ansi
 Use the single-byte @code{char} and the Win32 A functions natively,


Re: [PATCH] Optimize NE/EQ comparisons of narrow integer types in debug info (PR debug/49676)

2011-07-09 Thread Jason Merrill

OK.

Jason


Re: [PATCH (1/7)] New optab framework for widening multiplies

2011-07-09 Thread Andrew Stubbs

On 23/06/11 15:37, Andrew Stubbs wrote:

This patch should have no effect on the compiler output. It merely
replaces one way to represent widening operations with another, and
refactors the other parts of the compiler to match. The rest of the
patch set uses this new framework to implement the optimization
improvements.

I considered and discarded many approaches to this patch before arriving
at this solution, and I feel sure that there'll be somebody out there
who will think I chose the wrong one, so let me first explain how I got
here 

The aim is to be able to encode and query optabs that have any given
input mode, and any given output mode. This is similar to the
convert_optab, but not compatible with that optab since it is handled
completely differently in the code.

(Just to be clear, the existing widening multiply support only covers
instructions that widen by *one* mode, so it's only ever been necessary
to know the output mode, up to now.)

Option 1 was to add a second dimension to the handlers table in optab_d,
but I discarded this option because it would increase the memory usage
by the square of the number of modes, which is a bit much.

Option 2 was to add a whole new optab, similar to optab_d, but with a
second dimension like convert_optab_d, however this turned out to cause
way too many pointer type mismatches in the code, and would have been
very difficult to fix up.

Option 3 was to add new optab entries for widening by two modes, by
three modes, and so on. True, I would only need to add one extra set for
what I need, but there would be so many places in the code that compare
against smul_widen_optab, for example, that would need to be taught
about these, that it seemed like a bad idea.

Option 4 was to have a separate table that contained the widening
operations, and refer to that whenever a widening entry in the main
optab is referenced, but I found that there was no easy way to do the
mapping without putting some sort of switch table in
widening_optab_handler, and that negates the other advantages.

So, what I've done in the end is add a new pointer entry "widening" into
optab_d, and dynamically build the widening operations table for each
optab that needs it. I've then added new accessor functions that take
both input and output modes, and altered the code to use them where
appropriate.

The down-side of this approach is that the optab entries for widening
operations now have two "handlers" tables, one of which is redundant.
That said, those cases are in the minority, and it is the smaller table
which is unused.

If people find that very distasteful, it might be possible to remove the
*_widen_optab entries and unify smul_optab with smul_widen_optab, and so
on, and save space that way. I've not done so yet, but I expect I could
if people feel strongly about it.

As a side-effect, it's now possible for any optab to be "widening",
should some target happen to have a widening add, shift, or whatever.

Is this patch OK?


This update has been rebaselined to fix some conflicts with other recent 
commits in this area.


I also identified a small bug which resulted in the operands to some 
commutative operations being reversed. I don't believe the bug did any 
harm, logically speaking, but I suppose there could be a testcase that 
resulted in worse code being generated. With this fix, I now see exactly 
matching output in all my testcases.


Andrew
2011-07-09  Andrew Stubbs  

	gcc/
	* expr.c (expand_expr_real_2): Use widening_optab_handler.
	* genopinit.c (optabs): Use set_widening_optab_handler for $N.
	(gen_insn): $N now means $a must be wider than $b, not consecutive.
	* optabs.c (expand_widen_pattern_expr): Use widening_optab_handler.
	(expand_binop_directly): Likewise.
	(expand_binop): Likewise.
	* optabs.h (widening_optab_handlers): New struct.
	(optab_d): New member, 'widening'.
	(widening_optab_handler): New function.
	(set_widening_optab_handler): New function.
	* tree-ssa-math-opts.c (convert_mult_to_widen): Use
	widening_optab_handler.
	(convert_plusminus_to_widen): Likewise.

--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7640,7 +7640,8 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
 	  this_optab = usmul_widen_optab;
 	  if (mode == GET_MODE_2XWIDER_MODE (innermode))
 	{
-	  if (optab_handler (this_optab, mode) != CODE_FOR_nothing)
+	  if (widening_optab_handler (this_optab, mode, innermode)
+		!= CODE_FOR_nothing)
 		{
 		  if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
 		expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
@@ -7667,7 +7668,8 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
 	  if (mode == GET_MODE_2XWIDER_MODE (innermode)
 	  && TREE_CODE (treeop0) != INTEGER_CST)
 	{
-	  if (optab_handler (this_optab, mode) != CODE_FOR_nothing)
+	  if (widening_optab_handler (this_optab, mode, innermode)
+		!= CODE_FOR_nothing)
 		{
 		  expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
 	

Re: [trans-mem] Beginning of refactoring

2011-07-09 Thread Torvald Riegel
The attached patch makes flat nesting the default, while still
supporting closed nesting on demand (for user-controlled aborts via
__transaction_cancel).
Previously, a new transaction object was created for each nested
transaction. The patch changes this to using one transaction object
during the whole lifetime of a thread and keeping checkpoints of the
transaction state when starting closed nested transactions. This allows
us to easily use flat nesting and decreases the transaction start/commit
overheads to some extent.

OK for branch?
commit a6b608b3b7e942b2ffaff7f7b8a897dd7cfd62c1
Author: Torvald Riegel 
Date:   Sat Jul 9 16:22:21 2011 +0200

Use flat nesting by default and support closed nesting via checkpoints.

* local.cc (gtm_transaction::rollback_local): Support closed nesting.
* retry.cc (GTM::gtm_transaction::decide_retry_strategy): Same.
* eh_cpp.cc (GTM::gtm_transaction::revert_cpp_exceptions): Same.
* useraction.cc: Same. Also use vector instead of list to store actions.
* dispatch.h (GTM::abi_dispatch): Add can_run_uninstrumented_code and
closed_nesting flags, as well as a closed nesting alternative.
* method-serial.cc: Same.
* beginend.cc (GTM::gtm_transaction::begin_transaction): Change to
flat nesting as default, and closed nesting on demand.
(GTM::gtm_transaction::rollback): Same.
(_ITM_abortTransaction): Same.
(GTM::gtm_transaction::restart): Same.
(GTM::gtm_transaction::trycommit): Same.
(GTM::gtm_transaction::trycommit_and_finalize): Removed.
(choose_code_path): New.
(GTM::gtm_transaction_cp::save): New.
(GTM::gtm_transaction_cp::commit): New.
* query.cc (_ITM_inTransaction): Support flat nesting.
* aatree.h (aa_tree::remove): New.
(aa_tree::operator new): Add placement new.
* libitm_i.h: Add closed nesting as restart reason.
(GTM::gtm_transaction_cp): New helper struct for nesting.
(GTM::gtm_transaction::user_action): Same.
(GTM::gtm_transaction): Support flat and closed nesting.
* alloc.cc (commit_allocations_2): New.
(commit_cb_data): New helper struct.
(GTM::gtm_transaction::commit_allocations): Handle nested
commits/rollbacks.
* libitm.h (_ITM_codeProperties): Change pr_hasElse to the ABI's value.
* libitm.texi: Update user action section, add description of nesting.

diff --git a/libitm/aatree.h b/libitm/aatree.h
index 6d28890..3e11b95 100644
--- a/libitm/aatree.h
+++ b/libitm/aatree.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson .
 
This file is part of the GNU Transactional Memory Library (libitm).
@@ -141,6 +141,8 @@ class aa_tree : public aa_tree_key
   aa_tree() = default;
   ~aa_tree() { clear(); }
 
+  static void *operator new (size_t s, aa_tree* p) { return p; }
+
   DATA *find(KEY k) const
   {
 node_ptr n = static_cast(base::find (k));
@@ -160,6 +162,13 @@ class aa_tree : public aa_tree_key
 delete n;
   }
 
+  node_ptr remove(KEY k, DATA** data)
+  {
+node_ptr n = static_cast(base::erase (k));
+*data = (n ? &n->data : 0);
+return n;
+  }
+
   void clear()
   {
 node_ptr n = static_cast(this->m_tree);
diff --git a/libitm/alloc.cc b/libitm/alloc.cc
index 5c70144..9b60835 100644
--- a/libitm/alloc.cc
+++ b/libitm/alloc.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson .
 
This file is part of the GNU Transactional Memory Library (libitm).
@@ -52,6 +52,55 @@ gtm_transaction::forget_allocation (void *ptr, void 
(*free_fn)(void *))
   a->allocated = false;
 }
 
+namespace {
+struct commit_cb_data {
+  aa_tree* parent;
+  bool revert_p;
+};
+}
+
+static void
+commit_allocations_2 (uintptr_t key, gtm_alloc_action *a, void *data)
+{
+  void *ptr = (void *)key;
+  commit_cb_data *cb_data = static_cast(data);
+
+  if (cb_data->revert_p)
+{
+  // Roll back nested allocations.
+  if (a->allocated)
+a->free_fn (ptr);
+}
+  else
+{
+  if (a->allocated)
+{
+  // Add nested allocations to parent transaction.
+  gtm_alloc_action* a_parent = cb_data->parent->insert(key);
+  *a_parent = *a;
+}
+  else
+{
+  // Eliminate a parent allocation if it matches this memory release,
+  // otherwise just add it to the parent.
+  gtm_alloc_action* a_parent;
+  aa_tree::node_ptr node_ptr =
+  cb_data->parent->remove(key, &a_parent);
+  if (node_ptr)
+{
+  assert(a_parent->allocated);
+  a_parent->free_fn(ptr);
+  delete node_ptr;
+}
+  else
+{
+  a_parent = cb_dat

[v3] add

2011-07-09 Thread Jonathan Wakely
This adds the new  header. Currently only
std::vector has the necessary support for C++0x allocators to be
usable with std::scoped_allocator_adaptor.

* include/Makefile.am: Add new header.
* include/Makefile.in: Regenerate.
* include/std/scoped_allocator: New.
* doc/xml/manual/status_cxx200x.xml: Update.
* testsuite/20_util/scoped_allocator/1.cc: New.
* testsuite/20_util/scoped_allocator/propagation.cc: New.
* testsuite/20_util/scoped_allocator/requirements/typedefs.cc: New.
* testsuite/20_util/scoped_allocator/requirements/
explicit_instantiation.cc: New.

Tested x86_64-linux, commited to trunk

Remaining allocator work is to make the other containers and
std::shared_ptr use the new C++0x model, and make std::function use an
allocator.
Index: include/bits/stl_vector.h
===
--- include/bits/stl_vector.h   (revision 176072)
+++ include/bits/stl_vector.h   (working copy)
@@ -71,13 +71,15 @@
 struct _Vector_base
 {
   typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+  typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
+   pointer;
 
   struct _Vector_impl 
   : public _Tp_alloc_type
   {
-   typename _Tp_alloc_type::pointer _M_start;
-   typename _Tp_alloc_type::pointer _M_finish;
-   typename _Tp_alloc_type::pointer _M_end_of_storage;
+   pointer _M_start;
+   pointer _M_finish;
+   pointer _M_end_of_storage;
 
_Vector_impl()
: _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0)
@@ -93,6 +95,13 @@
  _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
 #endif
+
+   void _M_swap_data(_Vector_impl& __x)
+   {
+ std::swap(_M_start, __x._M_start);
+ std::swap(_M_finish, __x._M_finish);
+ std::swap(_M_end_of_storage, __x._M_end_of_storage);
+   }
   };
   
 public:
@@ -118,30 +127,30 @@
 
   _Vector_base(size_t __n)
   : _M_impl()
-  {
-   this->_M_impl._M_start = this->_M_allocate(__n);
-   this->_M_impl._M_finish = this->_M_impl._M_start;
-   this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
-  }
+  { _M_create_storage(__n); }
 
   _Vector_base(size_t __n, const allocator_type& __a)
   : _M_impl(__a)
-  {
-   this->_M_impl._M_start = this->_M_allocate(__n);
-   this->_M_impl._M_finish = this->_M_impl._M_start;
-   this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
-  }
+  { _M_create_storage(__n); }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
+  _Vector_base(_Tp_alloc_type&& __a)
+  : _M_impl(std::move(__a)) { }
+
   _Vector_base(_Vector_base&& __x)
   : _M_impl(std::move(__x._M_get_Tp_allocator()))
+  { this->_M_impl._M_swap_data(__x._M_impl); }
+
+  _Vector_base(_Vector_base&& __x, const allocator_type& __a)
+  : _M_impl(__a)
   {
-   this->_M_impl._M_start = __x._M_impl._M_start;
-   this->_M_impl._M_finish = __x._M_impl._M_finish;
-   this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage;
-   __x._M_impl._M_start = 0;
-   __x._M_impl._M_finish = 0;
-   __x._M_impl._M_end_of_storage = 0;
+   if (__x.get_allocator() == __a)
+ this->_M_impl._M_swap_data(__x._M_impl);
+   else
+ {
+   size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
+   _M_create_storage(__n);
+ }
   }
 #endif
 
@@ -152,16 +161,25 @@
 public:
   _Vector_impl _M_impl;
 
-  typename _Tp_alloc_type::pointer
+  pointer
   _M_allocate(size_t __n)
   { return __n != 0 ? _M_impl.allocate(__n) : 0; }
 
   void
-  _M_deallocate(typename _Tp_alloc_type::pointer __p, size_t __n)
+  _M_deallocate(pointer __p, size_t __n)
   {
if (__p)
  _M_impl.deallocate(__p, __n);
   }
+
+private:
+  void
+  _M_create_storage(size_t __n)
+  {
+   this->_M_impl._M_start = this->_M_allocate(__n);
+   this->_M_impl._M_finish = this->_M_impl._M_start;
+   this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
+  }
 };
 
 
@@ -196,10 +214,11 @@
 
 public:
   typedef _Tp   value_type;
-  typedef typename _Tp_alloc_type::pointer   pointer;
-  typedef typename _Tp_alloc_type::const_pointer const_pointer;
-  typedef typename _Tp_alloc_type::reference reference;
-  typedef typename _Tp_alloc_type::const_reference   const_reference;
+  typedef typename _Base::pointerpointer;
+  typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type>  _Alloc_traits;
+  typedef typename _Alloc_traits::const_pointer  const_pointer;
+  typedef typename _Alloc_traits::reference  reference;
+  typedef typename _Alloc_traits::const_referencec

Re: [Patch, Fortran] Add runtime_error function to libgfortran/caf/mpi.c

2011-07-09 Thread jvdelisle

On Sat, Jul 9, 2011 at 5:02 AM, Tobias Burnus wrote:


Tobias Burnus wrote:
This patch adds a run-time error function to mpi.c, which gives a 
proper error message including the image number. Additionally, it 
allows to clean up the error handling, avoiding the duplicated 
declaration of strings.


I have not touched the SYNC functions


Well, I did now. The attached patch combines my runtime_error function 
patch with Daniel's sync patch.


OK?


Tobias


Consider renaming it to mpi_runtime_error just to aid in clarity since 
we have runtime errors of other sorts elsewhere.  This is just a minor 
suggestion and I leave it to you.


Ok for trunk.

Jerry


Re: [pdp11] Emit prologue as rtl

2011-07-09 Thread Paul Koning

On Jul 8, 2011, at 6:13 PM, Richard Henderson wrote:

> This appears to do the right thing.  I didn't bother with
> markers for unwind info, since pdp11 is limited to a.out
> and thus will never use dwarf2.
> 
> There are improvements that could be made.  I added some
> comments to that effect but did not otherwise change the
> code generation.
> 
> Note that the existence of the epilogue and return patterns
> will by themselves cause changes.  In particular, basic block
> re-ordering will likely move the epilogue into the middle of
> the function, placing unlikely code paths later; something
> that was not possible with a text-based epilogue.

Thanks, that looks good.

paul



[v3] C++0x allocator support for std::vector

2011-07-09 Thread Jonathan Wakely
This patch adds full C++0x allocator support to std::vector, building
on the alloc_traits work I've been committing recently.

This is the easiest of the allocator-aware containers, I'm planning to
do the same for std::deque soon.

* include/bits/stl_vector.h: Use new allocator model in C++0x mode.
* include/bits/vector.tcc: Likewise.
* testsuite/util/testsuite_allocator.h (propagating_allocator): Define.
* testsuite/23_containers/vector/allocator/copy_assign.cc: New.
* testsuite/23_containers/vector/allocator/noexcept.cc: New.
* testsuite/23_containers/vector/allocator/copy.cc: New.
* testsuite/23_containers/vector/allocator/swap.cc: New.
* testsuite/23_containers/vector/allocator/move_assign.cc: New.
* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
Adjust dg-error line numbers.
* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
Likewise.
* 
testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc:
Likewise.
* 
testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc:
Likewise.

Tested x86_64-linux, committed to trunk.
Index: include/bits/stl_vector.h
===
--- include/bits/stl_vector.h   (revision 176072)
+++ include/bits/stl_vector.h   (working copy)
@@ -71,13 +71,15 @@
 struct _Vector_base
 {
   typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+  typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
+   pointer;
 
   struct _Vector_impl 
   : public _Tp_alloc_type
   {
-   typename _Tp_alloc_type::pointer _M_start;
-   typename _Tp_alloc_type::pointer _M_finish;
-   typename _Tp_alloc_type::pointer _M_end_of_storage;
+   pointer _M_start;
+   pointer _M_finish;
+   pointer _M_end_of_storage;
 
_Vector_impl()
: _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0)
@@ -93,6 +95,13 @@
  _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
 #endif
+
+   void _M_swap_data(_Vector_impl& __x)
+   {
+ std::swap(_M_start, __x._M_start);
+ std::swap(_M_finish, __x._M_finish);
+ std::swap(_M_end_of_storage, __x._M_end_of_storage);
+   }
   };
   
 public:
@@ -118,30 +127,30 @@
 
   _Vector_base(size_t __n)
   : _M_impl()
-  {
-   this->_M_impl._M_start = this->_M_allocate(__n);
-   this->_M_impl._M_finish = this->_M_impl._M_start;
-   this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
-  }
+  { _M_create_storage(__n); }
 
   _Vector_base(size_t __n, const allocator_type& __a)
   : _M_impl(__a)
-  {
-   this->_M_impl._M_start = this->_M_allocate(__n);
-   this->_M_impl._M_finish = this->_M_impl._M_start;
-   this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
-  }
+  { _M_create_storage(__n); }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
+  _Vector_base(_Tp_alloc_type&& __a)
+  : _M_impl(std::move(__a)) { }
+
   _Vector_base(_Vector_base&& __x)
   : _M_impl(std::move(__x._M_get_Tp_allocator()))
+  { this->_M_impl._M_swap_data(__x._M_impl); }
+
+  _Vector_base(_Vector_base&& __x, const allocator_type& __a)
+  : _M_impl(__a)
   {
-   this->_M_impl._M_start = __x._M_impl._M_start;
-   this->_M_impl._M_finish = __x._M_impl._M_finish;
-   this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage;
-   __x._M_impl._M_start = 0;
-   __x._M_impl._M_finish = 0;
-   __x._M_impl._M_end_of_storage = 0;
+   if (__x.get_allocator() == __a)
+ this->_M_impl._M_swap_data(__x._M_impl);
+   else
+ {
+   size_t __n = __x._M_impl._M_finish - __x._M_impl._M_start;
+   _M_create_storage(__n);
+ }
   }
 #endif
 
@@ -152,16 +161,25 @@
 public:
   _Vector_impl _M_impl;
 
-  typename _Tp_alloc_type::pointer
+  pointer
   _M_allocate(size_t __n)
   { return __n != 0 ? _M_impl.allocate(__n) : 0; }
 
   void
-  _M_deallocate(typename _Tp_alloc_type::pointer __p, size_t __n)
+  _M_deallocate(pointer __p, size_t __n)
   {
if (__p)
  _M_impl.deallocate(__p, __n);
   }
+
+private:
+  void
+  _M_create_storage(size_t __n)
+  {
+   this->_M_impl._M_start = this->_M_allocate(__n);
+   this->_M_impl._M_finish = this->_M_impl._M_start;
+   this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
+  }
 };
 
 
@@ -196,10 +214,11 @@
 
 public:
   typedef _Tp   value_type;
-  typedef typename _Tp_alloc_type::pointer   pointer;
-  typedef typename _Tp_alloc_type::const_pointer const_pointer;
-  typedef typename _Tp_alloc_type::reference reference;
-  typ

[v3] additions to ext/alloc_traits.h

2011-07-09 Thread Jonathan Wakely
* include/ext/alloc_traits.h (__allocator_always_compares_equal): New
trait, provide partial specializations for known allocators.
(__alloc_traits::construct, __alloc_traits::destroy): Overload for
non-standard pointer types.
(__alloc_traits::_S_always_equal): New trait for use with noexcept.
(__alloc_traits::_S_nothrow_move): Likewise.
(__alloc_traits::_S_nothrow_swap): Likewise.

This adds some new traits to __gnu_ext::__alloc_traits which allow
compile-time detection of allocator types that always compare equal,
allowing container operations to be more efficient and marked noexcept
when appropriate.

Tested x86_64-linux, committed to trunk.
Index: include/ext/alloc_traits.h
===
--- include/ext/alloc_traits.h  (revision 176072)
+++ include/ext/alloc_traits.h  (working copy)
@@ -37,15 +37,56 @@
 # include   // for __alloc_swap
 #endif
 
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template struct allocator;
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  /**
-   * @brief  Uniform interface to C++98 and C++0x allocators.
-   * @ingroup allocators
-  */
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
 template
+  struct __allocator_always_compares_equal
+  { static const bool value = false; };
+
+  template
+struct __allocator_always_compares_equal>
+{ static const bool value = true; };
+
+  template struct array_allocator;
+
+  template
+struct __allocator_always_compares_equal>
+{ static const bool value = true; };
+
+  template struct mt_allocator;
+
+  template
+struct __allocator_always_compares_equal>
+{ static const bool value = true; };
+
+  template struct new_allocator;
+
+  template
+struct __allocator_always_compares_equal>
+{ static const bool value = true; };
+
+  template struct pool_allocator;
+
+  template
+struct __allocator_always_compares_equal>
+{ static const bool value = true; };
+#endif
+
+/**
+ * @brief  Uniform interface to C++98 and C++0x allocators.
+ * @ingroup allocators
+*/
+template
   struct __alloc_traits
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
   : std::allocator_traits<_Alloc>
@@ -66,6 +107,27 @@
 using _Base_type::construct;
 using _Base_type::destroy;
 
+  private:
+template
+  struct __is_custom_pointer
+  : std::integral_constant::value
+ && !std::is_pointer<_Ptr>::value>
+  { };
+
+  public:
+template
+  static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
+  construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
+  {
+   _Base_type::construct(__a, std::addressof(*__p),
+ std::forward<_Args>(__args)...);
+  }
+
+template
+  static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
+  destroy(_Alloc& __a, _Ptr __p)
+  { _Base_type::destroy(__a, std::addressof(*__p)); }
+
 static _Alloc _S_select_on_copy(const _Alloc& __a)
 { return _Base_type::select_on_container_copy_construction(__a); }
 
@@ -81,6 +143,19 @@
 static constexpr bool _S_propagate_on_swap()
 { return _Base_type::propagate_on_container_swap::value; }
 
+static constexpr bool _S_always_equal()
+{ return __allocator_always_compares_equal<_Alloc>::value; }
+
+static constexpr bool _S_nothrow_move()
+{ return _S_propagate_on_move_assign() || _S_always_equal(); }
+
+static constexpr bool _S_nothrow_swap()
+{
+  using std::swap;
+  return !_S_propagate_on_swap()
+   || noexcept(swap(std::declval<_Alloc&>(), 
std::declval<_Alloc&>()));
+}
+
 #else
 
 typedef typename _Alloc::pointerpointer;


Re: [Patch, Fortran] Add runtime_error function to libgfortran/caf/mpi.c

2011-07-09 Thread Tobias Burnus

Tobias Burnus wrote:
This patch adds a run-time error function to mpi.c, which gives a 
proper error message including the image number. Additionally, it 
allows to clean up the error handling, avoiding the duplicated 
declaration of strings.


I have not touched the SYNC functions


Well, I did now. The attached patch combines my runtime_error function 
patch with Daniel's sync patch.


OK?


Tobias

2011-07-09  Tobias Burnus  
	Daniel Carrera  

	* caf/mpi.c (runtime_error): New function.
	(_gfortran_caf_register): Use it.
	(_gfortran_caf_sync_all): Use it, add STAT_STOPPED_IMAGE
	as possible status value.
	(_gfortran_caf_sync_images): Ditto.

diff --git a/libgfortran/caf/mpi.c b/libgfortran/caf/mpi.c
index 4e3a7eb..ce42c31 100644
--- a/libgfortran/caf/mpi.c
+++ b/libgfortran/caf/mpi.c
@@ -28,6 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include 
 #include 
 #include 	/* For memcpy.  */
+#include 	/* For variadic arguments.  */
 #include 
 
 
@@ -46,6 +47,25 @@ static int caf_is_finalized;
 caf_static_t *caf_static_list = NULL;
 
 
+static void
+runtime_error (int error, const char *message, ...)
+{
+  va_list ap;
+  fprintf (stderr, "Fortran runtime error on image %d: ", caf_this_image);
+  va_start (ap, message);
+  fprintf (stderr, message, ap);
+  va_end (ap);
+  fprintf (stderr, "\n");
+
+  /* FIXME: Shutdown the Fortran RTL to flush the buffer.  PR 43849.  */
+  /* FIXME: Do some more effort than just MPI_ABORT.  */
+  MPI_Abort (MPI_COMM_WORLD, error);
+
+  /* Should be unreachable, but to make sure also call exit.  */
+  exit (2);
+}
+
+
 /* Initialize coarray program.  This routine assumes that no other
MPI initialization happened before; otherwise MPI_Initialized
had to be used.  As the MPI library might modify the command-line
@@ -138,34 +158,31 @@ _gfortran_caf_register (ptrdiff_t size, caf_register_t type, void **token,
   return local;
 
 error:
-  if (stat)
-{
-  *stat = caf_is_finalized ? STAT_STOPPED_IMAGE : 1;
-  if (errmsg_len > 0)
-	{
-	  char *msg;
-	  if (caf_is_finalized)
-	msg = "Failed to allocate coarray - stopped images";
-	  else
-	msg = "Failed to allocate coarray";
-	  int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len
-		  : (int) strlen (msg);
-	  memcpy (errmsg, msg, len);
-	  if (errmsg_len > len)
-	memset (&errmsg[len], ' ', errmsg_len-len);
-	}
-  return NULL;
-}
-  else
-{
-  if (caf_is_finalized)
-	fprintf (stderr, "ERROR: Image %d is stopped, failed to allocate "
-		 "coarray", caf_this_image);
-  else
-	fprintf (stderr, "ERROR: Failed to allocate coarray on image %d\n",
-		 caf_this_image);
-  error_stop (1);
-}
+  {
+char *msg;
+
+if (caf_is_finalized)
+  msg = "Failed to allocate coarray - there are stopped images";
+else
+  msg = "Failed to allocate coarray";
+
+if (stat)
+  {
+	*stat = caf_is_finalized ? STAT_STOPPED_IMAGE : 1;
+	if (errmsg_len > 0)
+	  {
+	int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len
+			: (int) strlen (msg);
+	memcpy (errmsg, msg, len);
+	if (errmsg_len > len)
+	  memset (&errmsg[len], ' ', errmsg_len-len);
+	  }
+  }
+else
+  runtime_error (caf_is_finalized ? STAT_STOPPED_IMAGE : 1, msg);
+  }
+
+  return NULL;
 }
 
 
@@ -179,28 +196,34 @@ _gfortran_caf_deregister (void **token __attribute__ ((unused)))
 void
 _gfortran_caf_sync_all (int *stat, char *errmsg, int errmsg_len)
 {
-  /* TODO: Is ierr correct? When should STAT_STOPPED_IMAGE be used?  */
-  int ierr = MPI_Barrier (MPI_COMM_WORLD);
+  int ierr;
 
+  if (unlikely (caf_is_finalized))
+ierr = STAT_STOPPED_IMAGE;
+  else
+ierr = MPI_Barrier (MPI_COMM_WORLD);
+ 
   if (stat)
 *stat = ierr;
 
   if (ierr)
 {
-  const char msg[] = "SYNC ALL failed";
+  char *msg;
+  if (caf_is_finalized)
+	msg = "SYNC ALL failed - there are stopped images";
+  else
+	msg = "SYNC ALL failed";
+
   if (errmsg_len > 0)
 	{
-	  int len = ((int) sizeof (msg) > errmsg_len) ? errmsg_len
-		  : (int) sizeof (msg);
+	  int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len
+		  : (int) strlen (msg);
 	  memcpy (errmsg, msg, len);
 	  if (errmsg_len > len)
 	memset (&errmsg[len], ' ', errmsg_len-len);
 	}
   else
-	{
-	  fprintf (stderr, "SYNC ALL failed\n");
-	  error_stop (ierr);
-	}
+	runtime_error (caf_is_finalized ? STAT_STOPPED_IMAGE : ierr, msg);
 }
 }
 
@@ -243,27 +266,32 @@ _gfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg,
 }
 
   /* Handle SYNC IMAGES(*).  */
-  /* TODO: Is ierr correct? When should STAT_STOPPED_IMAGE be used?  */
-  ierr = MPI_Barrier (MPI_COMM_WORLD);
+  if (unlikely(caf_is_finalized))
+ierr = STAT_STOPPED_IMAGE;
+  else
+ierr = MPI_Barrier (MPI_COMM_WORLD);
+
   if (stat)
 *stat = ierr;
 
   if (ierr)
 {
-  const char msg[] = "SYNC IMAGES failed";
+  char *msg;
+  if (caf_is_fin

[Patch, Fortran] Add runtime_error function to libgfortran/caf/mpi.c

2011-07-09 Thread Tobias Burnus
This patch adds a run-time error function to mpi.c, which gives a proper 
error message including the image number. Additionally, it allows to 
clean up the error handling, avoiding the duplicated declaration of strings.


I have not touched the SYNC functions; they can be handled either after 
the committal of the patch at 
http://gcc.gnu.org/ml/fortran/2011-07/msg00074.html - or they can be 
handled by a replacement patch for the latter.


OK for the trunk?

Tobias
2011-07-09  Tobias Burnus  

	* caf/mpi.c (runtime_error): New function.
	(_gfortran_caf_register): Use it.

diff --git a/libgfortran/caf/mpi.c b/libgfortran/caf/mpi.c
index 4e3a7eb..d916478 100644
--- a/libgfortran/caf/mpi.c
+++ b/libgfortran/caf/mpi.c
@@ -28,6 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include 
 #include 
 #include 	/* For memcpy.  */
+#include 	/* For variadic arguments.  */
 #include 
 
 
@@ -46,6 +47,25 @@ static int caf_is_finalized;
 caf_static_t *caf_static_list = NULL;
 
 
+static void
+runtime_error (int error, const char *message, ...)
+{
+  va_list ap;
+  fprintf (stderr, "Fortran runtime error on image %d: ", caf_this_image);
+  va_start (ap, message);
+  fprintf (stderr, message, ap);
+  va_end (ap);
+  fprintf (stderr, "\n");
+
+  /* FIXME: Shutdown the Fortran RTL to flush the buffer.  PR 43849.  */
+  /* FIXME: Do some more effort than just MPI_ABORT.  */
+  MPI_Abort (MPI_COMM_WORLD, error);
+
+  /* Should be unreachable, but to make sure also call exit.  */
+  exit (2);
+}
+
+
 /* Initialize coarray program.  This routine assumes that no other
MPI initialization happened before; otherwise MPI_Initialized
had to be used.  As the MPI library might modify the command-line
@@ -138,34 +158,30 @@ _gfortran_caf_register (ptrdiff_t size, caf_register_t type, void **token,
   return local;
 
 error:
-  if (stat)
-{
-  *stat = caf_is_finalized ? STAT_STOPPED_IMAGE : 1;
-  if (errmsg_len > 0)
-	{
-	  char *msg;
-	  if (caf_is_finalized)
-	msg = "Failed to allocate coarray - stopped images";
-	  else
-	msg = "Failed to allocate coarray";
-	  int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len
-		  : (int) strlen (msg);
-	  memcpy (errmsg, msg, len);
-	  if (errmsg_len > len)
-	memset (&errmsg[len], ' ', errmsg_len-len);
-	}
-  return NULL;
-}
-  else
-{
-  if (caf_is_finalized)
-	fprintf (stderr, "ERROR: Image %d is stopped, failed to allocate "
-		 "coarray", caf_this_image);
-  else
-	fprintf (stderr, "ERROR: Failed to allocate coarray on image %d\n",
-		 caf_this_image);
-  error_stop (1);
-}
+  {
+char *msg;
+if (caf_is_finalized)
+  msg = "Failed to allocate coarray - there are stopped images";
+else
+  msg = "Failed to allocate coarray";
+
+if (stat)
+  {
+	*stat = caf_is_finalized ? STAT_STOPPED_IMAGE : 1;
+	if (errmsg_len > 0)
+	  {
+	int len = ((int) strlen (msg) > errmsg_len) ? errmsg_len
+			: (int) strlen (msg);
+	memcpy (errmsg, msg, len);
+	if (errmsg_len > len)
+	  memset (&errmsg[len], ' ', errmsg_len-len);
+	  }
+  }
+else
+  runtime_error (caf_is_finalized ? STAT_STOPPED_IMAGE : 1, msg);
+  }
+
+  return NULL;
 }
 
 


Re: [Patch, Fortra] Add STAT_STOPPED_IMAGE to SYC ALL/SYNC IMAGES

2011-07-09 Thread Tobias Burnus

Daniel Carrera wrote:
I'd like to submit the attached patch. This patch was just discussed 
in the gfortran list. It fixes a couple of TODO items in the MPI 
library. It is a simple patch.


OK with the following nits fixed.

* As you have now an SVN account, can you add yourself to the 
./MAINTAINERS file (section: "Write After Approval")? Don't forget to 
write an email to gcc-patches@ with that patch after committal.



libgfortran/ChangeLog

2011-07-07  Daniel Carrera 

* mpi.c (_gfortran_caf_sync_all): Add STAT_STOPPED_IMAGE as a
possible status value.
(_gfortran_caf_sync_images): Ditto.


Change "mpi.c" to "caf/mpi.c" - the file name is relative to the 
ChangeLog file.



+  char msg[30];
+  int len;
+
+  if (caf_is_finalized)
+   len = snprintf (msg, 30, "ERROR: Image %d is stopped", caf_this_image);
+  else
+   len = snprintf (msg, 30, "SYNC ALL failed");


I would like to avoid magic numbers like "30"; in this case, one can 
replace the 30 in snprintf by a simple "sizeof (msg)".




+  if (caf_is_finalized)
+   len = snprintf (msg, 30, "ERROR: Image %d is stopped", caf_this_image);
+  else
+   len = snprintf (msg, 30, "SYNC IMAGES failed");


Ditto.

Tobias


[v3] Ext Ptr tweaks

2011-07-09 Thread Jonathan Wakely
* include/ext/cast.h: Fix typo in include guard.
* include/ext/pointer.h (_Unqualified_type): Remove redundant
partial specializations for volatile types. Fix typos in comments.
(pointer_traits<_Pointer_adaptor>::pointer_to): Define.

Tested x86_64-linux, committed to trunk.
Index: include/ext/cast.h
===
--- include/ext/cast.h  (revision 176072)
+++ include/ext/cast.h  (working copy)
@@ -118,4 +118,4 @@
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
-#endif // __GLIBCXX_CAST_H
+#endif // _GLIBCXX_CAST_H
Index: include/ext/pointer.h
===
--- include/ext/pointer.h   (revision 176072)
+++ include/ext/pointer.h   (working copy)
@@ -232,7 +232,7 @@
 { typedef const volatile _Invalid_type&  reference; };
 
   /**
-   * This structure accomodates the way in which
+   * This structure accommodates the way in which
* std::iterator_traits<> is normally specialized for const T*, so
* that value_type is still T.
*/
@@ -244,14 +244,6 @@
 struct _Unqualified_type 
 { typedef _Tp type; };
 
-  template 
-struct _Unqualified_type 
-{ typedef volatile _Tp type; };
-
-  template 
-struct _Unqualified_type 
-{ typedef volatile _Tp type; };
-  
   /**
* The following provides an 'alternative pointer' that works with
* the containers when specified as the pointer typedef of the
@@ -266,7 +258,7 @@
* so that it becomes reusable for creating other pointer types.
*
* A key point of this class is also that it allows container
-   * writers to 'assume' Alocator::pointer is a typedef for a normal
+   * writers to 'assume' Allocator::pointer is a typedef for a normal
* pointer.  This class supports most of the conventions of a true
* pointer, and can, for instance handle implicit conversion to
* const and base class pointer types.  The only impositions on
@@ -274,7 +266,7 @@
* Allocator::pointer typedef appropriately for pointer types.  2)
* if you need pointer casting, use the __pointer_cast<> functions
* from ext/cast.h.  This allows pointer cast operations to be
-   * overloaded is necessary by custom pointers.
+   * overloaded as necessary by custom pointers.
*
* Note: The const qualifier works with this pointer adapter as
* follows:
@@ -437,7 +429,7 @@
   } \
 // END of _CXX_POINTER_ARITH_OPERATOR_SET macro
   
-  // Expand into the various pointer arithmatic operators needed.
+  // Expand into the various pointer arithmetic operators needed.
   _CXX_POINTER_ARITH_OPERATOR_SET(short);
   _CXX_POINTER_ARITH_OPERATOR_SET(unsigned short);
   _CXX_POINTER_ARITH_OPERATOR_SET(int);
@@ -528,7 +520,7 @@
 { return __rhs.get() != reinterpret_cast(__lhs); } 
 
   /**
-   * Comparison operators for _Pointer_adapter defer to the base class'es
+   * Comparison operators for _Pointer_adapter defer to the base class'
* comparison operators, when possible.
*/
   template
@@ -600,6 +592,9 @@
 public:
   typedef typename __gnu_cxx::_Pointer_adapter<_Rebound_policy> __type;
 };
+
+  static pointer pointer_to(typename pointer::reference __r) noexcept
+  { return pointer(std::addressof(__r)); }
 };
 
 _GLIBCXX_END_NAMESPACE_VERSION


[SPARC] Minor tweaks

2011-07-09 Thread Eric Botcazou
This removes a couple of unused macros and moves another around.

Tested on SPARC/Solaris, applied on the mainline.


2011-07-09  Eric Botcazou  

* config/sparc/sparc.h (STACK_SAVEAREA_MODE): Move around.
(FP_REG_P): Delete.
(IN_OR_GLOBAL_P): Likewise.


-- 
Eric Botcazou
Index: config/sparc/sparc.h
===
--- config/sparc/sparc.h	(revision 176072)
+++ config/sparc/sparc.h	(working copy)
@@ -630,6 +630,11 @@ extern enum cmodel sparc_cmodel;
  : MAX ((COMPUTED), (SPECIFIED)))			\
:  MAX ((COMPUTED), (SPECIFIED)))
 
+/* We need 2 words, so we can save the stack pointer and the return register
+   of the function containing a non-local goto target.  */
+#define STACK_SAVEAREA_MODE(LEVEL) \
+  ((LEVEL) == SAVE_NONLOCAL ? (TARGET_ARCH64 ? TImode : DImode) : Pmode)
+
 /* Make strings word-aligned so strcpy from constants will be faster.  */
 #define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
   ((TREE_CODE (EXP) == STRING_CST	\
@@ -1377,11 +1382,6 @@ do {	\
functions that have frame pointers.  */
 #define EXIT_IGNORE_STACK 1
 
-/* We need 2 words, so we can save the stack pointer and the return register
-   of the function containing a non-local goto target.  */
-#define STACK_SAVEAREA_MODE(LEVEL) \
-  ((LEVEL) == SAVE_NONLOCAL ? (TARGET_ARCH64 ? TImode : DImode) : Pmode)
-
 /* Length in units of the trampoline for entering a nested function.  */
 #define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16)
 
@@ -1517,24 +1517,11 @@ do {	\
 #define REGNO_OK_FOR_FP_P(REGNO) \
   (((unsigned) (REGNO) - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)) \
|| ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)))
+
 #define REGNO_OK_FOR_CCFP_P(REGNO) \
  (TARGET_V9 \
   && (((unsigned) (REGNO) - 96 < (unsigned)4) \
   || ((unsigned) reg_renumber[REGNO] - 96 < (unsigned)4)))
-
-/* Now macros that check whether X is a register and also,
-   strictly, whether it is in a specified class.
-
-   These macros are specific to the SPARC, and may be used only
-   in code for printing assembler insns and in conditions for
-   define_optimization.  */
-
-/* 1 if X is an fp register.  */
-
-#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
-
-/* Is X, a REG, an in or global register?  i.e. is regno 0..7 or 24..31 */
-#define IN_OR_GLOBAL_P(X) (REGNO (X) < 8 || (REGNO (X) >= 24 && REGNO (X) <= 31))
 
 /* Maximum number of registers that can appear in a valid memory address.  */
 


[v3] fix libstdc++/49668 - do not use std::bind for simple call wrappers

2011-07-09 Thread Jonathan Wakely
std::bind forwards the bound arguments as lvalues, so we shouldn't be
using it to implement the
INVOKE(DECAY_COPY(f), DECAY_COPY(args)...)
pseudo-expressions in the threads clauses. Using std::bind we can't
invoke functions which require rvalue arguments.

This patch adds a bind-like helper that can be used by call wrappers
in ,  and  instead of std::bind.  The call
wrapper returned by __bind_simple may not be copy constructible so
_Async_state and _Deferred_state cannot use std::function to store it.

PR libstdc++/49668
* include/std/functional (__bind_simple): Define.
* include/std/future (_Task_setter): Parameterize by type of result
pointer instead of state object.
(_S_task_setter): Type deduction helper.
(_Task_state): Use _S_task_setter and __bind_simple.
(_Deferred_state, _Async_state): Store call wrapper directly not as
std::function. Use _S_task_setter and __bind_simple.
(_S_make_deferred_state, _S_make_async_state): Type deduction helpers.
(async): Use new functions and __bind_simple.
* include/std/mutex (call_once): Use __bind_simple.
* include/std/thread (thread): Likewise. Remove unused headers.
* src/thread.cc: Add header.
* testsuite/30_threads/async/49668.cc: New.
* testsuite/30_threads/call_once/49668.cc: New.
* testsuite/30_threads/thread/cons/49668.cc: New.
* testsuite/30_threads/thread/cons/moveable.cc: Remove unused bool.

Tested x86_64-linux, committed to trunk.
Index: include/std/functional
===
--- include/std/functional  (revision 176072)
+++ include/std/functional  (working copy)
@@ -1499,6 +1499,77 @@
   std::forward<_BoundArgs>(__args)...);
 }
 
+  template
+struct _Bind_simple;
+
+  template
+struct _Bind_simple<_Callable(_Args...)>
+{
+  typedef typename result_of<_Callable(_Args...)>::type result_type;
+
+  template::type>
+explicit
+_Bind_simple(const _Callable& __callable, _Args2&&... __args)
+: _M_bound(__callable, std::forward<_Args2>(__args)...)
+{ }
+
+  template::type>
+explicit
+_Bind_simple(_Callable&& __callable, _Args2&&... __args)
+: _M_bound(std::move(__callable), std::forward<_Args2>(__args)...)
+{ }
+
+  _Bind_simple(const _Bind_simple&) = default;
+  _Bind_simple(_Bind_simple&&) = default;
+
+  result_type
+  operator()()
+  {
+typedef typename _Build_index_tuple::__type _Indices;
+return _M_invoke(_Indices());
+  }
+
+private:
+
+  template
+typename result_of<_Callable(_Args...)>::type
+_M_invoke(_Index_tuple<_Indices...>)
+{
+ // std::bind always forwards bound arguments as lvalues,
+ // but this type can call functions which only accept rvalues.
+  return std::forward<_Callable>(std::get<0>(_M_bound))(
+  std::forward<_Args>(std::get<_Indices+1>(_M_bound))...);
+}
+
+  std::tuple<_Callable, _Args...> _M_bound;
+};
+
+  template
+struct _Bind_simple_helper
+{
+  typedef _Maybe_wrap_member_pointer::type>
+__maybe_type;
+  typedef typename __maybe_type::type __func_type;
+  typedef _Bind_simple<__func_type(typename decay<_BoundArgs>::type...)>
+   __type;
+};
+
+  // Simplified version of std::bind for internal use, without support for
+  // unbound arguments, placeholders or nested bind expressions.
+  template
+typename _Bind_simple_helper<_Callable, _Args...>::__type
+__bind_simple(_Callable&& __callable, _Args&&... __args)
+{
+  typedef _Bind_simple_helper<_Callable, _Args...> __helper_type;
+  typedef typename __helper_type::__maybe_type __maybe_type;
+  typedef typename __helper_type::__type __result_type;
+  return __result_type(
+  __maybe_type::__do_wrap( std::forward<_Callable>(__callable)),
+  std::forward<_Args>(__args)...);
+}
+
   /**
*  @brief Exception class thrown when class template function's
*  operator() is called with an empty target.
Index: include/std/future
===
--- include/std/future  (revision 176072)
+++ include/std/future  (working copy)
@@ -488,17 +488,42 @@
   virtual void _M_run_deferred() { }
 };
 
-template
+template
   class _Deferred_state;
 
-template
+template
   class _Async_state;
 
 template
   class _Task_state;
 
-template
+template
+  static std::shared_ptr<_State_base>
+  _S_make_deferred_state(_BoundFn&& __fn);
+
+template
+  static std::shared_ptr<_State_base>
+  _S_make_async_state(_BoundFn&& __fn);
+
+template
   struct _Task_setter;
+
+template
+  class _Task_setter_helper
+  {
+   typedef typename remove_reference<_Bound