C++ PATCH for c++/50075 (ICE on recursive late-specified return type)

2011-08-14 Thread Jason Merrill
We were assuming that if current_function_decl is set, then we are at a 
local binding level.  But that isn't the case with a late-specified 
return type, so we need to check something else instead.  Since what we 
are interested in the binding level, let's check that directly.


Tested x86_64-pc-linux-gnu, applied to trunk.
commit c81176e5a49c52dfba88206b3c73aa38ee287db1
Author: Jason Merrill 
Date:   Sat Aug 13 17:58:45 2011 -0400

	PR c++/50075
	* name-lookup.c (local_bindings_p): New.
	* name-lookup.h: Declare it.
	* lex.c (unqualified_name_lookup_error): Use it.

diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 691a2ec..c11e3b3 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -456,7 +456,7 @@ unqualified_name_lookup_error (tree name)
 	}
   /* Prevent repeated error messages by creating a VAR_DECL with
 	 this NAME in the innermost block scope.  */
-  if (current_function_decl)
+  if (local_bindings_p ())
 	{
 	  tree decl;
 	  decl = build_decl (input_location,
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 1afd9ed..64456b4 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1608,6 +1608,15 @@ namespace_bindings_p (void)
   return b->kind == sk_namespace;
 }
 
+/* True if the innermost non-class scope is a block scope.  */
+
+bool
+local_bindings_p (void)
+{
+  cp_binding_level *b = innermost_nonclass_level ();
+  return b->kind < sk_function_parms || b->kind == sk_omp;
+}
+
 /* True if the current level needs to have a BLOCK made.  */
 
 bool
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 5974dce..a37afdb 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -292,6 +292,7 @@ extern bool kept_level_p (void);
 extern bool global_bindings_p (void);
 extern bool toplevel_bindings_p	(void);
 extern bool namespace_bindings_p (void);
+extern bool local_bindings_p (void);
 extern bool template_parm_scope_p (void);
 extern scope_kind innermost_scope_kind (void);
 extern cp_binding_level *begin_scope (scope_kind, tree);
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype32.C b/gcc/testsuite/g++.dg/cpp0x/decltype32.C
new file mode 100644
index 000..66731cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype32.C
@@ -0,0 +1,12 @@
+// PR c++/50075
+// { dg-options -std=c++0x }
+
+template 
+auto make_array(const T& il) ->	// { dg-error "not declared" }
+decltype(make_array(il))
+{ }
+
+int main()
+{
+  int z = make_array(1);	// { dg-error "no match" }
+}


Re: [x86] Use match_test for .md attributes

2011-08-14 Thread Uros Bizjak
Hello!

> Following on from the two patches I've just posted, this one makes
> config/i386/*.md use match_test for .md attributes.  Tested as
> described here:

> http://gcc.gnu.org/ml/gcc-patches/2011-08/msg01182.html

>   * config/i386/i386.md: Use (match_test ...) for attribute tests.
>   * config/i386/mmx.md: Likewise.
>   * config/i386/sse.md: Likewise.

-(eq (symbol_ref "TARGET_SSE2") (const_int 0)))
+(not (match_test "TARGET_SSE2")))

Jus a question - in predicates.md, i.e. (match_test "!TARGET_SSE2") is
used. Do we want to standardize on (not (match_test "...")) form
everywhere?

The patch is OK.


Re: [Patch ARM] Fix PR50022

2011-08-14 Thread Matthias Klose
On 08/12/2011 04:16 PM, Ramana Radhakrishnan wrote:
>>> @@ -24183,4 +24306,13 @@ arm_attr_length_push_multi(rtx parallel_op, rtx 
>>> first_op)
>>>return 4;
>>>  }
>>>
>>> +/* Compute the number of instructions emitted by output_move_double.  */
>>> +int
>>> +arm_count_output_move_double_insns (rtx *operands)
>>> +{
>>> +  int count;
>>> +  output_move_double (operands, 0, &count);
>>> +  return count;
>>> +}

@@ -24205,4 +24328,13 @@ arm_attr_length_push_multi(rtx parallel_op, rtx 
first_op)
   return 4;
 }

+/* Compute the number of instructions emitted by output_move_double.  */
+int
+arm_length_output_move_double_insns (rtx *operands)
+{
+  int count;
+  output_move_double (operands, false, &count);
+  return count;
+}
+

fails to build, rename it everywhere if needed.


Re: [Patch, fortran] PR fortran/50071 Duplicate statement labels from different scoping units rejected.

2011-08-14 Thread Tobias Burnus

Hi Mikael,

Mikael Morin wrote:

this patch fixes PR 50071 where statement labels in a type definition where
hooked to the parent scoping unit instead of the type scoping unit.


I think the following is valid and it is still rejected (it is accepted 
by NAG 5.1 and ifort):


1 type t
integer :: i
  end type t

  goto 1
1 print *, 'Hello'
end

Related but separate issue: BLOCK also starts a new scoping unit, but 
the following is rejected:


   block
 goto 1
 print *, 'Hello'
1continue
   end block
1  continue
end


Also the following is rejected:

   block
 goto 1
 print *, 'Hello'
1  end block
end

variant, which is rejected (note: Associate does not start a new scoping 
unit, just a new block):


  integer :: i
  associate (j => i)
goto 1
print *, 'Hello'
1  end associate
end

Tobias


Re: [PATCH 2/2] document ISL requirement for GCC installation

2011-08-14 Thread Richard Guenther
On Sat, Aug 13, 2011 at 6:26 PM, Matthias Klose  wrote:
> On 08/13/2011 06:02 PM, Sebastian Pop wrote:
>> On Sat, Aug 13, 2011 at 10:32, Joseph S. Myers  
>> wrote:
>>> I advise either removing the option for CLooG to use bundled ISL, or
>>> making the bundled version the recommended version for GCC.  Having too
>>> many ways to configure things is bad.
>>
>> I would prefer using the ISL bundled with CLooG and not have
>> to provide a way to configure GCC with ISL.
>
> which would be exactly the way no distribution would use it. So please just
> don't bundle ISL with CLoog.

Well, I would simply have linked the bundled ISL statically into libcloog.

Richard.


[Patch, Fortran, committed] PR 50073: gfortran must not accept function name when result name is present

2011-08-14 Thread Janus Weil
Hi all,

