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 <ja...@redhat.com> wrote:
> On Thu, Nov 16, 2017 at 11:21 AM, Nathan Froyd <froy...@mozilla.com> 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


[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 ">mStorage" "gimple" } }


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

2015-10-13 Thread Nathan Froyd
From: Nathan Froyd <froy...@gmail.com>

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  <froy...@gcc.gnu.org>
+
+   * 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  <jos...@codesourcery.com>
 
* 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



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::atomicT::compare_exchange_{weak,strong}

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

#include atomic

enum x { a, b };

std::atomicx 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::atomicT 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::atomicT::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 nfr...@mozilla.com ha scritto:
 Compiling the test program:
 
 #include atomic
 
 enum x { a, b };
 
 std::atomicx 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::atomicT::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 atomic
+#include testsuite_common_types.h
+
+#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_loweringORDER 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)   \
+  do {  \
+std::atomice x

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


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,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


[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
+;; http://www.gnu.org/licenses/.
+
+(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_REGS
+  @internal)
+
+(define_register_constraint Raw TARGET_A16 ? A_REGS : NO_REGS
+  @internal)
+

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


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  marc.gli...@inria.fr
 
   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
 http://www.gnu.org/licenses/.  */
 
 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_class
 #define BASE_REG_CLASS GENERAL_REGS
 #define 

[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
+;; http://www.gnu.org/licenses/.  */
+
+(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.h
index 4e8c338..62cdbae 100644
--- a/gcc/config/mmix/mmix-protos.h
+++ b/gcc/config/mmix/mmix-protos.h
@@ -40,6 +40,7 @@ 

[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 

[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_MODE (all-wide_lshr, wider_mode);
  XEXP 

[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

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: [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


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: [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: [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: [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


[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:


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


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:
case TS_VEC:
-   case TS_BLOCK:
case TS_BINFO:
case TS_STATEMENT_LIST:
case

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, 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_stmt_list;
 
   /* In C++, Nonzero if we should treat statements as full
  expressions.  In particular, this variable is no-zero if at the
@@ -483,11 +483,17 @@ struct GTY

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


[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 froy...@codesourcery.com 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
 Johnson  jani...@codesourcery.com
Nathan Froyd  froy...@codesourcery.com

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  jani...@codesourcery.com
Nathan Froyd  froy...@codesourcery.com

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/gcc/testsuite/g++.dg/parse/pr18770.C
new file mode 100644
index 000..df57be4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr18770.C
@@ -0,0 +1,175 @@
+/* { dg-do compile } */
+
+/* The ISO C++ standard says, in Section 3.3.2 sentence 4, that a name
+   declared in the for-init-statement or in the condition of an if, for
+   while, or switch statement can't be redeclared in the outermost block
+   of the controlled statement.  (Note, this is not an error in C.)  */
+
+extern void foo

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 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: [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 froy...@codesourcery.com 
 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] 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
index 

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 froy...@codesourcery.com 
 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: [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





[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 *cand, int 

[PATCH] remove some TYPE_ARG_TYPES usage in objc/

2011-05-20 Thread Nathan Froyd
This patch removes one of the two remaining uses of TYPE_ARG_TYPES in
the ObjC/C++ frontends.  (The other one should be addressed in a
different manner.)  Given the constraints of the function_args_iterator
interface, I thought rewriting the logic of the loop would make things
slightly clearer.

Tested on x86_64-unknown-linux-gnu with ObjC/C++.  OK to commit?

-Nathan

gcc/objc/
* objc-act.c (objc_compare_types): Use function_args_iterator
instead of TYPE_ARG_TYPES to compare function argument types.

diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 7e69b0d..0e15fe5 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -2420,6 +2420,8 @@ objc_compare_types (tree ltyp, tree rtyp, int argno, tree 
callee)
  lenient than C or C++ on this.  */
   if (TREE_CODE (ltyp) == FUNCTION_TYPE  TREE_CODE (rtyp) == FUNCTION_TYPE)
 {
+  function_args_iterator liter, riter;
+
   /* Return types must be covariant.  */
   if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
   !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
@@ -2427,16 +2429,31 @@ objc_compare_types (tree ltyp, tree rtyp, int argno, 
tree callee)
   return false;
 
   /* Argument types must be contravariant.  */
-  for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
-  ltyp  rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
+  function_args_iter_init (liter, ltyp);
+  function_args_iter_init (riter, rtyp);
+
+  while (1)
{
- if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
-  !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
- argno, callee))
+ ltyp = function_args_iter_cond (liter);
+ rtyp = function_args_iter_cond (riter);
+
+ /* If we've exhaused both lists simulateously, we're done.  */
+ if (ltyp == NULL_TREE  rtyp == NULL_TREE)
+   break;
+
+ /* If one list is shorter than the other, they fail to match.  */
+ if (ltyp == NULL_TREE || rtyp == NULL_TREE)
return false;
-  }
 
-  return (ltyp == rtyp);
+ if (!comptypes (rtyp, ltyp)
+  !objc_compare_types (rtyp, ltyp, argno, callee))
+   return false;
+
+ function_args_iter_next (liter);
+ function_args_iter_next (riter);
+   }
+
+  return true;
 }
 
   /* Past this point, we are only interested in ObjC class instances,


[PATCH] remove TYPE_ARG_TYPES from godump.c

2011-05-20 Thread Nathan Froyd
As $SUBJECT suggests.  It may be worth noting that we now do more work
after this patch (stdarg_p and prototype_p both traverse TYPE_ARG_TYPES
under the hood); one day those will be simple boolean tests.

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

-Nathan

gcc/
* godump.c (go_format_type): Don't use TYPE_ARG_TYPES.

diff --git a/gcc/godump.c b/gcc/godump.c
index 16a4803..c4557f8 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -741,9 +741,11 @@ go_format_type (struct godump_container *container, tree 
type,
 
 case FUNCTION_TYPE:
   {
-   tree args;
+   tree arg_type;
bool is_varargs;
tree result;
+   function_args_iterator iter;
+   bool seen_arg = false;
 
/* Go has no way to write a type which is a function but not a
   pointer to a function.  */
@@ -754,25 +756,20 @@ go_format_type (struct godump_container *container, tree 
type,
  }
 
obstack_1grow (ob, '(');
-   is_varargs = true;
-   for (args = TYPE_ARG_TYPES (type);
-args != NULL_TREE;
-args = TREE_CHAIN (args))
+   is_varargs = stdarg_p (type);
+   FOREACH_FUNCTION_ARGS (type, arg_type, iter)
  {
-   if (VOID_TYPE_P (TREE_VALUE (args)))
- {
-   gcc_assert (TREE_CHAIN (args) == NULL);
-   is_varargs = false;
-   break;
- }
-   if (args != TYPE_ARG_TYPES (type))
+   if (VOID_TYPE_P (arg_type))
+ break;
+   if (seen_arg)
  obstack_grow (ob, , , 2);
-   if (!go_format_type (container, TREE_VALUE (args), true, false))
+   if (!go_format_type (container, arg_type, true, false))
  ret = false;
+   seen_arg = true;
  }
if (is_varargs)
  {
-   if (TYPE_ARG_TYPES (type) != NULL_TREE)
+   if (prototype_p (type))
  obstack_grow (ob, , , 2);
obstack_grow (ob, ...interface{}, 14);
  }


Re: [PATCH,c++] describe reasons for function template overload resolution failure

2011-05-18 Thread Nathan Froyd
On 05/18/2011 01:45 PM, Jason Merrill wrote:
 Thanks for the background; I will keep the principle in mind.  IMHO, in
 a case like this where we're logically printing one diagnostic (one
 error and then some number of explanatory notes) keeping all the logic
 for the diagnostic centralized makes more sense.
 
 I understand, but that means we have to create a whole data structure to try
 and preserve information about the failure, and either having to duplicate
 every possible error or give less informative messages.  I feel even more
 strongly about this after looking more closely at your patch.

Thank you for the review.  I'll go back and try things the way you suggest;
before I go off and do that, I've taken your comments to mean that:

- fn_type_unification/type_unification_real and associated callers should take
  a boolean `explain' parameter, which is normally false;

- failed calls to fn_type_unification should save the arguments for the call
  for future explanation;

- printing diagnostic messages should call fn_type_unification with the saved
  arguments and a true `explain' parameter.

This is similar to passing `struct unification_info' and really only involves
shuffling code from call.c into the unify_* functions in pt.c and some minor
changes to the rejection_reason code in call.c.  The only wrinkle I see is
that in cases like these:

   if (TREE_PURPOSE (TREE_VEC_ELT (tparms, i)))
 {
   tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
   tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
   arg = tsubst_template_arg (arg, targs, tf_none, NULL_TREE);
   arg = convert_template_argument (parm, arg, targs, tf_none,
i, NULL_TREE, ui);
   if (arg == error_mark_node)
 return unify_parameter_deduction_failure (ui, parm);
 
 In this case, the problem is that we tried to use the default template
 argument but it didn't work for some reason; we should say that, not just say
 we didn't deduce something, or the users will say but there's a default
 argument!.
 
 In this case, we should do the substitution again with tf_warning_or_error so
 the user can see what the problem actually is, not just say that there was
 some unspecified problem.

 if (coerce_template_parms (parm_parms,
full_argvec,
TYPE_TI_TEMPLATE (parm),
tf_none,
/*require_all_args=*/true,
/*use_default_args=*/false, ui)
 == error_mark_node)
   return 1;
 
 Rather than pass ui down into coerce_template_parms we should just note when
 it fails and run it again at diagnostic time.
 
   converted_args
 = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, tf_none,
   /*require_all_args=*/false,
   /*use_default_args=*/false, ui));
   if (converted_args == error_mark_node)
 return 1;

 Here too.

   if (fntype == error_mark_node)
 return unify_substitution_failure (ui);
 
 And this should remember the arguments so we can do the tsubst again at
 diagnostic time.

and other bits of pt.c, I'm interpreting your suggestions to mean that
tf_warning_or_error should be passed if `explain' is true.  That doesn't seem
like the best interface for diagnostics, as we'll get:

foo.cc:105:40 error: no matching function for call to bar (...)
foo.cc:105:40 note: candidates are:
bar.hh:7000:30 note: bar (...)
bar.hh:7000:30 note: [some reason]
bar.hh:4095:63 note: bar (...)
bar.hh:... error: [some message from tf_warning_or_error code]

I'm not sure that the last location there will necessary be the same as the
one that's printed for the declaration.  I think I'll punt on that issue for
the time being until we see how the diagnostics work out.  There's also the
matter of the error vs. note diagnostic.  I think it'd be nicer to keep the
conformity of a note for all the explanations; the only way I see to do that
is something like:

- Add a tf_note flag; pass it at all appropriate call sites when explaining
  things;

- Add a tf_issue_diagnostic flag that's the union of tf_{warning,error,note};

- Change code that looks like:

  if (complain  tf_warning_or_error)
error (STUFF);

  to something like:

  if (complain  tf_issue_diagnostic)
emit_diagnostic (complain  tf_note ? DK_NOTE : DK_ERROR, STUFF);

  passing input_location if we're not already passing a location.

That involves a lot of code churn.  (Not a lot if you just modified the
functions above, but with this scheme, you'd have to call instantiate_template
again from the diagnostic code, and I assume you'd want to call that with
tf_note as well, which means hitting a lot more code.)  I don't see a better
way 

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

2011-05-17 Thread Nathan Froyd
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.

-Nathan


Re: Patch: New GTY ((atomic)) option

2011-05-15 Thread Nathan Froyd
On 05/15/2011 08:49 PM, Gabriel Dos Reis wrote:
 On Sun, May 15, 2011 at 7:13 PM, Nicola Pero
 nicola.p...@meta-innovation.com wrote:
 This patch adds a new GTY option, atomic, which is similar to the 
 identical option you have with Boehm GC
 and which can be used with pointers to inform the GC/PCH machinery that they 
 point to an area of memory that
 [...]
 This patch basically implements it, but at this stage requires you to 
 explicitly tell gengtype that the
 pointer is atomic (and that is safe for gengtype to ignore the memory it 
 points to).
 
 then should you not name the attribute ignore?

Or even the existing attribute skip?

-Nathan



Re: [PATCH] Fix PR46728 (move pow/powi folds to tree phases)

2011-05-13 Thread Nathan Froyd
On 05/13/2011 11:26 AM, Richard Guenther wrote:
 On Fri, May 13, 2011 at 5:01 PM, Nathan Froyd froy...@codesourcery.com 
 wrote:
 On 05/13/2011 10:52 AM, William J. Schmidt wrote:
 This patch addresses PR46728, which notes that pow and powi need to be
 lowered in tree phases to restore lost FMA opportunities and expose
 vectorization opportunities.

 +struct gimple_opt_pass pass_lower_pow =
 +{
 + {
 +  GIMPLE_PASS,
 +  lower_pow,   /* name */
 +  NULL,  /* gate */

 Please make this controlled by an option; this pass doesn't need to be run 
 all
 the time.

 IMHO, the pass shouldn't run at anything less than -O3, but that's for other
 people to decide.
 
 It was run unconditionally before, so unless we preserve the code at
 expansion time we have to do it here.

We were doing it unconditionally before because we were calling it through
folding and expansion, both of which only fired if we were expanding pow
calls; now we're groveling over the whole IR to look for optimization
opportunities that, let's be honest, the vast majority of code is never going
to care about.  The whole point of the patch is to restore lost FMA
opportunities and expose vectorization opportunities.  The first reason
*might* be good justification for running it at -O2, but the second reason
calls for -O3 or at the very least flag_tree_vectorize.

However, I don't think anybody's going to notice/care if -O1 stopped folding
pow calls; could we at least add a flag_expensive_optimizations  optimize 
gate?

-Nathan



[PATCH] fix PR middle-end/48965, CASE_CHAIN fallout

2011-05-11 Thread Nathan Froyd
The comment for pointer_map_traverse says:

/* Pass each pointer in PMAP to the function in FN, together with the pointer
to the value and the fixed parameter DATA.  If FN returns false, the
iteration stops.  */

However, the code in tree-cfg:edge_to_cases_cleanup does:

static bool
edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value,
   void *data ATTRIBUTE_UNUSED)
{
   tree t, next;

   for (t = (tree) *value; t; t = next)
 {
   next = CASE_CHAIN (t);
   CASE_CHAIN (t) = NULL;
 }

   *value = NULL;
   return false;
}

...
   pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL);

which means that we're only cleaning up one of the case chains stored in
EDGE_TO_CASES.  Since it's a pointer_map, we can potentially get
different chains selected each time.  Under -fcompare-debug, this leads
to problems later on when we walk the function body and collect all the
DECLs referenced therein; we might walk non-NULL CASE_CHAINs and reach
more DECLs, depending on the memory layout.

This wouldn't have shown up previously, since TREE_CHAIN was used, and
we wouldn't walk TREE_CHAIN of expressions to find DECLs.

The fix is simple: return true from the above function!  I've added
logic to verify_expr to catch this sort of thing.

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

-Nathan

gcc/
PR middle-end/48965
* tree-cfg.c (edge_to_cases_cleanup): Return true.
(verify_expr) [CASE_LABEL_EXPR]: Add checking.

diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index e1f8707..e2e84a2 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -843,7 +843,7 @@ edge_to_cases_cleanup (const void *key
ATTRIBUTE_UNUSED, void **value,
  }

*value = NULL;
-  return false;
+  return true;
  }

  /* Start recording information mapping edges to case labels.  */
@@ -2830,6 +2830,14 @@ verify_expr (tree *tp, int *walk_subtrees, void
*data ATTRIBUTE_UNUSED)
*walk_subtrees = 0;
break;

+case CASE_LABEL_EXPR:
+  if (CASE_CHAIN (t))
+   {
+ error (invalid CASE_CHAIN);
+ return t;
+   }
+  break;
+
  default:
break;
  }


[PATCH] use build_function_type less in c-family and LTO

2011-05-10 Thread Nathan Froyd
As $SUBJECT suggests.  Eradicating build_function_type from the C FE
entirely will take a bit more work.

The lto change is included because def_fn_type there is clearly a copy
of the C version; I am going to assume that given other approvals of
copy-paste code, this one is obvious.

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

-Nathan

gcc/c-family/
* c-common.c (def_fn_type): Don't call build_function_type, call
build_function_type_vec or build_varargs_function_type_vec instead.
(c_common_nodes_and_builtins): Likewise.

gcc/lto/
* lto-lang.c (def_fn_type): Don't call build_function_type, call
build_function_type_vec or build_varargs_function_type_vec instead.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 41cb717..a04801e 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4414,7 +4414,8 @@ static tree builtin_types[(int) BT_LAST + 1];
 static void
 def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
 {
-  tree args = NULL, t;
+  tree t;
+  tree *args = XALLOCAVEC (tree, n);
   va_list list;
   int i;
 
@@ -4425,18 +4426,17 @@ def_fn_type (builtin_type def, builtin_type ret, bool 
var, int n, ...)
   t = builtin_types[a];
   if (t == error_mark_node)
goto egress;
-  args = tree_cons (NULL_TREE, t, args);
+  args[i] = t;
 }
   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);
+  if (var)
+t = build_varargs_function_type_array (t, n, args);
+  else
+t = build_function_type_array (t, n, args);
 
  egress:
   builtin_types[def] = t;
@@ -4931,7 +4931,8 @@ c_common_nodes_and_builtins (void)
 uintptr_type_node =
   TREE_TYPE (identifier_global_value (c_get_ident (UINTPTR_TYPE)));
 
-  default_function_type = build_function_type (integer_type_node, NULL_TREE);
+  default_function_type
+= build_varargs_function_type_list (integer_type_node, NULL_TREE);
   ptrdiff_type_node
 = TREE_TYPE (identifier_global_value (get_identifier (PTRDIFF_TYPE)));
   unsigned_ptrdiff_type_node = c_common_unsigned_type (ptrdiff_type_node);
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index 5872928..5fe89b8 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -433,7 +433,8 @@ handle_format_arg_attribute (tree * ARG_UNUSED (node), tree 
ARG_UNUSED (name),
 static void
 def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
 {
-  tree args = NULL, t;
+  tree t;
+  tree *args = XALLOCAVEC (tree, n);
   va_list list;
   int i;
 
@@ -444,18 +445,17 @@ def_fn_type (builtin_type def, builtin_type ret, bool 
var, int n, ...)
   t = builtin_types[a];
   if (t == error_mark_node)
goto egress;
-  args = tree_cons (NULL_TREE, t, args);
+  args[i] = t;
 }
   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);
+  if (var)
+t = build_varargs_function_type_array (t, n, args);
+  else
+t = build_function_type_array (t, n, args);
 
  egress:
   builtin_types[def] = t;


[PATCH] don't use build_function_type in the Ada FE

2011-05-10 Thread Nathan Froyd
As $SUBJECT suggests.  Rather pleasant how easy this was.

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

-Nathan

gcc/ada/
* gcc-interface/utils.c (def_fn_type): Don't call build_function_type;
call build_function_type_vec or build_varargs_function_type_vec
instead.
(create_subprog_type): Likewise.

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index cfa58b9..efeceea 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -1181,24 +1181,16 @@ create_subprog_type (tree return_type, tree 
param_decl_list, tree cico_list,
 bool return_unconstrained_p, bool return_by_direct_ref_p,
 bool return_by_invisi_ref_p)
 {
-  /* A chain of TREE_LIST nodes whose TREE_VALUEs are the data type nodes of
- the subprogram formal parameters.  This list is generated by traversing
- the input list of PARM_DECL nodes.  */
-  tree param_type_list = NULL_TREE;
+  /* A list of the data type nodes of the subprogram formal parameters.
+ This list is generated by traversing the input list of PARM_DECL
+ nodes.  */
+  VEC(tree,gc) *param_type_list = NULL;
   tree t, type;
 
   for (t = param_decl_list; t; t = DECL_CHAIN (t))
-param_type_list = tree_cons (NULL_TREE, TREE_TYPE (t), param_type_list);
+VEC_safe_push (tree, gc, param_type_list, TREE_TYPE (t));
 
-  /* The list of the function parameter types has to be terminated by the void
- type to signal to the back-end that we are not dealing with a variable
- parameter subprogram, but that it has a fixed number of parameters.  */
-  param_type_list = tree_cons (NULL_TREE, void_type_node, param_type_list);
-
-  /* The list of argument types has been created in reverse so reverse it.  */
-  param_type_list = nreverse (param_type_list);
-
-  type = build_function_type (return_type, param_type_list);
+  type = build_function_type_vec (return_type, param_type_list);
 
   /* TYPE may have been shared since GCC hashes types.  If it has a different
  CICO_LIST, make a copy.  Likewise for the various flags.  */
@@ -4959,7 +4951,8 @@ static GTY(()) tree builtin_types[(int) BT_LAST + 1];
 static void
 def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
 {
-  tree args = NULL, t;
+  tree t;
+  tree *args = XALLOCAVEC (tree, n);
   va_list list;
   int i;
 
@@ -4970,18 +4963,17 @@ def_fn_type (builtin_type def, builtin_type ret, bool 
var, int n, ...)
   t = builtin_types[a];
   if (t == error_mark_node)
goto egress;
-  args = tree_cons (NULL_TREE, t, args);
+  args[i] = t;
 }
   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);
+  if (var)
+t = build_varargs_function_type_array (t, n, args);
+  else
+t = build_function_type_array (t, n, args);
 
  egress:
   builtin_types[def] = t;


[PATCH] don't use build_function_type in the Java FE

2011-05-10 Thread Nathan Froyd
As $SUBJECT suggests.  Nothing much to see here.

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

-Nathan

gcc/java/
* expr.c (build_jni_stub): Don't call build_function_type; call
build_function_type_vec instead.
* typeck.c (parse_signature_string): Likewise.

diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 3be1cff..5d9811a 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -2616,7 +2616,7 @@ expand_invoke (int opcode, int method_ref_index, int 
nargs ATTRIBUTE_UNUSED)
 tree
 build_jni_stub (tree method)
 {
-  tree jnifunc, call, body, method_sig, arg_types;
+  tree jnifunc, call, body, method_sig, arg_type;
   tree jniarg0, jniarg1, jniarg2, jniarg3;
   tree jni_func_type, tem;
   tree env_var, res_var = NULL_TREE, block;
@@ -2624,7 +2624,9 @@ build_jni_stub (tree method)
   tree meth_var;
   tree bind;
   VEC(tree,gc) *args = NULL;
+  VEC(tree,gc) *arg_types = NULL;
   int args_size = 0;
+  function_args_iterator iter;
 
   tree klass = DECL_CONTEXT (method);
   klass = build_class_ref (klass);
@@ -2684,13 +2686,17 @@ build_jni_stub (tree method)
 
   VEC_safe_push (tree, gc, args, tem);
 }
-  arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
 
-  /* Argument types for static methods and the JNIEnv structure.
- FIXME: Write and use build_function_type_vec to avoid this.  */
+  /* Argument types for static methods and the JNIEnv structure.  */
+  VEC_safe_push (tree, gc, arg_types, ptr_type_node);
   if (METHOD_STATIC (method))
-arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
-  arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
+VEC_safe_push (tree, gc, arg_types, object_ptr_type_node);
+  FOREACH_FUNCTION_ARGS (TREE_TYPE (method), arg_type, iter)
+{
+  if (arg_type == void_type_node)
+   break;
+  VEC_safe_push (tree, gc, arg_types, arg_type);
+}
 
   /* We call _Jv_LookupJNIMethod to find the actual underlying
  function pointer.  _Jv_LookupJNIMethod will throw the appropriate
@@ -2703,7 +2709,7 @@ build_jni_stub (tree method)
 IDENTIFIER_LENGTH (method_sig)));
   jniarg3 = build_int_cst (NULL_TREE, args_size);
 
-  tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
+  tem = build_function_type_vec (TREE_TYPE (TREE_TYPE (method)), arg_types);
 
 #ifdef MODIFY_JNI_METHOD_CALL
   tem = MODIFY_JNI_METHOD_CALL (tem);
diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c
index 6755217..247fd64 100644
--- a/gcc/java/typeck.c
+++ b/gcc/java/typeck.c
@@ -407,18 +407,17 @@ parse_signature_string (const unsigned char *sig_string, 
int sig_length)
 
   if (str  limit  str[0] == '(')
 {
-  tree argtype_list = NULL_TREE;
+  VEC(tree,gc) *argtypes = NULL;
   str++;
   while (str  limit  str[0] != ')')
{
  tree argtype = parse_signature_type (str, limit);
- argtype_list = tree_cons (NULL_TREE, argtype, argtype_list);
+ VEC_safe_push (tree, gc, argtypes, argtype);
}
   if (str++, str = limit)
abort ();
   result_type = parse_signature_type (str, limit);
-  argtype_list = chainon (nreverse (argtype_list), end_params_node);
-  result_type = build_function_type (result_type, argtype_list);
+  result_type = build_function_type_vec (result_type, argtypes);
 }
   else
 result_type = parse_signature_type (str, limit);


[PATCH] split tree_type, a.k.a. tuplifying types

2011-05-10 Thread Nathan Froyd
tree_type is a fairly big structure, and several of its fields are
overloaded.  This means we waste some space, depending on the type, and
it's also somewhat confusing as to who uses what.

The patch below implements the first step towards tuplifying types:
those pieces which all types use have been split out into a
tree_type_common structure and those pieces which are overloaded live in
a tree_type_non_common structure.  I choose to implement the
lang-specific bit as a separate substructure, on the off-chance that
some types are fortunate enough to not have langage-specific data
attached to them by the FEs--I have not gone through and made a detailed
check of this, but a skimming shows that nearly every interesting type
that we'd care about shrinking has TYPE_LANG_SPECIFIC set on it by some
FE.

There are several miscellaneous places that need to be fixed up after
the removal of tree_type.  The changes to the Ada, Java, ObjC/C++, and
C++ FEs mainly have to do with direct access to the fields of tree_type,
rather than going through accessor macros.  ggc-page.c creates a bucket
size for sizeof (struct tree_type); I changed it to use 'struct
tree_type_non_common' instead.  There are a couple of places in the
compiler where fields are accessed directly--stor-layout.c and
lto/lto.c--I chose to leave those alone.

After this reorganization, the most that we can shrink most types will
be 2-3 words (possibly more, if we moved TYPE_SIZE around so not all
types needed it).  According to PR 45375, the types on which we should
focus are:

- RECORD_TYPE
- FUNCTION_TYPE
- METHOD_TYPE
- POINTER_TYPE
- INTEGER_TYPE
- REFERENCE_TYPE

RECORD_TYPE is not straightforwardly shrinkable.  FUNCTION_TYPE and
METHOD_TYPE could probably be shrunk by a word or two; likewise for
POINTER_TYPE and REFERENCE_TYPE.  (POINTER_TYPE and REFERENCE_TYPE could
also be made smaller by not allocating an entire TREE_VEC for the one
cached value they put in TYPE_CACHED_VALUES...)  INTEGER_TYPE's binfo
field is used by Ada; INTEGER_TYPE could be shrunk by one word were it
not for this overloading.

Other types can of course be shrunk, but the memory savings from doing
so will be negligible

This patch also opens up the possibility of using language-specific
trees for types as well as decls; the C++ FE's tree_size langhook makes
an attempt to do this, but we never call the tree_size langhook for
types.

I haven't included the refactoring of types yet; I'll let this patch sit
on trunk for a couple of days before trying that.

Testing with all languages in progress on x86_64-unknown-linux-gnu;
ObjC/Go/Ada tests have completed with no regressions; C/C++/Fortran are
looking good as well.  OK to commit?

-Nathan

gcc/ada/
* gcc-interface/ada-tree.h (TYPE_OBJECT_RECORD_TYPE): Use TYPE_MINVAL.
(TYPE_GCC_MIN_VALUE): Use TYPE_MINVAL.
(TYPE_GCC_MAX_VALUE): Use TYPE_MAXVAL.

gcc/cp/
* cp-tree.h (TYPENAME_TYPE_FULLNAME, TYPEOF_TYPE_EXPR): Use
TYPE_VALUES_RAW.
(UNDERLYING_TYPE_TYPE, DECLTYPE_TYPE_EXPR): Likewise.
(DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P): Likewise.
(TEMPLATE_TYPE_PARM_INDEX): Likewise.

gcc/
* ggc-page.c (extra_order_size_table): Use struct
tree_type_non_common.
* lto-streamer-in.c (unpack_ts_type_value_fields): Rename to...
(unpack_ts_type_common_value_fields): ...this.  Update comment.
(unpack_value_fields): Adjust for renaming.
(lto_input_ts_type_tree_pointers): Split into...
(lto_input_ts_type_common_tree_pointer): ...this and...
(lto_input_ts_type_non_common_tree_pointers): ...this.
(lto_input_tree_pointers): Adjust for above split.
* lto-streamer-out.c (pack_ts_type_value_fields): Rename to...
(pack_ts_type_common_value_fields): ...this.  Update comment.
(lto_output_ts_type_tree_pointers): Split into...
(lto_output_ts_type_common_tree_pointers): ...this and...
(lto_output_ts_type_non_common_tree_pointers): ...this.
(lto_output_tree_pointers): Adjust for above split.
* lto-streamer.c (check_handled_ts_structures): Mark TS_TYPE_COMMON,
TS_TYPE_WITH_LANG_SPECIFIC, and TS_TYPE_NON_COMMON as handled.
* stor-layout.c (vector_type_mode): Adjust location of mode field.
* tree.h (MARK_TS_TYPE_COMMON, MARK_TS_TYPE_WITH_LANG_SPECIFIC):
Define.
(struct tree_type): Split into...
(struct tree_type_common: ...this and...
(struct tree_type_with_lang_specific): ...this and...
(struct tree_type_non_common): ...this.  Adjust accessor macros
accordingly.
(TYPE_VALUES_RAW): Define.
(union tree_node): Update for above changes.
* tree.c (tree_node_structure_for_code) [tcc_type]: Return
TS_TYPE_NON_COMMON.
(initialize_tree_contains_struct) [TS_TYPE]: Use TS_TYPE_COMMON.
Add TS_TYPE_WITH_LANG_SPECIFIC and TS_TYPE_NON_COMMON.
(tree_code_size) 

Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN

2011-05-10 Thread Nathan Froyd
On Fri, Mar 11, 2011 at 02:19:14PM +0100, Richard Guenther wrote:
 On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd froy...@codesourcery.com 
 wrote:
  Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR.  Nothing to
  see here.
 
 I wonder if there isn't a better way to do this ... like always requiring
 operand 2 of SWITCH_EXPRs.

I'm honestly not sure.  Would it be OK to commit the patch and discuss
other options later?  CASE_LABEL is the last expression-esque node using
TREE_CHAIN.

-Nathan


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

2011-05-10 Thread Nathan Froyd

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

-Nathan



[PATCH,c++] introduce {class,type}_of_this functions

2011-05-06 Thread Nathan Froyd
The patch below introduces simple accessors for getting at the class or
the type of the `this' parameter.  It hides a couple of TYPE_ARG_TYPES
usages and makes the code slightly more obvious, I think.

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

-Nathan

gcc/cp/
* cp-tree.h (type_of_this, class_of_this): New functions.
* call.c (standard_conversion): Call class_of_this.
* cxx-pretty-print.c (pp_cxx_implicit_parameter_type): Likewise.
(pp_cxx_direct_abstract_declarator): Likewise.
* decl2.c (change_return_type): Likewise.
(cp_reconstruct_complex_type): Likewise.
* error.c (dump_type_suffix, dump_function_decl): Likewise.
* mangle.c (write_function_type): Likewise.
* pt.c (unify): Likewise.
* typeck.c (merge_types, type_memfn_quals): Likewise.
* decl.c (build_this_parm): Call type_of_this.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f5bd521..7ad9279 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1146,8 +1146,8 @@ standard_conversion (tree to, tree from, tree expr, bool 
c_cast_p,
 {
   tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));
   tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
-  tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
-  tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
+  tree fbase = class_of_this (fromfn);
+  tree tbase = class_of_this (tofn);
 
   if (!DERIVED_FROM_P (fbase, tbase)
  || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9d13393..d410e02 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4616,6 +4616,24 @@ struct GTY(()) tinst_level {
   bool in_system_header_p;
 };
 
+/* Return the type of the `this' parameter of FNTYPE.  */
+
+static inline tree
+type_of_this (const_tree fntype)
+{
+  function_args_iterator iter;
+  function_args_iter_init (iter, fntype);
+  return function_args_iter_cond (iter);
+}
+
+/* Return the class of the `this' parameter of FNTYPE.  */
+
+static inline tree
+class_of_this (const_tree fntype)
+{
+  return TREE_TYPE (type_of_this (fntype));
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index bd0381b..eeb6d07 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -1363,7 +1363,7 @@ pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
 static inline tree
 pp_cxx_implicit_parameter_type (tree mf)
 {
-  return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf;
+  return class_of_this (TREE_TYPE (mf));
 }
 
 /*
@@ -1652,8 +1652,7 @@ pp_cxx_direct_abstract_declarator (cxx_pretty_printer 
*pp, tree t)
   if (TREE_CODE (t) == METHOD_TYPE)
{
  pp_base (pp)-padding = pp_before;
- pp_cxx_cv_qualifier_seq
-   (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t;
+ pp_cxx_cv_qualifier_seq (pp, class_of_this (t));
}
   pp_cxx_exception_specification (pp, t);
   break;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 3622c2c..962dd22 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6924,7 +6924,7 @@ build_this_parm (tree type, cp_cv_quals quals)
   tree parm;
   cp_cv_quals this_quals;
 
-  this_type = TREE_VALUE (TYPE_ARG_TYPES (type));
+  this_type = type_of_this (type);
   /* The `this' parameter is implicitly `const'; it cannot be
  assigned to.  */
   this_quals = (quals  TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index ef8de31..02d9fd9 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -161,8 +161,7 @@ change_return_type (tree new_ret, tree fntype)
 }
   else
 newtype = build_method_type_directly
-  (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
-   new_ret, TREE_CHAIN (args));
+  (class_of_this (fntype), new_ret, TREE_CHAIN (args));
   if (raises)
 newtype = build_exception_variant (newtype, raises);
   if (attrs)
@@ -1249,8 +1248,7 @@ cp_reconstruct_complex_type (tree type, tree bottom)
 so we must compensate by getting rid of it.  */
   outer
= build_method_type_directly
-   (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))),
-inner,
+   (class_of_this (type), inner,
 TREE_CHAIN (TYPE_ARG_TYPES (type)));
 }
   else if (TREE_CODE (type) == OFFSET_TYPE)
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index fce7403..b364824 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -794,8 +794,7 @@ dump_type_suffix (tree t, int flags)
dump_parameters (arg, flags  ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
 
if (TREE_CODE (t) == METHOD_TYPE)
- pp_cxx_cv_qualifier_seq
-   (cxx_pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t;
+ pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this (t));
else
  

Re: [google]: initialize language field for clone function struct

2011-05-04 Thread Nathan Froyd
On Wed, May 04, 2011 at 08:30:40AM -0400, Richard Kenner wrote:
  There are pros and cons about early optimization, actually.
  Generating extremely optimized IL very early can actually tie up
  subsequent passes.  For instance, loop unrolling and vectorization.
  There are others in the literature.
 
 Sure, in the sorts of examples you mention where there's a level of
 globality to it.  But I don't see it in the types of things that
 fold does.  How could it ever be better to leave a - a in the tree
 instead of 0?

If you ever want to do things beside compile the code--automated
refactoring, renaming, pretty-printing, etc.--fidelity to the source is
preferred.

-Nathan


Re: [PATCH] less build_function_type usage in the Fortran FE

2011-05-04 Thread Nathan Froyd
On Wed, May 04, 2011 at 11:22:02AM +0200, Tobias Burnus wrote:
 On 05/03/2011 09:06 PM, Nathan Froyd wrote:
 Testing in progress on x86_64-unknown-linux-gnu.  OK to commit if
 testing successful?

 The Fortran part is OK. Thanks for the janitorial work.

Thanks for the review!  We'll see if the janitorial work actually leads
to something useful later on. :)

I've committed the patch below as r173375; testing showed a couple
failures.  I had originally changed this bit in trans-types.c:

  if (typelist)
typelist = chainon (typelist, void_list_node);
  else if (sym-attr.is_main_program || sym-attr.if_source != IFSRC_UNKNOWN)
typelist = void_list_node;

to this:

  if (typelist)
is_varargs = false;
  else if (sym-attr.is_main_program || sym-attr.if_source != IFSRC_UNKNOWN)
{
  VEC_free (tree, gc, typelist);
  typelist = NULL;
}

Except that change makes the 'else if' case create a varargs function
where we weren't before.  The VEC_free is totally pointless there,
because typelist would be NULL anyway.  And we ought to be testing with
VEC_empty instead.  A little thought shows that:

  if (!VEC_empty (tree, typelist)
  || sym-attr.is_main_program
  || sym-attr.if_source != IFSRC_UNKNOWN)
is_varargs = false;

is what we really want.

-Nathan

gcc/
* tree.h (build_function_type_array): Declare.
(build_varargs_function_type_array): Declare.
(build_function_type_vec, build_varargs_function_type_vec):
Define.
* tree.c (build_function_type_array_1): New function.
(build_function_type_array): New function.
(build_varargs_function_type_array): New function.

gcc/fortran/
* trans-decl.c (build_library_function_decl_1): Call
build_function_type_vec.  Adjust argument list building
accordingly.
* trans-intrinsic.c (gfc_get_intrinsic_lib_fndecl): Likewise.
* trans-types.c (gfc_get_function_type): Likewise.

diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index f80c9db..dc381f9 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2478,8 +2478,7 @@ static tree
 build_library_function_decl_1 (tree name, const char *spec,
   tree rettype, int nargs, va_list p)
 {
-  tree arglist;
-  tree argtype;
+  VEC(tree,gc) *arglist;
   tree fntype;
   tree fndecl;
   int n;
@@ -2488,20 +2487,18 @@ build_library_function_decl_1 (tree name, const char 
*spec,
   gcc_assert (current_function_decl == NULL_TREE);
 
   /* Create a list of the argument types.  */
-  for (arglist = NULL_TREE, n = abs (nargs); n  0; n--)
+  arglist = VEC_alloc (tree, gc, abs (nargs));
+  for (n = abs (nargs); n  0; n--)
 {
-  argtype = va_arg (p, tree);
-  arglist = gfc_chainon_list (arglist, argtype);
-}
-
-  if (nargs = 0)
-{
-  /* Terminate the list.  */
-  arglist = chainon (arglist, void_list_node);
+  tree argtype = va_arg (p, tree);
+  VEC_quick_push (tree, arglist, argtype);
 }
 
   /* Build the function type and decl.  */
-  fntype = build_function_type (rettype, arglist);
+  if (nargs = 0)
+fntype = build_function_type_vec (rettype, arglist);
+  else
+fntype = build_varargs_function_type_vec (rettype, arglist);
   if (spec)
 {
   tree attr_args = build_tree_list (NULL_TREE,
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 10dadf7..bbbf64f 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -722,7 +722,7 @@ static tree
 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
 {
   tree type;
-  tree argtypes;
+  VEC(tree,gc) *argtypes;
   tree fndecl;
   gfc_actual_arglist *actual;
   tree *pdecl;
@@ -803,14 +803,13 @@ gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, 
gfc_expr * expr)
ts-kind);
 }
 
-  argtypes = NULL_TREE;
+  argtypes = NULL;
   for (actual = expr-value.function.actual; actual; actual = actual-next)
 {
   type = gfc_typenode_for_spec (actual-expr-ts);
-  argtypes = gfc_chainon_list (argtypes, type);
+  VEC_safe_push (tree, gc, argtypes, type);
 }
-  argtypes = chainon (argtypes, void_list_node);
-  type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
+  type = build_function_type_vec (gfc_typenode_for_spec (ts), argtypes);
   fndecl = build_decl (input_location,
   FUNCTION_DECL, get_identifier (name), type);
 
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 27dcf82..cc82037 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -2534,10 +2534,11 @@ tree
 gfc_get_function_type (gfc_symbol * sym)
 {
   tree type;
-  tree typelist;
+  VEC(tree,gc) *typelist;
   gfc_formal_arglist *f;
   gfc_symbol *arg;
   int alternate_return;
+  bool is_varargs = true;
 
   /* Make sure this symbol is a function, a subroutine or the main
  program.  */
@@ -2548,13 +2549,11 @@ gfc_get_function_type

[PATCH] don't use TYPE_ARG_TYPES in c-family/

2011-05-04 Thread Nathan Froyd
As $SUBJECT suggests.  The patch is somewhat larger than it needs to be
due to reindenting c-common.c:check_main_parameter_types.

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

-Nathan

gcc/c-family/
* c-common.c (check_main_parameter_types): Reindent.  Don't use
TYPE_ARG_TYPES directly.
(handle_nonnull_attribute): Likewise.
(sync_resolve_params): Likewise.
* c-format.c (handle_format_arg_attribute): Likewise.  Adjust call
to check_format_string.
(handle_format_attribute): Likewise.
(check_format_string): Take a function type to examine instead of
a type list.  Use a function_arg_iterator to step through argument
types.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 802040d..ca65d19 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1662,45 +1662,44 @@ strict_aliasing_warning (tree otype, tree type, tree 
expr)
 void
 check_main_parameter_types (tree decl)
 {
-  tree args;
+  function_args_iterator iter;
+  tree type;
   int argct = 0;
 
-  for (args = TYPE_ARG_TYPES (TREE_TYPE (decl)); args;
-  args = TREE_CHAIN (args))
-   {
- tree type = args ? TREE_VALUE (args) : 0;
-
- if (type == void_type_node || type == error_mark_node )
-   break;
-
- ++argct;
- switch (argct)
-   {
-   case 1:
- if (TYPE_MAIN_VARIANT (type) != integer_type_node)
-   pedwarn (input_location, OPT_Wmain, first argument of %q+D should 
be %int%,
-   decl);
- break;
-
-   case 2:
- if (TREE_CODE (type) != POINTER_TYPE
- || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
- != char_type_node))
-   pedwarn (input_location, OPT_Wmain, second argument of %q+D should 
be %char **%,
-   decl);
- break;
-
-   case 3:
- if (TREE_CODE (type) != POINTER_TYPE
- || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
- != char_type_node))
-  pedwarn (input_location, OPT_Wmain, third argument of %q+D should 
probably be 
-   %char **%, decl);
- break;
-   }
-   }
+  FOREACH_FUNCTION_ARGS (TREE_TYPE (decl), type, iter)
+{
+  /* XXX void_type_node belies the abstraction.  */
+  if (type == void_type_node || type == error_mark_node )
+   break;
+
+  ++argct;
+  switch (argct)
+   {
+   case 1:
+ if (TYPE_MAIN_VARIANT (type) != integer_type_node)
+   pedwarn (input_location, OPT_Wmain, first argument of %q+D should 
be %int%,
+decl);
+ break;
+
+   case 2:
+ if (TREE_CODE (type) != POINTER_TYPE
+ || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+ || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+ != char_type_node))
+   pedwarn (input_location, OPT_Wmain, second argument of %q+D should 
be %char **%,
+decl);
+ break;
+
+   case 3:
+ if (TREE_CODE (type) != POINTER_TYPE
+ || TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+ || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+ != char_type_node))
+   pedwarn (input_location, OPT_Wmain, third argument of %q+D should 
probably be 
+%char **%, decl);
+ break;
+   }
+}
 
   /* It is intentional that this message does not mention the third
 argument because it's only mentioned in an appendix of the
@@ -7394,7 +7393,6 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED 
(name),
  a pointer argument.  */
   for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
 {
-  tree argument;
   unsigned HOST_WIDE_INT arg_num = 0, ck_num;
 
   if (!get_nonnull_operand (TREE_VALUE (args), arg_num))
@@ -7405,18 +7403,21 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED 
(name),
  return NULL_TREE;
}
 
-  argument = TYPE_ARG_TYPES (type);
-  if (argument)
+  if (prototype_p (type))
{
- for (ck_num = 1; ; ck_num++)
+ function_args_iterator iter;
+ tree argument;
+
+ function_args_iter_init (iter, type);
+ for (ck_num = 1; ; ck_num++, function_args_iter_next (iter))
{
- if (!argument || ck_num == arg_num)
+ argument = function_args_iter_cond (iter);
+ if (argument == NULL_TREE || ck_num == arg_num)
break;
- argument = TREE_CHAIN (argument);
}
 
  if (!argument
- || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
+ || TREE_CODE (argument) == VOID_TYPE)
{
  error (nonnull argument with out-of-range operand number 
(argument %lu, operand %lu),
   

[obv] remove gfc_chainon_list

2011-05-04 Thread Nathan Froyd
As promised in http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00211.html .

Tested by building f951.  Committed as r173386.

-Nathan

gcc/fortran/
* trans.h (gfc_chainon_list): Delete.
* trans.c (gfc_chainon_list): Delete.

Index: gcc/fortran/ChangeLog
===
Index: gcc/fortran/trans.c
===
--- gcc/fortran/trans.c (revision 173382)
+++ gcc/fortran/trans.c (working copy)
@@ -63,19 +63,6 @@ gfc_advance_chain (tree t, int n)
 }
 
 
-/* Wrap a node in a TREE_LIST node and add it to the end of a list.  */
-
-tree
-gfc_chainon_list (tree list, tree add)
-{
-  tree l;
-
-  l = tree_cons (NULL_TREE, add, NULL_TREE);
-
-  return chainon (list, l);
-}
-
-
 /* Strip off a legitimate source ending from the input
string NAME of length LEN.  */
 
Index: gcc/fortran/trans.h
===
--- gcc/fortran/trans.h (revision 173382)
+++ gcc/fortran/trans.h (working copy)
@@ -319,9 +319,6 @@ void gfc_conv_string_parameter (gfc_se *
 /* Compare two strings.  */
 tree gfc_build_compare_string (tree, tree, tree, tree, int, enum tree_code);
 
-/* Add an item to the end of TREE_LIST.  */
-tree gfc_chainon_list (tree, tree);
-
 /* When using the gfc_conv_* make sure you understand what they do, i.e.
when a POST chain may be created, and what the returned expression may be
used for.  Note that character strings have special handling.  This


[PATCH] don't use build_function_type in the ObjC/C++ frontends

2011-05-04 Thread Nathan Froyd
The last remaining uses of build_function_type in the ObjC/C++ frontends
comes from this pattern:

  tree method_param_types =
get_arg_type_list (method_prototype, METHOD_REF, super_flag);
  tree ftype = build_function_type (ret_type, method_param_types);

To eliminate this, I made the following changes:

- Package the above pattern up into a function,
  build_function_type_for_method.  This change meant that
  get_arg_type_list didn't need to exist as a separate function, so I
  made get_arg_type_list go away.

- To make build_function_type_for_method call build_function_type_vec, I
  needed to change the interface to the runtime hook function
  get_arg_type_list_base: it now takes a VEC to which it appends the
  necessary arguments.  build_function_type_for_method then appends the
  appropriate arguments and builds the new function type.

- However, the NeXT v2 ABI method call builder used the type list
  returned by get_arg_type_list separately, passing it to
  objc_copy_to_temp_side_effect_params.  I therefore changed that
  function to consult the newly built function type instead, using an
  iterator.

I also adjust the header comments to reflect the new world order and
wrapped them to  80 columns where appropriate.

Tested on x86_64-unknown-linux-gnu, ObjC/C++ testsuites.  I will fix any
Darwin breakage that comes up, though I may need some debugging help to
do so.  OK to commit?

-Nathan

gcc/objc/
* objc-runtime-shared-support.h (get_arg_type_list): Delete.
(build_function_type_for_method): Declare.
* objc-runtime-hooks.h (struct _objc_runtime_hooks_r): Change
type of get_arg_type_base_list field.
* objc-act.h (OBJC_VOID_AT_END): Delete.
* objc-act.c (get_arg_type_list): Delete.
(build_function_type_for_method): New function.
(objc_decl_method_attributes): Call build_function_type_for_method.
(really_start_method): Likewise.
* objc-gnu-runtime-abi-01.c
(gnu_runtime_abi_01_get_type_arg_list_base): Change prototype and
adjust function accordingly.  Update header comment.
(build_objc_method_call): Call build_function_type_for_method.
* objc-next-runtime-abi-01.c
(next_runtime_abi_01_get_type_arg_list_base): Change prototype and
adjust function accordingly.  Update header comment.
(build_objc_method_call): Call build_function_type_for_method.
* objc-next-runtime-abi-02.c
(next_runtime_abi_02_get_type_arg_list_base): Change prototype and
adjust function accordingly.  Update header comment.
(objc_copy_to_temp_side_effect_params): Take fntype instead of a
typelist.  Use function_args_iterator for traversing fntype.
(build_v2_build_objc_method_call): Adjust call to it.
Call build_function_type_for_method

diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 025f375..e3de6db 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -5040,8 +5040,9 @@ objc_decl_method_attributes (tree *node, tree attributes, 
int flags)
 (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
 is nothing to do.  */
   tree saved_type = TREE_TYPE (*node);
-  TREE_TYPE (*node) = build_function_type
-   (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
+  TREE_TYPE (*node)
+   = build_function_type_for_method (TREE_VALUE (saved_type), *node,
+ METHOD_REF, 0);
   decl_attributes (node, filtered_attributes, flags);
   METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
   TREE_TYPE (*node) = saved_type;
@@ -5054,60 +5055,66 @@ objc_method_decl (enum tree_code opcode)
   return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
 }
 
-/* Used by `build_objc_method_call'.  Return an argument list for
-   method METH.  CONTEXT is either METHOD_DEF or METHOD_REF, saying
-   whether we are trying to define a method or call one.  SUPERFLAG
-   says this is for a send to super; this makes a difference for the
-   NeXT calling sequence in which the lookup and the method call are
-   done together.  If METH is null, user-defined arguments (i.e.,
-   beyond self and _cmd) shall be represented by `...'.  */
+/* Return a function type for METHOD with RETURN_TYPE.  CONTEXT is
+   either METHOD_DEF or METHOD_REF, indicating whether we are defining a
+   method or calling one.  SUPER_FLAG indicates whether this is a send
+   to super; this makes a difference for the NeXT calling sequence in
+   which the lookup and the method call are done together.  If METHOD is
+   NULL, user-defined arguments (i.e., beyond self and _cmd) shall be
+   represented as varargs.  */
 
 tree
-get_arg_type_list (tree meth, int context, int superflag)
+build_function_type_for_method (tree return_type, tree method,
+   int context, bool super_flag)
 {
-  tree arglist, akey;
+  VEC(tree,gc) 

[PATCH] less build_function_type usage in the Fortran FE

2011-05-03 Thread Nathan Froyd
The patch below eliminates almost all cases of build_function_type in
the Fortran FE.  (The last case uses TYPE_ARG_TYPES directly and will
need to be dealt with separately.)  This is accomplished by introducing
two new functions, build_{,varargs_}function_type_array, which do what
you think, and two small macro wrappers around them,
build_{,varargs_}function_type_vec.  The macro wrappers are used so that
one can use heap-, gc-, or stack-allocated vectors, as necessary.

Comments on the middle-end bits welcome; some sort of FUNCTION_TYPE
builder with a dynamically determined number of argument types is needed
for working towards the elimination of TYPE_ARG_TYPES.

As a happy side-effect, the patch eliminates uses of gfc_chainon_list
and makes the specific instances below of building function types
linear, instead of quadratic.  If the patch is approved, I will delete
gfc_chainon_list as an obvious followon patch.

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

-Nathan

gcc/
* tree.h (build_function_type_array): Declare.
(build_varargs_function_type_array): Declare.
(build_function_type_vec, build_varargs_function_type_vec): Define.
* tree.c (build_function_type_array_1): New function.
(build_function_type_array): New function.
(build_varargs_function_type_array): New function.

gcc/fortran/
* trans-decl.c (build_library_function_decl_1): Call
build_function_type_vec.  Adjust argument list building accordingly.
* trans-intrinsic.c (gfc_get_intrinsic_lib_fndecl): Likewise.
* trans-types.c (gfc_get_function_type): Likewise.

diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index f80c9db..dc381f9 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2478,8 +2478,7 @@ static tree
 build_library_function_decl_1 (tree name, const char *spec,
   tree rettype, int nargs, va_list p)
 {
-  tree arglist;
-  tree argtype;
+  VEC(tree,gc) *arglist;
   tree fntype;
   tree fndecl;
   int n;
@@ -2488,20 +2487,18 @@ build_library_function_decl_1 (tree name, const char 
*spec,
   gcc_assert (current_function_decl == NULL_TREE);
 
   /* Create a list of the argument types.  */
-  for (arglist = NULL_TREE, n = abs (nargs); n  0; n--)
+  arglist = VEC_alloc (tree, gc, abs (nargs));
+  for (n = abs (nargs); n  0; n--)
 {
-  argtype = va_arg (p, tree);
-  arglist = gfc_chainon_list (arglist, argtype);
-}
-
-  if (nargs = 0)
-{
-  /* Terminate the list.  */
-  arglist = chainon (arglist, void_list_node);
+  tree argtype = va_arg (p, tree);
+  VEC_quick_push (tree, arglist, argtype);
 }
 
   /* Build the function type and decl.  */
-  fntype = build_function_type (rettype, arglist);
+  if (nargs = 0)
+fntype = build_function_type_vec (rettype, arglist);
+  else
+fntype = build_varargs_function_type_vec (rettype, arglist);
   if (spec)
 {
   tree attr_args = build_tree_list (NULL_TREE,
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 180aba1..360723c 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -722,7 +722,7 @@ static tree
 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
 {
   tree type;
-  tree argtypes;
+  VEC(tree,gc) *argtypes;
   tree fndecl;
   gfc_actual_arglist *actual;
   tree *pdecl;
@@ -803,14 +803,13 @@ gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, 
gfc_expr * expr)
ts-kind);
 }
 
-  argtypes = NULL_TREE;
+  argtypes = NULL;
   for (actual = expr-value.function.actual; actual; actual = actual-next)
 {
   type = gfc_typenode_for_spec (actual-expr-ts);
-  argtypes = gfc_chainon_list (argtypes, type);
+  VEC_safe_push (tree, gc, argtypes, type);
 }
-  argtypes = chainon (argtypes, void_list_node);
-  type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
+  type = build_function_type_vec (gfc_typenode_for_spec (ts), argtypes);
   fndecl = build_decl (input_location,
   FUNCTION_DECL, get_identifier (name), type);
 
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index ebc8c23..4606f68 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -2534,10 +2534,11 @@ tree
 gfc_get_function_type (gfc_symbol * sym)
 {
   tree type;
-  tree typelist;
+  VEC(tree,gc) *typelist;
   gfc_formal_arglist *f;
   gfc_symbol *arg;
   int alternate_return;
+  bool is_varargs = true;
 
   /* Make sure this symbol is a function, a subroutine or the main
  program.  */
@@ -2548,13 +2549,11 @@ gfc_get_function_type (gfc_symbol * sym)
 return TREE_TYPE (sym-backend_decl);
 
   alternate_return = 0;
-  typelist = NULL_TREE;
+  typelist = NULL;
 
   if (sym-attr.entry_master)
-{
-  /* Additional parameter for selecting an entry point.  */
-  typelist = gfc_chainon_list (typelist, 

Re: [google]: initialize language field for clone function struct

2011-05-03 Thread Nathan Froyd
On Tue, May 03, 2011 at 07:06:58PM +, Joseph S. Myers wrote:
 In my view we should require front ends to take responsibility for 
 variable-size types, and get rid of this language-independent function 
 (copying such parts as are needed into the front ends that need them).  C 
 for example uses its own version as the language-independent one isn't 
 right for C.  Similarly, the pending_size code should be local to front 
 ends.

The raft of changes/improvements enabled by this change would be most
welcome.  *_SIZE becoming double_ints or HOST_WIDE_INT instead of trees
is the first thing that comes to mind; perhaps there are others.

-Nathan


Re: [google]: initialize language field for clone function struct

2011-05-03 Thread Nathan Froyd
On Tue, May 03, 2011 at 07:27:24PM +, Joseph S. Myers wrote:
 On Tue, 3 May 2011, Nathan Froyd wrote:
  The raft of changes/improvements enabled by this change would be most
  welcome.  *_SIZE becoming double_ints or HOST_WIDE_INT instead of trees
  is the first thing that comes to mind; perhaps there are others.
 
 I don't see how you can do that; you'll still have variable-sized types 
 and objects, it would just be entirely the front end's responsibility to 
 ensure that the size expression is evaluated exactly once (whenever 
 required by the language).

Ah, you're right.  I got carried away about thinking about FE-specific
data structures for things.

-Nathan


[PATCH] don't use TYPE_ARG_TYPES in the Ada FE

2011-05-03 Thread Nathan Froyd
As $SUBJECT suggests; the patch makes the Ada FE use iterators instead.

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

-Nathan

* gcc-interface/decl.c (intrin_arglists_compatible_p): Use iterators
instead of accessing TYPE_ARG_TYPES directly.
* gcc-interface/utils.c (handle_nonnull_attribute): Likewise.

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 14929b8..2a55940 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -8331,23 +8331,27 @@ intrin_types_incompatible_p (tree t1, tree t2)
 static bool
 intrin_arglists_compatible_p (intrin_binding_t * inb)
 {
-  tree ada_args = TYPE_ARG_TYPES (inb-ada_fntype);
-  tree btin_args = TYPE_ARG_TYPES (inb-btin_fntype);
+  function_args_iterator ada_iter, btin_iter;
+
+  function_args_iter_init (ada_iter, inb-ada_fntype);
+  function_args_iter_init (btin_iter, inb-btin_fntype);
 
   /* Sequence position of the last argument we checked.  */
   int argpos = 0;
 
-  while (ada_args != 0 || btin_args != 0)
+  while (1)
 {
-  tree ada_type, btin_type;
+  tree ada_type = function_args_iter_cond (ada_iter);
+  tree btin_type = function_args_iter_cond (btin_iter);
+
+  /* If we've exhausted both lists simultaneously, we're done.  */
+  if (ada_type == NULL_TREE  btin_type == NULL_TREE)
+   break;
 
   /* If one list is shorter than the other, they fail to match.  */
-  if (ada_args == 0 || btin_args == 0)
+  if (ada_type == NULL_TREE || btin_type == NULL_TREE)
return false;
 
-  ada_type = TREE_VALUE (ada_args);
-  btin_type = TREE_VALUE (btin_args);
-
   /* If we're done with the Ada args and not with the internal builtin
 args, or the other way around, complain.  */
   if (ada_type == void_type_node
@@ -8374,8 +8378,9 @@ intrin_arglists_compatible_p (intrin_binding_t * inb)
  return false;
}
 
-  ada_args = TREE_CHAIN (ada_args);
-  btin_args = TREE_CHAIN (btin_args);
+  
+  function_args_iter_next (ada_iter);
+  function_args_iter_next (btin_iter);
 }
 
   return true;
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 2e81c18..2b29748 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -5219,7 +5219,6 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED 
(name),
  a pointer argument.  */
   for (attr_arg_num = 1; args; args = TREE_CHAIN (args))
 {
-  tree argument;
   unsigned HOST_WIDE_INT arg_num = 0, ck_num;
 
   if (!get_nonnull_operand (TREE_VALUE (args), arg_num))
@@ -5230,18 +5229,21 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED 
(name),
  return NULL_TREE;
}
 
-  argument = TYPE_ARG_TYPES (type);
-  if (argument)
+  if (prototype_p (type))
{
- for (ck_num = 1; ; ck_num++)
+ function_args_iterator iter;
+ tree argument;
+
+ function_args_iter_init (iter, type);
+ for (ck_num = 1; ; ck_num++, function_args_iter_next (iter))
{
+ argument = function_args_iter_cond (iter);
  if (!argument || ck_num == arg_num)
break;
- argument = TREE_CHAIN (argument);
}
 
  if (!argument
- || TREE_CODE (TREE_VALUE (argument)) == VOID_TYPE)
+ || TREE_CODE (argument) == VOID_TYPE)
{
  error (nonnull argument with out-of-range operand number 
 (argument %lu, operand %lu),
@@ -5250,7 +5252,7 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED 
(name),
  return NULL_TREE;
}
 
- if (TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE)
+ if (TREE_CODE (argument) != POINTER_TYPE)
{
  error (nonnull argument references non-pointer operand 
 (argument %lu, operand %lu),


[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_rtx 

[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: [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


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: [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 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 mikest...@comcast.net 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 froy...@codesourcery.com 
 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


[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 

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


[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);
 
   /* 

[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 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 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,
+

[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
-= 

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


  1   2   >