Re: Use conditional casting with symtab_node

2012-10-05 Thread Nathan Froyd
- Original Message -
> I see all these patches with mixed feeling - it puts breaks on all
> developers
> because they need to learn the new interface which does not bring any
> immediate benefit.  So I think _your_ development time would be
> better
> spent by fixing open bugs or by tackling some of the existing
> scalability
> issues in GCC (rather than quoting funny '0.001% faster with 99%
> confidence'
> stuff).

This tone is unnecessary.

I, for one, think that it's excellent that Lawrence is writing these
cleanup patches and measuring what impact they have on performance.
Bonus points that they are making the compiler faster.  Speed of the 
compiler *is* a scalability issue, and it's one that GCC doesn't
appear to have paid all that much attention to over the years.

-Nathan


Re: patch to fix constant math

2012-10-08 Thread Nathan Froyd
- Original Message -
> Btw, as for Richards idea of conditionally placing the length field
> in
> rtx_def looks like overkill to me.  These days we'd merely want to
> optimize for 64bit hosts, thus unconditionally adding a 32 bit
> field to rtx_def looks ok to me (you can wrap that inside a union to
> allow both descriptive names and eventual different use - see what
> I've done to tree_base)

IMHO, unconditionally adding that field isn't "optimize for 64-bit
hosts", but "gratuitously make one of the major compiler data
structures bigger on 32-bit hosts".  Not everybody can cross-compile
from a 64-bit host.  And even those people who can don't necessarily
want to.  Please try to consider what's best for all the people who
use GCC, not just the cases you happen to be working with every day.

-Nathan


[PATCH] reduce size penalty for including C++11 on x86 systems

2015-10-13 Thread Nathan Froyd
From: Nathan Froyd 

Including  in C++11 mode (typically done for
std::{min,max,swap}) includes , for
std::uniform_int_distribution.  On x86 platforms,  manages to
drag in  through x86's opt_random.h header, and
 has gotten rather large recently with the addition of AVX
intrinsics.  The comparison between C++03 mode and C++11 mode is not
quite exact, but it gives an idea of the penalty we're talking about
here:

froydnj@thor:~/src$ echo '#include ' | g++ -x c++ - -o - -E 
-std=c++11 | wc
  53460  127553 1401268
froydnj@thor:~/src$ echo '#include ' | g++ -x c++ - -o - -E 
-std=c++03 | wc
   9202   18933  218189

That's approximately a 7x penalty in C++11 mode (granted, C++11 includes
more than just ) with GCC 4.9.2 on a Debian system; current
mainline is somewhat worse:

froydnj@thor: gcc-build$ echo '#include ' | xgcc [...] -std=c++11 | 
wc
  84851  210475 2369616
froydnj@thor: gcc-build$ echo '#include ' | xgcc [...] -std=c++03 | 
wc
   9383   19402  239676

 itself clocks in at 1.3MB+ of preprocessed text.

This patch aims to reduce that size penalty by recognizing that both of
the places that #include  do not need the full set of x86
intrinsics, but can get by with a smaller, more focused header in each
case.   needs only  to declare __m128i, while
x86's opt_random.h must include  for declarations of
various intrinsic functions.

The net result is that the size of mainline's  is significantly 
reduced:

froydnj@thor: gcc-build$ echo '#include ' | xgcc [...] -std=c++11 | 
wc
  39174   88538 1015281

which seems like a win.

Bootstrapped on x86_64-pc-linux-gnu with --enable-languages=c,c++,
tested with check-target-libstdc++-v3, no regressions.  Also verified
that  and  pass -fsyntax-check with
-march=native (on a recent Haswell chip); if an -march=native bootstrap
is necessary, I am happy to do that if somebody instructs me in getting
everything properly set up.

OK?

-Nathan

* config/cpu/i486/opt/bits/opt_random.h: Include pmmintrin.h instead
of x86intrin.h, and only do so when __SSE3__
* include/ext/random: Include emmintrin.h instead of x86intrin.h
---
 libstdc++-v3/ChangeLog | 6 ++
 libstdc++-v3/config/cpu/i486/opt/bits/opt_random.h | 4 +++-
 libstdc++-v3/include/ext/random| 2 +-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index e3061ef..ff0b048 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2015-10-13  Nathan Froyd  
+
+   * config/cpu/i486/opt/bits/opt_random.h: Include pmmintrin.h instead
+   of x86intrin.h, and only do so when __SSE3__
+   * include/ext/random: Include emmintrin.h instead of x86intrin.h
+
 2015-10-11  Joseph Myers  
 
* crossconfig.m4 (GLIBCXX_CROSSCONFIG) <*-linux* | *-uclinux* |
diff --git a/libstdc++-v3/config/cpu/i486/opt/bits/opt_random.h 
b/libstdc++-v3/config/cpu/i486/opt/bits/opt_random.h
index 4495569..a9f6c13 100644
--- a/libstdc++-v3/config/cpu/i486/opt/bits/opt_random.h
+++ b/libstdc++-v3/config/cpu/i486/opt/bits/opt_random.h
@@ -30,7 +30,9 @@
 #ifndef _BITS_OPT_RANDOM_H
 #define _BITS_OPT_RANDOM_H 1
 
-#include 
+#ifdef __SSE3__
+#include 
+#endif
 
 
 #pragma GCC system_header
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index 0bcfa4a..ba363ce 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -40,7 +40,7 @@
 #include 
 #include 
 #ifdef __SSE2__
-# include 
+# include 
 #endif
 
 #if defined(_GLIBCXX_USE_C99_STDINT_TR1) && defined(UINT32_C)
-- 
2.1.4



[PATCH][PR c++/82888] smarter code for default initialization of scalar arrays

2017-11-16 Thread Nathan Froyd
Default-initialization of scalar arrays in C++ member initialization
lists produced rather slow code, laboriously setting each element of the
array to zero.  It would be much faster to block-initialize the array,
and that's what this patch does.

The patch works for me, but I'm not sure if it's the best way to
accomplish this.  At least two other possibilities come to mind:

1) Detect this case in build_vec_init_expr and act as though the user
   wrote 'member{0}', which the front-end already produces efficient
   code for.

2) Detect this case in build_vec_init, but again, act as though the user
   wrote 'member{0}' and let everything proceed as normal.
   (Alternatively, handle this case prior to calling build_vec_init and
   pass different arguments to build_vec_init.)

Opinions as to the best way forward here?  I'm unsure of whether the
code below is front-end friendly; I see in the gimple dumps that the
solution below adds an extra CLOBBER on 'this' for 'member()', whereas
'member{0}' does not.  It's possible that I'm missing something.

Bootstrapped on x86_64-unknown-linux-gnu, no regressions.

OK for trunk?

-Nathan

gcc/cp/
PR c++/82888
* init.c (build_vec_init): Handle default-initialization of array
types.

gcc/testsuite/
PR c++/82888
* g++.dg/init/pr82888.C: New.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index c76460d..53d6133 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -4038,6 +4038,15 @@ build_vec_init (tree base, tree maxindex, tree init,
}
 }
 
+  /* Default-initialize scalar arrays directly.  */
+  if (TREE_CODE (atype) == ARRAY_TYPE
+  && SCALAR_TYPE_P (TREE_TYPE (atype))
+  && !init)
+{
+  gcc_assert (!from_array);
+  return build2 (MODIFY_EXPR, atype, base, build_constructor (atype, 
NULL));
+}
+
   /* If we have a braced-init-list or string constant, make sure that the array
  is big enough for all the initializers.  */
   bool length_check = (init
diff --git a/gcc/testsuite/g++.dg/init/pr82888.C 
b/gcc/testsuite/g++.dg/init/pr82888.C
new file mode 100644
index 000..9225e23
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/pr82888.C
@@ -0,0 +1,18 @@
+// { dg-do compile }
+// { dg-options "-fdump-tree-gimple" }
+
+class A
+{
+public:
+  A();
+
+private:
+  unsigned char mStorage[4096];
+};
+
+A::A()
+  : mStorage()
+{}
+
+// { dg-final { scan-tree-dump "this->mStorage = {}" "gimple" } }
+// { dg-final { scan-tree-dump-not "&this->mStorage" "gimple" } }


Re: [PATCH][PR c++/82888] smarter code for default initialization of scalar arrays

2017-11-17 Thread Nathan Froyd
On Fri, Nov 17, 2017 at 8:50 AM, Jason Merrill  wrote:
> On Thu, Nov 16, 2017 at 11:21 AM, Nathan Froyd  wrote:
>> diff --git a/gcc/cp/init.c b/gcc/cp/init.c
>> index c76460d..53d6133 100644
>> --- a/gcc/cp/init.c
>> +++ b/gcc/cp/init.c
>> @@ -4038,6 +4038,15 @@ build_vec_init (tree base, tree maxindex, tree init,
>> }
>>  }
>>
>> +  /* Default-initialize scalar arrays directly.  */
>> +  if (TREE_CODE (atype) == ARRAY_TYPE
>> +  && SCALAR_TYPE_P (TREE_TYPE (atype))
>> +  && !init)
>
> This should check explicit_value_init._p rather than !init.  And also
> check zero_init_p.

Do you mean explicit_value_init_p && zero_init_p (atype)?  zero_init_p
doesn't sound like the correct thing to use here, because it doesn't
take into account whether a class array type has a constructor.  I am
probably misunderstanding the purpose of the zero_init_p check,
though.

-Nathan


Re: More informative ODR warnings

2014-07-02 Thread Nathan Froyd
- Original Message -
> /aux/hubicka/firefox/netwerk/sctp/datachannel/DataChannel.h:64:0: warning:
> field ‘mSpa’ (of type ‘struct BufferedMsg’) violates one definition rule
> [-Wodr]

Can we reword this warning?  The "of type 'struct BufferedMsg'" could be easily 
taken to mean that the type of the field is 'struct BufferedMsg', rather than 
the intended meaning.  Perhaps "within type 'struct BufferedMsg'"?

-Nathan


[PATCH] fix generic std::atomic::compare_exchange_{weak,strong}

2013-07-26 Thread Nathan Froyd
Compiling the test program:

#include 

enum x { a, b };

std::atomic v;

bool test_strong()
{
  x expected = a;
  return v.compare_exchange_strong(expected, b, std::memory_order_acq_rel);
}

bool test_weak()
{
  x expected = a;
  return v.compare_exchange_weak(expected, b, std::memory_order_acq_rel);
}

results in mysterious errors:

In file included from /home/froydnj/mini-atomic-bug.cpp:1:0:
/usr/include/c++/4.7/atomic: In function ‘bool test_strong()’:
/usr/include/c++/4.7/atomic:259:69: error: invalid failure memory model for 
‘__atomic_compare_exchange’
/usr/include/c++/4.7/atomic: In function ‘bool test_weak()’:
/usr/include/c++/4.7/atomic:235:68: error: invalid failure memory model for 
‘__atomic_compare_exchange’

as the generic std::atomic versions of compare_exchange_strong and
compare_exchange_weak do not call __cmpexch_failure_order.

This patch corrects that oversight.  Tested on x86_64-unknown-linux-gnu.

OK to commit to trunk and active branches?

-Nathan