I just committed as obvious the fix for an accepts-invalid problem
involving function results. I simply took an existing check, separated
it off into a small function, and called it from another place (where
it was missed previously):

http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=177745

Cheers,
Janus


Re: [PATCH] [JAVA] patch for Java on RTEMS

2011-08-14 Thread Jie Liu
Hi,

I have add the boehm-gc patch and the configure for gcc patch to the
patch attached. So we can add this patch and then compile gcj for
RTEMS.

Best Regards,
Jie


gcj-rtems.patch
Description: Binary data


[M32C] Hookize PREFERRED_RELOAD_CLASS and PREFERRED_OUTPUT_RELOAD_CLASS

2011-08-14 Thread Anatoly Sokolov
Hi.

  This patch removes obsolete PREFERRED_RELOAD_CLASS and 
PREFERRED_OUTPUT_RELOAD_CLASS macros from M32C back end in the GCC and 
introduces equivalent TARGET_PREFERRED_RELOAD_CLASS and
TARGET_PREFERRED_OUTPUT_RELOAD_CLASS target hooks.

  Regression tested on m32c-unknown-elf.

  OK to install?

* config/m32c/m32c.h (PREFERRED_RELOAD_CLASS,
PREFERRED_OUTPUT_RELOAD_CLASS): Remove macro.
* config/m32c/m32c-protos.h (m32c_preferred_reload_class,
m32c_preferred_output_reload_class): Remove.
* config/m32c/m32c.c (m32c_preferred_reload_class): Make static.
Change rclass argument and return types to reg_class_t. Use
reg_class_subset_p instead of class_sizes.
(m32c_preferred_output_reload_class): Make static. Change rclass
argument and return types to reg_class_t.
(TARGET_PREFERRED_RELOAD_CLASS,
TARGET_PREFERRED_OUTPUT_RELOAD_CLASS): Define.


Index: gcc/config/m32c/m32c.c
===
--- gcc/config/m32c/m32c.c  (revision 177745)
+++ gcc/config/m32c/m32c.c  (working copy)
@@ -729,12 +729,16 @@
 
 #define DEBUG_RELOAD 0
 
-/* Implements PREFERRED_RELOAD_CLASS.  In general, prefer general
+/* Implements TARGET_PREFERRED_RELOAD_CLASS.  In general, prefer general
registers of the appropriate size.  */
-int
-m32c_preferred_reload_class (rtx x, int rclass)
+
+#undef TARGET_PREFERRED_RELOAD_CLASS
+#define TARGET_PREFERRED_RELOAD_CLASS m32c_preferred_reload_class
+
+static reg_class_t
+m32c_preferred_reload_class (rtx x, reg_class_t rclass)
 {
-  int newclass = rclass;
+  reg_class_t newclass = rclass;
 
 #if DEBUG_RELOAD
   fprintf (stderr, "\npreferred_reload_class for %s is ",
@@ -759,7 +763,7 @@
   else if (newclass == QI_REGS && GET_MODE_SIZE (GET_MODE (x)) > 2)
 newclass = SI_REGS;
   else if (GET_MODE_SIZE (GET_MODE (x)) > 4
-  && ~class_contents[rclass][0] & 0x000f)
+  && ! reg_class_subset_p (R03_REGS, rclass))
 newclass = DI_REGS;
 
   rclass = reduce_class (rclass, newclass, rclass);
@@ -779,9 +783,13 @@
   return rclass;
 }
 
-/* Implements PREFERRED_OUTPUT_RELOAD_CLASS.  */
-int
-m32c_preferred_output_reload_class (rtx x, int rclass)
+/* Implements TARGET_PREFERRED_OUTPUT_RELOAD_CLASS.  */
+
+#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
+#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS m32c_preferred_output_reload_class
+
+static reg_class_t
+m32c_preferred_output_reload_class (rtx x, reg_class_t rclass)
 {
   return m32c_preferred_reload_class (x, rclass);
 }
Index: gcc/config/m32c/m32c.h
===
--- gcc/config/m32c/m32c.h  (revision 177745)
+++ gcc/config/m32c/m32c.h  (working copy)
@@ -417,8 +417,6 @@
 #define REGNO_OK_FOR_BASE_P(NUM) m32c_regno_ok_for_base_p (NUM)
 #define REGNO_OK_FOR_INDEX_P(NUM) 0
 
-#define PREFERRED_RELOAD_CLASS(X,CLASS) m32c_preferred_reload_class (X, CLASS)
-#define PREFERRED_OUTPUT_RELOAD_CLASS(X,CLASS) 
m32c_preferred_output_reload_class (X, CLASS)
 #define LIMIT_RELOAD_CLASS(MODE,CLASS) \
   (enum reg_class) m32c_limit_reload_class (MODE, CLASS)
 
Index: gcc/config/m32c/m32c-protos.h
===
--- gcc/config/m32c/m32c-protos.h   (revision 177745)
+++ gcc/config/m32c/m32c-protos.h   (working copy)
@@ -66,8 +66,6 @@
 int  m32c_modes_tieable_p (enum machine_mode, enum machine_mode);
 bool m32c_mov_ok (rtx *, enum machine_mode);
 char * m32c_output_compare (rtx, rtx *);
-int  m32c_preferred_output_reload_class (rtx, int);
-int  m32c_preferred_reload_class (rtx, int);
 int  m32c_prepare_move (rtx *, enum machine_mode);
 int  m32c_prepare_shift (rtx *, int, int);
 int  m32c_reg_ok_for_base_p (rtx, int);

Anatoly.



[patch, fortran] PR 46659 - extend conversion warnings to assignments

2011-08-14 Thread Thomas Koenig

Hello world,

the attached patch extends conversion warnings to assignments.

OK for trunk?

Thomas

011-08-14  Thomas Koenig  

PR fortran/46659
* expr.c (gfc_check_assign): Check for type conversions when the
right-hand side is a constant REAL cor COMPLEX contstant the
left-hand side is also REAL or COMPLEX.  Don't warn when a
narrowing conversion does not change the value of the constant.

2011-08-14  Thomas Koenig  

PR fortran/46659
* gfortran.dg/warn_conversion_2.f90:  Also warn about conversion
of a constant resulting from simplification.
* gfortran.dg/warn_conversion_3.f90:  New test.
Index: fortran/expr.c
===
--- fortran/expr.c	(Revision 177746)
+++ fortran/expr.c	(Arbeitskopie)
@@ -3190,6 +3190,53 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rval
 	}
 }
 
