Re: [PATCH][PR c++/82888] smarter code for default initialization of scalar arrays
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
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
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
- 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}
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}
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}
- 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
- 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
- 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
- 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
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
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
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
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
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
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
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
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
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
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
- 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)
- 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
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)
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
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
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
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
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
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
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
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)
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
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
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
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)
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
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
`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
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
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
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
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
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/
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
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
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
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
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)
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
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
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
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
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
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
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
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
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
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
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/
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
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
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
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
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
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
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
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
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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