* include/std/atomic (compare_exchange_weak, compare_exchange_strong):
Add call to __cmpexch_failure_order.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ac2cb45..a822d0f 100644
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 813f574..2d66729 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -252,12 +252,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   bool
   compare_exchange_weak(_Tp& __e, _Tp __i,
memory_order __m = memory_order_seq_cst) noexcept
-  { return compare_exchange_weak(__e, __i, __m, __m); }
+  { return compare_exchange_weak(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
 
   bool
   compare_exchange_weak(_Tp& __e, _Tp __i,
 memory_order __m = memory_order_seq_cst) volatile noexcept
-  { return compare_exchange_weak(__e, __i, __m, __m); }
+  { return compare_exchange_weak(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
 
   bool
   compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
@@ -276,12 +278,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   bool
   compare_exchange_strong(_Tp& __e, _Tp __i,
   memory_order __m = memory_order_seq_cst) noexcept
-  { return compare_exchange_strong(__e, __i, __m, __m); }
+  { return compare_exchange_strong(__e, __i, __m,
+   __cmpexch_failure_order(__m)); }
 
   bool
   compare_exchange_strong(_Tp& __e, _Tp __i,
 memory_order __m = memory_order_seq_cst) volatile noexcept
-  { return compare_exchange_strong(__e, __i, __m, __m); }
+  { return compare_exchange_strong(__e, __i, __m,
+   __cmpexch_failure_order(__m)); }
 };
 
 



Re: [PATCH] fix generic std::atomic::compare_exchange_{weak,strong}

2013-07-26 Thread Nathan Froyd
Sure, I can do that.  For maximum effectiveness, it'd be good to have it check 
the specializations for atomic<>, too.  Is there something in the libstdc++ 
testsuite for iterating template instantiations over a list of types, or do I 
have to roll the list myself?

Thanks,
-Nathan

- Original Message -
> 
> 
> Hi,
> 
> Nathan Froyd  ha scritto:
> >Compiling the test program:
> >
> >#include 
> >
> >enum x { a, b };
> >
> >std::atomic v;
> >
> >bool test_strong()
> >{
> >  x expected = a;
> >return v.compare_exchange_strong(expected, b,
> >std::memory_order_acq_rel);
> >}
> >
> >bool test_weak()
> >{
> >  x expected = a;
> >return v.compare_exchange_weak(expected, b, std::memory_order_acq_rel);
> >}
> 
> In any case, why not adding the testcase?
> 
> Paolo
> 


Re: [PATCH] fix generic std::atomic::compare_exchange_{weak,strong}

2013-07-26 Thread Nathan Froyd
- Original Message -
> On 07/26/2013 08:42 PM, Nathan Froyd wrote:
> > Sure, I can do that.  For maximum effectiveness, it'd be good to have it
> > check the specializations for atomic<>, too.  Is there something in the
> > libstdc++ testsuite for iterating template instantiations over a list of
> > types, or do I have to roll the list myself?
> testsuite/29_atomics already uses testsuite_common_types.h

New patch, this time with tests.  Let me know if test placement, etc. need
adjusting.

Tested on x86_64-unknown-linux-gnu.  OK for commit to trunk and active branches?

-Nathan

* include/std/atomic (compare_exchange_weak, compare_exchange_strong):
Add call to __cmpexch_failure_order.
* testsuite/util/testsuite_common_types.h
(compare_exchange_order_lowering): New generator.
* testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc:
New test.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ac2cb45..3b79d91 100644
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 813f574..2d66729 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -252,12 +252,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   bool
   compare_exchange_weak(_Tp& __e, _Tp __i,
memory_order __m = memory_order_seq_cst) noexcept
-  { return compare_exchange_weak(__e, __i, __m, __m); }
+  { return compare_exchange_weak(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
 
   bool
   compare_exchange_weak(_Tp& __e, _Tp __i,
 memory_order __m = memory_order_seq_cst) volatile noexcept
-  { return compare_exchange_weak(__e, __i, __m, __m); }
+  { return compare_exchange_weak(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
 
   bool
   compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
@@ -276,12 +278,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   bool
   compare_exchange_strong(_Tp& __e, _Tp __i,
   memory_order __m = memory_order_seq_cst) noexcept
-  { return compare_exchange_strong(__e, __i, __m, __m); }
+  { return compare_exchange_strong(__e, __i, __m,
+   __cmpexch_failure_order(__m)); }
 
   bool
   compare_exchange_strong(_Tp& __e, _Tp __i,
 memory_order __m = memory_order_seq_cst) volatile noexcept
-  { return compare_exchange_strong(__e, __i, __m, __m); }
+  { return compare_exchange_strong(__e, __i, __m,
+   __cmpexch_failure_order(__m)); }
 };
 
 
diff --git 
a/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc
 
b/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc
new file mode 100644
index 000..75e7406
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2008-2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include 
+#include 
+
+#define TEST_ALL_ORDERS()   \
+  do {  \
+ORDER_TEST(std::memory_order_relaxed);  \
+ORDER_TEST(std::memory_order_consume);  \
+ORDER_TEST(std::memory_order_acquire);  \
+ORDER_TEST(std::memory_order_release);  \
+ORDER_TEST(std::memory_order_acq_rel);  \
+ORDER_TEST(std::memory_order_seq_cst);  \
+  } while(0)
+  
+void test01()
+{
+#define ORDER_TEST(ORDER)   \
+  do {  \
+__gnu_test::compare_exchange_order_lowering test;\
+__gnu_cxx::typelist::apply_generator(test,  \
+ __gnu_test::integral_types::type()); \
+  } while (0);
+  TEST_ALL_ORDERS();
+#undef ORDER_TEST
+
+  enum e { a, b, c };
+#define ORDER_TEST(ORDER)   \
+ 

Re: [Patch ARM] Fix PR target/50106

2011-10-19 Thread Nathan Froyd

On 10/19/2011 3:27 PM, Ramana Radhakrishnan wrote:

Index: gcc/config/arm/arm.c
-  live_regs_mask |= extra_mask<<  (size / UNITS_PER_WORD);
+  live_regs_mask |= extra_mask<<  ((size + 3) / UNITS_PER_WORD);


IIUC, wouldn't ((size + UNITS_PER_WORD - 1) / UNITS_PER_WORD) be clearer?

-Nathan


Re: Beyond Complex Register Management

2012-08-08 Thread Nathan Froyd
On Wed, Aug 08, 2012 at 10:52:28AM -0700, Mike Stump wrote:
> As we move to C++, I'd love for port maintainers to be able to get together 
> and hoist _up_ code from the port so other ports can use it and thus, have 
> more sharing.  We make heavily stylized uses, which could be wrapped into a 
> prettier api, given a reasonably powerful language.  C++ might be powerful 
> enough.  I'd love to see someone improve the FIXED_REGISTERS, REGISTER_NAMES, 
> REG_CLASS_CONTENTS, REGNO_REG_CLASS, REGNO_GLOBAL_BASE_REG_P, CLASS_MAX_NREGS 
> experience, as the current api sucks; for example.  I dread the slightest 
> change to any of my registers, as the change ripples throughout a ton of 
> disparate places, and it is currently too easy to forget one of them.  Bonus 
> points for cleaning up TARGET_SECONDARY_RELOAD at the same time as the above. 
>  I find that api sucks in ways I can't begin to describe.

Would a registers.md for defining registers and register classes
(and maybe things like FIXED_REGISTERS and the like) be a good
start for you, or do you want something more developed first?

-Nathan


[PATCH] convert m32c to constraints.md

2012-08-17 Thread Nathan Froyd
As $SUBJECT suggests.

I haven't tested this.  It's possible my dejagnu installation is too old
and/or I have forgotten many subtleties for testing embedded targets,
but I could not make m32c-sim work and I didn't want to spend an
enormous amount of time making it work.

Nonetheless, I have compared assembly for libgcc and newlib on unpatched
and patched compilers and they are identical, so that is encouraging.

I suppose transferring the documentation from doc/md.texi to
constraints.md would be good.  I'd beg leaving that for a followup,
please.

m32c is the last machine (pending committal of the mmix constraints.md
patch) to be converted to constraints.md.  I suppose there is some
cleanup to come surrounding the constraints support; if anybody has bold
plans for what needs work, I'd be happy to hear them out.

OK to commit?

-Nathan

* config/m32c/constraints.md: New file.
* config/m32c/t-m32c (MD_FILES): Add constraints.
* config/m32c/m32c-protos.h (m32c_const_ok_for_constraint_p): Delete.
(m32c_extra_address_constraint, m32c_extra_memory_constraint): Delete.
(m32c_reg_class_from_constraint): Delete.
(m32c_extra_constraint_p, m32c_extra_constraint_p2): Delete.
(m32c_matches_constraint_p): Declare.
* config/m32c/m32c.h (CONSTRAINT_LEN): Delete.
(REG_CLASS_FROM_CONSTRAINT): Delete.
(CONST_OK_FOR_CONSTRAINT_P): Delete.
(CONST_DOUBLE_OK_FOR_CONSTRAINT_P): Delete.
(EXTRA_CONSTRAINT_STR): Delete.
(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Delete.
* config/m32c/m32c.c: Include tm-constrs.h
(m32c_reg_class_from_constraint): Delete.
(m32c_const_ok_for_constraint_p): Delete.
(m32c_extra_constraint_p2): Rename to...
(m32c_matches_constraint_p): ...this.  Make it return bool.  Tweak
formatting.
(m32c_extra_constraint_p): Delete.
(m32c_extra_address_constraint, m32c_extra_memory_constraint): Delete.
(m32c_split_move): Use satisfies_constraint_Ss.
* config/m32c/predicates.md (memsym_operand): Use 
satisfies_constraint_Si.
(memimmed_operand): Use satisfies_constraint_Sp.
(m32c_psi_scale, m32c_1bit8_operand): Use satisfies_constraint_Ilb.
(m32c_1bit16_operand): Use satisfies_constraint_Ilw.
(m32c_1mask8_operand): Use satisfies_constraint_ImB.
(m32c_1mask16_operand): Use satisfies_constraint_Imw.

---
 gcc/config/m32c/constraints.md |  225 
 gcc/config/m32c/m32c-protos.h  |7 +-
 gcc/config/m32c/m32c.c |  322 +++-
 gcc/config/m32c/m32c.h |   19 ---
 gcc/config/m32c/predicates.md  |   14 +-
 gcc/config/m32c/t-m32c |2 +-
 6 files changed, 286 insertions(+), 303 deletions(-)
 create mode 100644 gcc/config/m32c/constraints.md

diff --git a/gcc/config/m32c/constraints.md b/gcc/config/m32c/constraints.md
new file mode 100644
index 000..da7dda4
--- /dev/null
+++ b/gcc/config/m32c/constraints.md
@@ -0,0 +1,225 @@
+;; m32c constraints
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; .
+
+(define_register_constraint "Rsp" "SP_REGS"
+  "@internal")
+
+(define_register_constraint "Rfb" "FB_REGS"
+  "@internal")
+
+(define_register_constraint "Rsb" "SB_REGS"
+  "@internal")
+
+(define_register_constraint "Rcr" "TARGET_A16 ? CR_REGS : NO_REGS"
+  "@internal")
+
+(define_register_constraint "Rcl" "TARGET_A24 ? CR_REGS : NO_REGS"
+  "@internal")
+
+(define_register_constraint "R0w" "R0_REGS"
+  "@internal")
+
+(define_register_constraint "R1w" "R1_REGS"
+  "@internal")
+
+(define_register_constraint "R2w" "R2_REGS"
+  "@internal")
+
+(define_register_constraint "R3w" "R3_REGS"
+  "@internal")
+
+(define_register_constraint "R02" "R02_REGS"
+  "@internal")
+
+(define_register_constraint "R13" "R13_REGS"
+  "@internal")
+
+(define_register_constraint "R03" "R03_REGS"
+  "@internal")
+
+(define_register_constraint "Rdi" "DI_REGS"
+  "@internal")
+
+(define_register_constraint "Rhl" "HL_REGS"
+  "@internal")
+
+(define_register_constraint "R23" "R23_REGS"
+  "@internal")
+
+(define_register_constraint "Ra0" "A0_REGS"
+  "@internal")
+
+(define_register_constraint "Ra1" "A1_REGS"
+  "@internal")
+
+(define_register_constraint "Raa" "A_R

Re: [PATCH,mmix] convert to constraints.md

2012-09-12 Thread Nathan Froyd
- Original Message -
> Nathan, again thanks.  There are a few minor tweaks compared to your
> version:

Thanks for fixing this up!

> - Keeping old layout of "mmix_reg_or_8bit_operand".  That looked like
>   a spurious change and I prefer the ior construct to the
>   if_then_else.

ISTR without this change, there were lots of assembly changes like:

set rx, 6
cmp rz, ry, rx

instead of the previous and better:

cmp rz, ry, 6

(apologies if the assembly syntax isn't correct; hopefully the intent is clear)

but if you double-checked that the assembly didn't change after your changes, 
maybe something else that you tweaked fixed this.

> - Replacing undefined-constraint-"H" with "I" instead of removing it.
>   It was either renamed early or a genuine typo.  Good catch.

Hard not to see it; the gen* machinery complains about undefined constraints. :)

-Nathan


Re: __int256

2012-07-13 Thread Nathan Froyd
On Fri, Jul 13, 2012 at 10:36:35AM -0700, Mike Stump wrote:
> I just checked all in tree gcc targets, and none claim OImode support.

./s390/s390-modes.def:23:INT_MODE (OI, 32);
./spu/spu-modes.def:29:INT_MODE (OI, 32);
./ia64/ia64-modes.def:68:INT_MODE (OI, 32);
./i386/i386-modes.def:88:INT_MODE (OI, 32);
./arm/arm-modes.def:82:INT_MODE (OI, 32);

At least for ARM, OImode gets used for Neon intrinsics.  Can't speak for
the other ports, though.

-Nathan


[PATCH] convert target_expmed macro accessors into inline functions

2012-07-27 Thread Nathan Froyd
As suggested by rth here:

http://gcc.gnu.org/ml/gcc-patches/2012-07/msg01281.html

this patch converts all the #define accessors in expmed.h to use inline
functions instead.

By itself, doing that conversion is not very exciting.  Followup patches
might:

* Move setters into expmed.c;
* Reduce space of fields by not using NUM_MACHINE_MODES, similar to the
  convert_cost case;
* Possibly moving the getters into expmed.c, assuming that LTO will take
  care of the performance hit.  Doing so enables target_expmed to not be
  exposed everywhere.
* Lazily initialize the costs.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

* expmed.h (alg_hash, alg_hash_used_p, sdiv_pow2_cheap,
smod_pow2_cheap, zero_cost, add_cost, neg_cost, shift_cost)
shiftadd_cost, shiftsub0_cost, shiftsub1_cost, mul_cost,
sdiv_cost, udiv_cost, mul_widen_cost, mul_highpart_cost): Delete
macro definitions and re-purpose as inline functions.
(alg_hash_entry_ptr, set_alg_hash_used_p, sdiv_pow2_cheap_ptr,
set_sdiv_pow2_cheap, smod_pow2_cheap_ptr, set_smod_pow2_cheap,
zero_cost_ptr, set_zero_cost, add_cost_ptr, set_add_cost,
neg_cost_ptr, set_neg_cost, shift_cost_ptr, set_shift_cost,
shiftadd_cost_ptr, set_shiftadd_cost, shiftsub0_cost_ptr,
set_shiftsub0_cost, shiftsub1_cost_ptr, set_shiftsub1_cost,
mul_cost_ptr, set_mul_cost, sdiv_cost_ptr, set_sdiv_cost,
udiv_cost_ptr, set_udiv_cost, mul_widen_cost_ptr,
set_mul_widen_cost, mul_highpart_cost_ptr, set_mul_highpart_cost):
New functions.
(convert_cost_ptr): New function, split out from...
(set_convert_cost, convert_cost): ...here.
* expmed.c, tree-ssa-loop-ivopts.c: Update for new functions.
* gimple-ssa-strength-reduction.c: Likewise.

---
 gcc/expmed.c|  230 ++-
 gcc/expmed.h|  441 +++
 gcc/gimple-ssa-strength-reduction.c |6 +-
 gcc/tree-ssa-loop-ivopts.c  |   24 +-
 4 files changed, 533 insertions(+), 168 deletions(-)

diff --git a/gcc/expmed.c b/gcc/expmed.c
index e660a3f..9743fc0 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -143,20 +143,24 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
   PUT_MODE (&all->shift_sub1, mode);
   PUT_MODE (&all->convert, mode);
 
-  add_cost[speed][mode] = set_src_cost (&all->plus, speed);
-  neg_cost[speed][mode] = set_src_cost (&all->neg, speed);
-  mul_cost[speed][mode] = set_src_cost (&all->mult, speed);
-  sdiv_cost[speed][mode] = set_src_cost (&all->sdiv, speed);
-  udiv_cost[speed][mode] = set_src_cost (&all->udiv, speed);
-
-  sdiv_pow2_cheap[speed][mode] = (set_src_cost (&all->sdiv_32, speed)
- <= 2 * add_cost[speed][mode]);
-  smod_pow2_cheap[speed][mode] = (set_src_cost (&all->smod_32, speed)
- <= 4 * add_cost[speed][mode]);
-
-  shift_cost[speed][mode][0] = 0;
-  shiftadd_cost[speed][mode][0] = shiftsub0_cost[speed][mode][0]
-= shiftsub1_cost[speed][mode][0] = add_cost[speed][mode];
+  set_add_cost (speed, mode, set_src_cost (&all->plus, speed));
+  set_neg_cost (speed, mode, set_src_cost (&all->neg, speed));
+  set_mul_cost (speed, mode, set_src_cost (&all->mult, speed));
+  set_sdiv_cost (speed, mode, set_src_cost (&all->sdiv, speed));
+  set_udiv_cost (speed, mode, set_src_cost (&all->udiv, speed));
+
+  set_sdiv_pow2_cheap (speed, mode, (set_src_cost (&all->sdiv_32, speed)
+<= 2 * add_cost (speed, mode)));
+  set_smod_pow2_cheap (speed, mode, (set_src_cost (&all->smod_32, speed)
+<= 4 * add_cost (speed, mode)));
+
+  set_shift_cost (speed, mode, 0, 0);
+  {
+int cost = add_cost (speed, mode);
+set_shiftadd_cost (speed, mode, 0, cost);
+set_shiftsub0_cost (speed, mode, 0, cost);
+set_shiftsub1_cost (speed, mode, 0, cost);
+  }
 
   n = MIN (MAX_BITS_PER_WORD, mode_bitsize);
   for (m = 1; m < n; m++)
@@ -164,10 +168,10 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
   XEXP (&all->shift, 1) = all->cint[m];
   XEXP (&all->shift_mult, 1) = all->pow2[m];
 
-  shift_cost[speed][mode][m] = set_src_cost (&all->shift, speed);
-  shiftadd_cost[speed][mode][m] = set_src_cost (&all->shift_add, speed);
-  shiftsub0_cost[speed][mode][m] = set_src_cost (&all->shift_sub0, speed);
-  shiftsub1_cost[speed][mode][m] = set_src_cost (&all->shift_sub1, speed);
+  set_shift_cost (speed, mode, m, set_src_cost (&all->shift, speed));
+  set_shiftadd_cost (speed, mode, m, set_src_cost (&all->shift_add, 
speed));
+  set_shiftsub0_cost (speed, mode, m, set_src_cost (&all->shift_sub0, 
speed));
+  set_shiftsub1_cost (speed, mode, m, set_src_cost (&all->shift_sub1, 
speed));
 }
 
   if (SCALAR_INT_MODE_P (mode))
@@ -181,10 +185,8 @@ init_expmed_one_mode (struct init_expmed_rtl *all,
  PUT

[PATCH] delete last traces of GO_IF_MODE_DEPENDENT_ADDRESS

2012-07-27 Thread Nathan Froyd
Subject says it all, really.  Two targets with redundant definitions, and
two targets with trivial definitions.  Time to remove this.

Tested on x86_64-unknown-linux-gnu.  Crosses to {alpha,vax}-linux-gnu built
as well.  OK to commit?

-Nathan

* defaults.h (GO_IF_MODE_DEPENDENT_ADDRESS): Delete.
* targhooks.c (default_mode_dependent_address_p): Delete code
for GO_IF_MODE_DEPENDENT_ADDRESS.
* system.h (GO_IF_MODE_DEPENDENT_ADDRESS): Poison.
* doc/tm.texi.in (GO_IF_MODE_DEPENDENT_ADDRESS): Delete documention.
* doc/tm.texi: Regenerate.
* config/alpha.h (GO_IF_MODE_DEPENDENT_ADDRESS): Move code to...
* config/alpha.c (alpha_mode_dependent_address_p): ...here.  New
function.
(TARGET_MODE_DEPENDENT_ADDRESS_P): Define.
* config/cr16/cr16.h (GO_IF_MODE_DEPENDENT_ADDRESS): Delete.
* config/mep/mep.h (GO_IF_MODE_DEPENDENT_ADDRESS): Delete.
* config/vax/vax-protos.h (vax_mode_dependent_address_p): Delete.
* config/vax/vax.h (GO_IF_MODE_DEPENDENT_ADDRESS): Delete.
* config/vax/vax.c (vax_mode_dependent_address_p): Make static.
Take a const_rtx.
(TARGET_MODE_DEPENDENT_ADDRESS_P): Define.

---
 gcc/config/alpha/alpha.c|   12 
 gcc/config/alpha/alpha.h|7 ---
 gcc/config/cr16/cr16.h  |4 
 gcc/config/mep/mep.h|2 --
 gcc/config/vax/vax-protos.h |1 -
 gcc/config/vax/vax.c|7 +--
 gcc/config/vax/vax.h|5 -
 gcc/defaults.h  |7 ---
 gcc/doc/tm.texi |   18 --
 gcc/doc/tm.texi.in  |   18 --
 gcc/system.h|3 ++-
 gcc/targhooks.c |   12 
 12 files changed, 19 insertions(+), 77 deletions(-)

diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 5617ea3..6d455ef 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -1038,6 +1038,16 @@ alpha_legitimize_address (rtx x, rtx oldx 
ATTRIBUTE_UNUSED,
   return new_x ? new_x : x;
 }
 
+/* Return true if ADDR has an effect that depends on the machine mode it
+   is used for.  On the Alpha this is true only for the unaligned modes.
+   We can simplify the test since we know that the address must be valid.  */
+
+static bool
+alpha_mode_dependent_address_p (const_rtx addr)
+{
+  return GET_CODE (addr) == AND;
+}
+
 /* Primarily this is required for TLS symbols, but given that our move
patterns *ought* to be able to handle any symbol at any time, we
should never be spilling symbolic operands to the constant pool, ever.  */
@@ -9709,6 +9719,8 @@ alpha_conditional_register_usage (void)
 
 #undef TARGET_LEGITIMIZE_ADDRESS
 #define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
+#undef TARGET_MODE_DEPENDENT_ADDRESS_P
+#define TARGET_MODE_DEPENDENT_ADDRESS_P alpha_mode_dependent_address_p
 
 #undef TARGET_ASM_FILE_START
 #define TARGET_ASM_FILE_START alpha_file_start
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 8520ea8..cdb7c49 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -851,13 +851,6 @@ do {   
 \
 }   \
 } while (0)
 
-/* Go to LABEL if ADDR (a legitimate address expression)
-   has an effect that depends on the machine mode it is used for.
-   On the Alpha this is true only for the unaligned modes.   We can
-   simplify this test since we know that the address must be valid.  */
-
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)  \
-{ if (GET_CODE (ADDR) == AND) goto LABEL; }
 
 /* Specify the machine mode that this machine uses
for the index in the tablejump instruction.  */
diff --git a/gcc/config/cr16/cr16.h b/gcc/config/cr16/cr16.h
index 54794e1..cf5bdf1 100644
--- a/gcc/config/cr16/cr16.h
+++ b/gcc/config/cr16/cr16.h
@@ -460,10 +460,6 @@ struct cumulative_args
 #define REG_OK_FOR_INDEX_P(X)   1
 #endif /* not REG_OK_STRICT.  */
 
-/* Go to LABEL if ADDR (a legitimate address expression) has 
-   an effect that depends on the machine mode it is used for.  */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
-
 /* Assume best case (branch predicted).  */
 #define BRANCH_COST(speed_p, predictable_p)   2
 
diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h
index ad5b36d..920120c 100644
--- a/gcc/config/mep/mep.h
+++ b/gcc/config/mep/mep.h
@@ -561,8 +561,6 @@ typedef struct
   if (mep_legitimize_reload_address (&(X), (MODE), (OPNUM), (TYPE), 
(IND_LEVELS))) \
 goto WIN
 
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
-
 #define SELECT_CC_MODE(OP, X, Y)  CCmode
 
 
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index 3f24794..5363877 100644
--- a/gcc/config/vax/vax-protos.h
+++ b/gcc/config/vax/vax-protos.h
@@ -19,7 +19,6 @@ along with GCC; see the file COPYING3.  If not see

[PATCH] shrink storage for target_expmed cost fields

2012-07-30 Thread Nathan Froyd
Now that we can freely change the representation of the cost fields in
struct target_expmed, the patch below does so, by only requiring arrays
to hold enough storage for integer modes and/or vector integer modes,
as appropriate.

default_target_expmed shrinks from ~200KB to ~85KB on
x86_64-unknown-linux-gnu as a result of this patch (20+ (!) vector
integer modes).  As a comparison point, it shrinks from ~120KB to ~45KB
on alpha-linux-gnu (5 vector integer modes).  So it should be helpful no
matter what your target looks like.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

* expmed.h (NUM_MODE_VECTOR_INT): Define.
(struct expmed_op_cheap, struct expmed_op_costs): New structures.
(struct target_expmed): Convert x_mul_highpart_cost and
x_mul_widen_cost fields to be indexed by integer modes.
Convert x_sdiv_pow2_cheap and x_smod_pow2_cheap fields to be
of type struct expmed_op_cheap.  Convert other cost fields to be
of type struct_expmed_op_costs.
(mul_widen_cost_ptr, mul_highpart_cost_ptr): Adjust for new
indexing of respective fields.
(expmed_op_cheap_ptr): New function.
(sdiv_pow2_cheap_ptr, smod_pow2_cheap_ptr): Call it.
(expmed_op_cost_ptr): New function.
(add_cost_ptr, neg_cost_ptr, shift_cost_ptr, shiftadd_cost_ptr,
shiftsub0_cost_ptr, shiftsub1_cost_ptr, mul_cost_ptr,
sdiv_cost_ptr, udiv_cost_ptr): Call it.

---
 gcc/ChangeLog |   18 
 gcc/expmed.h  |  124 +
 2 files changed, 116 insertions(+), 26 deletions(-)

diff --git a/gcc/expmed.h b/gcc/expmed.h
index 97e17f3..bde5cae 100644
--- a/gcc/expmed.h
+++ b/gcc/expmed.h
@@ -125,6 +125,23 @@ struct alg_hash_entry {
 #endif
 
 #define NUM_MODE_INT (MAX_MODE_INT - MIN_MODE_INT + 1)
+#define NUM_MODE_VECTOR_INT (MAX_MODE_VECTOR_INT - MIN_MODE_VECTOR_INT + 1)
+
+struct expmed_op_cheap {
+  /* Whether an operation is cheap in a given integer mode.  */
+  bool cheap_int[2][NUM_MODE_INT];
+
+  /* Whether an operation is cheap in a given vector integer mode.  */
+  bool cheap_vector_int[2][NUM_MODE_VECTOR_INT];
+};
+
+struct expmed_op_costs {
+  /* The cost of an operation in a given integer mode.  */
+  int int_cost[2][NUM_MODE_INT];
+
+  /* The cost of an operation in a given vector integer mode.  */
+  int vector_int_cost[2][NUM_MODE_VECTOR_INT];
+};
 
 /* Target-dependent globals.  */
 struct target_expmed {
@@ -140,23 +157,23 @@ struct target_expmed {
  powers of two, so don't use branches; emit the operation instead.
  Usually, this will mean that the MD file will emit non-branch
  sequences.  */
-  bool x_sdiv_pow2_cheap[2][NUM_MACHINE_MODES];
-  bool x_smod_pow2_cheap[2][NUM_MACHINE_MODES];
+  struct expmed_op_cheap x_sdiv_pow2_cheap;
+  struct expmed_op_cheap x_smod_pow2_cheap;
 
   /* Cost of various pieces of RTL.  Note that some of these are indexed by
  shift count and some by mode.  */
   int x_zero_cost[2];
-  int x_add_cost[2][NUM_MACHINE_MODES];
-  int x_neg_cost[2][NUM_MACHINE_MODES];
-  int x_shift_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
-  int x_shiftadd_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
-  int x_shiftsub0_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
-  int x_shiftsub1_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
-  int x_mul_cost[2][NUM_MACHINE_MODES];
-  int x_sdiv_cost[2][NUM_MACHINE_MODES];
-  int x_udiv_cost[2][NUM_MACHINE_MODES];
-  int x_mul_widen_cost[2][NUM_MACHINE_MODES];
-  int x_mul_highpart_cost[2][NUM_MACHINE_MODES];
+  struct expmed_op_costs x_add_cost;
+  struct expmed_op_costs x_neg_cost;
+  struct expmed_op_costs x_shift_cost[MAX_BITS_PER_WORD];
+  struct expmed_op_costs x_shiftadd_cost[MAX_BITS_PER_WORD];
+  struct expmed_op_costs x_shiftsub0_cost[MAX_BITS_PER_WORD];
+  struct expmed_op_costs x_shiftsub1_cost[MAX_BITS_PER_WORD];
+  struct expmed_op_costs x_mul_cost;
+  struct expmed_op_costs x_sdiv_cost;
+  struct expmed_op_costs x_udiv_cost;
+  int x_mul_widen_cost[2][NUM_MODE_INT];
+  int x_mul_highpart_cost[2][NUM_MODE_INT];
 
   /* Conversion costs are only defined between two scalar integer modes
  of different sizes.  The first machine mode is the destination mode,
@@ -195,12 +212,58 @@ set_alg_hash_used_p (bool usedp)
   this_target_expmed->x_alg_hash_used_p = usedp;
 }
 
+/* Return a pointer to a boolean contained in EOC indicating whether
+   a particular operation performed in MODE is cheap when optimizing
+   for SPEED.  */
+
+static inline bool *
+expmed_op_cheap_ptr (struct expmed_op_cheap *eoc, bool speed,
+enum machine_mode mode)
+{
+  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
+
+  if (GET_MODE_CLASS (mode) == MODE_INT)
+{
+  int idx = mode - MIN_MODE_INT;
+  return &eoc->cheap_int[speed][idx];
+}
+  else
+{
+  int idx = mode - MIN_MODE_VECTOR_INT;
+  return &eoc

Re: ORDERED_EXPR in invert_tree_comparison

2012-08-02 Thread Nathan Froyd
On Thu, Aug 02, 2012 at 02:48:08PM +0200, Marc Glisse wrote:
> I am redoing the bootstrap+regtest, then I'll commit if I don't hear
> protests about the testcase.
> 
> gcc/ChangeLog
> 2012-06-15  Marc Glisse  
> 
>   PR tree-optimization/53805
>   * fold-const.c (invert_tree_comparison): Do invert ORDERED_EXPR and
>   UNORDERED_EXPR for floating point.

Minor protest about the ChangeLog: I think you mean "Do _not_ invert..."

-Nathan


Re: ORDERED_EXPR in invert_tree_comparison

2012-08-02 Thread Nathan Froyd
On Thu, Aug 02, 2012 at 05:20:24PM +0200, Marc Glisse wrote:
> On Thu, 2 Aug 2012, Nathan Froyd wrote:
> >>PR tree-optimization/53805
> >>* fold-const.c (invert_tree_comparison): Do invert ORDERED_EXPR and
> >>UNORDERED_EXPR for floating point.
> >
> >Minor protest about the ChangeLog: I think you mean "Do _not_ invert..."
> 
> No, I do mean do invert. The point of the patch is that even for
> floating point and even with trapping-math, it is still safe to
> invert them.

Ahhh, yes.  I misread the patch.

> Maybe I can reformulate as: "Invert ORDERED_EXPR and UNORDERED_EXPR
> even for trapping floating point." ?

That works for me.

-Nathan


[PATCH] [mep] delete unused constraint-related macros and functions

2012-08-02 Thread Nathan Froyd
mep uses {constraints,predicates}.md and #if 0'd out the old macro versions.
In the interest of not keeping dead code around, I'd like to delete these.
I think this falls under the obvious rule, so I'll commit this in a couple of
days after waiting to hear from DJ.

Tested by building mep-elf.

-Nathan

* config/mep/mep.h (REG_CLASS_FROM_CONSTRAINT): Delete.
(CONST_OK_FOR_LETTER_P, CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
(CONSTRAINT_LEN, EXTRA_CONSTRAINT): Delete.
* config/mep/mep.c (mep_reg_class_from_constraint): Delete.
(mep_const_ok_for_letter_p, mep_extra_constraint): Delete.
* config/mep/mep-protos.h (mep_reg_class_from_constraint): Delete.
(mep_const_ok_for_letter_p, mep_extra_constraint): Delete.
---
 gcc/ChangeLog   |   10 
 gcc/config/mep/mep-protos.h |3 -
 gcc/config/mep/mep.c|  126 ---
 gcc/config/mep/mep.h|   15 -
 4 files changed, 10 insertions(+), 144 deletions(-)

diff --git a/gcc/config/mep/mep-protos.h b/gcc/config/mep/mep-protos.h
index edfbaf7..f0f3496 100644
--- a/gcc/config/mep/mep-protos.h
+++ b/gcc/config/mep/mep-protos.h
@@ -20,9 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 extern int mep_regno_reg_class (int);
-extern int mep_reg_class_from_constraint (int, const char *);
-extern bool mep_const_ok_for_letter_p (HOST_WIDE_INT, int);
-extern bool mep_extra_constraint (rtx, int);
 extern rtx mep_mulr_source (rtx, rtx, rtx, rtx);
 extern bool mep_reuse_lo_p (rtx, rtx, rtx, bool);
 extern bool mep_use_post_modify_p (rtx, rtx, rtx);
diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c
index bba0327..5089e03 100644
--- a/gcc/config/mep/mep.c
+++ b/gcc/config/mep/mep.c
@@ -596,132 +596,6 @@ mep_regno_reg_class (int regno)
   return NO_REGS;
 }
 
-#if 0
-int
-mep_reg_class_from_constraint (int c, const char *str)
-{
-  switch (c)
-{
-case 'a':
-  return SP_REGS;
-case 'b':
-  return TP_REGS;
-case 'c':
-  return CONTROL_REGS;
-case 'd':
-  return HILO_REGS;
-case 'e':
-  {
-   switch (str[1])
- {
- case 'm':
-   return LOADABLE_CR_REGS;
- case 'x':
-   return mep_have_copro_copro_moves_p ? CR_REGS : NO_REGS;
- case 'r':
-   return mep_have_core_copro_moves_p ? CR_REGS : NO_REGS;
- default:
-   return NO_REGS;
- }
-  }
-case 'h':
-  return HI_REGS;
-case 'j':
-  return RPC_REGS;
-case 'l':
-  return LO_REGS;
-case 't':
-  return TPREL_REGS;
-case 'v':
-  return GP_REGS;
-case 'x':
-  return CR_REGS;
-case 'y':
-  return CCR_REGS;
-case 'z':
-  return R0_REGS;
-
-case 'A':
-case 'B':
-case 'C':
-case 'D':
-  {
-   enum reg_class which = c - 'A' + USER0_REGS;
-   return (reg_class_size[which] > 0 ? which : NO_REGS);
-  }
-
-default:
-  return NO_REGS;
-}
-}
-
-bool
-mep_const_ok_for_letter_p (HOST_WIDE_INT value, int c)
-{
-  switch (c)
-{
-  case 'I': return value >= -32768 && value <  32768;
-  case 'J': return value >=  0 && value <  65536;
-  case 'K': return value >=  0 && value < 0x0100;
-  case 'L': return value >=-32 && value < 32;
-  case 'M': return value >=  0 && value < 32;
-  case 'N': return value >=  0 && value < 16;
-  case 'O':
-   if (value & 0x)
- return false;
-   return value >= -2147483647-1 && value <= 2147483647;
-default:
-  gcc_unreachable ();
-}
-}
-
-bool
-mep_extra_constraint (rtx value, int c)
-{
-  encode_pattern (value);
-
-  switch (c)
-{
-case 'R':
-  /* For near symbols, like what call uses.  */
-  if (GET_CODE (value) == REG)
-   return 0;
-  return mep_call_address_operand (value, GET_MODE (value));
-
-case 'S':
-  /* For signed 8-bit immediates.  */
-  return (GET_CODE (value) == CONST_INT
- && INTVAL (value) >= -128
- && INTVAL (value) <= 127);
-
-case 'T':
-  /* For tp/gp relative symbol values.  */
-  return (RTX_IS ("u3s") || RTX_IS ("u2s")
-  || RTX_IS ("+u3si") || RTX_IS ("+u2si"));
-
-case 'U':
-  /* Non-absolute memories.  */
-  return GET_CODE (value) == MEM && ! CONSTANT_P (XEXP (value, 0));
-
-case 'W':
-  /* %hi(sym) */
-  return RTX_IS ("Hs");
-
-case 'Y':
-  /* Register indirect.  */
-  return RTX_IS ("mr");
-
-case 'Z':
-  return mep_section_tag (value) == 'c' && RTX_IS ("ms");
-}
-
-  return false;
-}
-#endif
-
-#undef PASS
-#undef FAIL
-
 static bool
 const_in_range (rtx x, int minv, int maxv)
 {
diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h
index 920120c..9a382e6 100644
--- a/gcc/config/mep/mep.h
+++ b/gcc/config/mep/mep.h
@@ -408,11 +408,6 @@ enum reg_c

[PATCH,mmix] convert to constraints.md

2012-08-02 Thread Nathan Froyd
As $SUBJECT says.  There's not too much interesting here.  I did a
fairly literal-minded conversion, so it's possible there's smarter ways
to do some things.

Compiled with cross to mmix-knuth-mmixware and spot-checked by comparing
libgcc object files.  I have no idea how to set up a simulator
environment.  H-P, if you'd like to test beforehand, that'd be great.

OK to commit?

-Nathan

* config/mmix/mmix.h (REG_CLASS_FROM_LETTER): Delete.
(CONST_OK_FOR_LETTER_P, CONST_DOUBLE_OK_FOR_LETTER_P): Delete.
(EXTRA_CONSTRAINT): Delete.
* config/mmix/mmix-protos.h (mmix_intval): Declare.
(mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete.
(mmix_const_double_ok_for_letter_p): Delete.
* config/mmix/constraints.md: New file.
* config/mmix/mmix.md: Include it.
(iordi3): Delete dead H constraint.
* config/mmix/predicates.md (mmix_reg_or_8bit_operand): Use
satisfies_constraint_I.
(mmix_address_operand): New predicate.
* config/mmix/mmix.c: #include tm-constrs.h.
(mmix_intval): Delete declaration.  Make non-static.
(mmix_const_ok_for_letter_p, mmix_extra_constraint): Delete.
(mmix_const_double_ok_for_letter_p): Delete.
(mmix_legitimate_address_p): Use satisfies_constraint_I.
(mmix_print_operand_address): Likewise.
---
 gcc/ChangeLog  |   21 +
 gcc/config/mmix/constraints.md |   93 
 gcc/config/mmix/mmix-protos.h  |4 +-
 gcc/config/mmix/mmix.c |   93 ++-
 gcc/config/mmix/mmix.h |   15 --
 gcc/config/mmix/mmix.md|3 +-
 gcc/config/mmix/predicates.md  |   14 --
 7 files changed, 132 insertions(+), 111 deletions(-)
 create mode 100644 gcc/config/mmix/constraints.md

diff --git a/gcc/config/mmix/constraints.md b/gcc/config/mmix/constraints.md
new file mode 100644
index 000..b8cc690
--- /dev/null
+++ b/gcc/config/mmix/constraints.md
@@ -0,0 +1,93 @@
+;; MMIX constraints
+;; Copyright (C) 2012 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; .  */
+
+(define_register_constraint "x" "SYSTEM_REGS"
+  "@internal")
+
+(define_register_constraint "y" "REMAINDER_REG"
+  "@internal")
+
+(define_register_constraint "z" "HIMULT_REG"
+  "@internal")
+
+(define_constraint "I"
+  "A 8-bit unsigned integer"
+  (and (match_code "const_int")
+   (match_test "IN_RANGE (ival, 0, 255)")))
+
+(define_constraint "J"
+  "A 16-bit unsigned integer."
+  (and (match_code "const_int")
+   (match_test "IN_RANGE (ival, 0, 65535)")))
+
+(define_constraint "K"
+  "An integer between -255 and 0."
+  (and (match_code "const_int")
+   (match_test "IN_RANGE (ival, -255, 0)")))
+
+(define_constraint "L"
+  "@internal"
+  (and (match_code "const_int")
+   (match_test "mmix_shiftable_wyde_value (ival)")))
+
+(define_constraint "M"
+  "The value 0."
+  (and (match_code "const_int")
+   (match_test "ival == 0")))
+
+(define_constraint "N"
+  "@internal"
+  (and (match_code "const_int")
+   (match_test "mmix_shiftable_wyde_value (~ival)")))
+
+(define_constraint "O"
+  "The value 3, 5, 9, or 17."
+  (and (match_code "const_int")
+   (ior (match_test "ival == 3")
+   (match_test "ival == 5")
+   (match_test "ival == 9")
+   (match_test "ival == 17"
+
+(define_constraint "G"
+  "Floating-point zero."
+  (and (match_code "const_double")
+   (match_test "op == CONST0_RTX (mode)")))
+
+(define_constraint "R"
+  "@internal"
+  (and (not (match_code "const_int,const_double"))
+   (match_test "mmix_constant_address_p (op)")
+   (ior (match_test "!TARGET_BASE_ADDRESSES")
+   (match_code "LABEL_REF")
+   (and (match_code "SYMBOL_REF")
+(match_test "SYMBOL_REF_FLAG (op)")
+
+(define_constraint "S"
+  "@internal"
+  (and (match_code "const_int,const_double")
+   (match_test "mmix_shiftable_wyde_value (mmix_intval (op))")))
+
+(define_constraint "T"
+  "@internal"
+  (and (match_code "const_int,const_double")
+   (match_test "mmix_shiftable_wyde_value (~mmix_intval (op))")))
+
+(define_constraint "U"
+  "@internal"
+  (match_operand 0 "mmix_address_operand"))
diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.

Re: [PATCH] Fix part of PR30442

2012-06-05 Thread Nathan Froyd
On Tue, Jun 05, 2012 at 02:35:30PM +0200, Richard Guenther wrote:
> Index: gcc/tree-vect-data-refs.c
> !   gimple stmt = gsi_stmt (gsi);
> !   if (!find_data_references_in_stmt (NULL, stmt,
> !  &BB_VINFO_DATAREFS (bb_vinfo)))
> ! {
> !   /* Mark the rest of the basic-block as unvectorizable.  */
> !   for (; !gsi_end_p (gsi); gsi_next (&gsi))

I see iteration through the rest of the basic block...

> ! STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)) = false;

...but I don't see corresponding updates to stmt.

-Nathan


Re: [AVR,committed]: ad PR45099: change error to warning

2011-09-21 Thread Nathan Froyd

On 9/21/2011 5:49 AM, Georg-Johann Lay wrote:

As proposed in PR45099, avr-gcc will now just print a warning instead of an
error when a fixed register is needed to pass a parameter to a function.


Where's the proposal in the PR?  I see a problem report that was 
addressed four months ago by adding an error, the addition of an error 
message, an explanation of why we're issuing an error message, and then 
this commit, which changes the error back into a warning (!).


I guess the original report proposed a warning, but an error seems like 
a *much* better idea.  Better to tell the user early that things are 
going to break, IMHO.


-Nathan



Re: [google] Linker plugin to do function reordering using callgraph edge profiles (issue5124041)

2011-09-26 Thread Nathan Froyd

On 9/23/2011 6:03 PM, Sriraman Tallam wrote:

This patch adds a new linker plugin to re-order functions.


This is great stuff.  We were experimenting with using the coverage 
files to generate an ordering for --section-ordering-file, but this 
might be even better, will have to experiment with it.


A couple of comments on the code itself:


Index: function_reordering_plugin/callgraph.h
+inline static Edge_list *
+make_edge_list (Edge *e)
+{
+  Edge_list *list = (Edge_list *)malloc (sizeof (Edge_list));


If you are going to use libiberty via hashtab.h, you might as well make 
use of the *ALLOC family of macros to make this and other allocations a 
little neater.



+/*Represents an edge in the call graph.  */
+struct __edge__


I think the usual convention is to call this edge_d or something 
similar, avoiding the profusion of underscores.



+void
+map_section_name_to_index (char *section_name, void *handle, int shndx)
+{
+  void **slot;
+  char *function_name;
+
+  if (is_prefix_of (".text.hot.", section_name))
+function_name = section_name + 10 /* strlen (".text.hot.") */;
+  else if (is_prefix_of (".text.unlikely.", section_name))
+function_name = section_name + 15 /* strlen (".text.unlikely.") */;
+  else if (is_prefix_of (".text.cold.", section_name))
+function_name = section_name + 11 /* strlen (".text.cold.") */;
+  else if (is_prefix_of (".text.startup.", section_name))
+function_name = section_name + 14 /* strlen (".text.startup.") */;
+  else
+function_name = section_name + 6 /*strlen (".text.") */;


You don't handle plain .text; this is assuming -ffunction-sections, 
right?  Can this limitation be easily removed?


I think it is customary to put the comment after the semicolon.

Might just be easier to say something like:

  const char *sections[] = { ".text.hot", ... }
  char *function_name = NULL;

  for (i = 0; i < ARRAY_SIZE (sections); i++)
if (is_prefix_of (sections[i], section_name))
  {
 function_name = section_name + strlen (sections[i]);
 break;
  }

  if (!function_name)
function_name = section_name + 6; /* strlen (".text.") */

I guess that's not much shorter.


+void
+cleanup ()
+{
+  Node *node;
+  Edge *edge;
+
+  /* Free all nodes and edge_lists.  */
+  for (node = node_chain; node != NULL; )
+{
+  Node *next_node = node->next;
+  Edge_list *it;
+  for (it = node->edge_list; it != NULL; )
+{
+  Edge_list *next_it = it->next;
+  free (it);
+  it = next_it;
+}


Write a free_edge_list function, since you do this once here and twice 
below.


-Nathan


Re: [SH] PR 50751 - add HImode displacement addressing support

2012-04-10 Thread Nathan Froyd
- Original Message -
> > BTW, do you have the numbers of CSiBE with this?
> 
> Only for "-m4-single -ml -O2 -mpretend-cmove" so far.
> Not so spectacular :T
> I'll also do a comparison of more variants to see if something went
> really bad.  It's a bit difficult to isolate the degradations because
> there's quite some code reordering happening after the patch...

Are you looking at execution time or code size?  If the latter, you could try 
disabling scheduling for comparison purposes (-fno-schedule-insns 
-fno-schedule-insns2).  Even if you're looking at execution time, disabling 
scheduling might make it easier to see where things are going wrong in the 
patched code.

-Nathan


Re: [PATCH] Don't optimize away non-pure/const calls during ccp (PR tree-optimization/51683)

2011-12-28 Thread Nathan Froyd
- Original Message -
> else if (is_gimple_call (def_stmt))
> {
> + int flags = gimple_call_flags (def_stmt);
> +
> + /* Don't optimize away calls that have side-effects. */
> + if ((flags & (ECF_CONST|ECF_PURE)) == 0
> + || (flags & ECF_LOOPING_CONST_OR_PURE))

This patch does this computation twice; grepping through the tree for ECF_CONST 
suggests it's done quite a few more times.  Could we get a predicate in 
gimple.h to encapsulate this?

-Nathan


[PATCH] don't use TYPE_ARG_TYPES when calling c-family:check_function_arguments

2011-05-21 Thread Nathan Froyd
The calling interface for check_function_arguments requires the caller
to extract TYPE_ATTRIBUTES and TYPE_ARG_TYPES prior to calling it.  This
is somewhat silly, as well as being incompatible with an eventual
removal of TYPE_ARG_TYPES.  The patch below changes things to pass the
FUNCTION_TYPE itself into check_function_arguments, wherein it extracts
TYPE_ATTRIBUTES and iterates over the argument types as necessary.

Tested on x86_64-unknown-linux-gnu.  OK to commit?  (The approval is for
the c-family bits; I think the C/C++ bits are obvious once that's
approved.)

-Nathan

gcc/
* c-typeck.c (build_function_call_vec): Tweak call to
check_function_arguments.

gcc/c-family/
* c-common.h (check_function_arguments): Tweak prototype of
check_function_arguments.
* c-common.c (check_function_arguments): Likewise.  Adjust
calls to check_function_nonnull, check_function_format, and
check_function_sentinel.
(check_function_sentinel): Take a FUNCTION_TYPE rather than
separate attributes and typelist arguments.  Use
FOREACH_FUNCTION_ARGS to iterate over argument types.

gcc/cp/
* call.c (build_over_call): Tweak call to check_function_arguments.
* typeck.c (cp_build_function_call_vec): Likewise.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 8fc68eb..fef8ded 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7479,20 +7479,23 @@ check_function_nonnull (tree attrs, int nargs, tree 
*argarray)
array ARGARRAY.  */
 
 static void
-check_function_sentinel (tree attrs, int nargs, tree *argarray, tree typelist)
+check_function_sentinel (const_tree fntype, int nargs, tree *argarray)
 {
-  tree attr = lookup_attribute ("sentinel", attrs);
+  tree attr = lookup_attribute ("sentinel", TYPE_ATTRIBUTES (fntype));
 
   if (attr)
 {
   int len = 0;
   int pos = 0;
   tree sentinel;
+  function_args_iterator iter;
+  tree t;
 
   /* Skip over the named arguments.  */
-  while (typelist && len < nargs)
+  FOREACH_FUNCTION_ARGS (fntype, t, iter)
{
- typelist = TREE_CHAIN (typelist);
+ if (len == nargs)
+   break;
  len++;
}
 
@@ -7937,26 +7940,24 @@ handle_no_split_stack_attribute (tree *node, tree name,
   return NULL_TREE;
 }
 
-/* Check for valid arguments being passed to a function.
-   ATTRS is a list of attributes.  There are NARGS arguments in the array
-   ARGARRAY.  TYPELIST is the list of argument types for the function.
- */
+/* Check for valid arguments being passed to a function with FNTYPE.
+   There are NARGS arguments in the array ARGARRAY.  */
 void
-check_function_arguments (tree attrs, int nargs, tree *argarray, tree typelist)
+check_function_arguments (const_tree fntype, int nargs, tree *argarray)
 {
   /* Check for null being passed in a pointer argument that must be
  non-null.  We also need to do this if format checking is enabled.  */
 
   if (warn_nonnull)
-check_function_nonnull (attrs, nargs, argarray);
+check_function_nonnull (TYPE_ATTRIBUTES (fntype), nargs, argarray);
 
   /* Check for errors in format strings.  */
 
   if (warn_format || warn_missing_format_attribute)
-check_function_format (attrs, nargs, argarray);
+check_function_format (TYPE_ATTRIBUTES (fntype), nargs, argarray);
 
   if (warn_format)
-check_function_sentinel (attrs, nargs, argarray, typelist);
+check_function_sentinel (fntype, nargs, argarray);
 }
 
 /* Generic argument checking recursion routine.  PARAM is the argument to
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 7136b01..89d4b80 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -687,7 +687,7 @@ extern void finish_fname_decls (void);
 extern const char *fname_as_string (int);
 extern tree fname_decl (location_t, unsigned, tree);
 
-extern void check_function_arguments (tree, int, tree *, tree);
+extern void check_function_arguments (const_tree, int, tree *);
 extern void check_function_arguments_recurse (void (*)
  (void *, tree,
   unsigned HOST_WIDE_INT),
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 6016db2..e609611 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -2808,8 +2808,7 @@ build_function_call_vec (location_t loc, tree function, 
VEC(tree,gc) *params,
 return error_mark_node;
 
   /* Check that the arguments to the function are valid.  */
-  check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
-   TYPE_ARG_TYPES (fntype));
+  check_function_arguments (fntype, nargs, argarray);
 
   if (name != NULL_TREE
   && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 09ad4ae..972dca3 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6477,8 +6477,7 @@ build_over_call (struct z_candidate *ca

[PATCH] get rid of some TYPE_ARG_TYPES usage by introducing nth_arg_type

2011-05-23 Thread Nathan Froyd
Various places in the compiler grab TYPE_ARG_TYPES and grovel through it
when what they're really trying to do is index into the list of argument
types.  The patch below introduces nth_arg_type for such situatiosn and
changes a hodgepodge of places to use it.  You could, of course, use
function_args_iterator, but I think this approach is somewhat clearer.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

gcc/
* tree.h (nth_arg_type): Declare.
* tree.c (nth_arg_type): Define.
* dbxout.c (dbxout_type_method_1): Call it.
* dwarf2out.c (decl_class_context): Likewise.
* tree-ssa-math-opts.c (execute_optimize_bswap): Likewise.

gcc/cp/
* cp-tree.h (DECL_CONST_MEMFUNC_P): Call nth_arg_type.
(DECL_VOLATILE_MEMFUNC_P, type_of_this_parm): Likewise.

gcc/fortran/
* trans-decl.c (create_main_function): Call nth_arg_type.

gcc/objc/
* objc-next-runtime-abi-01.c (next_sjlj_build_enter_and_setjmp):
Call nth_arg_type.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ada01fb..53848c3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2256,15 +2256,13 @@ struct GTY((variable_size)) lang_decl {
has `this' as const X *const.  */
 #define DECL_CONST_MEMFUNC_P(NODE)  \
   (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)  \
-   && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE\
- (TYPE_ARG_TYPES (TREE_TYPE (NODE))
+   && CP_TYPE_CONST_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0
 
 /* Nonzero for FUNCTION_DECL means that this member function
has `this' as volatile X *const.  */
 #define DECL_VOLATILE_MEMFUNC_P(NODE)   \
   (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)  \
-   && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE
 \
- (TYPE_ARG_TYPES (TREE_TYPE (NODE))
+   && CP_TYPE_VOLATILE_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0
 
 /* Nonzero for a DECL means that this member is a non-static member.  */
 #define DECL_NONSTATIC_MEMBER_P(NODE)  \
@@ -4660,10 +4658,8 @@ struct GTY(()) tinst_level {
 static inline tree
 type_of_this_parm (const_tree fntype)
 {
-  function_args_iterator iter;
   gcc_assert (TREE_CODE (fntype) == METHOD_TYPE);
-  function_args_iter_init (&iter, fntype);
-  return function_args_iter_cond (&iter);
+  return nth_arg_type (fntype, 0);
 }
 
 /* Return the class of the `this' parameter of FNTYPE.  */
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 3190803..f5e985e 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -1585,7 +1585,7 @@ dbxout_type_method_1 (tree decl)
 c2 = '?';
   else /* it's a METHOD_TYPE.  */
 {
-  tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)));
+  tree firstarg = nth_arg_type (TREE_TYPE (decl), 0);
   /* A for normal functions.
 B for `const' member functions.
 C for `volatile' member functions.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b85a55e..d95c3f4 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -7484,7 +7484,7 @@ decl_class_context (tree decl)
 context = DECL_CONTEXT (decl);
   else
 context = TYPE_MAIN_VARIANT
-  (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl);
+  (TREE_TYPE (nth_arg_type (TREE_TYPE (decl), 0)));
 
   if (context && !TYPE_P (context))
 context = NULL_TREE;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index d771484..19d3e03 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -4518,7 +4518,7 @@ create_main_function (tree fndecl)
 {
   tree old_context;
   tree ftn_main;
-  tree tmp, decl, result_decl, argc, argv, typelist, arglist;
+  tree tmp, decl, result_decl, argc, argv, fntype, arglist;
   stmtblock_t body;
 
   old_context = current_function_decl;
@@ -4559,21 +4559,20 @@ create_main_function (tree fndecl)
   /* Get the arguments.  */
 
   arglist = NULL_TREE;
-  typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
+  fntype = TREE_TYPE (ftn_main);
 
-  tmp = TREE_VALUE (typelist);
+  tmp = nth_arg_type (fntype, 0);
   argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
   DECL_CONTEXT (argc) = ftn_main;
-  DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
+  DECL_ARG_TYPE (argc) = tmp;
   TREE_READONLY (argc) = 1;
   gfc_finish_decl (argc);
   arglist = chainon (arglist, argc);
 
-  typelist = TREE_CHAIN (typelist);
-  tmp = TREE_VALUE (typelist);
+  tmp = nth_arg_type (fntype, 1);
   argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
   DECL_CONTEXT (argv) = ftn_main;
-  DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
+  DECL_ARG_TYPE (argv) = tmp;
   TREE_READONLY (argv) = 1;
   DECL_BY_REFERENCE (argv) = 1;
   gfc_finish_decl (argv);
diff --git a/gcc/objc/objc-next-runtime-abi-01.c 
b/gcc/objc/objc-next-runtime-abi-01.c
i

Re: [PATCH] get rid of some TYPE_ARG_TYPES usage by introducing nth_arg_type

2011-05-23 Thread Nathan Froyd
On 05/23/2011 10:05 AM, Richard Guenther wrote:
> On Mon, May 23, 2011 at 3:53 PM, Nathan Froyd  
> wrote:
>> +/* Return the Nth argument type from FNTYPE.  */
>> +
>> +tree
>> +nth_arg_type (const_tree fntype, int n)
>> +{
>> +  function_args_iterator iter;
>> +  tree t;
>> +  int i;
>> +
>> +  gcc_assert (fntype != NULL_TREE);
>> +  gcc_assert (n >= 0);
> 
> Please merge the asserts and do s/gcc_assert/gcc_checking_assert/

Ack.

> And if n should be >= 0 why not pass it in as unsigned?

Consistency with all the other interfaces where n is logically unsigned but
passed in as int?

> The patch is ok with both changes.

Thanks for the review.

-Nathan



Re: [PING][PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED

2011-05-23 Thread Nathan Froyd
On 05/17/2011 11:31 AM, Nathan Froyd wrote:
> On 05/10/2011 04:18 PM, Nathan Froyd wrote:
>> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>>> After all that, we can finally make tree_exp inherit from typed_tree.
>>> Quite anticlimatic.
>>
>> Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html
> 
> Ping^2.

Ping^3 to put it in Richi's INBOX. ;)

-Nathan


Re: [PATCH] split tree_type, a.k.a. "tuplifying types"

2011-05-23 Thread Nathan Froyd
On 05/22/2011 02:24 PM, Tom de Vries wrote:
> Now that struct tree_type does not exist anymore, 'sizeof (struct tree_type)'
> generates an error in the following assert in fold_checksum_tree:
> ...
>   gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
>  <= sizeof (struct tree_function_decl))
> && sizeof (struct tree_type) <= sizeof (struct 
> tree_function_decl));
> ...
> 
> This error is triggered with -enable-checking=fold.

Doh.  Thanks for the report.

The easy fix is s/tree_type/tree_type_non_common/.  But I don't see why the
assert has to even care about tree_type; doesn't:

  gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
  <= sizeof (union tree_node));

accomplish the same thing?

-Nathan




Re: external declaration of dominance debug functions

2011-05-23 Thread Nathan Froyd
On 05/23/2011 04:23 PM, Richard Guenther wrote:
>> So I don't buy Richie's argument. Otherwise, someone would propose a
>> patch to remove the hundreds of debug_ declarations in public header
>> files (i.e. those visible to plugins), and if he did, I hope such a
>> naughty patch won't be accepted.
> 
> Such a patch would be pre-approved by me ;)  Watch for not breaking
> -Wstrict-prototypes and move them to their respective .c file.

JFTR, the reason some of the prototypes are in headers are that they are
*gasp* needed by multiple files in GCC (debug_tree comes to mind).  Removing
the ones that aren't so needed would be useful, but you can't delete them all
willy-nilly.

-Nathan





Re: [PING][PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED

2011-05-24 Thread Nathan Froyd
`0On Mon, May 23, 2011 at 04:58:06PM +0200, Richard Guenther wrote:
> On Mon, May 23, 2011 at 4:18 PM, Nathan Froyd  
> wrote:
> > On 05/17/2011 11:31 AM, Nathan Froyd wrote:
> >> On 05/10/2011 04:18 PM, Nathan Froyd wrote:
> >>> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
> >>>> After all that, we can finally make tree_exp inherit from typed_tree.
> >>>> Quite anticlimatic.
> >>>
> >>> Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html
> >>
> >> Ping^2.
> >
> > Ping^3 to put it in Richi's INBOX. ;)
> 
> Ok ;)
>
> Please check for sizeof () uses of the structs you touched sofar.
> ISTR a bug about fold-checking.

That doesn't apply here, because I'm not renaming the struct.  But I did
find some problems with LTO when I was rebootstrapping prior to
committing; not sure how I missed these the first time through, maybe I
was mistakenly compiling without LTO support.  Since we now have things
being dumped to LTO that don't have TREE_CHAIN, we need to take care to
not access TREE_CHAIN on such things, which the patch below does.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

gcc/
* tree.h (struct tree_exp): Inherit from struct tree_typed.
* tree.c (initialize_tree_contains_struct): Mark TS_EXP as TS_TYPED
instead of TS_COMMON.

gcc/lto/
* lto.c (lto_ft_typed): New function.
(lto_ft_common): Call it.
(lto_ft_constructor): Likewise.
(lto_ft_expr): Likewise.
(lto_fixup_prevailing_decls): Check for TS_COMMON before accessing
TREE_CHAIN.

diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index d64ba18..1067b51 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -254,14 +254,20 @@ remember_with_vars (tree t)
 
 static void lto_fixup_types (tree);
 
-/* Fix up fields of a tree_common T.  */
+/* Fix up fields of a tree_typed T.  */
 
 static void
-lto_ft_common (tree t)
+lto_ft_typed (tree t)
 {
-  /* Fixup our type.  */
   LTO_FIXUP_TREE (TREE_TYPE (t));
+}
+
+/* Fix up fields of a tree_common T.  */
 
+static void
+lto_ft_common (tree t)
+{
+  lto_ft_typed (t);
   LTO_FIXUP_TREE (TREE_CHAIN (t));
 }
 
@@ -398,7 +404,7 @@ lto_ft_constructor (tree t)
   unsigned HOST_WIDE_INT idx;
   constructor_elt *ce;
 
-  LTO_FIXUP_TREE (TREE_TYPE (t));
+  lto_ft_typed (t);
 
   for (idx = 0;
VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (t), idx, ce);
@@ -415,7 +421,7 @@ static void
 lto_ft_expr (tree t)
 {
   int i;
-  lto_ft_common (t);
+  lto_ft_typed (t);
   for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
 LTO_FIXUP_TREE (TREE_OPERAND (t, i));
 }
@@ -2029,7 +2035,8 @@ lto_fixup_prevailing_decls (tree t)
 {
   enum tree_code code = TREE_CODE (t);
   LTO_NO_PREVAIL (TREE_TYPE (t));
-  LTO_NO_PREVAIL (TREE_CHAIN (t));
+  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+LTO_NO_PREVAIL (TREE_CHAIN (t));
   if (DECL_P (t))
 {
   LTO_NO_PREVAIL (DECL_NAME (t));
diff --git a/gcc/tree.c b/gcc/tree.c
index 3357d84..9cc99fe 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -380,6 +380,7 @@ initialize_tree_contains_struct (void)
case TS_COMPLEX:
case TS_SSA_NAME:
case TS_CONSTRUCTOR:
+   case TS_EXP:
  MARK_TS_TYPED (code);
  break;
 
@@ -388,7 +389,6 @@ initialize_tree_contains_struct (void)
case TS_TYPE_COMMON:
case TS_LIST:
case TS_VEC:
-   case TS_EXP:
case TS_BLOCK:
case TS_BINFO:
case TS_STATEMENT_LIST:
diff --git a/gcc/tree.h b/gcc/tree.h
index 805fe06..142237f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1917,7 +1917,7 @@ enum omp_clause_default_kind
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, 
OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind)
 
 struct GTY(()) tree_exp {
-  struct tree_common common;
+  struct tree_typed typed;
   location_t locus;
   tree block;
   tree GTY ((special ("tree_exp"),


[PATCH PING] unreviewed tree-slimming patches

2011-05-25 Thread Nathan Froyd
These patches:

  (C, C++, middle-end)
  [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED
  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00560.html

  (C, Java, middle-end)
  [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE
  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00564.html

are still pending review.  Jason commented on the TS_STATEMENT_LIST patch, but
the discussion didn't come to a resolution.  I forgot to CC the TS_BLOCK patch
to the Java folks the first time around.

Thanks,
-Nathan


Re: [PATCH PING] unreviewed tree-slimming patches

2011-05-25 Thread Nathan Froyd
On 05/25/2011 02:06 PM, Tom Tromey wrote:
>>>>>> "Nathan" == Nathan Froyd  writes:
> 
> Nathan>   (C, Java, middle-end)
> Nathan>   [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE
> Nathan>   http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00564.html
> 
> The Java parts are ok.
> 
> I think these sorts of changes should be obvious once approved from a
> middle-end perspective, at least assuming that there are no regressions.
> 
> I mentioned this idea before but I didn't see any discussion of it.  I
> am happy to continue looking at patches like this if that is what the
> more active maintainers would prefer.

I think Jason mentioned considering them approved after waiting a week.  If we
want to enshrine that as policy, I think that'd be reasonable.  All in favor...?

-Nathan


Re: [PATCH][4.6] detect C++ errors to fix 2288 and 18770

2011-05-25 Thread Nathan Froyd
nt i;
  for (int i : a)
  {
int i;
  }

is incorrect (the innermost `i' is an erroneous redeclaration).  If you
apply the expansion of range-based for loops from [stmt.ranged]p1, you'd
get something like:

  for (...; ...; ...)
   {
 int i = ...;
 int i;
   }

which is bad.  I believe [basic.scope.local]p4 says much the same thing.

Tested with g++ testsuite on x86_64-unknown-linux-gnu; tests in progress
for libstdc++.  OK to commit?

-Nathan

gcc/cp/
2011-xx-xx  Janis Johnson  
Nathan Froyd  

PR c++/2288
PR c++/18770
    * name-lookup.h (enum scope_kind): Add sk_cond.
* name-lookup.c (pushdecl_maybe_friend): Get scope of shadowed local.
Detect and report error for redeclaration from for-init or if
or switch condition.
(begin_scope): Handle sk_cond.
* semantics.c (begin_if_stmt): Use sk_cond.
(begin switch_stmt): Ditto.

gcc/testsuite/
2011-xx-xx  Janis Johnson  
Nathan Froyd  

PR c++/2288
PR c++/18770
* g++.old-deja/g++.jason/cond.C: Remove xfails.
* g++.dg/parse/pr18770.C: New test.
* g++.dg/cpp0x/range-for5.C: Add dg-error marker.

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index bb6d4b9..723f36f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -957,8 +957,15 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
   else
{
  /* Here to install a non-global value.  */
- tree oldlocal = innermost_non_namespace_value (name);
  tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
+ tree oldlocal = NULL_TREE;
+ cxx_scope *oldscope = NULL;
+ cxx_binding *oldbinding = outer_binding (name, NULL, true);
+ if (oldbinding)
+   {
+ oldlocal = oldbinding->value;
+ oldscope = oldbinding->scope;
+   }
 
  if (need_new_binding)
{
@@ -1087,6 +1094,20 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
   }
   }
}
+ /* Error if redeclaring a local declared in a
+for-init-statement or in the condition of an if or
+switch statement when the new declaration is in the
+outermost block of the controlled statement.
+Redeclaring a variable from a for or while condition is
+detected elsewhere.  */
+ else if (TREE_CODE (oldlocal) == VAR_DECL
+  && oldscope == current_binding_level->level_chain
+  && (oldscope->kind == sk_cond
+  || oldscope->kind == sk_for))
+   {
+ error ("redeclaration of %q#D", x);
+ error ("%q+#D previously declared here", oldlocal);
+   }
 
  if (warn_shadow && !nowarn)
{
@@ -1446,6 +1467,7 @@ begin_scope (scope_kind kind, tree entity)
 case sk_try:
 case sk_catch:
 case sk_for:
+case sk_cond:
 case sk_class:
 case sk_scoped_enum:
 case sk_function_parms:
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 4bf253f..90b56e4 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -109,6 +109,8 @@ typedef enum scope_kind {
   sk_catch, /* A catch-block.  */
   sk_for,   /* The scope of the variable declared in a
for-init-statement.  */
+  sk_cond,  /* The scope of the variable declared in the condition
+   of an if or switch statement.  */
   sk_function_parms, /* The scope containing function parameters.  */
   sk_class, /* The scope containing the members of a class.  */
   sk_scoped_enum,/* The scope containing the enumertors of a C++0x
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 55ad117..7833d76 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -656,7 +656,7 @@ tree
 begin_if_stmt (void)
 {
   tree r, scope;
-  scope = do_pushlevel (sk_block);
+  scope = do_pushlevel (sk_cond);
   r = build_stmt (input_location, IF_STMT, NULL_TREE,
  NULL_TREE, NULL_TREE, scope);
   begin_cond (&IF_COND (r));
@@ -1013,7 +1013,7 @@ begin_switch_stmt (void)
 {
   tree r, scope;
 
-  scope = do_pushlevel (sk_block);
+  scope = do_pushlevel (sk_cond);
   r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, 
NULL_TREE, scope);
 
   begin_cond (&SWITCH_STMT_COND (r));
diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for5.C 
b/gcc/testsuite/g++.dg/cpp0x/range-for5.C
index 9c97ad5..2fe4702 100644
--- a/gcc/testsuite/g++.dg/cpp0x/range-for5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/range-for5.C
@@ -49,6 +49,6 @@ void test1()
   int i;
   for (int i : a)
   {
-int i;
+int i; // { dg-error "redeclaration" }
   }
 }
diff --git a/gcc/testsuite/g++.dg/parse/pr18770.C 
b/g

Re: C++ PATCH for c++/45698 (crash with variadics)

2011-05-25 Thread Nathan Froyd
On 05/25/2011 03:45 PM, Jason Merrill wrote:
> While looking at this, I also noticed that print_node expects everything to
> have TREE_TYPE, which is no longer correct.

Technically, I think this is not true; everything inherits from tree_common;
or at least tree_typed.  (I had the bit of print_node fixing in one of my
patches; thanks for getting it in ahead of me!)  Once the STATEMENT_LIST and
BLOCK slimming patches are in, there will indeed be things that don't have
TREE_TYPE.  If something doesn't have TREE_TYPE, then the Right Thing to do
would be to fix the tree structure so that it only inherits from tree_base.

Like the following (totally untested) patch.  WDYT?  (It's certainly possible
that other C++-specific trees could be modified in the same way;
tree_static_assert jumps out, for instance.)

-Nathan

gcc/cp/
* cp-tree.h (struct tree_argument_pack_select): Inherit from
tree_base.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ada01fb..a315986 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -534,7 +534,7 @@ struct GTY (()) tree_static_assert {
 };

 struct GTY (()) tree_argument_pack_select {
-  struct tree_common common;
+  struct tree_base base;
   tree argument_pack;
   int index;
 };


Re: [PATCH][4.6] detect C++ errors to fix 2288 and 18770

2011-05-25 Thread Nathan Froyd
On Wed, May 25, 2011 at 03:22:07PM -0400, Nathan Froyd wrote:
> The patch just requires some shuffling of logic to catch issues now;
> below is a version that works for me on the trunk.
> 
> This new checking does require modifying g++.dg/cpp0x/range-for5.C.
> 
> Tested with g++ testsuite on x86_64-unknown-linux-gnu; tests in progress
> for libstdc++.  OK to commit?

Below is a slightly revised patch that actually adds all the necessary
dg-error directives to range-for5.C.  Tested the same way; Peter Bergner
was kind enough to bootstrap and test the previous patch on
powerpc64-linux-gnu with (almost) clean results as well.

gcc/cp/
2011-xx-xx  Janis Johnson  
    Nathan Froyd  

PR c++/2288
PR c++/18770
* name-lookup.h (enum scope_kind): Add sk_cond.
* name-lookup.c (pushdecl_maybe_friend): Get scope of shadowed local.
Detect and report error for redeclaration from for-init or if
or switch condition.
(begin_scope): Handle sk_cond.
* semantics.c (begin_if_stmt): Use sk_cond.
(begin switch_stmt): Ditto.

gcc/testsuite/
2011-xx-xx  Janis Johnson  
    Nathan Froyd  

PR c++/2288
PR c++/18770
* g++.old-deja/g++.jason/cond.C: Remove xfails.
* g++.dg/parse/pr18770.C: New test.
* g++.dg/cpp0x/range-for5.C: Add dg-error marker.

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index bb6d4b9..723f36f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -957,8 +957,15 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
   else
{
  /* Here to install a non-global value.  */
- tree oldlocal = innermost_non_namespace_value (name);
  tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
+ tree oldlocal = NULL_TREE;
+ cxx_scope *oldscope = NULL;
+ cxx_binding *oldbinding = outer_binding (name, NULL, true);
+ if (oldbinding)
+   {
+ oldlocal = oldbinding->value;
+ oldscope = oldbinding->scope;
+   }
 
  if (need_new_binding)
{
@@ -1087,6 +1094,20 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend)
   }
   }
}
+ /* Error if redeclaring a local declared in a
+for-init-statement or in the condition of an if or
+switch statement when the new declaration is in the
+outermost block of the controlled statement.
+Redeclaring a variable from a for or while condition is
+detected elsewhere.  */
+ else if (TREE_CODE (oldlocal) == VAR_DECL
+  && oldscope == current_binding_level->level_chain
+  && (oldscope->kind == sk_cond
+  || oldscope->kind == sk_for))
+   {
+ error ("redeclaration of %q#D", x);
+ error ("%q+#D previously declared here", oldlocal);
+   }
 
  if (warn_shadow && !nowarn)
{
@@ -1446,6 +1467,7 @@ begin_scope (scope_kind kind, tree entity)
 case sk_try:
 case sk_catch:
 case sk_for:
+case sk_cond:
 case sk_class:
 case sk_scoped_enum:
 case sk_function_parms:
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 4bf253f..90b56e4 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -109,6 +109,8 @@ typedef enum scope_kind {
   sk_catch, /* A catch-block.  */
   sk_for,   /* The scope of the variable declared in a
for-init-statement.  */
+  sk_cond,  /* The scope of the variable declared in the condition
+   of an if or switch statement.  */
   sk_function_parms, /* The scope containing function parameters.  */
   sk_class, /* The scope containing the members of a class.  */
   sk_scoped_enum,/* The scope containing the enumertors of a C++0x
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 55ad117..7833d76 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -656,7 +656,7 @@ tree
 begin_if_stmt (void)
 {
   tree r, scope;
-  scope = do_pushlevel (sk_block);
+  scope = do_pushlevel (sk_cond);
   r = build_stmt (input_location, IF_STMT, NULL_TREE,
  NULL_TREE, NULL_TREE, scope);
   begin_cond (&IF_COND (r));
@@ -1013,7 +1013,7 @@ begin_switch_stmt (void)
 {
   tree r, scope;
 
-  scope = do_pushlevel (sk_block);
+  scope = do_pushlevel (sk_cond);
   r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, 
NULL_TREE, scope);
 
   begin_cond (&SWITCH_STMT_COND (r));
diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for5.C 
b/gcc/testsuite/g++.dg/cpp0x/range-for5.C
index 9c97ad5..fd6f761 100644
--- a/gcc/testsuite/g++.dg/cpp0x/range-for5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/range-for5.C
@@ -47,8 +47,8 @@ voi

Re: [PATCH PING] unreviewed tree-slimming patches

2011-05-25 Thread Nathan Froyd
On 05/25/2011 10:18 AM, Jason Merrill wrote:
> On 05/25/2011 10:00 AM, Nathan Froyd wrote:
>> Jason commented on the TS_STATEMENT_LIST patch, but
>> the discussion didn't come to a resolution.
> 
> Right, from your last mail I thought that you were investigating my question
> about add_stmt and your suggestion about dropping the NULL checking in
> append_to_statement_list_1.

Ah, OK.  That was not clear to me.

I stand by what I said about add_stmt.  Before, if we weren't
building_stmt_tree (i.e. cur_stmt_list was NULL), we'd just pass a pointer to
NULL into append_to_statement_list and append_to_statement_list would DTRT.
Now if we have a NULL stack, then passing a pointer to the stack doesn't work,
because it's not typed correctly and we'd be clobbering the VEC, not pushing
onto the stack.

An alternative solution would be to initialize cur_stmt_list somewhere with an
actual 1-element VEC; the check in add_stmt would then be unnecessary, as we'd
always be assured of having someplace in the stack to store it.  I don't trust
myself to write a patch like that tonight; I'll twiddle with that tomorrow.

As to the NULL checking in append_to_statement_list_1, I was being hasty and
naive.  There are scores of places throughout the compiler that depend on this
behavior; I don't think it's worthwhile to change all the callers to ensure
the pointer-to-statement_list points to a non-NULL thing.

-Nathan



Re: [PATCH PING] unreviewed tree-slimming patches

2011-05-26 Thread Nathan Froyd
On 05/26/2011 09:39 AM, Jason Merrill wrote:
> On 05/25/2011 10:21 PM, Nathan Froyd wrote:
>> An alternative solution would be to initialize cur_stmt_list somewhere with 
>> an
>> actual 1-element VEC;
> 
> Or just push NULL onto the stack and let append_to_statement_list_1 allocate
> the VEC?

Did you misspeak here?  append_to_statement_1 shouldn't be caring about VECs.
 Or do you mean pushing NULL_TREE someplace else, as in:

>> the check in add_stmt would then be unnecessary, as we'd
>> always be assured of having someplace in the stack to store it.  I don't 
>> trust
>> myself to write a patch like that tonight; I'll twiddle with that tomorrow.
> 
> Right, that's what I was thinking about.  I think we should only need to do
> this once per function.

...here?

-Nathan



Re: [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE

2011-05-26 Thread Nathan Froyd
On Thu, Mar 10, 2011 at 11:23:26PM -0500, Nathan Froyd wrote:
> Now that we've  encapsulated all uses of BLOCK_CHAINON properly, we can
> make BLOCKs inherit from tree_base and redirect BLOCK_CHAINON to use a
> tree_block-private field instead of tree_common's chain.  Doing so saves
> the never-used TREE_TYPE field.

This patch was approved:

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00564.html
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg01844.html

However, during retesting, I hit problems in find_decls_types_r; the
following bit of code doesn't work if your trees don't have TREE_TYPE:

  if (TREE_CODE (t) != IDENTIFIER_NODE)
fld_worklist_push (TREE_TYPE (t), fld);

This didn't show up when I was developing the patch, since the
adjustments to IDENTIFIER_NODE:

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00561.html

had done:

@@ -4795,7 +4791,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
   fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
 }
 
-  fld_worklist_push (TREE_TYPE (t), fld);
+  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
+fld_worklist_push (TREE_TYPE (t), fld);
 
   return NULL_TREE;
 }

And the later BLOCK-adjusting made use of that bit.  Given that removing
TREE_TYPE from IDENTIFIER_NODE required more invasive surgery than I'm
qualified to do at this point, that bit (and several others) got
dropped, leading to our present situation.

Since Richi approved the IDENTIFIER_NODE changes, I feel justified in
committing the slightly tweaked patch below.  The relevant bit that
wasn't in the initial mail is:

@@ -4892,7 +4892,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
   fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
 }
 
-  if (TREE_CODE (t) != IDENTIFIER_NODE)
+  if (TREE_CODE (t) != IDENTIFIER_NODE
+  && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
 fld_worklist_push (TREE_TYPE (t), fld);
 
   return NULL_TREE;

If people feel that checking TREE_CODE for BLOCK or just 'return'ing
from the BLOCK block just above would be more appropriate, I can commit
that as a followup patch.

Tested on x86_64-unknown-linux-gnu.  Committed as r174300.

-Nathan

gcc/
* tree.c (initialize_tree_contains_struct): Mark TS_BLOCK as
TS_BASE instead of TS_COMMON.
* tree.h (struct tree_block): Inherit from tree_base, not tree_common.
Add chain field.
(BLOCK_CHAIN): Use new chain field.

gcc/c-family/
* c-common.c (warning_candidate_p): Check for BLOCKs.

gcc/java/
* decl.c (poplevel): Don't access TREE_TYPE of BLOCKs.
* expr.c (build_jni_stub): Likewise.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 2d4e492..fa7ebc5 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2367,6 +2367,9 @@ warning_candidate_p (tree x)
   if (DECL_P (x) && DECL_ARTIFICIAL (x))
 return 0;
 
+  if (TREE_CODE (x) == BLOCK)
+return 0;
+
   /* VOID_TYPE_P (TREE_TYPE (x)) is workaround for cp/tree.c
  (lvalue_p) crash on TRY/CATCH. */
   if (TREE_TYPE (x) == NULL_TREE || VOID_TYPE_P (TREE_TYPE (x)))
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 47b4ebe..e958136 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1425,10 +1425,7 @@ poplevel (int keep, int reverse, int functionbody)
 
   block = 0;
   if (keep || functionbody)
-{
-  block = make_node (BLOCK);
-  TREE_TYPE (block) = void_type_node;
-}
+block = make_node (BLOCK);
 
   if (current_binding_level->exception_range)
 expand_end_java_handler (current_binding_level->exception_range);
@@ -1456,7 +1453,7 @@ poplevel (int keep, int reverse, int functionbody)
}
  *var = NULL;

- bind = build3 (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block), 
+ bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 
 BLOCK_EXPR_BODY (block), block);
  BIND_EXPR_BODY (bind) = current_binding_level->stmts;
  
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 3be1cff..b9293e0 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -2649,7 +2649,6 @@ build_jni_stub (tree method)
   method_args = DECL_ARGUMENTS (method);
   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
   TREE_SIDE_EFFECTS (block) = 1;
-  TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
 
   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
   body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
diff --git a/gcc/tree.c b/gcc/tree.c
index 1dfad04..d5b5dac 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -368,6 +368,7 @@ initialize_tree_contains_struct (void)
   switch (ts_code)
{
case TS_TYPED:
+   case TS_BLOCK:
  MARK_TS_BASE (code);
  break;
 
@@ -389,7 +390,6 @@ initialize_tree_contains_struct (void)
case TS_TYPE_COMMON:
case TS_LIST:
 

Re: [PATCH PING] unreviewed tree-slimming patches

2011-05-26 Thread Nathan Froyd
On Thu, May 26, 2011 at 09:39:30AM -0400, Jason Merrill wrote:
> On 05/25/2011 10:21 PM, Nathan Froyd wrote:
> >An alternative solution would be to initialize cur_stmt_list somewhere with 
> >an
> >actual 1-element VEC;
> 
> Or just push NULL onto the stack and let append_to_statement_list_1
> allocate the VEC?
> 
> >the check in add_stmt would then be unnecessary, as we'd
> >always be assured of having someplace in the stack to store it.  I don't 
> >trust
> >myself to write a patch like that tonight; I'll twiddle with that tomorrow.
> 
> Right, that's what I was thinking about.  I think we should only
> need to do this once per function.

Sigh, I am an idiot.  It appears that we always have something pushed by
the time add_stmt is called.  (I ran into problems implementing the
above approach, as I wound up with [ NULL_TREE,  ] and that gave
pop_stmt heartburn.)  I can't recall why I added the check in the first
place; it might have been because I ran into problems in the C FE and
blindly assumed I needed the same fix in the C++ FE.

Below is a revised patch with the dubious code taken out of add_stmt and
an assert added.  Bootstrap/testing in progress on
x86_64-unknown-linux-gnu, but we've built libstdc++ a couple of times,
so I don't anticipate any surprises.  OK to commit?

-Nathan

gcc/
* c-decl.c (c_push_function_context): Copy the current statement
list stack.
(add_stmt): Check building_stmt_list_p and push_stmt if necessary.
(finish_struct): Call building_stmt_list_p instead of checking
cur_stmt_list.
* c-parser.c (c_parser_postfix_expression): Likewise.
* c-typeck.c (c_end_compound_stmt): Likewise.
* print-tree.c (print_node) [STATEMENT_LIST]: Don't print TREE_CHAIN.
* tree-iterator.c (stmt_list_cache): Change to a VEC.
(alloc_stmt_list): Adjust for stmt_list_cache's new type.
(free_stmt_list): Likewise.
* tree.h (struct tree_statement_list): Include typed_tree instead
of tree_common.
* tree.c (initialize_tree_contains_struct): Mark TS_STATEMENT_LIST
as TS_TYPED instead of TS_COMMON.

gcc/c-family/
* c-common.h (struct stmt_tree_s) [x_cur_stmt_list]: Change to a VEC.
(stmt_list_stack): Define.
(cur_stmt_list): Adjust for new type of x_cur_stmt_list.
* c-semantics.c (push_stmt_list, pop_stmt_list): Likewise.

gcc/cp/
* cp-tree.h (building_stmt_tree): Delete.
* decl.c (save_function_data): Tweak initializer for x_cur_stmt_list.
(build_aggr_init_full_exprs): Call building_stmt_list_p
instead of building_stmt_tree.
(initialize_local_var): Likewise.
(finish_function): Likewise.
* decl2.c (finish_anon_union): Likewise.
* init.c (begin_init_stmts): Likewise.
(finish_init_stmts): Likewise.
(expand_aggr_init_1): Likewise.
* name-lookup.c (do_local_using_decl): Likewise.
(do_namespace_alias): Likewise.
(do_using_directive): Likewise.
(cp_emit_debug_info_for_using): Likewise.
* semantics.c (add_stmt): Assert that stmt_list_stack is non-empty.

diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index a7cc965..1d43126 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -552,6 +552,8 @@ add_stmt (tree t)
 
   /* Add T to the statement-tree.  Non-side-effect statements need to be
  recorded during statement expressions.  */
+  if (!building_stmt_list_p ())
+push_stmt_list ();
   append_to_statement_list_force (t, &cur_stmt_list);
 
   return t;
@@ -7188,7 +7190,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
   /* If we're inside a function proper, i.e. not file-scope and not still
  parsing parameters, then arrange for the size of a variable sized type
  to be bound now.  */
-  if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE))
+  if (building_stmt_list_p () && variably_modified_type_p (t, NULL_TREE))
 add_stmt (build_stmt (loc,
  DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
 
@@ -8424,6 +8426,8 @@ c_push_function_context (void)
   cfun->language = p;
 
   p->base.x_stmt_tree = c_stmt_tree;
+  c_stmt_tree.x_cur_stmt_list
+= VEC_copy (tree, gc, c_stmt_tree.x_cur_stmt_list);
   p->x_break_label = c_break_label;
   p->x_cont_label = c_cont_label;
   p->x_switch_stack = c_switch_stack;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 65f8ad1..1b658b1 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -452,8 +452,8 @@ typedef enum ref_operator {
 /* Information about a statement tree.  */
 
 struct GTY(()) stmt_tree_s {
-  /* The current statement list being collected.  */
-  tree x_cur_stmt_list;
+  /* A stack of statement lists being collected.  */
+  VEC(tree,gc) *x_cur_st

Re: [pph] More C++ Tree Nodes (issue4526083)

2011-05-26 Thread Nathan Froyd
On 05/26/2011 10:24 PM, Lawrence Crowl wrote:
> Index: gcc/cp/cp-objcp-common.c
> ===
> --- gcc/cp/cp-objcp-common.c  (revision 174301)
> +++ gcc/cp/cp-objcp-common.c  (working copy)
> @@ -99,6 +99,8 @@ cp_tree_size (enum tree_code code)
>  
>  case TEMPLATE_INFO: return sizeof (struct tree_template_info);
>  
> +case TREE_BINFO:return sizeof (struct tree_binfo);
> +
>  default:
>gcc_unreachable ();
>  }

This does not look right; TREE_BINFO is a variable-sized structure (and is not
C++-specific in any event).  Maybe you should be using tree_size instead of
tree_code_size someplace?

-Nathan


MAINTAINERS: update my email address

2011-05-27 Thread Nathan Froyd
As $SUBJECT suggests.

-Nathan

* MAINTAINERS (Write After Approval): Update my email address.

Index: MAINTAINERS
===
--- MAINTAINERS (revision 174345)
+++ MAINTAINERS (working copy)
@@ -352,7 +352,7 @@ Li Feng 
nemoking...@gmail.com
 Thomas Fitzsimmons fitz...@redhat.com
 Brian Ford f...@vss.fsi.com
 John Freeman   jfreema...@gmail.com
-Nathan Froyd   froy...@codesourcery.com
+Nathan Froyd   froy...@gcc.gnu.org
 Chao-ying Fu   f...@mips.com
 Gary Funck g...@intrepid.com
 Pompapathi V Gadad pompapathi.v.ga...@nsc.com


[PATCH,C/C++/ObjC/C++] get rid of build_function_call

2011-06-17 Thread Nathan Froyd
build_function_call uses an outdated interface (a TREE_LIST containing
the arguments passed to the function) and is only used by the ObjC/C++
FEs.  The patch below deletes it and introduces a new
build_function_call_nary interface modeled after
cp_build_function_call_nary.

The C/C++ changes are minimal; the bulk of the patch is dealing with
objc-act.c.  I took the liberty of cleaning up a few
build_function_call_vec calls to use build_function_call_nary where
appropriate.

The objc_runtime_hooks.build_objc_method_call interface could use some
cleanup after this conversion so as to not build TREE_LISTs that
eventually get converted into VECs, but doing that cleanup requires some
invasive surgery (brought on by
objcp_tsubst_copy_and_build:MESSAGE_SEND_EXPR).

Tested on x86_64-unknown-linux-gnu with the appropriate testsuites.  OK
to commit?

-Nathan

gcc/c-family/
* c-common.h (build_function_call): Delete.
(build_function_call_nary): Declare.

gcc/
* c-typeck.c (build_function_call): Delete.
(build_function_call_nary): New function.
(build_function_call_vec): Call build_function_call_nary instead.

gcc/cp/
* cp-tree.h (cp_build_function_call): Delete.
* decl.c (register_dtor_fn): Update comment.
* typeck.c (build_function_call): Delete.
(cp_build_function_call): Delete.
(build_function_call_nary_1): New function, split out from...
(cp_build_function_call_nary): ...here.  Call it.
(build_function_call_nary): New function.

gcc/objc/
* objc-act.c (objc_build_ivar_assignment): Call
build_function_call_nary instead of build_function_call.
(objc_build_global_assignment): Likewise.
(objc_build_strong_cast_assignment): Likewise.
(objc_build_synchronized): Likewise.
(objc_synthesize_getter, objc_synthesize_setter): Likewise.
(objc_finish_foreach_loop): Likewise.
* objc-gnu-runtime-abi-01.c
(gnu_runtime_abi_01_get_class_reference): Likewise.
(build_objc_method_call): Likewise.
(gnu_runtime_abi_01_get_category_super_ref): Likewise.
(build_module_initializer_routine): Likewise.
(objc_generate_static_init_call): Likewise.
(build_throw_stmt): Likewise.
* objc-next-runtime-abi-01.c
(next_runtime_abi_01_get_class_reference): Likewise.
(next_runtime_abi_01_get_category_super_ref): Likewise.
(next_sjlj_build_try_exit): Likewise.
(next_sjlj_build_enter_and_setjmp): Likewise.
(next_sjlj_build_exc_extract): Likewise.
(next_sjlj_build_catch_list): Likewise.
(next_sjlj_build_try_catch_finally): Likewise.
(build_throw_stmt): Likewise.
* objc-next-runtime-abi-02.c
(next_runtime_abi_02_get_class_reference): Likewise.
(next_runtime_abi_02_get_category_super_ref): Likewise.
(build_v2_build_objc_method_call): Likewise.
(build_throw_stmt): Likewise.
(begin_catch, finish_catch): Likewise.

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index c63b40d..7325b64 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -867,8 +867,8 @@ extern tree c_add_case_label (location_t, splay_tree, tree, 
tree, tree, tree);
 
 extern void c_do_switch_warnings (splay_tree, location_t, tree, tree);
 
-extern tree build_function_call (location_t, tree, tree);
-
+extern tree build_function_call_nary (location_t, tree, ...)
+  ATTRIBUTE_SENTINEL;
 extern tree build_function_call_vec (location_t, tree,
 VEC(tree,gc) *, VEC(tree,gc) *);
 
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index a451606..5ffbe4b 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -2654,24 +2654,24 @@ c_expr_sizeof_type (location_t loc, struct c_type_name 
*t)
   return ret;
 }
 
-/* Build a function call to function FUNCTION with parameters PARAMS.
-   The function call is at LOC.
-   PARAMS is a list--a chain of TREE_LIST nodes--in which the
-   TREE_VALUE of each node is a parameter-expression.
-   FUNCTION's data type may be a function type or a pointer-to-function.  */
+/* Build a function call to function FUNCTION with parameters passed
+   as varargs, terminated with NULL_TREE.  The function call is at LOC.  */
 
 tree
-build_function_call (location_t loc, tree function, tree params)
+build_function_call_nary (location_t loc, tree function, ...)
 {
-  VEC(tree,gc) *vec;
-  tree ret;
+  VEC(tree,gc) *v = make_tree_vector ();
+  va_list args;
+  tree t;
 
-  vec = VEC_alloc (tree, gc, list_length (params));
-  for (; params; params = TREE_CHAIN (params))
-VEC_quick_push (tree, vec, TREE_VALUE (params));
-  ret = build_function_call_vec (loc, function, vec, NULL);
-  VEC_free (tree, gc, vec);
-  return ret;
+  va_start (args, function);
+  for (t = va_arg (args, tree) ; t != NULL_TREE; t = va_arg (args, tree))
+VEC_safe_push (tree, gc, v, t);
+  va_end (args);
+
+  t = build_function_

[PATCH] parallelize g++ testing a bit more

2011-06-17 Thread Nathan Froyd
I've done a lot of g++-only testsuite runs lately and I noticed that it
didn't parallelize all that well.  The patch below adds a couple more
.exp files to the parallel infrastructure.  dg-torture.exp is the big
one; it takes about as much time as old-deja.exp.

Other valid candidates are lto.exp and debug.exp, but the patch cuts g++
testing time in half as-is, so I felt it was a sufficient stopping
point.

OK to commit?

-Nathan

gcc/cp/
* Make-lang.in (check_g++_parallelize): Add more .exp files.

diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 45efd67..95bae37 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -154,7 +154,7 @@ check-c++-subtargets : check-g++-subtargets
 lang_checks += check-g++
 lang_checks_parallelized += check-g++
 # For description see comment above check_gcc_parallelize in gcc/Makefile.in.
-check_g++_parallelize = old-deja.exp dg.exp
+check_g++_parallelize = old-deja.exp dg.exp dg-torture.exp struct-layout-1.exp
 
 #
 # Install hooks:


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

2011-07-15 Thread Nathan Froyd

On 7/9/2011 8: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.


+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);

Did you mean to call vfprintf here?  (And I guess the recent patches for 
the CAF support need to be changed accordingly as well...)


-Nathan


Re: [PATCH] add statistics counting to postreload, copy-rename, and math-opts

2011-04-12 Thread Nathan Froyd
On Tue, Apr 12, 2011 at 04:27:01PM +0200, Richard Guenther wrote:
> On Tue, Apr 12, 2011 at 4:16 PM, Nathan Froyd  
> wrote:
> > It's a shame more passes don't make use of the statistics_*
> > infrastructure.  This patch is a step towards rectifying that and adds
> > statistics_counter_event calls to passes mentioned in $SUBJECT.
> > postreload-gcse already tracked the stats for the dump file and so only
> > needs the statistics_counter_event calls; the other passes needed to be
> > taught about the statistics also.
> 
> Ok if there are no complaints within 24h.  I actually have a local patch
> adding many of these which I use whenever fiddling with the pass pipeline ...
> (attached).

Thanks.  I may go twiddle that patch to do something similar to mine and
submit that.  Do you use your patch for checking that the same set of
optimizations get performed, then?  I'm interested in using the
statistics for identifying passes that don't buy us much across a wide
variety of codebases.  (Suggestions for suitable ones welcome!)

-Nathan


Re: [PATCH] add statistics counting to postreload, copy-rename, and math-opts

2011-04-12 Thread Nathan Froyd
On Tue, Apr 12, 2011 at 04:37:42PM +0200, Richard Guenther wrote:
> On Tue, Apr 12, 2011 at 4:32 PM, Nathan Froyd  
> wrote:
> > Thanks.  I may go twiddle that patch to do something similar to mine and
> > submit that.  Do you use your patch for checking that the same set of
> > optimizations get performed, then?  I'm interested in using the
> > statistics for identifying passes that don't buy us much across a wide
> > variety of codebases.  (Suggestions for suitable ones welcome!)
> 
> Yes, I used it exactly for that.  And also to verify that passes don't
> do anything if replicated (well, for those that shouldn't at least).
> 
> Don't expect any low-hanging fruit though ;)  I catched all of it already.
> 
> Candidates are obviously SPEC and GCC itself.  I also use tramp3d
> of course.  That said, even if a pass does nearly nothing we often
> have testcases that need it ...

True, but maybe those testcases should be adjusted--per-pass flags,
rather than blindly assuming -O2 includes them.  And it's not clear to
me that the statistics_counter_event infrastructure really helps
catching do-nothing passes, since it doesn't record stats that increment
by zero...

-Nathan


Re: [PATCH] add statistics counting to postreload, copy-rename, and math-opts

2011-04-12 Thread Nathan Froyd
On Tue, Apr 12, 2011 at 04:54:43PM +0200, Richard Guenther wrote:
> On Tue, Apr 12, 2011 at 4:51 PM, Nathan Froyd  
> wrote:
> > True, but maybe those testcases should be adjusted--per-pass flags,
> > rather than blindly assuming -O2 includes them.  And it's not clear to
> 
> It's easier to add things to GCC than to argue removing things ...

And sometimes not even easy to argue for adding things. :)

> > me that the statistics_counter_event infrastructure really helps
> > catching do-nothing passes, since it doesn't record stats that increment
> > by zero...
> 
> Well, if the overall count is zero then nothing was done.

Granted, but that fact should still be recorded.  The situation we have
today, for something like:

func1: statistic for "statx" was 0
  - nothing is recorded in the statistics table
func2: statistic for "statx" was 0
  - nothing is recorded in the statistics table
func3: statistic for "statx" was 0
  - nothing is recorded in the statistics table
...

and so forth, is that at the end of the day, the dump file won't even
include any information about "statx".  If you had some func7387 where
"statx" was non-zero, you could infer that nothing else happened in the
previous 7386 functions.  For the case where a pass is truly useless on
a TU, it's hard to figure out from the statistics dump alone.  And I'd
argue that it's useful to see explicitly that the pass only helped in 1
out of 7387 functions, rather than trying to infer it from missing data.

-Nathan


Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses

2011-04-12 Thread Nathan Froyd
On Thu, Mar 10, 2011 at 11:23:10PM -0500, Nathan Froyd wrote:
> Now that we have a structure where not every node might include
> TREE_CHAIN or TREE_TYPE, we need to make sure that when we call said
> accessors that the argument is properly typed.  This requires a number
> of changes:

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00565.html

Ping.  I was going to commit this, but I realized I hadn't received
approval for the go or LTO bits.  They probably qualify as obvious,
given that they're exactly the same as all the other languages, but just
to rubber-stamp everything...

> gcc/go/
>   * go-lang.c (union lang_tree_node): Check for TS_COMMON before
>   calling TREE_CHAIN.
> 
> gcc/lto/
>   * lto-tree.h (union lang_tree_node): Check for TS_COMMON before
>   calling TREE_CHAIN.
>   * lto.c (lto_fixup_common): Likewise.

Thanks,
-Nathan


Re: [PATCH] add statistics counting to postreload, copy-rename, and math-opts

2011-04-13 Thread Nathan Froyd
On Wed, Apr 13, 2011 at 11:07:15AM +0200, Richard Guenther wrote:
> On Tue, Apr 12, 2011 at 5:09 PM, Nathan Froyd  
> wrote:
> > Granted, but that fact should still be recorded.  The situation we have
> > today, for something like:
> >
> > func1: statistic for "statx" was 0
> >  - nothing is recorded in the statistics table
> > func2: statistic for "statx" was 0
> >  - nothing is recorded in the statistics table
> > func3: statistic for "statx" was 0
> >  - nothing is recorded in the statistics table
> > ...
> >
> > and so forth, is that at the end of the day, the dump file won't even
> > include any information about "statx".  If you had some func7387 where
> > "statx" was non-zero, you could infer that nothing else happened in the
> > previous 7386 functions.  For the case where a pass is truly useless on
> > a TU, it's hard to figure out from the statistics dump alone.  And I'd
> > argue that it's useful to see explicitly that the pass only helped in 1
> > out of 7387 functions, rather than trying to infer it from missing data.
> 
> I always use statistics-stats (thus, overall stats, not per function).  The
> per function ones omit zero counts during dumping on purpose
> (to make the dump smaller).

I didn't know about statistics-stats (or didn't realize that's what the
code was trying to do), that's useful.  And it looks like all the
statistics dumping things omit zero counts on purpose, not just the
per-function ones.

But that has no bearing on the point above: zero counts are not even
*recorded* today.  E.g. if you apply the patch upthread, grab a random C
file, compile it with -O2/3 -fdump-statistics/-stats, and examine the
dump file, you might not even know that new statistics counters have
been added.  Taking out the checks to avoid printing zero counts doesn't
help either, because the data simply doesn't get recorded.  This
infrastructure makes it somewhat difficult to figure out, in an
automated way from the dump file alone, whether passes are actually
doing anything.

Enough grousing.  I'm assuming turning on accumulation and dumping of
zero counts always would be frowned upon; would it be acceptable to turn
accumulation and dumping of zero counts if -details is given?

-Nathan


Re: [PATCH PING] c++-specific bits of tree-slimming patches

2011-04-14 Thread Nathan Froyd
On Fri, Apr 08, 2011 at 01:50:24PM -0400, Jason Merrill wrote:
> On 03/24/2011 09:15 AM, Nathan Froyd wrote:
>> +  tree t = make_node (CASE_LABEL_EXPR);
>> +
>> +  TREE_TYPE (t) = void_type_node;
>> +  SET_EXPR_LOCATION (t, input_location);
>
> As jsm and richi said, using input_location like this is a regression.  
> Can we use DECL_SOURCE_LOCATION (label_decl) instead?

Sure.  Joseph, Richi, are you happy with that change?  It would fix the
C/C++ regression, as c_add_case_label does:

  /* Create the LABEL_DECL itself.  */
  label = create_artificial_label (loc);
  ...
  /* Add a CASE_LABEL to the statement-tree.  */
  case_label = add_stmt (build_case_label (loc, low_value, high_value, label));

so the DECL_SOURCE_LOCATION would be the same as the location_t we were
passing in anyway.  For the other languages, I think it would be neutral
or an improvement (they all use input_location or UNKNOWN_LOCATION for
the CASE_LABEL anyway).

>>[PATCH 11/18] mark EXPR_PACK_EXPANSION as typed only
>>http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00563.html
>
> It looks like you need to add EXPR_PACK_EXPANSION cases to  
> value_dependent_expression_p and cp_tree_equal.  Maybe split out the  
> code from write_expression that overrides TREE_OPERAND_LENGTH in some  
> cases and use that new function instead of TREE_OPERAND_LENGTH in these  
> places.

Thanks for catching this, will do.

-Nathan


Re: [PATCH,c++] fix PR objc++/48479, ICE in cxx_mark_addressable

2011-04-14 Thread Nathan Froyd
On Thu, Apr 07, 2011 at 09:37:17AM -0400, Nathan Froyd wrote:
> My recent patch removing DECL_RTL from CONST_DECLs caused regressions in
> the ObjC++ testsuite on Darwin targets.  The problem is that
> DECL_REGISTER was being called on CONST_DECLs; DECL_REGISTER says:
> 
> /* In VAR_DECL and PARM_DECL nodes, nonzero means declared `register'.  */
> #define DECL_REGISTER(NODE) (DECL_WRTL_CHECK (NODE)->decl_common.decl_flag_0)
> 
> Previously, the DECL_WRTL_CHECK was succeeding when given CONST_DECLs;
> it no longer does.
> 
> The suggested fix is to simply move the CONST_DECL case in
> cxx_mark_addressable; since DECL_REGISTER would have always returned
> false for CONST_DECLs, there's no change in functionality.  Fixing
> DECL_REGISTER to accurately reflect its comment would be helpful, but
> there are other ICEs to fix if DECL_REGISTER only takes PARM_DECL and
> VAR_DECL; I thought it best to submit that as a separate fix, if at all.
> 
> Patch was tested on Darwin targets via IainS and Dominique and fixed the
> regression. OK to commit?

Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-04/msg00548.html

-Nathan


[PATCH] factor asm op chaining out from stmt.c:expand_asm_stmt

2011-04-15 Thread Nathan Froyd
There are several cut-and-pasted loops in expand_asm_stmt that could be
parameterized by the functions used to access the particular operands.
The patch below does that.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

 * stmt.c (chain_asm_ops): New function.
(expand_asm_stmt): Call it.

diff --git a/gcc/stmt.c b/gcc/stmt.c
index 1a9f9e5..1fc09e9 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1114,13 +1114,34 @@ expand_asm_operands (tree string, tree outputs, tree 
inputs,
   free_temp_slots ();
 }
 
+/* Return the operands of STMT, a GIMPLE_ASM, as described by OP_FN and
+   N_OPS connected via TREE_CHAIN.  */
+
+static tree
+chain_asm_ops (const_gimple stmt, unsigned (*n_ops) (const_gimple),
+  tree (*op_fn) (const_gimple, unsigned))
+{
+  unsigned i, n;
+  tree ret = NULL_TREE, t;
+
+  n = (*n_ops) (stmt);
+  if (n > 0)
+{
+  t = ret = (*op_fn) (stmt, 0);
+  for (i = 1; i < n; i++)
+   t = TREE_CHAIN (t) = (*op_fn) (stmt, i);
+}
+
+  return ret;
+}
+
 void
 expand_asm_stmt (gimple stmt)
 {
   int noutputs;
-  tree outputs, tail, t;
+  tree outputs, tail;
   tree *o;
-  size_t i, n;
+  size_t i;
   const char *s;
   tree str, out, in, cl, labels;
   location_t locus = gimple_location (stmt);
@@ -1128,41 +1149,10 @@ expand_asm_stmt (gimple stmt)
   /* Meh... convert the gimple asm operands into real tree lists.
  Eventually we should make all routines work on the vectors instead
  of relying on TREE_CHAIN.  */
-  out = NULL_TREE;
-  n = gimple_asm_noutputs (stmt);
-  if (n > 0)
-{
-  t = out = gimple_asm_output_op (stmt, 0);
-  for (i = 1; i < n; i++)
-   t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
-}
-
-  in = NULL_TREE;
-  n = gimple_asm_ninputs (stmt);
-  if (n > 0)
-{
-  t = in = gimple_asm_input_op (stmt, 0);
-  for (i = 1; i < n; i++)
-   t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
-}
-
-  cl = NULL_TREE;
-  n = gimple_asm_nclobbers (stmt);
-  if (n > 0)
-{
-  t = cl = gimple_asm_clobber_op (stmt, 0);
-  for (i = 1; i < n; i++)
-   t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
-}
-
-  labels = NULL_TREE;
-  n = gimple_asm_nlabels (stmt);
-  if (n > 0)
-{
-  t = labels = gimple_asm_label_op (stmt, 0);
-  for (i = 1; i < n; i++)
-   t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
-}
+  out = chain_asm_ops (stmt, gimple_asm_noutputs, gimple_asm_output_op);
+  in = chain_asm_ops (stmt, gimple_asm_ninputs, gimple_asm_input_op);
+  cl = chain_asm_ops (stmt, gimple_asm_nclobbers, gimple_asm_clobber_op);
+  labels = chain_asm_ops (stmt, gimple_asm_nlabels, gimple_asm_label_op);
 
   s = gimple_asm_string (stmt);
   str = build_string (strlen (s), s);


[PATCH] refactor gimple asm memory clobber checking

2011-04-15 Thread Nathan Froyd
There are a couple places that check GIMPLE_ASMs for clobbering memory;
this patch centralizes the logic in gimple.c.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

* gimple.h (gimple_asm_clobbers_memory_p): Declare.
* gimple.c (gimple_asm_clobbers_memory_p): Define.
* ipa-pure-const.c (check_stmt): Call it.
* tree-ssa-operands.c (get_asm_expr_operands): Likewise.

diff --git a/gcc/gimple.c b/gcc/gimple.c
index 090fc94..5dc62ea 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -5142,4 +5142,21 @@ gimple_call_builtin_p (gimple stmt, enum 
built_in_function code)
  && DECL_FUNCTION_CODE (fndecl) == code);
 }
 
+/* Return true if STMT clobbers memory.  STMT is required to be a
+   GIMPLE_ASM.  */
+
+bool
+gimple_asm_clobbers_memory_p (const_gimple stmt)
+{
+  unsigned i;
+
+  for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
+{
+  tree op = gimple_asm_clobber_op (stmt, i);
+  if (strcmp (TREE_STRING_POINTER (TREE_VALUE (op)), "memory") == 0)
+   return true;
+}
+
+  return false;
+}
 #include "gt-gimple.h"
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 572cabc..840e149 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -973,6 +973,7 @@ extern bool walk_stmt_load_store_ops (gimple, void *,
  bool (*)(gimple, tree, void *));
 extern bool gimple_ior_addresses_taken (bitmap, gimple);
 extern bool gimple_call_builtin_p (gimple, enum built_in_function);
+extern bool gimple_asm_clobbers_memory_p (const_gimple);
 
 /* In gimplify.c  */
 extern tree create_tmp_var_raw (tree, const char *);
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index b7deb57..eb5b0f6 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -639,7 +639,6 @@ static void
 check_stmt (gimple_stmt_iterator *gsip, funct_state local, bool ipa)
 {
   gimple stmt = gsi_stmt (*gsip);
-  unsigned int i = 0;
 
   if (is_gimple_debug (stmt))
 return;
@@ -693,16 +692,12 @@ check_stmt (gimple_stmt_iterator *gsip, funct_state 
local, bool ipa)
}
   break;
 case GIMPLE_ASM:
-  for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
+  if (gimple_asm_clobbers_memory_p (stmt))
{
- tree op = gimple_asm_clobber_op (stmt, i);
- if (strcmp (TREE_STRING_POINTER (TREE_VALUE (op)), "memory") == 0)
-   {
-  if (dump_file)
-fprintf (dump_file, "memory asm clobber is not 
const/pure");
- /* Abandon all hope, ye who enter here. */
- local->pure_const_state = IPA_NEITHER;
-   }
+ if (dump_file)
+   fprintf (dump_file, "memory asm clobber is not const/pure");
+ /* Abandon all hope, ye who enter here. */
+ local->pure_const_state = IPA_NEITHER;
}
   if (gimple_asm_volatile_p (stmt))
{
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 57f443f..7f76cbf 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -832,15 +832,8 @@ get_asm_expr_operands (gimple stmt)
 }
 
   /* Clobber all memory and addressable symbols for asm ("" : : : "memory");  
*/
-  for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
-{
-  tree link = gimple_asm_clobber_op (stmt, i);
-  if (strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory") == 0)
-   {
- add_virtual_operand (stmt, opf_def);
- break;
-   }
-}
+  if (gimple_asm_clobbers_memory_p (stmt))
+add_virtual_operand (stmt, opf_def);
 }
 
 


Re: [PATCH, SMS] Free sccs field

2011-04-15 Thread Nathan Froyd
On Fri, Apr 15, 2011 at 06:27:05PM +0300, Revital Eres wrote:
> +  if (all_sccs->sccs)
> +free (all_sccs->sccs);

No need to check for non-NULL prior to free'ing.

-Nathan



Re: [PATCH] Fix PR48650

2011-04-18 Thread Nathan Froyd
On Mon, Apr 18, 2011 at 12:46:52PM +0200, Richard Guenther wrote:
> STRING_CST is now derived from tree_typed but we still clear a
> tree_common sized chunk.  Nathan, maybe grep for other sizeof()s
> around the tree?

Ouch, thanks for fixing.  I grepped for 'struct tree_common' and turned
up a few things that might trigger when tree_exp gets smaller, but not
much else.  I'll check those before committing the tree_exp slimming and
post patches if necessary.

-Nathan


Re: Allow more PowerPC sibling calls

2011-04-18 Thread Nathan Froyd
On Sat, Apr 09, 2011 at 12:21:46PM +0930, Alan Modra wrote:
> a) Allow sibling calls via function pointer.  At the time
>rs6000_function_ok_for_sibcall was written, I don't think access to
>arg types of function pointer calls was available in the target
>hook/macro.
>
> +  /* Functions with vector parameters are required to have a
> +  prototype, so the argument type info must be available
> +  here.  */
> +  for (type = TYPE_ARG_TYPES (fntype);
> +type;
> +type = TREE_CHAIN (type))
> + if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE
> + && (ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_VALUE (type)))
> + || VSX_VECTOR_MODE (TYPE_MODE (TREE_VALUE (type)
> +   nvreg++;
> +
> +  for (type = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
> +type;
> +type = TREE_CHAIN (type))
> + if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE
> + && (ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_VALUE (type)))
> + || VSX_VECTOR_MODE (TYPE_MODE (TREE_VALUE (type)
> +   nvreg--;

Could I request that you use FOREACH_FUNCTION_ARGS in these two cases?
The conversion is trivial, and avoiding more exposed TYPE_ARG_TYPES
calls is a good thing.

Thanks,
-Nathan


Re: [PATCH] make LABEL_DECL has its own rtx field for its associated CODE_LABEL

2011-04-19 Thread Nathan Froyd
On Tue, Apr 05, 2011 at 05:55:33PM +0200, Michael Matz wrote:
> I have a preference in having just one DECL_RTL field for conceptual 
> reasons:
> 
> Most DECLs are actually objects (there are some prominent exceptions, but 
> those always would be better described with something like NAMED_ENTITY, 
> if we had something like that, namespaces and translation_unit would 
> qualify).  All these have a RTL representation, so one field for them 
> seems appropriate.  That some of those don't have a size (either because 
> size makes no sense or is always available via type size) hints towards a 
> problem in the inheritance.  I would think it should look like so:
> 
> decl_common {}  # no size, no rtl, no align, no pt_uid
> decl_with_rtl : decl_common {
>   # add rtl, align, pt_uid
> }
> decl_with_size : decl_with_rtl {
>   # add size, size_unit
> }
> 
> Then decl_common can still be used for 
> imported_decl/namespace/translation_unit; objects 
> are at least decl_with_rtl, and some objects will be decl_with_size.

I had occasion to try this today; this inheritance structure doesn't
work.  The truncated inheritance tree looks like:

* decl_common
  * field_decl
  * const_decl
  * decl_with_rtl
* label_decl
* result_decl
* parm_decl
* decl_with_vis...

In particular, FIELD_DECLs have a size, but they have no RTL associated
with them.  And LABEL_DECLs have RTL, but no size.  So if you went with
the above, FIELD_DECLs would grow by one (useless) word.  And the
reverse is the situation we have today, where CONST_DECLs and
LABEL_DECLs (at least) have a pointless DECL_SIZE.  Ideally, we could
fix things like FUNCTION_DECLs having a size, too...

And I didn't check the C++ FE to see if there are problematic cases
there, either.

What do you think is the next step?  To address this issue, we could
just give LABEL_DECL its own rtx field as in the original patch, and
that would resolve that.  But maybe we should go further, say by making
DECL_SIZE{,_UNIT} and/or DECL_RTL into actual (out-of-line function)
accessors; these accessors can then access structure-specific bits of
data.  Then we don't have to worry about the inheritance structure, and
maybe could adopt alternate storage schemes for different DECLs, such as
the off-to-the-side table that Steven suggested.

-Nathan


[PATCH] make Ada runtime function building use build_function_type_list

2011-04-20 Thread Nathan Froyd
This patch changes most of the uses of build_function_type in the Ada to
use build_function_type_list.  There are a handful of
build_function_type calls left; replacing those will have to wait until
we get a build_function_type_{n,vec} interface.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

* gcc-interface/trans.c (gigi): Call build_function_type_list
instead of build_function_type.  Adjust calls to...
(build_raise_check): ...this.  Do not take a void_tree parameter.
Call build_function_type_list instead of build_function_type.

diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 378f88c..05e2842 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -214,7 +214,7 @@ static void set_expr_location_from_node (tree, Node_Id);
 static bool set_end_locus_from_node (tree, Node_Id);
 static void set_gnu_expr_location_from_node (tree, Node_Id);
 static int lvalue_required_p (Node_Id, tree, bool, bool, bool);
-static tree build_raise_check (int, tree, enum exception_info_kind);
+static tree build_raise_check (int, enum exception_info_kind);
 
 /* Hooks for debug info back-ends, only supported and used in a restricted set
of configurations.  */
@@ -236,7 +236,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name 
ATTRIBUTE_UNUSED,
   Entity_Id standard_exception_type, Int gigi_operating_mode)
 {
   Entity_Id gnat_literal;
-  tree long_long_float_type, exception_type, t;
+  tree long_long_float_type, exception_type, t, ftype;
   tree int64_type = gnat_type_for_size (64, 0);
   struct elab_info *info;
   int i;
@@ -344,47 +344,39 @@ gigi (Node_Id gnat_root, int max_gnat_node, int 
number_name ATTRIBUTE_UNUSED,
   DECL_IGNORED_P (t) = 1;
   save_gnu_tree (gnat_literal, t, false);
 
-  void_ftype = build_function_type (void_type_node, NULL_TREE);
+  void_ftype = build_function_type_list (void_type_node, NULL_TREE);
   ptr_void_ftype = build_pointer_type (void_ftype);
 
   /* Now declare run-time functions.  */
-  t = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
 
+  ftype = build_function_type_list (ptr_void_type_node, sizetype, NULL_TREE);
   /* malloc is a function declaration tree for a function to allocate
  memory.  */
   malloc_decl
 = create_subprog_decl (get_identifier ("__gnat_malloc"), NULL_TREE,
-  build_function_type (ptr_void_type_node,
-   tree_cons (NULL_TREE,
-  sizetype, t)),
-  NULL_TREE, false, true, true, NULL, Empty);
+  ftype, NULL_TREE, false, true, true, NULL, Empty);
   DECL_IS_MALLOC (malloc_decl) = 1;
 
   /* malloc32 is a function declaration tree for a function to allocate
  32-bit memory on a 64-bit system.  Needed only on 64-bit VMS.  */
   malloc32_decl
 = create_subprog_decl (get_identifier ("__gnat_malloc32"), NULL_TREE,
-  build_function_type (ptr_void_type_node,
-   tree_cons (NULL_TREE,
-  sizetype, t)),
-  NULL_TREE, false, true, true, NULL, Empty);
+  ftype, NULL_TREE, false, true, true, NULL, Empty);
   DECL_IS_MALLOC (malloc32_decl) = 1;
 
   /* free is a function declaration tree for a function to free memory.  */
+  ftype = build_function_type_list (void_type_node,
+   ptr_void_type_node, NULL_TREE);
   free_decl
 = create_subprog_decl (get_identifier ("__gnat_free"), NULL_TREE,
-  build_function_type (void_type_node,
-   tree_cons (NULL_TREE,
-  ptr_void_type_node,
-  t)),
-  NULL_TREE, false, true, true, NULL, Empty);
+  ftype, NULL_TREE, false, true, true, NULL, Empty);
 
   /* This is used for 64-bit multiplication with overflow checking.  */
+  ftype = build_function_type_list (int64_type,
+   int64_type, int64_type, NULL_TREE);
   mulv64_decl
 = create_subprog_decl (get_identifier ("__gnat_mulv64"), NULL_TREE,
-  build_function_type_list (int64_type, int64_type,
-int64_type, NULL_TREE),
-  NULL_TREE, false, true, true, NULL, Empty);
+  ftype, NULL_TREE, false, true, true, NULL, Empty);
 
   /* Name of the _Parent field in tagged record types.  */
   parent_name_id = get_identifier (Get_Name_String (Name_uParent));
@@ -401,61 +393,54 @@ gigi (Node_Id gnat_root, int max_gnat_node, int 
number_name ATTRIBUTE_UNUSED,
   jmpbuf_ptr_type = build_pointer_type (jmpbuf_type);
 
   /* F

[PATCH] use build_function_type_list a few places in the ObjC frontend

2011-04-20 Thread Nathan Froyd
Just as $SUBJECT suggests.  All the other uses of
build_function_type_list are tied up with get_arg_type_list and will
therefore have to wait for a better FUNCTION_TYPE builder.

Tested on x86_64-unknown-linux-gnu.  IIUC the changes to
objc-next-runtime-abi-02.c would not be tested on that platform, so it
would be helpful to have a Darwin tester double-check my work.

OK to commit?

-Nathan

* objc-act.c (synth_module_prologue): Call build_function_type_list
instead of build_function_type.
* objc-next-runtime-abi-02.c (next_runtime_02_initialize):
Likewise.

diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index b48f179..0b6b793 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -2995,8 +2995,8 @@ synth_module_prologue (void)
   build_fast_enumeration_state_template ();
   
   /* void objc_enumeration_mutation (id) */
-  type = build_function_type (void_type_node,
- tree_cons (NULL_TREE, objc_object_type, 
NULL_TREE));
+  type = build_function_type_list (void_type_node,
+  objc_object_type, NULL_TREE);
   objc_enumeration_mutation_decl 
 = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN, 
NULL, NULL_TREE);
diff --git a/gcc/objc/objc-next-runtime-abi-02.c 
b/gcc/objc/objc-next-runtime-abi-02.c
index 4ce0159..f3cf359 100644
--- a/gcc/objc/objc-next-runtime-abi-02.c
+++ b/gcc/objc/objc-next-runtime-abi-02.c
@@ -492,9 +492,8 @@ static void next_runtime_02_initialize (void)
   build_v2_ehtype_template ();
 
   /* void * objc_begin_catch (void *) */
-  type = build_function_type (ptr_type_node,
- tree_cons (NULL_TREE, ptr_type_node,
- OBJC_VOID_AT_END));
+  type = build_function_type_list (ptr_type_node,
+  ptr_type_node, NULL_TREE);
 
   objc2_begin_catch_decl = add_builtin_function ("objc_begin_catch",
 type, 0, NOT_BUILT_IN,
@@ -502,14 +501,13 @@ static void next_runtime_02_initialize (void)
   TREE_NOTHROW (objc2_begin_catch_decl) = 0;
 
   /* void objc_end_catch () */
-  type = build_function_type (void_type_node, OBJC_VOID_AT_END);
+  type = build_function_type_list (void_type_node, NULL_TREE);
   objc2_end_catch_decl = add_builtin_function ("objc_end_catch",
type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
   TREE_NOTHROW (objc2_end_catch_decl) = 0;
 
   /* void objc_exception_rethrow (void) */
-  type = build_function_type (void_type_node, OBJC_VOID_AT_END);
   objc_rethrow_exception_decl = 
add_builtin_function ("objc_exception_rethrow",
  type, 0, NOT_BUILT_IN,


[PATCH] use build_function_type_list in the alpha backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to alpha-elf.  OK to commit?

-Nathan

* config/alpha/alpha.c (alpha_init_builtins): Call
build_function_type_list instead of build_function_type.

diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 5e85e2b..237e9b3 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -6409,7 +6409,7 @@ alpha_init_builtins (void)
   implicit_built_in_decls[(int) BUILT_IN_FWRITE_UNLOCKED] = NULL_TREE;
 #endif
 
-  ftype = build_function_type (dimode_integer_type_node, void_list_node);
+  ftype = build_function_type_list (dimode_integer_type_node, NULL_TREE);
   alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins),
  ftype);
 
@@ -6424,7 +6424,7 @@ alpha_init_builtins (void)
   alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins),
  ftype);
 
-  ftype = build_function_type (ptr_type_node, void_list_node);
+  ftype = build_function_type_list (ptr_type_node, NULL_TREE);
   alpha_builtin_function ("__builtin_thread_pointer", ftype,
  ALPHA_BUILTIN_THREAD_POINTER, ECF_NOTHROW);
 


[PATCH] use build_function_type_list in the bfin backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to bfin-elf.  OK to commit?

-Nathan

* config/bfin/bfin.c (bfin_init_builtins): Call
build_function_type_list instead of build_function_type.

diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 5d08437..03a833d 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -5967,7 +5967,7 @@ bfin_init_builtins (void)
 {
   tree V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
   tree void_ftype_void
-= build_function_type (void_type_node, void_list_node);
+= build_function_type_list (void_type_node, NULL_TREE);
   tree short_ftype_short
 = build_function_type_list (short_integer_type_node, 
short_integer_type_node,
NULL_TREE);


[PATCH] use build_function_type_list in the frv backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to frv-elf.  OK to commit?

-Nathan

* config/frv/frv.c (frv_init_builtins): Delete `endlink' variable.
Call builtin_function_type_list instead of builtin_function_type.
(UNARY, BINARY, TRINARY, QUAD): Likewise.

diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 0913765..564baa0 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -8390,7 +8390,6 @@ static struct builtin_description bdesc_stores[] =
 static void
 frv_init_builtins (void)
 {
-  tree endlink = void_list_node;
   tree accumulator = integer_type_node;
   tree integer = integer_type_node;
   tree voidt = void_type_node;
@@ -8405,24 +8404,18 @@ frv_init_builtins (void)
   tree iacc   = integer_type_node;
 
 #define UNARY(RET, T1) \
-  build_function_type (RET, tree_cons (NULL_TREE, T1, endlink))
+  build_function_type_list (RET, T1, NULL_TREE)
 
 #define BINARY(RET, T1, T2) \
-  build_function_type (RET, tree_cons (NULL_TREE, T1, \
-   tree_cons (NULL_TREE, T2, endlink)))
+  build_function_type_list (RET, T1, T2, NULL_TREE)
 
 #define TRINARY(RET, T1, T2, T3) \
-  build_function_type (RET, tree_cons (NULL_TREE, T1, \
-   tree_cons (NULL_TREE, T2, \
-   tree_cons (NULL_TREE, T3, endlink
+  build_function_type_list (RET, T1, T2, T3, NULL_TREE)
 
 #define QUAD(RET, T1, T2, T3, T4) \
-  build_function_type (RET, tree_cons (NULL_TREE, T1, \
-   tree_cons (NULL_TREE, T2, \
-   tree_cons (NULL_TREE, T3, \
-   tree_cons (NULL_TREE, T4, endlink)
+  build_function_type_list (RET, T1, T2, T3, NULL_TREE)
 
-  tree void_ftype_void = build_function_type (voidt, endlink);
+  tree void_ftype_void = build_function_type_list (voidt, NULL_TREE);
 
   tree void_ftype_acc = UNARY (voidt, accumulator);
   tree void_ftype_uw4_uw1 = BINARY (voidt, uword4, uword1);


[PATCH] use build_function_type_list in the i386 backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  There's still one use of build_function_type;
replacing that type will have to wait for an improved
FUNCTION_TYPE-building interface.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

* config/i386/i386.c (ix86_code_end): Call build_function_type_list
instead of build_function_type.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b6d41f0..40151f4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -8833,7 +8833,7 @@ ix86_code_end (void)
 
   decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
 get_identifier (name),
-build_function_type (void_type_node, void_list_node));
+build_function_type_list (void_type_node, NULL_TREE));
   DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
   NULL_TREE, void_type_node);
   TREE_PUBLIC (decl) = 1;


[PATCH] use build_function_type_list in the ia64 backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to ia64-linux-gnu.  OK to
commit?

-Nathan

* config/ia64/ia64.c (ia64_init_builtins): Call
build_function_type_list instead of builtin_function_type.

diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 5f22b17..166ec43 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10165,11 +10165,10 @@ ia64_init_builtins (void)
   (*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
 
   /* TFmode support builtins.  */
-  ftype = build_function_type (float128_type, void_list_node);
-  decl = add_builtin_function ("__builtin_infq", ftype,
-  IA64_BUILTIN_INFQ, BUILT_IN_MD,
-  NULL, NULL_TREE);
-  ia64_builtins[IA64_BUILTIN_INFQ] = decl;
+  ftype = build_function_type_list (float128_type, NULL_TREE);
+  add_builtin_function ("__builtin_infq", ftype,
+   IA64_BUILTIN_INFQ, BUILT_IN_MD,
+   NULL, NULL_TREE);
 
   decl = add_builtin_function ("__builtin_huge_valq", ftype,
   IA64_BUILTIN_HUGE_VALQ, BUILT_IN_MD,
@@ -10211,15 +10210,13 @@ ia64_init_builtins (void)
   add_builtin_function ((name), (type), (code), BUILT_IN_MD,   \
   NULL, NULL_TREE)
 
-  decl = def_builtin ("__builtin_ia64_bsp",
-  build_function_type (ptr_type_node, void_list_node),
+  def_builtin ("__builtin_ia64_bsp",
+  build_function_type_list (ptr_type_node, NULL_TREE),
   IA64_BUILTIN_BSP);
-  ia64_builtins[IA64_BUILTIN_BSP] = decl;
 
-  decl = def_builtin ("__builtin_ia64_flushrs",
-  build_function_type (void_type_node, void_list_node),
+  def_builtin ("__builtin_ia64_flushrs",
+  build_function_type_list (void_type_node, NULL_TREE),
   IA64_BUILTIN_FLUSHRS);
-  ia64_builtins[IA64_BUILTIN_FLUSHRS] = decl;
 
 #undef def_builtin
 


[PATCH] use build_function_type_list in the iq2000 backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to iq2000-elf.  OK to commit?

-Nathan

* config/iq2000/i2000.c (iq2000_init_builtins): Call
build_function_type_list instead of build_function_type.
Delete `endlink' variable.

diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c
index 2d69085..aa63674 100644
--- a/gcc/config/iq2000/iq2000.c
+++ b/gcc/config/iq2000/iq2000.c
@@ -2466,7 +2466,6 @@ iq2000_output_conditional_branch (rtx insn, rtx * 
operands, int two_operands_p,
 static void
 iq2000_init_builtins (void)
 {
-  tree endlink = void_list_node;
   tree void_ftype, void_ftype_int, void_ftype_int_int;
   tree void_ftype_int_int_int;
   tree int_ftype_int, int_ftype_int_int, int_ftype_int_int_int;
@@ -2474,76 +2473,55 @@ iq2000_init_builtins (void)
 
   /* func () */
   void_ftype
-= build_function_type (void_type_node,
-  tree_cons (NULL_TREE, void_type_node, endlink));
+= build_function_type_list (void_type_node, NULL_TREE);
 
   /* func (int) */
   void_ftype_int
-= build_function_type (void_type_node,
-  tree_cons (NULL_TREE, integer_type_node, endlink));
+= build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
 
   /* void func (int, int) */
   void_ftype_int_int
-= build_function_type (void_type_node,
-   tree_cons (NULL_TREE, integer_type_node,
-  tree_cons (NULL_TREE, integer_type_node,
- endlink)));
+= build_function_type_list (void_type_node,
+integer_type_node,
+integer_type_node,
+NULL_TREE);
 
   /* int func (int) */
   int_ftype_int
-= build_function_type (integer_type_node,
-   tree_cons (NULL_TREE, integer_type_node, endlink));
+= build_function_type_list (integer_type_node,
+integer_type_node, NULL_TREE);
 
   /* int func (int, int) */
   int_ftype_int_int
-= build_function_type (integer_type_node,
-   tree_cons (NULL_TREE, integer_type_node,
-  tree_cons (NULL_TREE, integer_type_node,
- endlink)));
+= build_function_type_list (integer_type_node,
+integer_type_node,
+integer_type_node,
+NULL_TREE);
 
   /* void func (int, int, int) */
-void_ftype_int_int_int
-= build_function_type
-(void_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-   tree_cons (NULL_TREE, integer_type_node,
-  tree_cons (NULL_TREE,
- integer_type_node,
- endlink;
-
-  /* int func (int, int, int, int) */
-  int_ftype_int_int_int_int
-= build_function_type
-(integer_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-   tree_cons (NULL_TREE, integer_type_node,
-  tree_cons (NULL_TREE,
- integer_type_node,
- tree_cons (NULL_TREE,
-integer_type_node,
-endlink);
+  void_ftype_int_int_int
+= build_function_type_list (void_type_node,
+integer_type_node,
+integer_type_node,
+integer_type_node,
+NULL_TREE);
 
   /* int func (int, int, int) */
   int_ftype_int_int_int
-= build_function_type
-(integer_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-   tree_cons (NULL_TREE, integer_type_node,
-  tree_cons (NULL_TREE,
- integer_type_node,
- endlink;
+= build_function_type_list (integer_type_node,
+integer_type_node,
+integer_type_node,
+integer_type_node,
+NULL_TREE);
 
   /* int func (int, int, int, int) */
   int_ftype_int_int_int_int
-= build_function_type
-(integer_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-   tree_cons (NULL_TREE, integer_type_node,
-  tree_cons (NULL_TREE,
- integer_type_node,
- tree_cons (NULL_TREE,
-integer_type_node,
-endlink);
+= build_function_type_list (integer_type_node,
+integer_type_node,
+  

[PATCH] use build_function_type_list in the mep backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to mep-elf.  OK to commit?

-Nathan

* config/mep/mep.c (mep_init_builtins): Call build_function_type_list
instead of build_function_type.

diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c
index 02c825a..b8ef440 100644
--- a/gcc/config/mep/mep.c
+++ b/gcc/config/mep/mep.c
@@ -6133,7 +6133,7 @@ mep_init_builtins (void)
if (cgen_insns[i].cret_p)
  ret_type = mep_cgen_regnum_to_type (cgen_insns[i].regnums[0].type);
 
-   bi_type = build_function_type (ret_type, 0);
+   bi_type = build_function_type_list (ret_type, NULL_TREE);
add_builtin_function (cgen_intrinsics[cgen_insns[i].intrinsic],
  bi_type,
  cgen_insns[i].intrinsic, BUILT_IN_MD, NULL, NULL);


[PATCH] use build_function_type_list in the mips backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to mips-elf.  OK to commit?

-Nathan

* config/mips/mips.c (mips16_build_function_stub): Call
build_function_type_list instead of build_function_type.
(mips16_build_call_stub): Likewise.

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index e075c4f..4d4d639 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -6075,7 +6075,7 @@ mips16_build_function_stub (void)
   /* Build a decl for the stub.  */
   stubdecl = build_decl (BUILTINS_LOCATION,
 FUNCTION_DECL, get_identifier (stubname),
-build_function_type (void_type_node, NULL_TREE));
+build_function_type_list (void_type_node, NULL_TREE));
   DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
   DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
   RESULT_DECL, NULL_TREE, void_type_node);
@@ -6321,7 +6321,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx 
args_size, int fp_code)
   stubid = get_identifier (stubname);
   stubdecl = build_decl (BUILTINS_LOCATION,
 FUNCTION_DECL, stubid,
-build_function_type (void_type_node, NULL_TREE));
+build_function_type_list (void_type_node, 
NULL_TREE));
   DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
   DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
   RESULT_DECL, NULL_TREE,


[PATCH] use build_function_type_list in the s390 backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to s390-linux-gnu.  OK to
commit?

-Nathan

* config/s390/s390.c (s390_init_builtins): Call
build_function_type_list instead of build_function_type.

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index caee077..adacfa3 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9172,7 +9172,7 @@ s390_init_builtins (void)
 {
   tree ftype;
 
-  ftype = build_function_type (ptr_type_node, void_list_node);
+  ftype = build_function_type_list (ptr_type_node, NULL_TREE);
   add_builtin_function ("__builtin_thread_pointer", ftype,
S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
NULL, NULL_TREE);



[PATCH] use build_function_type_list in the sparc backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to sparc-elf.  OK to commit?

-Nathan

* config/sparc/sparc.c (sparc_file_end): Call
build_function_type_list instead of build_function_type.

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 03b5e66..e7dd75b 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -9501,8 +9501,8 @@ sparc_file_end (void)
{
  tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
  get_identifier (name),
- build_function_type (void_type_node,
-  void_list_node));
+ build_function_type_list (void_type_node,
+NULL_TREE));
  DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
   NULL_TREE, void_type_node);
  TREE_STATIC (decl) = 1;


[PATCH] use build_function_type_list in the xtensa backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to xtensa-elf.  OK to commit?

-Nathan

* config/xtensa/xtensa.c (xtensa_init_builtins): Call
build_function_type_list instead of build_function_type.

diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index fe70270..574e08e 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -3083,7 +3083,7 @@ xtensa_init_builtins (void)
 
   if (TARGET_THREADPTR)
 {
-  ftype = build_function_type (ptr_type_node, void_list_node);
+  ftype = build_function_type_list (ptr_type_node, NULL_TREE);
   decl = add_builtin_function ("__builtin_thread_pointer", ftype,
   XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
   NULL, NULL_TREE);


[PATCH] use build_function_type_list in the rs6000 backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  The only tricky part is in builtin_function_type,
where we fill in unused args with NULL_TREE so that passing extra
arguments to build_function_type_list doesn't matter.

Tested with cross to powerpc-eabi.  OK to commit?

-Nathan

* config/rs6000/rs6000.c (spe_init_builtins): Call
build_function_type_list instead of build_function_type.
(paired_init_builtins, altivec_init_builtins): Likewise.
(builtin_function_type): Likewise.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8182bf0..c08c16e 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -12824,107 +12824,97 @@ enable_mask_for_builtins (struct builtin_description 
*desc, int size,
 static void
 spe_init_builtins (void)
 {
-  tree endlink = void_list_node;
   tree puint_type_node = build_pointer_type (unsigned_type_node);
   tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
   struct builtin_description *d;
   size_t i;
 
   tree v2si_ftype_4_v2si
-= build_function_type
-(opaque_V2SI_type_node,
- tree_cons (NULL_TREE, opaque_V2SI_type_node,
-   tree_cons (NULL_TREE, opaque_V2SI_type_node,
-  tree_cons (NULL_TREE, opaque_V2SI_type_node,
- tree_cons (NULL_TREE, 
opaque_V2SI_type_node,
-endlink);
+= build_function_type_list (opaque_V2SI_type_node,
+opaque_V2SI_type_node,
+opaque_V2SI_type_node,
+opaque_V2SI_type_node,
+opaque_V2SI_type_node,
+NULL_TREE);
 
   tree v2sf_ftype_4_v2sf
-= build_function_type
-(opaque_V2SF_type_node,
- tree_cons (NULL_TREE, opaque_V2SF_type_node,
-   tree_cons (NULL_TREE, opaque_V2SF_type_node,
-  tree_cons (NULL_TREE, opaque_V2SF_type_node,
- tree_cons (NULL_TREE, 
opaque_V2SF_type_node,
-endlink);
+= build_function_type_list (opaque_V2SF_type_node,
+opaque_V2SF_type_node,
+opaque_V2SF_type_node,
+opaque_V2SF_type_node,
+opaque_V2SF_type_node,
+NULL_TREE);
 
   tree int_ftype_int_v2si_v2si
-= build_function_type
-(integer_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-   tree_cons (NULL_TREE, opaque_V2SI_type_node,
-  tree_cons (NULL_TREE, opaque_V2SI_type_node,
- endlink;
+= build_function_type_list (integer_type_node,
+integer_type_node,
+opaque_V2SI_type_node,
+opaque_V2SI_type_node,
+NULL_TREE);
 
   tree int_ftype_int_v2sf_v2sf
-= build_function_type
-(integer_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-   tree_cons (NULL_TREE, opaque_V2SF_type_node,
-  tree_cons (NULL_TREE, opaque_V2SF_type_node,
- endlink;
+= build_function_type_list (integer_type_node,
+integer_type_node,
+opaque_V2SF_type_node,
+opaque_V2SF_type_node,
+NULL_TREE);
 
   tree void_ftype_v2si_puint_int
-= build_function_type (void_type_node,
-  tree_cons (NULL_TREE, opaque_V2SI_type_node,
- tree_cons (NULL_TREE, puint_type_node,
-tree_cons (NULL_TREE,
-   integer_type_node,
-   endlink;
+= build_function_type_list (void_type_node,
+opaque_V2SI_type_node,
+puint_type_node,
+integer_type_node,
+NULL_TREE);
 
   tree void_ftype_v2si_puint_char
-= build_function_type (void_type_node,
-  tree_cons (NULL_TREE, opaque_V2SI_type_node,
- tree_cons (NULL_TREE, puint_type_node,
-tree_cons (NULL_TREE,
-   char_type_node,
-   endlink;
+= build_function_type_list (void_type_node,
+opaque_V2SI_type_node,
+puint_type_node,
+char_t

[PATCH] use build_function_type_list in the picochip backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to picochip-elf.  OK to commit?

-Nathan

* config/picochip/picochip.c (picochip_init_builtins): Call
build_function_type_list instead of build_function_type.
Delete `endlink' variable.

diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c
index 1ca95b4..4442d1e 100644
--- a/gcc/config/picochip/picochip.c
+++ b/gcc/config/picochip/picochip.c
@@ -4216,18 +4216,6 @@ void
 picochip_init_builtins (void)
 {
   tree noreturn;
-  tree endlink = void_list_node;
-  tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
-  tree unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-  tree long_endlink = tree_cons (NULL_TREE, long_integer_type_node, endlink);
-  tree int_int_endlink =
-tree_cons (NULL_TREE, integer_type_node, int_endlink);
-  tree int_int_int_endlink =
-tree_cons (NULL_TREE, integer_type_node, int_int_endlink);
-  tree int_long_endlink =
-tree_cons (NULL_TREE, integer_type_node, long_endlink);
-  tree long_int_int_int_endlink =
-tree_cons (NULL_TREE, long_integer_type_node, int_int_int_endlink);
 
   tree int_ftype_int, int_ftype_int_int;
   tree long_ftype_int, long_ftype_int_int_int;
@@ -4236,36 +4224,51 @@ picochip_init_builtins (void)
   tree void_ftype_void, unsigned_ftype_unsigned;
 
   /* void func (void) */
-  void_ftype_void = build_function_type (void_type_node, endlink);
+  void_ftype_void = build_function_type_list (void_type_node, NULL_TREE);
 
   /* int func (int) */
-  int_ftype_int = build_function_type (integer_type_node, int_endlink);
+  int_ftype_int = build_function_type_list (integer_type_node,
+   integer_type_node, NULL_TREE);
 
   /* unsigned int func (unsigned int) */
-  unsigned_ftype_unsigned = build_function_type (unsigned_type_node, 
unsigned_endlink);
+  unsigned_ftype_unsigned
+= build_function_type_list (unsigned_type_node,
+   unsigned_type_node, NULL_TREE);
 
   /* int func(int, int) */
   int_ftype_int_int
-= build_function_type (integer_type_node, int_int_endlink);
+= build_function_type_list (integer_type_node,
+   integer_type_node, integer_type_node,
+   NULL_TREE);
 
   /* long func(int) */
-  long_ftype_int = build_function_type (long_integer_type_node, int_endlink);
+  long_ftype_int = build_function_type_list (long_integer_type_node,
+integer_type_node, NULL_TREE);
 
   /* long func(int, int, int) */
   long_ftype_int_int_int
-= build_function_type (long_integer_type_node, int_int_int_endlink);
+= build_function_type_list (long_integer_type_node,
+   integer_type_node, integer_type_node,
+   integer_type_node, NULL_TREE);
 
   /* int func(int, int, int) */
   int_ftype_int_int_int
-= build_function_type (integer_type_node, int_int_int_endlink);
+= build_function_type_list (integer_type_node,
+   integer_type_node, integer_type_node,
+   integer_type_node, NULL_TREE);
 
   /* void func(int, long) */
   void_ftype_int_long
-= build_function_type (void_type_node, int_long_endlink);
+= build_function_type_list (void_type_node,
+   integer_type_node, long_integer_type_node,
+   NULL_TREE);
 
   /* void func(long, int, int, int) */
   void_ftype_long_int_int_int
-= build_function_type (void_type_node, long_int_int_int_endlink);
+= build_function_type_list (void_type_node,
+   long_integer_type_node, integer_type_node,
+   integer_type_node, integer_type_node,
+   NULL_TREE);
 
   /* Initialise the sign-bit-count function. */
   add_builtin_function ("__builtin_sbc", int_ftype_int,


[PATCH] use build_function_type_list in the avr backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to avr-elf.  OK to commit?

-Nathan

* config/avr/avr.c (avr_init_builtins): Call
build_function_type_list instead of build_function_type.

diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 500a5b2..6dbf8b4 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -6535,7 +6535,7 @@ static void
 avr_init_builtins (void)
 {
   tree void_ftype_void
-= build_function_type (void_type_node, void_list_node);
+= build_function_type_list (void_type_node, NULL_TREE);
   tree uchar_ftype_uchar
 = build_function_type_list (unsigned_char_type_node, 
 unsigned_char_type_node,


[PATCH] use build_function_type_list in the pa backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  Tested with cross to hppa-linux-gnu.  OK to
commit?

-Nathan

* config/pa/pa.c (pa_init_builtins): Call build_function_type_list
instead of build_function_type.

diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index e05cf19..aeb8061 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -641,7 +641,7 @@ pa_init_builtins (void)
   TREE_READONLY (decl) = 1;
   pa_builtins[PA_BUILTIN_COPYSIGNQ] = decl;
 
-  ftype = build_function_type (long_double_type_node, void_list_node);
+  ftype = build_function_type_list (long_double_type_node, NULL_TREE);
   decl = add_builtin_function ("__builtin_infq", ftype,
   PA_BUILTIN_INFQ, BUILT_IN_MD,
   NULL, NULL_TREE);


[PATCH] use build_function_type_list in the arm backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  There's one remaining use of build_function_type,
but replace that will have to wait until we have a better
FUNCTION_TYPE-building interface.

Tested with cross to arm-eabi.  OK to commit?

-Nathan

* config/arm/arm.c (arm_init_iwmmxt_builtins): Call
build_function_type_list instead of build_function_type.
Delete variable `endlink'.

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5f964d6..9f10ac4 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -18915,196 +18915,137 @@ arm_init_iwmmxt_builtins (void)
 {
   const struct builtin_description * d;
   size_t i;
-  tree endlink = void_list_node;
 
   tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
   tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
   tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
 
   tree int_ftype_int
-= build_function_type (integer_type_node,
-  tree_cons (NULL_TREE, integer_type_node, endlink));
+= build_function_type_list (integer_type_node,
+   integer_type_node, NULL_TREE);
   tree v8qi_ftype_v8qi_v8qi_int
-= build_function_type (V8QI_type_node,
-  tree_cons (NULL_TREE, V8QI_type_node,
- tree_cons (NULL_TREE, V8QI_type_node,
-tree_cons (NULL_TREE,
-   integer_type_node,
-   endlink;
+= build_function_type_list (V8QI_type_node,
+   V8QI_type_node, V8QI_type_node,
+   integer_type_node, NULL_TREE);
   tree v4hi_ftype_v4hi_int
-= build_function_type (V4HI_type_node,
-  tree_cons (NULL_TREE, V4HI_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-endlink)));
+= build_function_type_list (V4HI_type_node,
+   V4HI_type_node, integer_type_node, NULL_TREE);
   tree v2si_ftype_v2si_int
-= build_function_type (V2SI_type_node,
-  tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-endlink)));
+= build_function_type_list (V2SI_type_node,
+   V2SI_type_node, integer_type_node, NULL_TREE);
   tree v2si_ftype_di_di
-= build_function_type (V2SI_type_node,
-  tree_cons (NULL_TREE, long_long_integer_type_node,
- tree_cons (NULL_TREE,
-long_long_integer_type_node,
-endlink)));
+= build_function_type_list (V2SI_type_node,
+   long_long_integer_type_node,
+   long_long_integer_type_node,
+   NULL_TREE);
   tree di_ftype_di_int
-= build_function_type (long_long_integer_type_node,
-  tree_cons (NULL_TREE, long_long_integer_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-endlink)));
+= build_function_type_list (long_long_integer_type_node,
+   long_long_integer_type_node,
+   integer_type_node, NULL_TREE);
   tree di_ftype_di_int_int
-= build_function_type (long_long_integer_type_node,
-  tree_cons (NULL_TREE, long_long_integer_type_node,
- tree_cons (NULL_TREE, integer_type_node,
-tree_cons (NULL_TREE,
-   integer_type_node,
-   endlink;
+= build_function_type_list (long_long_integer_type_node,
+   long_long_integer_type_node,
+   integer_type_node,
+   integer_type_node, NULL_TREE);
   tree int_ftype_v8qi
-= build_function_type (integer_type_node,
-  tree_cons (NULL_TREE, V8QI_type_node,
- endlink));
+= build_function_type_list (integer_type_node,
+   V8QI_type_node, NULL_TREE);
   tree int_ftype_v4hi
-= build_function_type (integer_type_node,
-  tree_cons (NULL_TREE, V4HI_type_node,
- endlink));
+= build_function_type_list (integer_type_node,
+   V4HI_type_node, NULL_TREE);
   tree int_ftype_v2si
-= build_function_ty

Re: [PATCH] use build_function_type_list in the ia64 backend

2011-04-20 Thread Nathan Froyd
On Wed, Apr 20, 2011 at 03:29:19PM -0400, Nathan Froyd wrote:
> As $SUBJECT suggests.  Tested with cross to ia64-linux-gnu.  OK to
> commit?
>
> -  ftype = build_function_type (float128_type, void_list_node);
> -  decl = add_builtin_function ("__builtin_infq", ftype,
> -IA64_BUILTIN_INFQ, BUILT_IN_MD,
> -NULL, NULL_TREE);
> -  ia64_builtins[IA64_BUILTIN_INFQ] = decl;
> +  ftype = build_function_type_list (float128_type, NULL_TREE);
> +  add_builtin_function ("__builtin_infq", ftype,
> + IA64_BUILTIN_INFQ, BUILT_IN_MD,
> + NULL, NULL_TREE);

Of course, the patch I tested didn't delete the assignment to
ia64_builtins.  Please disregard that bit.

-Nathan


[PATCH] use build_function_type_list in the spu backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  The only tricky bit is initializing all the args
to NULL_TREE so that we can safely pass all the args to
build_function_type_list.

Tested with cross to spu-elf; I couldn't build all of libgcc, but that
appears to be a pre-existing problem.  OK to commit?

-Nathan

* config/spu/spu.c (spu_init_builtins): Call build_function_type_list
instead of build_function_type.  Rearrange gathering of args to
do so.
* config/spu/spu-builtins.def (SPU_MAX_ARGS_TO_BUILTIN): Define.

diff --git a/gcc/config/spu/spu-builtins.def b/gcc/config/spu/spu-builtins.def
index 4d01d94..6dfdf8c 100644
--- a/gcc/config/spu/spu-builtins.def
+++ b/gcc/config/spu/spu-builtins.def
@@ -23,6 +23,8 @@
 #define _A3(a,b,c)   {a, b, c, SPU_BTI_END_OF_PARAMS}
 #define _A4(a,b,c,d) {a, b, c, d, SPU_BTI_END_OF_PARAMS}
 
+#define SPU_MAX_ARGS_TO_BUILTIN 3
+
 /* definitions to support si intrinsic functions: (These and other builtin
  * definitions must precede definitions of the overloaded generic intrinsics */
 
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index 941194b..ea9d580 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -5777,9 +5777,10 @@ spu_init_builtins (void)
  sure nodes are shared. */
   for (i = 0, d = spu_builtins; i < NUM_SPU_BUILTINS; i++, d++)
 {
-  tree p;
+  tree ftype;
   char name[64];   /* build_function will make a copy. */
-  int parm;
+  int parm, i;
+  tree args[SPU_MAX_ARGS_TO_BUILTIN];
 
   if (d->name == 0)
continue;
@@ -5788,15 +5789,23 @@ spu_init_builtins (void)
   for (parm = 1; d->parm[parm] != SPU_BTI_END_OF_PARAMS; parm++)
;
 
-  p = void_list_node;
+  gcc_assert (parm <= (SPU_MAX_ARGS_TO_BUILTIN + 1));
+
+  for (i = 0; i < ARRAY_SIZE (args); i++)
+   args[i] = NULL_TREE;
+
   while (parm > 1)
-   p = tree_cons (NULL_TREE, spu_builtin_types[d->parm[--parm]], p);
+   {
+ tree arg = spu_builtin_types[d->parm[--parm]];
+ args[parm-1] = arg;
+   }
 
-  p = build_function_type (spu_builtin_types[d->parm[0]], p);
+  ftype = build_function_type_list (spu_builtin_types[d->parm[0]],
+   args[0], args[1], args[2], NULL_TREE);
 
   sprintf (name, "__builtin_%s", d->name);
   spu_builtin_decls[i] =
-   add_builtin_function (name, p, i, BUILT_IN_MD, NULL, NULL_TREE);
+   add_builtin_function (name, ftype, i, BUILT_IN_MD, NULL, NULL_TREE);
   if (d->fcode == SPU_MASK_FOR_LOAD)
TREE_READONLY (spu_builtin_decls[i]) = 1;   
 


[PATCH] use build_function_type_list in the stormy16 backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  For safety's sake, we initialize all the
arguments to NULL before passing them to build_function_type_list.  This
is not necessary currently, as we always completely fill in the args
array, but it might save some future coder from quite some grief...

Tested with cross to xstormy16-elf.  OK to commit?

-Nathan

* config/stormy16/stormy16 (xstormy16_init_builtins): Call
build_function_type_list instead of build_function_type.
Rearrange initialization of `args' to do so.

diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index 052285c..1a90e16 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -2255,15 +2255,21 @@ static struct
 static void
 xstormy16_init_builtins (void)
 {
-  tree args, ret_type, arg;
-  int i, a;
+  tree args[2], ret_type, arg = NULL_TREE, ftype;
+  int i, a, n_args;
 
   ret_type = void_type_node;
 
   for (i = 0; s16builtins[i].name; i++)
 {
-  args = void_list_node;
-  for (a = strlen (s16builtins[i].arg_types) - 1; a >= 0; a--)
+  n_args = strlen (s16builtins[i].arg_types) - 1;
+
+  gcc_assert (n_args <= (int) ARRAY_SIZE (args));
+
+  for (a = n_args; a >= 0; a--)
+   args[a] = NULL_TREE;
+
+  for (a = n_args; a >= 0; a--)
{
  switch (s16builtins[i].arg_types[a])
{
@@ -2276,10 +2282,10 @@ xstormy16_init_builtins (void)
  if (a == 0)
ret_type = arg;
  else
-   args = tree_cons (NULL_TREE, arg, args);
+   args[a-1] = arg;
}
-  add_builtin_function (s16builtins[i].name,
-   build_function_type (ret_type, args),
+  ftype = build_function_type_list (ret_type, arg[0], arg[1], NULL_TREE);
+  add_builtin_function (s16builtins[i].name, ftype,
i, BUILT_IN_MD, NULL, NULL);
 }
 }


[PATCH] use build_function_type_list in the sh backend

2011-04-20 Thread Nathan Froyd
As $SUBJECT suggests.  The only tricky bit is the initialization of
`args' to NULL_TREEs so that we can safely pass all of the relevant args
to build_function_type_list, regardless of whether the function type in
question has that many args.

Tested with cross to sh-elf.  OK to commit?

-Nathan

* config/sh/sh.c (sh_media_init_builtins): Call
build_function_type_list instead of build_function_type.

diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 78f6f0f..0f158d5 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -11222,6 +11222,7 @@ sh_media_init_builtins (void)
   else
{
  int has_result = signature_args[signature][0] != 0;
+ tree args[3];
 
  if ((signature_args[signature][1] & 8)
  && (((signature_args[signature][1] & 1) && TARGET_SHMEDIA32)
@@ -11230,7 +11231,8 @@ sh_media_init_builtins (void)
  if (! TARGET_FPU_ANY
  && FLOAT_MODE_P (insn_data[d->icode].operand[0].mode))
continue;
- type = void_list_node;
+ for (i = 0; i < (int) ARRAY_SIZE (args); i++)
+   args[i] = NULL_TREE;
  for (i = 3; ; i--)
{
  int arg = signature_args[signature][i];
@@ -11248,9 +11250,10 @@ sh_media_init_builtins (void)
arg_type = void_type_node;
  if (i == 0)
break;
- type = tree_cons (NULL_TREE, arg_type, type);
+ args[i-1] = arg_type;
}
- type = build_function_type (arg_type, type);
+ type = build_function_type_list (arg_type, args[0], args[1],
+  args[2], NULL_TREE);
  if (signature < SH_BLTIN_NUM_SHARED_SIGNATURES)
shared[signature] = type;
}


Re: [PATCH] use build_function_type_list in the ia64 backend

2011-04-20 Thread Nathan Froyd
On Wed, Apr 20, 2011 at 02:09:49PM -0700, Steve Ellcey wrote:
> I am not sure what the patch would look like then.  You removed the
> assignment to decl, so what are you putting in ia64_builtins?  Can you
> send the full correct patch.

Sure.  Updated patch below, which probably looks somewhat more sane.

-Nathan

diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 5f22b17..880aa8d 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10165,7 +10165,7 @@ ia64_init_builtins (void)
   (*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
 
   /* TFmode support builtins.  */
-  ftype = build_function_type (float128_type, void_list_node);
+  ftype = build_function_type_list (float128_type, NULL_TREE);
   decl = add_builtin_function ("__builtin_infq", ftype,
   IA64_BUILTIN_INFQ, BUILT_IN_MD,
   NULL, NULL_TREE);
@@ -10212,13 +10212,13 @@ ia64_init_builtins (void)
   NULL, NULL_TREE)
 
   decl = def_builtin ("__builtin_ia64_bsp",
-  build_function_type (ptr_type_node, void_list_node),
-  IA64_BUILTIN_BSP);
+ build_function_type_list (ptr_type_node, NULL_TREE),
+ IA64_BUILTIN_BSP);
   ia64_builtins[IA64_BUILTIN_BSP] = decl;
 
   decl = def_builtin ("__builtin_ia64_flushrs",
-  build_function_type (void_type_node, void_list_node),
-  IA64_BUILTIN_FLUSHRS);
+ build_function_type_list (void_type_node, NULL_TREE),
+ IA64_BUILTIN_FLUSHRS);
   ia64_builtins[IA64_BUILTIN_FLUSHRS] = decl;
 
 #undef def_builtin


[PATCH] centralize builtin function type building

2011-04-21 Thread Nathan Froyd
This patch does two things:

- centralizes some infrastructure for defining builtin function types
  for frontends by providing a common function that
  DEF_FUNCTION_TYPE_FOO macros can call; and

- in order to do that well, it also introduces
  build{,_varargs}_function_type_array for cases when
  build_function_type_list's interface doesn't work so well.

build_function_type_list could have been used instead, but it would lose
the error_mark_node handling provided in the C/C++/Ada/LTO frontends.
This new interface will be necessary for eliminating other uses of
build_function_type anyway.

It would have been easier to move all of the builtin-types stuff into
the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
did, I suppose it's possible that some new front-end could have its own
set of builtin types, so I'm leaving things as they are.

The new functions can eliminate some of the games that were played with
the recent backend changes to use build_function_type_list; if this
patch is approved, I'll make the (currently uncommitted) patches that
could use build_function_type_array do so.

Bootstrap and testing in progress on x86_64-unknown-linux-gnu.  OK to
commit if successful?

-Nathan

gcc/ada/
* gcc-interface/utils.c (def_fn_type): Delete.
(DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
define_builtin_function_type.
(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
(DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
(DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
(DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.

gcc/c-family/:
* c-common.c (def_fn_type): Delete.
(DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
define_builtin_function_type.
(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
(DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
(DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
(DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.

gcc/
* tree.h (build_function_type_array): Declare.
(build_varargs_function_type_array, define_builtin_function_type):
Declare.
* tree.c (build_function_type_array_1): Define.
(build_function_type_array, build_varargs_function_type_array): Define.
(define_builtin_function_type): Define.

gcc/fortran/
* f95-lang.c (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change
to use define_builtin_function_type.
(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
(DEF_FUNCTION_TYPE_VAR_0): Likewise.

gcc/lto/
* lto-lang.c (def_fn_type): Delete.
(DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
define_builtin_function_type.
(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
(DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
(DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
(DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 1031ee9..6eb136d 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -4952,47 +4952,6 @@ typedef enum c_builtin_type builtin_type;
 /* A temporary array used in communication with def_fn_type.  */
 static GTY(()) tree builtin_types[(int) BT_LAST + 1];
 
-/* A helper function for install_builtin_types.  Build function type
-   for DEF with return type RET and N arguments.  If VAR is true, then the
-   function should be variadic after those N arguments.
-
-   Takes special care not to ICE if any of the types involved are
-   error_mark_node, which indicates that said type is not in fact available
-   (see builtin_type_for_size).  In which case the function type as a whole
-   should be error_mark_node.  */
-
-static void
-def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
-{
-  tree args = NULL, t;
-  va_list list;
-  int i;
-
-  va_start (list, n);
-  for (i = 0; i < n; ++i)
-{
-  builtin_type a = (builtin_type) va_arg (list, int);
-  t = builtin_types[a];
-  if (t == error_mark_node)
-   goto egress;
-  args = tree_cons (NULL_TREE, t, args);
-}
-  va_end (list);
-
-  args = nreverse (args);
-  if (!var)
-args = chainon (args, void_list_node);
-
-  t = builtin_types[ret];
-  if (t == error_mark_node)
-goto egress;
-  t = build_function_type (t, args);
-
- egress:
-  builtin_types[def] = t;
-  va_end (list);
-}
-
 /* Build the builtin function types and install them in the builtin_types
array for later use in builtin func

Re: [PATCH] make LABEL_DECL has its own rtx field for its associated CODE_LABEL

2011-04-21 Thread Nathan Froyd
On Thu, Apr 21, 2011 at 05:54:28PM +0200, Michael Matz wrote:
> > > In particular, FIELD_DECLs have a size, but they have no RTL associated
> > > with them.  And LABEL_DECLs have RTL, but no size.
> 
> Blaeh.  So far about nice clean ideas :)  One hacky idea: change my 
> proposal to this:
> 
>  decl_common {}  # no size, no rtl, no align, no pt_uid
>  decl_with_rtl_or_size : decl_common {
>    # add align, pt_uid
>union {
>  rtx rtl;
>  tree size;
>} u;
>  }
>  decl_with_size : decl_with_rtl_or_size {
>    # add size, size_unit
>  }
> 
> Use the rtl_or_size struct primarily for the current _with_rtl things that 
> don't naturally have a size, but use it also for FIELD_DECLs via the 
> union.

I'm not sure I follow this wrt FIELD_DECLs.  Before you have:

  ...lots of decl fields..
  tree size;
  tree size_unit;

After you have:

  ...lots of decl fields...
  union { rtx rtl; tree size; } u;
  tree size;
  tree size_unit;

Or did you mean something like:

  /* As above.  */
  decl_with_rtl_or_size
  /* Add a size_unit field.  */
  decl_with_size_unit : decl_with_rtl_or_size /* FIELD_DECL */
  /* Add a size field for DECLs that do have RTL.  */
  decl_with_rtl_and_size : decl_with_size_unit /* VAR_DECL, PARM_DECL, etc.  */

which looks just awful. :)

> Alternatively I could also envision making a new tree_ struct for just 
> field_decls, that would contain the size and other fields that currently 
> are in decl_common just for fields (in particular the off_align) member.
> The various accessors like DECL_SIZE would then need to dispatch based on 
> tree code.

You could also do something like:

struct tree_decl_size {
  tree size;
  tree size_unit;
  ...
};

struct tree_field_decl {
  ...
  struct tree_decl_size size;
};

struct tree_var_decl {
  ...
  struct tree_decl_size size;
};

static inline tree *
decl_size_1 (tree node)
{
  switch (TREE_CODE (node))
{
case FIELD_DECL: return &node->field_decl.size.size;
case VAR_DECL: return &node->var_decl.size.size;
...
default: gcc_unreachable ();
}
}

/* Might also need a HAS_DECL_SIZE_P predicate or similar.  */
#define DECL_SIZE(NODE) (*decl_size_1 (NODE))
...

which would make it somewhat more obvious when things have sizes, as
well as letting you remove DECL_SIZE{,_UNIT} from FUNCTION_DECL.
Slimming CONST_DECL and LABEL_DECL like this is useful mostly for code
cleanliness, but eliminating such fields from FUNCTION_DECL would have a
much more noticeable memory size impact.

-Nathan


Re: [PATCH PING] c++-specific bits of tree-slimming patches

2011-04-21 Thread Nathan Froyd
On Fri, Apr 08, 2011 at 01:50:24PM -0400, Jason Merrill wrote:
> On 03/24/2011 09:15 AM, Nathan Froyd wrote:
>> +  tree t = make_node (CASE_LABEL_EXPR);
>> +
>> +  TREE_TYPE (t) = void_type_node;
>> +  SET_EXPR_LOCATION (t, input_location);
>
> As jsm and richi said, using input_location like this is a regression.  
> Can we use DECL_SOURCE_LOCATION (label_decl) instead?

I went off and tried that; some callers provide a NULL label_decl.
What's the right thing to do in that case--use UNKNOWN_LOCATION or
input_location?  I'm leaning towards the former.

-Nathan


Re: [PATCH PING] c++-specific bits of tree-slimming patches

2011-04-21 Thread Nathan Froyd
On Thu, Apr 21, 2011 at 10:49:05PM -0400, Jason Merrill wrote:
> On 04/21/2011 08:50 PM, Nathan Froyd wrote:
>> On Fri, Apr 08, 2011 at 01:50:24PM -0400, Jason Merrill wrote:
>>> As jsm and richi said, using input_location like this is a regression.
>>> Can we use DECL_SOURCE_LOCATION (label_decl) instead?
>>
>> I went off and tried that; some callers provide a NULL label_decl.
>
> Hunh.  How does that work?  They fill in CASE_LABEL later?  Can that be  
> changed?

Yeah, tree-eh.c:lower_try_finally_switch.  I don't know how easy it is
to fix; it certainly looks non-trivial.

-Nathan


Re: [PATCH PING] c++-specific bits of tree-slimming patches

2011-04-22 Thread Nathan Froyd
On Fri, Apr 22, 2011 at 11:12:01AM +0200, Richard Guenther wrote:
> On Fri, Apr 22, 2011 at 8:13 AM, Mike Stump  wrote:
> > Unsurprising...  It will never fail during testsuite run, and won't
> > always fail during a bootstrap.
> >
> >> I can't think what the comment would be talking about with pointers
> >> not providing a stable order; I don't see anything that would rely
> >> on that.
> >
> >  http://gcc.gnu.org/ml/gcc/2005-04/msg00161.html
> >
> > has the details of why the code was put in.  Essentially, the Ada
> > boostrap on x86 linux.  What's worse is, at the time, it would only
> > occasionally fail, so, a bootstrap that works won't prove anything.
> 
> Well, unless we are not walking a pointer-based hashtable I don't see
> how this matters here.

I can't see the pointer traversal, either--unless there's some subtlety
in how things are added to the goto_queue.

I'm going to leave the code alone for the moment.

> To Nathan: yes, UNKNOWN_LOCATION would be correct.  Whoever then sets
> the label should adjust it accordingly.

Will commit with that change in build_case_label, then.  I will leave
the location-setting to a separate commit, if any.

-Nathan


Re: [PATCH] centralize builtin function type building

2011-04-22 Thread Nathan Froyd
On Thu, Apr 21, 2011 at 05:36:42PM +0200, Richard Guenther wrote:
> On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd  
> wrote:
> > This patch does two things:
> >
> > - centralizes some infrastructure for defining builtin function types
> >  for frontends by providing a common function that
> >  DEF_FUNCTION_TYPE_FOO macros can call; and
> >
> > - in order to do that well, it also introduces
> >  build{,_varargs}_function_type_array for cases when
> >  build_function_type_list's interface doesn't work so well.
> >
> > It would have been easier to move all of the builtin-types stuff into
> > the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
> > did, I suppose it's possible that some new front-end could have its own
> > set of builtin types, so I'm leaving things as they are.
> 
> But this is what should be done, at least for all builtins in the
> BUILT_IN_NORMAL category.  ISTR Fortran was once running into
> the issue of assigning different DECL_FUNCTION_CODE numbers to
> those builtins than other languages, breaking LTO.
> 
> So, it would be indeed nice to have a central middle-end place to
> instantiate those builtins and their required types.  I'm not sure how
> far we are from that and am too lazy to look right now ...

I agree that it would be better to have a central middle-end place for
this; I'm not entirely sure why Fortran opts to use a separate set of
types; AFAICS, it's a strict subset.  Fortran folks...?

The question of decls is something different and unrelated to this
patch, IMHO.  Is the patch OK as-is, or should I work on merging the
types into the middle-end in addition?

-Nathan


Re: [PATCH] centralize builtin function type building

2011-04-22 Thread Nathan Froyd
On Fri, Apr 22, 2011 at 02:58:31PM -0400, Michael Meissner wrote:
> On Thu, Apr 21, 2011 at 11:04:47AM -0400, Nathan Froyd wrote:
> > - centralizes some infrastructure for defining builtin function types
> >   for frontends by providing a common function that
> >   DEF_FUNCTION_TYPE_FOO macros can call; and
> > 
> > - in order to do that well, it also introduces
> >   build{,_varargs}_function_type_array for cases when
> >   build_function_type_list's interface doesn't work so well.
> 
> 1) For the DEF_FUNCTION_* replacements, the lines exceed the normal 79
>character limits we use as coding guidelines.

Will fix.

> 2) I'm not a fan of having a varargs function with an explicit count.  I tend
>to prefer a marker element (like NULL_TREE) as the last element.  In this
>case, since it is being used in macros that do have fixed elements, it 
> isn't
>a problem.

We have both kinds of varargs usage in-tree; I think the explicit count
version ought to be preferred, as it makes sharing code between the
takes-varargs version and the takes-count-and-pointer (or the takes-VEC
or takes-std::vector) version easier.  (The explicit count version makes
future function overloading with takes-count-and-pointer more difficult,
though, and of course there's __attribute__((sentinel)) support for
varargs-with-marker functions.)

I suppose you could just write the macros to use
build_function_type_list instead, but it seems nice to delegate all the
accesses to someplace else.

> 3) I'm also not a fan of passing the index into the type array, instead of a
>tree value to the call.  If you pass a tree, then it allows MD builtins to
>call it before we switch to having the MD and front end builtins share the
>bultin index.

Yes, I suppose so.

-Nathan


Re: [PATCH PING] c++-specific bits of tree-slimming patches

2011-04-25 Thread Nathan Froyd
On Fri, Apr 22, 2011 at 12:59:21AM -0400, Jason Merrill wrote:
> On 04/21/2011 10:55 PM, Nathan Froyd wrote:
>> On Thu, Apr 21, 2011 at 10:49:05PM -0400, Jason Merrill wrote:
>>> Hunh.  How does that work?  They fill in CASE_LABEL later?  Can that be
>>> changed?
>>
>> Yeah, tree-eh.c:lower_try_finally_switch.  I don't know how easy it is
>> to fix; it certainly looks non-trivial.
>
> Well, I tried adjusting it and regression testing seems fine so far.  I  
> can't think what the comment would be talking about with pointers not  
> providing a stable order; I don't see anything that would rely on
> that.

Based on discussion downthread, I plan to commit something like your
patch (I think `label' is unused after this, so requires trivial
changes) on your behalf tomorrow, unless you beat me to it or unless
somebody yells.  I'd rather have this not mixed up with the rest of the
build_case_label changes.

-Nathan


Re: [PATCH] make Ada runtime function building use build_function_type_list

2011-04-27 Thread Nathan Froyd
On Wed, Apr 20, 2011 at 10:08:21AM -0700, Nathan Froyd wrote:
> This patch changes most of the uses of build_function_type in the Ada to
> use build_function_type_list.  There are a handful of
> build_function_type calls left; replacing those will have to wait until
> we get a build_function_type_{n,vec} interface.
> 
> Tested on x86_64-unknown-linux-gnu.  OK to commit?

Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-04/msg01675.html

-Nathan


Re: trial fix to null pointer free

2011-04-27 Thread Nathan Froyd
On Wed, Apr 27, 2011 at 04:23:42PM -0700, Xinliang David Li wrote:
> This can happen when the module does not have function bodies.
>
> -   VEC_free (cgraph_node_ptr, heap, cgraph_node_map);
> -   cgraph_node_map = NULL;
> +  if (cgraph_node_map)
> +VEC_free (cgraph_node_ptr, heap, cgraph_node_map);
> +  cgraph_node_map = NULL;

Why are you doing this?  This is exactly what VEC_free already does.

-Nathan


Re: [google] Add -fstrict-enum-precision flag (issue4433083)

2011-04-28 Thread Nathan Froyd
On Thu, Apr 28, 2011 at 03:50:45PM -0400, Diego Novillo wrote:
> Committed to google/main.  Jason, Silvius, what do you think would be
> the best approach to merge this into trunk?

When this code does get merged to trunk, can the testcases abort() on
failure rather than returning 1?  This is friendlier for embedded target
testing.

-Nathan


[PATCH] convert nonlocal_goto_handler_labels to a VEC

2011-04-29 Thread Nathan Froyd
As $SUBJECT suggests.  The memory savings from this conversion is
negligible; the real benefit, IMHO, is use of a proper container instead
of EXPR_LIST.

remove_node_from_expr_list is unused after this patch; I will delete it
as an obvious followon patch if this patch is approved.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

* function.h (struct rtl_data) [x_nonlocal_goto_handler_labels]:
Convert to a VEC.
(note_nonlocal_goto_handler_label): New function.
(remove_from_nonlocal_goto_handler_labels): New function.
* builtins.c (expand_builtin): Call them.
* cfgrtl.c (delete_insn): Call
remove_from_nonlocal_goto_handler_labels.
* stmt.c (expand_label): Call note_nonlocal_goto_handler_label.
* cfgbuild.c (make_edges): Adjust for new type of
nonlocal_goto_handler_labels.
* cfglayout.c (cfg_layout_initialize): Likewise.
* except.c (insn_nothrow_p): Likewise.
* recog.c (peep2_attempt): Likewise.
* sched-rgn.c (is_cfg_nonregular): Likewise.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index b2534ce..839b212 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6168,9 +6168,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum 
machine_mode mode,
 
  /* This is copied from the handling of non-local gotos.  */
  expand_builtin_setjmp_setup (buf_addr, label_r);
- nonlocal_goto_handler_labels
-   = gen_rtx_EXPR_LIST (VOIDmode, label_r,
-nonlocal_goto_handler_labels);
+ note_nonlocal_goto_handler_label (label_r);
  /* ??? Do not let expand_label treat us as such since we would
 not want to be both on the list of non-local labels and on
 the list of forced labels.  */
@@ -6188,7 +6186,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum 
machine_mode mode,
 
  /* Remove the dispatcher label from the list of non-local labels
 since the receiver labels have been added to it above.  */
- remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
+ remove_from_nonlocal_goto_handler_labels (label_r);
  return const0_rtx;
}
   break;
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 6f0d69e..82b5e63 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -338,7 +338,8 @@ make_edges (basic_block min, basic_block max, int update_p)
  /* Add any appropriate EH edges.  */
  rtl_make_eh_edge (edge_cache, bb, insn);
 
- if (code == CALL_INSN && nonlocal_goto_handler_labels)
+ if (code == CALL_INSN
+ && !VEC_empty (rtx, nonlocal_goto_handler_labels))
{
  /* ??? This could be made smarter: in some cases it's possible
 to tell that certain calls will not do a nonlocal goto.
@@ -347,9 +348,13 @@ make_edges (basic_block min, basic_block max, int update_p)
 those functions or to other nested functions that use them
 could possibly do nonlocal gotos.  */
  if (can_nonlocal_goto (insn))
-   for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
- make_label_edge (edge_cache, bb, XEXP (x, 0),
-  EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
+   {
+ unsigned int ix;
+ FOR_EACH_VEC_ELT_REVERSE (rtx, nonlocal_goto_handler_labels,
+   ix, x)
+   make_label_edge (edge_cache, bb, x,
+EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
+   }
}
}
 
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index 548e21f..38db3f4 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -1291,6 +1291,7 @@ cfg_layout_initialize (unsigned int flags)
 {
   rtx x;
   basic_block bb;
+  unsigned int ix;
 
   initialize_original_copy_tables ();
 
@@ -1299,9 +1300,9 @@ cfg_layout_initialize (unsigned int flags)
   record_effective_endpoints ();
 
   /* Make sure that the targets of non local gotos are marked.  */
-  for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
+  FOR_EACH_VEC_ELT_REVERSE (rtx, nonlocal_goto_handler_labels, ix, x)
 {
-  bb = BLOCK_FOR_INSN (XEXP (x, 0));
+  bb = BLOCK_FOR_INSN (x);
   bb->flags |= BB_NON_LOCAL_GOTO_TARGET;
 }
 
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index c450ca0..a3e1202 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -134,7 +134,7 @@ delete_insn (rtx insn)
  NOTE_DELETED_LABEL_NAME (insn) = name;
}
 
-  remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
+  remove_from_nonlocal_goto_handler_labels (insn);
 }
 
   if (really_delete)
diff --git a/gcc/except.c b/gcc/except.c
index 5c6359e..c8da137 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1819,7 +1819,7 @@ insn_nothrow_p (const_rtx insn)
 bool
 can_nonlocal_goto (const

[PATCH] convert forced_labels to a VEC

2011-04-29 Thread Nathan Froyd
As $SUBJECT suggests.  Just like the nonlocal_goto_handler_labels, the
real benefit is a proper container instead of an EXPR_LIST.

in_expr_list_p is unused after this patch; I will delete it as obvious
in a followon patch if this patch is approved.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

* cfgbuild.c (struct expr_status) [x_forced_labels]: Change to a
VEC.
(note_forced_label): New function.
* stmt.c (force_label_rtx, expand_label): Call it.
* except.c (sjlj_emit_dispatch_table): Likewise.
* cfgbuild.c (make_edges): Adjust for new type of forced_labels.
* sched-rgn.c (is_cfg_nonregular): Likewise.
* reload1.c (set_initial_label_offsets): Likewise.
* jump.c (rebuild_jump_labels): Likewise.
* cfgrtl.c (can_delete_label_p): Likewise.  Change return type
to
bool.

diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 6f0d69e..642f57e 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -216,7 +216,7 @@ make_edges (basic_block min, basic_block max, int update_p)
   /* Heavy use of computed goto in machine-generated code can lead to
  nearly fully-connected CFGs.  In that case we spend a significant
  amount of time searching the edge lists for duplicates.  */
-  if (forced_labels || cfun->cfg->max_jumptable_ents > 100)
+  if (!VEC_empty (rtx, forced_labels) || cfun->cfg->max_jumptable_ents > 100)
 edge_cache = sbitmap_alloc (last_basic_block);
 
   /* By nature of the way these get numbered, ENTRY_BLOCK_PTR->next_bb block
@@ -296,8 +296,9 @@ make_edges (basic_block min, basic_block max, int update_p)
 everything on the forced_labels list.  */
  else if (computed_jump_p (insn))
{
- for (x = forced_labels; x; x = XEXP (x, 1))
-   make_label_edge (edge_cache, bb, XEXP (x, 0), EDGE_ABNORMAL);
+ unsigned int ix;
+ FOR_EACH_VEC_ELT_REVERSE (rtx, forced_labels, ix, x)
+   make_label_edge (edge_cache, bb, x, EDGE_ABNORMAL);
}
 
  /* Returns create an exit out.  */
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index c450ca0..e01b7bb 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -65,7 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "df.h"
 
 static int can_delete_note_p (const_rtx);
-static int can_delete_label_p (const_rtx);
+static bool can_delete_label_p (const_rtx);
 static basic_block rtl_split_edge (edge);
 static bool rtl_move_block_after (basic_block, basic_block);
 static int rtl_verify_flow_info (void);
@@ -101,13 +101,20 @@ can_delete_note_p (const_rtx note)
 
 /* True if a given label can be deleted.  */
 
-static int
+static bool
 can_delete_label_p (const_rtx label)
 {
-  return (!LABEL_PRESERVE_P (label)
- /* User declared labels must be preserved.  */
- && LABEL_NAME (label) == 0
- && !in_expr_list_p (forced_labels, label));
+  rtx x;
+  unsigned int ix;
+
+  if (LABEL_PRESERVE_P (label) || LABEL_NAME (label) != 0)
+return false;
+
+  FOR_EACH_VEC_ELT_REVERSE (rtx, forced_labels, ix, x)
+if (x == label)
+  return false;
+
+  return true;
 }
 
 /* Delete INSN by patching it out.  Return the next insn.  */
diff --git a/gcc/except.c b/gcc/except.c
index 5c6359e..858dde7 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1233,8 +1233,7 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int 
num_dispatch)
  label on the nonlocal_goto_label list.  Since we're modeling these
  CFG edges more exactly, we can use the forced_labels list instead.  */
   LABEL_PRESERVE_P (dispatch_label) = 1;
-  forced_labels
-= gen_rtx_EXPR_LIST (VOIDmode, dispatch_label, forced_labels);
+  note_forced_label (dispatch_label);
 #endif
 
   /* Load up exc_ptr and filter values from the function context.  */
diff --git a/gcc/function.h b/gcc/function.h
index fa44958..5b1ebfe 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -137,7 +137,7 @@ struct GTY(()) expr_status {
   rtx x_apply_args_value;
 
   /* List of labels that must never be deleted.  */
-  rtx x_forced_labels;
+  VEC(rtx,gc) *x_forced_labels;
 };
 
 typedef struct call_site_record_d *call_site_record;
@@ -463,6 +463,14 @@ extern GTY(()) struct rtl_data x_rtl;
want to do differently.  */
 #define crtl (&x_rtl)
 
+/* Add X to the forced_labels list.  */
+
+static inline void
+note_forced_label (rtx x)
+{
+  VEC_safe_push (rtx, gc, forced_labels, x);
+}
+
 struct GTY(()) stack_usage
 {
   /* # of bytes of static stack space allocated by the function.  */
diff --git a/gcc/jump.c b/gcc/jump.c
index 39fc234..7977f3d 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -76,7 +76,8 @@ static int returnjump_p_1 (rtx *, void *);
 static void
 rebuild_jump_labels_1 (rtx f, bool count_forced)
 {
-  rtx insn;
+  rtx x;
+  unsigned int ix;
 
   timevar_push (TV_REBUILD_JUMP);
   init_label_info (f);
@@ -87,9 +88,9 @@ rebuild_jump_labels_1 (rtx f, bool count_forced)
  count doesn't drop to z

[PATCH,c++] delete TREE_NEGATED_INT

2011-04-29 Thread Nathan Froyd
As $SUBJECT suggests.  It is write-only; I'm not sure what it was ever
used for.

Tested on x86_64-unknonw-linux-gnu.  OK to commit?

-Nathan

gcc/cp/
* cp-tree.h (TREE_NEGATED_INT): Delete.
* semantics.c (finish_unary_op_expr): Don't try to set it.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a65998d..899959e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2937,10 +2937,6 @@ more_aggr_init_expr_args_p (const 
aggr_init_expr_arg_iterator *iter)
 #define TYPENAME_IS_RESOLVING_P(NODE) \
   (TREE_LANG_FLAG_2 (TYPENAME_TYPE_CHECK (NODE)))
 
-/* Nonzero in INTEGER_CST means that this int is negative by dint of
-   using a twos-complement negated operand.  */
-#define TREE_NEGATED_INT(NODE) TREE_LANG_FLAG_0 (INTEGER_CST_CHECK (NODE))
-
 /* [class.virtual]
 
A class that declares or inherits a virtual function is called a
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 815824a..99ca28b 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2302,19 +2302,7 @@ tree
 finish_unary_op_expr (enum tree_code code, tree expr)
 {
   tree result = build_x_unary_op (code, expr, tf_warning_or_error);
-  /* Inside a template, build_x_unary_op does not fold the
- expression. So check whether the result is folded before
- setting TREE_NEGATED_INT.  */
-  if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST
-  && TREE_CODE (result) == INTEGER_CST
-  && !TYPE_UNSIGNED (TREE_TYPE (result))
-  && INT_CST_LT (result, integer_zero_node))
-{
-  /* RESULT may be a cached INTEGER_CST, so we must copy it before
-setting TREE_NEGATED_INT.  */
-  result = copy_node (result);
-  TREE_NEGATED_INT (result) = 1;
-}
+
   if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
 overflow_warning (input_location, result);
 


Re: [google] Add new warning -Wreal-conversion (issue4436068)

2011-04-29 Thread Nathan Froyd
On Fri, Apr 29, 2011 at 10:59:31AM -0400, Diego Novillo wrote:
>   * g++.dg/warn/Wreal-conversion-1.C: New.
>   * gcc.dg/Wreal-conversion-1.c: New.

Could a single copy of the test be placed in c-c++-common, instead?

-Nathan


Re: Turn streamer cache to pointer_map

2011-05-02 Thread Nathan Froyd
On Mon, May 02, 2011 at 04:46:23PM +0200, Richard Guenther wrote:
> >> *** typedef void (lto_free_section_data_f) (
> >> *** 346,355 
> >>  struct lto_streamer_cache_d
> >>  {
> >>    /* The mapping between tree nodes and slots into the nodes array.  */
> >> !   htab_t node_map;
> >> !
> >> !   /* Node map to store entries into.  */
> >> !   alloc_pool node_map_entries;
> >>
> >>    /* The nodes pickled so far.  */
> >>    VEC(tree,heap) *nodes;
> >> --- 346,352 
> >>  struct lto_streamer_cache_d
> >>  {
> >>    /* The mapping between tree nodes and slots into the nodes array.  */
> >> !   struct pointer_map_t GTY((skip)) *node_map;
> >
> > If you skip node_map you can end up with false entries for re-used
> > trees.  So I don't think that's a good idea.
> 
> Or we can safely mark the whole struct as non-GC (and also allocate
> it that way).

We already do (see lto-streamer.c:lto_streamer_cache_create; there's no
GTY marker on lto_streamer_cache_d.  So Honza's original GTY annotation
there is superfluous.

-Nathan


Re: [Patch,AVR]: Fix PR45099

2011-05-02 Thread Nathan Froyd
On Mon, May 02, 2011 at 05:23:48PM +0200, Georg-Johann Lay wrote:
> PR45099 is an extension that gives an error when a fixed register is
> needed to pass a parameter to a function.
> 
> Because the program will show malfunction when such code is generated,
> anyway, I think an error is more appropriate than a warning (as
> proposed in the PR).

This seems like something that should be handled by common code.

-Nathan


  1   2   3   >