+  /*  If lvalue is REAL and rvalue is a REAL constant with different,
+  warn about possible errors the user may have done during conversion.  */
+
+  if (rvalue->expr_type == EXPR_CONSTANT
+  && (lvalue->ts.type == BT_REAL || lvalue->ts.type == BT_COMPLEX)
+  && (rvalue->ts.type == BT_REAL || rvalue->ts.type == BT_COMPLEX))
+{
+  if (lvalue->ts.kind < rvalue->ts.kind && gfc_option.gfc_warn_conversion)
+	{
+	  /* As a special bonus, don't warn about REAL rvalues which are not
+	 changed by the conversion if -Wconversion is specified.  */
+	  if (rvalue->ts.type == BT_REAL && mpfr_number_p (rvalue->value.real))
+	{
+	  /* Calculate the difference between the constant and the rounded
+		 value and check it against zero.  */
+	  mpfr_t rv, diff;
+	  gfc_set_model_kind (lvalue->ts.kind);
+	  mpfr_init (rv);
+	  gfc_set_model_kind (rvalue->ts.kind);
+	  mpfr_init (diff);
+	  
+	  mpfr_set (rv, rvalue->value.real, GFC_RND_MODE);
+	  mpfr_sub (diff, rv, rvalue->value.real, GFC_RND_MODE);
+	  
+	  if (!mpfr_zero_p (diff))
+		gfc_warning ("Change of value in conversion from "
+			 " %s to %s at %L", gfc_typename (&rvalue->ts),
+			 gfc_typename (&lvalue->ts), &rvalue->where);
+	  
+	  mpfr_clear (rv);
+	  mpfr_clear (diff);
+	}
+	  else
+	gfc_warning ("Possible change of value in conversion from %s "
+			 "to %s at %L",gfc_typename (&rvalue->ts),
+			 gfc_typename (&lvalue->ts), &rvalue->where);
+
+	}
+  else if (gfc_option.warn_conversion_extra
+	   && lvalue->ts.kind > rvalue->ts.kind)
+	{
+	  gfc_warning ("Conversion from %s to %s at %L",
+		   gfc_typename (&rvalue->ts), gfc_typename (&lvalue->ts),
+		   &rvalue->where);
+	}
+}
+
   if (gfc_compare_types (&lvalue->ts, &rvalue->ts))
 return SUCCESS;
 
Index: testsuite/gfortran.dg/warn_conversion_2.f90
===
--- testsuite/gfortran.dg/warn_conversion_2.f90	(Revision 177746)
+++ testsuite/gfortran.dg/warn_conversion_2.f90	(Arbeitskopie)
@@ -7,5 +7,5 @@
   x = 2.0
   sqrt2 = sqrt(x)  ! { dg-warning "Conversion" }
 
-  sqrt2 = sqrt(2.0)! no warning; simplified to a constant and range checked
+  sqrt2 = sqrt(2.0)! { dg-warning "Conversion" }
 end
! { dg-do compile }
! { dg-options "-Wconversion -Wconversion-extra" }
! PR 47659 - warning about conversions on assignment
! Based on a test case by Thomas Henlich
program main
  double precision d1, d2
  real :: r1, r2
  r1 = 2.3d0 ! { dg-warning "Change of value in conversion" }
  r2 = 2.5d0 ! No warning because the value does not change
  d1 = .13 ! { dg-warning "Conversion" }
  d2 = .13d0
end program main


Re: [patch, fortran] PR 46659 - extend conversion warnings to assignments

2011-08-14 Thread Thomas Koenig

I wrote:

Hello world,

the attached patch extends conversion warnings to assignments.

OK for trunk?


... and forgot to say that this has been regression-tested.

Thomas


Re: PING: PATCH: PR target/46770: Use .init_array/.fini_array sections

2011-08-14 Thread H.J. Lu
PING

On Tue, Aug 9, 2011 at 6:56 AM, H.J. Lu  wrote:
> PING.
>
> On Sat, Aug 6, 2011 at 7:40 AM, H.J. Lu  wrote:
>> PING.
>>
>> On Fri, Jul 22, 2011 at 7:06 AM, H.J. Lu  wrote:
>>> On Fri, Jul 22, 2011 at 7:00 AM, H.J. Lu  wrote:
 On Fri, Jul 22, 2011 at 6:03 AM, H.J. Lu  wrote:
> On Fri, Jul 22, 2011 at 5:30 AM, Jakub Jelinek  wrote:
>> On Fri, Jul 22, 2011 at 04:59:28AM -0700, H.J. Lu wrote:
>>> @@ -2660,6 +2664,7 @@ esac
>>>  case ${target} in
>>>  i[34567]86-*-linux* | x86_64-*-linux*)
>>>       tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
>>> +     use_initfini_array=yes
>>>       ;;
>>>  i[34567]86-*-* | x86_64-*-*)
>>>       tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
>>
>> What is i?86/x86_64 specific on it?  Don't most other glibc targets
>> want to use it too, perhaps with some arch specific tweaks?
>
> I do have a patch for all ELF targets:
>
> http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01416.html
>
> It touches many targets. .  But I only have one feedback from one
> target maintainer.  I don't know how long it will take to review it.
>
>
>>> --- /dev/null
>>> +++ b/gcc/config/initfini-array.c
>>
>> This is ugly.  varasm.c already has lots of ELF specific code, simply
>> put them there as well and only let configury set some macro which will
>> allow targets to choose which of the implementations in the generic code
>> they want to use (or if they want their own which e.g. calls the generic
>> routine and does something additional to it etc.).  The sections probably
>> can be created only the first time you actually need them.
>
> I will do that.
>
>>> --- a/gcc/crtstuff.c
>>> +++ b/gcc/crtstuff.c
>>> @@ -189,6 +190,9 @@ typedef void (*func_ptr) (void);
>>>     refer to only the __CTOR_END__ symbol in crtend.o and the 
>>> __DTOR_LIST__
>>>     symbol in crtbegin.o, where they are defined.  */
>>>
>>> +/* No need for .ctors/.dtors section if linker can place them in
>>> +   .init_array/.fini_array section.  */
>>> +#ifndef NO_CTORS_DTORS_SECTIONS
>>>  /* The -1 is a flag to __do_global_[cd]tors indicating that this table
>>>     does not start with a count of elements.  */
>>>  #ifdef CTOR_LIST_BEGIN
>>> @@ -219,6 +223,7 @@ STATIC func_ptr __DTOR_LIST__[1]
>>>    __attribute__((section(".dtors"), aligned(sizeof(func_ptr
>>>    = { (func_ptr) (-1) };
>>>  #endif /* __DTOR_LIST__ alternatives */
>>> +#endif /* NO_CTORS_DTORS_SECTIONS */
>>>
>>>  #ifdef USE_EH_FRAME_REGISTRY
>>>  /* Stick a label at the beginning of the frame unwind info so we can 
>>> register
>>> @@ -489,6 +494,9 @@ __do_global_ctors_1(void)
>>>
>>>  #elif defined(CRT_END) /* ! CRT_BEGIN */
>>>
>>> +/* No need for .ctors/.dtors section if linker can place them in
>>> +   .init_array/.fini_array section.  */
>>> +#ifndef NO_CTORS_DTORS_SECTIONS
>>>  /* Put a word containing zero at the end of each of our two lists of 
>>> function
>>>     addresses.  Note that the words defined here go into the .ctors and 
>>> .dtors
>>>     sections of the crtend.o file, and since that file is always linked 
>>> in
>>> @@ -534,6 +542,7 @@ STATIC func_ptr __DTOR_END__[1]
>>>    __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr
>>>    = { (func_ptr) 0 };
>>>  #endif
>>> +#endif /* NO_CTORS_DTORS_SECTIONS */
>>>
>>>  #ifdef EH_FRAME_SECTION_NAME
>>>  /* Terminate the frame unwind info section with a 4byte 0 as a 
>>> sentinel;
>>
>> I don't see how you can do this.  It would IMO break any time you link 
>> code
>> built by different gcc versions where some code emitted by the older gcc
>> used .ctors or .dtors.
>
> crtstuff.c is used to generate crt*.o, which is the part of GCC.  You 
> only use
> it with the GCC you are using.  Since your GCC doesn't put anything in
> .ctors/.dtors section, you don't need them.  As for .o files generated by
> old GCCs, that is the linker test, use_initfini_array, is for.  The newer 
> linker
> can put input .ctors/.dtors sections in output .init_array/,fini_array 
> sections.
>
>

 Here is the updated patch.  Any comments?

 Thanks.

 --
 H.J.
 ---
 2011-07-22  H.J. Lu  

        PR target/46770
        * config.gcc (use_initfini_array): New variable.
        Use .init_arary/.fini_array if they are supported.

        * crtstuff.c: Don't generate .ctors nor .dtors sections if
        USE_INITFINI_ARRAY is defined.

        * output.h (default_initfini_array_init_sections): New.
        * varasm.c (elf_init_array_section): Likewise.
        (elf_fini_array_section): Likewise.
        (get_elf_initfini_array_pri

Re: PATCH: PR middle-end/49721: convert_memory_address_addr_space may generate invalid new insns

2011-08-14 Thread H.J. Lu
Hi,

This patch is needed for x32 and only affects x32.  Any comments/objections
to apply this to finish x32 support?

Thanks.


H.J.

On Thu, Aug 11, 2011 at 6:25 AM, H.J. Lu  wrote:
> Hi,
>
> This is the last patch needed for x32 support.
> convert_memory_address_addr_space
> is called to convert a memory address without overflow/underflow.  It
> should be safe
> to transform
>
> (zero_extend:DI (plus:SI (FOO:SI) (const_int Y)))
>
> to
>
> (plus:DI (zero_extend:DI (FOO:SI)) (const_int Y))
>
> GCC only works this way.  Any comments?
>
> Thanks.
>
> H.J.
> 
> On Sun, Aug 7, 2011 at 1:08 PM, H.J. Lu  wrote:
>> Hi,
>>
>> We transform
>>
>> ptr_extend:DI (plus:SI (FOO:SI) (const_int Y)))
>>
>> to
>>
>> (plus:DI (ptr_extend:DI (FOO:SI)) (const_int Y))
>>
>> since this is how Pmode != ptr_mode is supported even if the resulting
>> address may overflow/underflow.   It is also true for x32 which has
>> zero_extend instead of ptr_extend.  I have tried different approaches
>> to avoid transforming
>>
>> (zero_extend:DI (plus:SI (FOO:SI) (const_int Y)))
>>
>> to
>>
>> (plus:DI (zero_extend:DI (FOO:SI)) (const_int Y))
>>
>> without success.  This patch relaxes the condition to check
>> POINTERS_EXTEND_UNSIGNED != 0 instead if POINTERS_EXTEND_UNSIGNED < 0
>> to cover both ptr_extend and zero_extend. We can investigate a better
>> approach for ptr_extend and zero_extend later.  For now, I believe it
>> is the saftest way to support ptr_extend and zero_extend.
>>
>> Any comments?
>>
>> Thanks.
>>
>>
>> H.J.
>> ---
>> gcc/
>>
>> 2011-08-06  H.J. Lu  
>>
>>        PR middle-end/49721
>>        * explow.c (convert_memory_address_addr_space): Also permute the
>>        conversion and addition of constant for zero-extend.
>>
>> gcc/testsuite/
>>
>> 2011-08-06  H.J. Lu  
>>
>>        PR middle-end/49721
>>        * gfortran.dg/pr49721.f: New.
>>
>> diff --git a/gcc/explow.c b/gcc/explow.c
>> index f8262db..ed2f621 100644
>> --- a/gcc/explow.c
>> +++ b/gcc/explow.c
>> @@ -384,18 +384,23 @@ 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).
>> +      /* FIXME: For addition, we used to permute the conversion and
>> +       * addition operation only 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) even if the resulting address
>> +        may overflow/underflow.  We relax the condition to include
>> +        zero-extend (POINTERS_EXTEND_UNSIGNED > 0) since the other
>> +        parts of the compiler depend on it.  See PR 49721.
>> +
>>         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)))
>> +             && (POINTERS_EXTEND_UNSIGNED != 0
>> +                 || XEXP (x, 1) == convert_memory_address_addr_space
>> +                                       (to_mode, XEXP (x, 1), as
>>        return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
>>                               convert_memory_address_addr_space
>>                                 (to_mode, XEXP (x, 0), as),
>> diff --git a/gcc/testsuite/gfortran.dg/pr49721.f 
>> b/gcc/testsuite/gfortran.dg/pr49721.f
>> new file mode 100644
>> index 000..39e2ed7
>> --- /dev/null
>> +++ b/gcc/testsuite/gfortran.dg/pr49721.f
>> @@ -0,0 +1,35 @@
>> +! PR middle-end/49721
>> +! { dg-do compile }
>> +! { dg-options "-O3 -funroll-loops" }
>> +
>> +      subroutine midbloc6(c,a2,a2i,q)
>> +      parameter (ndim2=6)
>> +      parameter (ndim=3)
>> +      dimension ri(ndim2),cr(ndim2,ndim2),xj(ndim2,ndim2),q(*)
>> +     @,sai(ndim2,ndim2),cm(ndim2,ndim2),w(ndim2,ndim2)
>> +      dimension vr(ndim2,ndim2),vi(ndim2,ndim2),s1(ndim2,ndim2),p(ndim)
>> +      dimension xq(6),qb(2),qc(2),ifl(6),iplane(3)
>> +      save
>> +      call eig66(cr,rr,ri,vr,vi)
>> +      xq(i)=asin(ri(i))/x2pi
>> +      i9=6
>> +      qb(1)=q(1)/x2pi
>> +        do 180 i=1,2
>> +          do 170 j=1,6
>> +  120       if(xq(j)) 130,190,140
>> +  130       if(qb(i)-0.5d0) 160,150,150
>> +  140       if(qb(i)-0.5d0) 150,150,160
>> +  150       continue
>> +            tst=abs(abs(qb(i))-abs(xq(j)))
>> +  160       continue
>> +  170     continue
>> +          iplane(i)=k
>> +  180   continue
>> +  190   continue
>

Re: [MMIX] Hookize PREFERRED_RELOAD_CLASS and PREFERRED_OUTPUT_RELOAD_CLASS

2011-08-14 Thread Anatoly Sokolov
Hi.

>   This patch removes obsolete PREFERRED_RELOAD_CLASS and 
> PREFERRED_OUTPUT_RELOAD_CLASS macros from MMIX back end in the GCC and 
> introduces equivalent TARGET_PREFERRED_RELOAD_CLASS and
> TARGET_PREFERRED_OUTPUT_RELOAD_CLASS target hooks.

> --- gcc/config/mmix/mmix.c  (revision 176858)

> +static reg_class_t mmix_preferred_reload_class (rtx, reg_class_t);
> +static reg_class_t mmix_preferred_output_reload_class (rtx, reg_class_t);

> +#undef TARGET_PREFERRED_RELOAD_CLASS
> +#define TARGET_PREFERRED_RELOAD_CLASS mmix_preferred_reload_class
> +#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
> +#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS mmix_preferred_reload_class


  The TARGET_PREFERRED_OUTPUT_RELOAD_CLASS macro incorrectly defined. This 
patch fix it.

  Regression tested on mmix-knuth-mmixware.

  Committed as obvious.

* config/mmix/mmix.c (TARGET_PREFERRED_OUTPUT_RELOAD_CLASS): Redefine
as mmix_preferred_output_reload_class.

Index: gcc/config/mmix/mmix.c
===
--- gcc/config/mmix/mmix.c  (revision 177747)
+++ gcc/config/mmix/mmix.c  (working copy)
@@ -260,7 +260,7 @@
 #undef TARGET_PREFERRED_RELOAD_CLASS
 #define TARGET_PREFERRED_RELOAD_CLASS mmix_preferred_reload_class
 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
-#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS mmix_preferred_reload_class
+#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS mmix_preferred_output_reload_class
 
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_Pmmix_legitimate_address_p


Anatoly.



[PATCH, i386]: Expand round(a) = sgn(a) * floor(fabs(a) + 0.5) using SSE4 ROUND insn

2011-08-14 Thread Uros Bizjak
Hello!

We can use ROUNDSP/ROUNDSD in round(a) expansion. Currently, we expand
round(a) as (-O2 -ffast-math):

.LFB0:
.cfi_startproc
movsd   .LC1(%rip), %xmm1
movapd  %xmm0, %xmm2
movsd   .LC0(%rip), %xmm3
andpd   %xmm1, %xmm2
ucomisd %xmm2, %xmm3
jbe .L2
addsd   .LC2(%rip), %xmm2
andnpd  %xmm0, %xmm1
movapd  %xmm1, %xmm0
cvttsd2siq  %xmm2, %rax
cvtsi2sdq   %rax, %xmm2
orpd%xmm2, %xmm0
.L2:
rep
ret

Adding -msse4, we now generate branchless code using roundsd:

.LFB0:
.cfi_startproc
movsd   .LC0(%rip), %xmm2
movapd  %xmm0, %xmm1
andpd   %xmm2, %xmm1
andnpd  %xmm0, %xmm2
addsd   .LC1(%rip), %xmm1
roundsd $1, %xmm1, %xmm1
orpd%xmm2, %xmm1
movapd  %xmm1, %xmm0
ret

The patch also simplifies a couple of checks in related patterns.

2011-08-14  Uros Bizjak  

* config/i386/i386.c (ix86_expand_round_sse4): New function.
* config/i386/i386-protos.h (ix86_expand_round_sse4): New prototype.
* config/i386/i386.md (round2): Use ix86_expand_round_sse4
for TARGET_ROUND.

(rint2): Simplify TARGET_ROUND check.
(floor2): Ditto.
(ceil2): Ditto.
(btrunc2): Ditto.

Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32},
will be committed to mainline soon.

Uros.
Index: i386.md
===
--- i386.md (revision 177746)
+++ i386.md (working copy)
@@ -14394,11 +14394,11 @@
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
   && !flag_trapping_math)
 {
-  if (!TARGET_ROUND && optimize_insn_for_size_p ())
-   FAIL;
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
+  else if (optimize_insn_for_size_p ())
+FAIL;
   else
ix86_expand_rint (operand0, operand1);
 }
@@ -14431,7 +14431,12 @@
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
   && !flag_trapping_math && !flag_rounding_math)
 {
-  if (TARGET_64BIT || (mode != DFmode))
+  if (TARGET_ROUND)
+{
+ operands[1] = force_reg (mode, operands[1]);
+ ix86_expand_round_sse4 (operands[0], operands[1]);
+   }
+  else if (TARGET_64BIT || (mode != DFmode))
ix86_expand_round (operands[0], operands[1]);
   else
ix86_expand_rounddf_32 (operands[0], operands[1]);
@@ -14663,14 +14668,13 @@
&& !flag_trapping_math)"
 {
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-  && !flag_trapping_math
-  && (TARGET_ROUND || optimize_insn_for_speed_p ()))
+  && !flag_trapping_math)
 {
-  if (!TARGET_ROUND && optimize_insn_for_size_p ())
-   FAIL;
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
   (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
+  else if (optimize_insn_for_size_p ())
+FAIL;
   else if (TARGET_64BIT || (mode != DFmode))
ix86_expand_floorceil (operand0, operand1, true);
   else
@@ -14922,8 +14926,7 @@
&& !flag_trapping_math)"
 {
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-  && !flag_trapping_math
-  && (TARGET_ROUND || optimize_insn_for_speed_p ()))
+  && !flag_trapping_math)
 {
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
@@ -15179,8 +15182,7 @@
&& !flag_trapping_math)"
 {
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-  && !flag_trapping_math
-  && (TARGET_ROUND || optimize_insn_for_speed_p ()))
+  && !flag_trapping_math)
 {
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
Index: i386-protos.h
===
--- i386-protos.h   (revision 177746)
+++ i386-protos.h   (working copy)
@@ -174,6 +174,7 @@
 extern void ix86_expand_rint (rtx, rtx);
 extern void ix86_expand_floorceil (rtx, rtx, bool);
 extern void ix86_expand_floorceildf_32 (rtx, rtx, bool);
+extern void ix86_expand_round_sse4 (rtx, rtx);
 extern void ix86_expand_round (rtx, rtx);
 extern void ix86_expand_rounddf_32 (rtx, rtx);
 extern void ix86_expand_trunc (rtx, rtx);
Index: i386.c
===
--- i386.c  (revision 177746)
+++ i386.c  (working copy)
@@ -32676,6 +32676,40 @@
 
   emit_move_insn (operand0, res);
 }
+
+/* Expand SSE sequence for computing round
+   from OP1 storing into OP0 using sse4 round insn.  */
+void
+ix86_expand_round_sse4 (rtx op0, rtx op1)
+{
+  enum machine_mode mode = GET_MODE (op0);
+  rtx e1, e2, e3, res, half, mask;
+
+  half = CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, mode);
+
+  /* round(a) = sgn(a) * floor(fabs(a) + 0.5) */
+
+  /* e1 = fabs(op1) */
+  e1 = ix86_expand_sse_fabs (op1, &mask);
+
+  /* e2 = e1 + 0.5 */
+  half = force_reg (mode, half);
+

Re: [PATCH, i386]: Expand round(a) = sgn(a) * floor(fabs(a) + 0.5) using SSE4 ROUND insn

2011-08-14 Thread Uros Bizjak
On Sun, Aug 14, 2011 at 7:24 PM, Uros Bizjak  wrote:

> We can use ROUNDSP/ROUNDSD in round(a) expansion. Currently, we expand
> round(a) as (-O2 -ffast-math):

I forgot to add that this expansion is expanded only under
flag_unsafe_math_optimizations due to addition of 0.5. For the input
of 0x1.fp-2, new insn sequence returns 1.0.

Uros.


[COMMITTED, Fortran] Spell referrenced correctly

2011-08-14 Thread Steve Kargl
2011-08-14  Steven G. Kargl  

* module.c (use_iso_fortran_env_module):  Spell 'referrenced' correctly.

Index: module.c
===
--- module.c(revision 177414)
+++ module.c(working copy)
@@ -5577,7 +5577,7 @@ use_iso_fortran_env_module (void)
  u->found = 1;
 
  if (gfc_notify_std (symbol[i].standard, "The symbol '%s', "
- "referrenced at %C, is not in the selected "
+ "referenced at %C, is not in the selected "
  "standard", symbol[i].name) == FAILURE)
continue;
 
-- 
Steve


[PATCH v2, i386]: Expand round(a) = sgn(a) * trunc(fabs(a) + 0.5++) using SSE4 ROUND insn

2011-08-14 Thread Uros Bizjak
On Sun, Aug 14, 2011 at 8:00 PM, Uros Bizjak  wrote:

>> We can use ROUNDSP/ROUNDSD in round(a) expansion. Currently, we expand
>> round(a) as (-O2 -ffast-math):
>
> I forgot to add that this expansion is expanded only under
> flag_unsafe_math_optimizations due to addition of 0.5. For the input
> of 0x1.fp-2, new insn sequence returns 1.0.

Actually, using an algorithm, proposed by Richi - sgn(a)*trunc(fabs(a)
+ 0.5++) - solves this failure.

New version of patch attached.

2011-08-14  Uros Bizjak  

* config/i386/i386.c (ix86_expand_round_sse4): New function.
* config/i386/i386-protos.h (ix86_expand_round_sse4): New prototype.
* config/i386/i386.md (round2): Use ix86_expand_round_sse4
for TARGET_ROUND.

(rint2): Simplify TARGET_ROUND check.
(floor2): Ditto.
(ceil2): Ditto.
(btrunc2): Ditto.

Bootstrapped on x86_64-pc-linux-gnu {,-m32}, regression test still in progress.

Uros.
Index: i386.md
===
--- i386.md (revision 177746)
+++ i386.md (working copy)
@@ -14394,11 +14394,11 @@
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
   && !flag_trapping_math)
 {
-  if (!TARGET_ROUND && optimize_insn_for_size_p ())
-   FAIL;
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
+  else if (optimize_insn_for_size_p ())
+FAIL;
   else
ix86_expand_rint (operand0, operand1);
 }
@@ -14431,7 +14431,12 @@
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
   && !flag_trapping_math && !flag_rounding_math)
 {
-  if (TARGET_64BIT || (mode != DFmode))
+  if (TARGET_ROUND)
+{
+ operands[1] = force_reg (mode, operands[1]);
+ ix86_expand_round_sse4 (operands[0], operands[1]);
+   }
+  else if (TARGET_64BIT || (mode != DFmode))
ix86_expand_round (operands[0], operands[1]);
   else
ix86_expand_rounddf_32 (operands[0], operands[1]);
@@ -14663,14 +14668,13 @@
&& !flag_trapping_math)"
 {
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-  && !flag_trapping_math
-  && (TARGET_ROUND || optimize_insn_for_speed_p ()))
+  && !flag_trapping_math)
 {
-  if (!TARGET_ROUND && optimize_insn_for_size_p ())
-   FAIL;
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
   (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
+  else if (optimize_insn_for_size_p ())
+FAIL;
   else if (TARGET_64BIT || (mode != DFmode))
ix86_expand_floorceil (operand0, operand1, true);
   else
@@ -14922,8 +14926,7 @@
&& !flag_trapping_math)"
 {
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-  && !flag_trapping_math
-  && (TARGET_ROUND || optimize_insn_for_speed_p ()))
+  && !flag_trapping_math)
 {
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
@@ -15179,8 +15182,7 @@
&& !flag_trapping_math)"
 {
   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-  && !flag_trapping_math
-  && (TARGET_ROUND || optimize_insn_for_speed_p ()))
+  && !flag_trapping_math)
 {
   if (TARGET_ROUND)
emit_insn (gen_sse4_1_round2
Index: i386-protos.h
===
--- i386-protos.h   (revision 177746)
+++ i386-protos.h   (working copy)
@@ -174,6 +174,7 @@ extern void ix86_expand_lfloorceil (rtx, rtx, bool
 extern void ix86_expand_rint (rtx, rtx);
 extern void ix86_expand_floorceil (rtx, rtx, bool);
 extern void ix86_expand_floorceildf_32 (rtx, rtx, bool);
+extern void ix86_expand_round_sse4 (rtx, rtx);
 extern void ix86_expand_round (rtx, rtx);
 extern void ix86_expand_rounddf_32 (rtx, rtx);
 extern void ix86_expand_trunc (rtx, rtx);
Index: i386.c
===
--- i386.c  (revision 177746)
+++ i386.c  (working copy)
@@ -32676,6 +32676,52 @@ ix86_expand_round (rtx operand0, rtx operand1)
 
   emit_move_insn (operand0, res);
 }
+
+/* Expand SSE sequence for computing round
+   from OP1 storing into OP0 using sse4 round insn.  */
+void
+ix86_expand_round_sse4 (rtx op0, rtx op1)
+{
+  enum machine_mode mode = GET_MODE (op0);
+  rtx e1, e2, e3, res, half, mask;
+  const struct real_format *fmt;
+  REAL_VALUE_TYPE pred_half, half_minus_pred_half;
+  rtx (*gen_round) (rtx, rtx, rtx);
+
+  switch (mode)
+{
+case SFmode:
+  gen_round = gen_sse4_1_roundsf2;
+  break;
+case DFmode:
+  gen_round = gen_sse4_1_rounddf2;
+  break;
+default:
+  gcc_unreachable ();
+}
+
+  /* e1 = fabs(op1) */
+  e1 = ix86_expand_sse_fabs (op1, &mask);
+
+  /* load nextafter (0.5, 0.0) */
+  fmt = REAL_MODE_FORMAT (mode);
+  real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
+  REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf, half_minus_pred_half);
+
+  /* e2 = e1

Re: [M32C] Hookize PREFERRED_RELOAD_CLASS and PREFERRED_OUTPUT_RELOAD_CLASS

2011-08-14 Thread DJ Delorie

Ok.


Re: [patch, fortran] PR 46659 - extend conversion warnings to assignments

2011-08-14 Thread Tobias Burnus

Thomas Koenig wrote:

the attached patch extends conversion warnings to assignments.
OK for trunk?


I get now two warnings for:

complex(8), parameter :: z = cmplx (0.5, 0.5)
r = z
end


Untested: Instead of checking

  if (rvalue->expr_type == EXPR_CONSTANT
&& (lvalue->ts.type == BT_REAL || lvalue->ts.type == BT_COMPLEX)
&& (rvalue->ts.type == BT_REAL || rvalue->ts.type == BT_COMPLEX))

one might check for:

  if (rvalue->expr_type == EXPR_CONSTANT
&& (lvalue->ts.type == BT_REAL || lvalue->ts.type == BT_COMPLEX)
&& (rvalue->ts.type ==rvalue->ts.type)

Tobias


Fix spurious match testsuite regressions from "[PATCH, middle end]: Introduce BUILT_IN_I{CEIL_FLOOR_ROUND_RINT} FP-to-int conversion functions"

2011-08-14 Thread Hans-Peter Nilsson
This patch:

> 2011-08-11  Uros Bizjak  
> 
>   * builtins.def (BUILT_IN_ICEIL{,F,L}, BUILT_IN_IFLOOR{,F,L},
>   BUILT_IN_IRINT{,F,L}, BUILT_IN_IROUND{,F,L}: New builtin definitions.
>   * convert.c (convert_to_integer): Convert to BUILT_IN_ICEIL,
>   BUILT_IN_IFLOOR, BUILT_IN_IRINT or BUILT_INT_IROUND when converting
>   to integer_type_node.
>   * fold-const.c (tree_call_nonnegative_warnv_p): Handle BUILT_IN_ICEIL,
>   BUILT_IN_IFLOOR, BUILT_IN_IRINT and BUILT_INT_IROUND.
>   * builtins.c (expand_builtin_in): Ditto.
>   (mathfn_built_in_1): Ditto.
>   (expand_builtin_int_roundingfn): Handle BUILT_IN_ICEIL and
>   BUILT_IN_IFLOOR.
>   (expand_builtin_int_roundingfn_2): Handle BUILT_IN_IRINT and
>   BUILT_IN_IROUND.
>   (fold_fixed_mathfn): Canonicalize BUILT_IN_ICEIL, BUILTIN_IN_IFLOOR,
>   BUILT_IN_IRINT and BUILT_IN_IROUND to BUILT_IN_LCEIL,
>   BUILTIN_IN_LFLOOR, BUILT_IN_LRINT and BUILT_IN_LROUND on ILP32 targets.

"caused" this regression for cris-elf:

Running /tmp/hpautotest-gcc1/gcc/gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp ...
...
FAIL: gcc.dg/tree-ssa/vrp61.c scan-tree-dump-not vrp1 "1234"

Looking at vrp61.c only yields a big WTF, but when looking at
the vrp61.c.067t.vrp1 dump file all is explained, because there,
at the top is:

;; Function f (f, funcdef_no=0, decl_uid=1234, cgraph_uid=0)

Hilarious.  Probably not the instance intended to not-look for.
Anyway, I decided not to try and do anything else but a
brain-dead tweak, hoping that someone used to writing such
test-cases would jump in with a better solution (like, not
dumping the decl_uid unless the dump verbosity-level is
higher)... doh!  Anyhow, the following should fit nicely with
16-bitters and allow for another ten-fold of built-in functions...

So, ok as is?
If not, would you preapprove tree-dumping decl_uids only at a
higher dump verbosity level?

gcc/testsuite:
* gcc.dg/tree-ssa/vrp61.c: Increase magic number from 1234 to
12345.

Index: gcc.dg/tree-ssa/vrp61.c
===
--- gcc.dg/tree-ssa/vrp61.c (revision 177757)
+++ gcc.dg/tree-ssa/vrp61.c (working copy)
@@ -7,10 +7,10 @@ int f (int x, int y)
 {
   x = x ^ y;
   if (x < 0 || x > 1023)
-   return 1234;
+   return 12345;
 }
   return x;
 }
 
-/* { dg-final { scan-tree-dump-not "1234" "vrp1" } } */
+/* { dg-final { scan-tree-dump-not "12345" "vrp1" } } */
 /* { dg-final { cleanup-tree-dump "vrp1" } } */

brgds, H-P


[PATCH, SMS] Support instructions with REG_INC_NOTE (re-submisson)

2011-08-14 Thread Revital Eres
Hello,

This is a re-submission of the patch to support instructions with REG_INC_NOTE.
(http://gcc.gnu.org/ml/gcc-patches/2011-04/msg01309.html)

It contains a minor change from the previous submission suggested by
Richard Sandiford: to use reg_referenced_p instead of
rtx_referenced_p.

The patch supports instructions with auto inc/dec operations as to
support such instructions we can not assume that there is only one
definition in the instruction. This assumption is currently used to
generate reg-moves information. Because the auto inc/dec instruction
defines more then one register we need to generate different reg-moves
for each of the definitions. At some point in the SMS procedure we
need to find
the first reg-move generated for a specific definition(*) and if there
is more than one definition in the instruction (lets call it insn1)
we can not simply assume it's first reg-move instruction is the first
instruction right before insn1.

for example, the following instruction defines two variables: x and i:
x = mem [POST_INC (i)]

lets say both of them need reg-move

insn 1) reg_move_i = i
insn 2) reg_move_x = x
insn 3) x = mem [POST_INC (i)]

then in order to reach the first reg-move of i we can not just go to
insn 2 like in the current implementation, so we need to save for each
definition in the instruction it's first reg-move instruction.

(*) I'm referring to the generation of prologue and epilogue
(duplicate_insns_of_cycles) which uses first_reg_move field in
node_sched_params structure, and SCHED_FIRST_REG_MOVE definition in
modulo-sched.c.

Reg-tested and bootstrap on ppc64-redhat-linux enabling SMS on loops with SC 1.

OK for mainline?

Thanks,
Revital


* modulo-sched.c (record_inc_dec_insn_info,
free_node_sched_params): New functions.
(SCHED_FIRST_REG_MOVE, SCHED_NREG_MOVES): Remove.
(struct regmove_info): New.
(insn_regmove_info): New field in node_sched_params.
(print_node_sched_params): Print information for all the
definitions in the instructions.
(generate_reg_moves, duplicate_insns_of_cycles,
set_node_sched_params): Adjust the code to handle instructions
that have multiple definitions.
(sms_schedule): Handle loops that contain instructions with
FIND_REG_INC_NOTE and call free_node_sched_params.
Index: modulo-sched.c
===
--- modulo-sched.c  (revision 177648)
+++ modulo-sched.c  (working copy)
@@ -213,32 +213,50 @@ static bool try_scheduling_node_in_cycle
  sbitmap);
 static bool remove_node_from_ps (partial_schedule_ptr, ps_insn_ptr);
 
+static int record_inc_dec_insn_info (rtx, rtx, rtx, rtx, rtx, void *);
+
+
 #define SCHED_ASAP(x) (((node_sched_params_ptr)(x)->aux.info)->asap)
 #define SCHED_TIME(x) (((node_sched_params_ptr)(x)->aux.info)->time)
-#define SCHED_FIRST_REG_MOVE(x) \
-   (((node_sched_params_ptr)(x)->aux.info)->first_reg_move)
-#define SCHED_NREG_MOVES(x) \
-   (((node_sched_params_ptr)(x)->aux.info)->nreg_moves)
 #define SCHED_ROW(x) (((node_sched_params_ptr)(x)->aux.info)->row)
 #define SCHED_STAGE(x) (((node_sched_params_ptr)(x)->aux.info)->stage)
 #define SCHED_COLUMN(x) (((node_sched_params_ptr)(x)->aux.info)->column)
 
-/* The scheduling parameters held for each node.  */
-typedef struct node_sched_params
+/* Information about register-move generated for a definition.  */
+struct regmove_info
 {
-  int asap;/* A lower-bound on the absolute scheduling cycle.  */
-  int time;/* The absolute scheduling cycle (time >= asap).  */
-
+  /* The definition for which the register-move is generated for.  */
+  rtx def;
+  
   /* The following field (first_reg_move) is a pointer to the first
- register-move instruction added to handle the modulo-variable-expansion
- of the register defined by this node.  This register-move copies the
- original register defined by the node.  */
+ register-move instruction added to handle the
+ modulo-variable-expansion of the register defined by this node.
+ This register-move copies the original register defined by the node.
+  */
   rtx first_reg_move;
-
+  
   /* The number of register-move instructions added, immediately preceding
  first_reg_move.  */
   int nreg_moves;
+  
+  /* Auxiliary info used in the calculation of the register-moves.  */
+  void *aux;
+};
+
+typedef struct regmove_info *regmove_info_ptr;
+DEF_VEC_P (regmove_info_ptr);
+DEF_VEC_ALLOC_P (regmove_info_ptr, heap);
 
+/* The scheduling parameters held for each node.  */
+typedef struct node_sched_params
+{
+  int asap;/* A lower-bound on the absolute scheduling cycle.  */
+  int time;/* The absolute scheduling cycle (time >= asap).  */
+  
+  /* Information about register-moves needed for
+ definitions in the instruction.  */
+  VEC (regmove_info_ptr, heap) *insn_regmove_info;
+  
   int row;/* Holds time % ii