Re: PATCH: PR other/48007: Unwind library doesn't work with UNITS_PER_WORD > sizeof (void *)
On Wed, Mar 23, 2011 at 12:22 PM, Ulrich Weigand wrote: > Richard Henderson wrote: >> Because, really, if we consider the structure truly public, we can't even >> change the number of registers for a given port to support new features of >> the cpu. > > Indeed, and I remember we got bitten by that a long time ago, which is why > s390.h now has this comment: > > /* Number of hardware registers that go into the DWARF-2 unwind info. > To avoid ABI incompatibility, this number must not change even as > 'fake' hard registers are added or removed. */ > #define DWARF_FRAME_REGISTERS 34 > >> I don't suppose there's any way that we can declare these old >> programs Just Broken, and drop this compatibility stuff? > > I wouldn't like that ... we did run into this problem in the wild, and > some s390 users really run very old programs for some reason. > > However, I'm wondering: this bug that leaked the implementation of > _Unwind_Context only ever affected the *original* version of the > structure -- it was fixed before the extended context was ever > added, right? > > If this is true, we'd still need to keep the original context format > unchanged, but we'd be free to modify the *extended* format at any > time, without ABI considerations and need for further versioning ... > From what I can tell, the issues are: 1. _Unwind_Context is supposed to be opaque and we are free to change it. We should be able to extend DWARF_FRAME_REGISTERS to support the new hard registers if needed, without breaking binary compatibility. 2. _Unwind_Context was leaked and wasn't really opaque. To provide backward binary compatibility, we are stuck with what we had. Is that possible to implement something along the line: 1. Add some bits to _Unwind_Context so that we can detect the leaked _Unwind_Context. 2. When a leaked _Unwind_Context is detected at run-time, as a compile time option, a target can either provide binary compatibility or issue a run-time error. -- H.J.
[Patch, testsuite]: Don't xfail sibcalls on AVR
Target avr now supports tail calls, so don't xfail on that. testsuite/ 2011-03-24 Georg-Johann Lay * gcc.dg/sibcall-3.c: Don't xfail on AVR. * gcc.dg/sibcall-4.c: Don't xfail on AVR. Index: testsuite/gcc.dg/sibcall-3.c === --- testsuite/gcc.dg/sibcall-3.c (Revision 171039) +++ testsuite/gcc.dg/sibcall-3.c (Arbeitskopie) @@ -5,7 +5,7 @@ Copyright (C) 2002 Free Software Foundation Inc. Contributed by Hans-Peter Nilsson*/ -/* { dg-do run { xfail { { arc-*-* avr-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ +/* { dg-do run { xfail { { arc-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ /* -mlongcall disables sibcall patterns. */ /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ /* { dg-options "-O2 -foptimize-sibling-calls" } */ Index: testsuite/gcc.dg/sibcall-4.c === --- testsuite/gcc.dg/sibcall-4.c (Revision 171039) +++ testsuite/gcc.dg/sibcall-4.c (Arbeitskopie) @@ -5,7 +5,7 @@ Copyright (C) 2002 Free Software Foundation Inc. Contributed by Hans-Peter Nilsson*/ -/* { dg-do run { xfail { { arc-*-* avr-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ +/* { dg-do run { xfail { { arc-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ /* -mlongcall disables sibcall patterns. */ /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ /* { dg-options "-O2 -foptimize-sibling-calls" } */
[patch, ARM] Enable auto-detection of vector size for NEON
Hi, This patch implements TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES for ARM NEON. Regtested on arm-linux-gnueabi. OK for trunk? Thanks, Ira ChangeLog: * config/arm/arm.c (arm_autovectorize_vector_sizes): New function. (TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Define. testsuite/ChangeLog: * gcc.dg/vect/vect-outer-5.c: Reduce the distance between data accesses to preserve the meaning of the test for doubleword vectors. * gcc.dg/vect/no-vfa-pr29145.c: Likewise. * gcc.dg/vect/slp-3.c: Reduce the loop bound for the same reason. Index: config/arm/arm.c === --- config/arm/arm.c(revision 171339) +++ config/arm/arm.c(working copy) @@ -252,6 +252,7 @@ static bool arm_builtin_support_vector_misalignmen bool is_packed); static void arm_conditional_register_usage (void); static reg_class_t arm_preferred_rename_class (reg_class_t rclass); +static unsigned int arm_autovectorize_vector_sizes (void); ^L /* Table of machine attributes. */ @@ -404,6 +405,9 @@ static const struct default_options arm_option_opt #define TARGET_VECTOR_MODE_SUPPORTED_P arm_vector_mode_supported_p #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arm_preferred_simd_mode +#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES +#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \ + arm_autovectorize_vector_sizes #undef TARGET_MACHINE_DEPENDENT_REORG #define TARGET_MACHINE_DEPENDENT_REORG arm_reorg @@ -23528,6 +23532,12 @@ arm_expand_sync (enum machine_mode mode, } } +static unsigned int +arm_autovectorize_vector_sizes (void) +{ + return TARGET_NEON_VECTORIZE_QUAD ? 16 | 8 : 0; +} + static bool arm_vector_alignment_reachable (const_tree type, bool is_packed) { Index: testsuite/gcc.dg/vect/vect-outer-5.c === --- testsuite/gcc.dg/vect/vect-outer-5.c(revision 171339) +++ testsuite/gcc.dg/vect/vect-outer-5.c(working copy) @@ -17,7 +17,7 @@ int main1 () float B[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); float C[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); float D[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); - float E[4] = {0,1,2,480}; + float E[4] = {0,480,960,1440}; float s; int i, j; @@ -55,7 +55,7 @@ int main1 () s = 0; for (j=0; j
Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes
On 03/21/2011 06:36 PM, Kai Tietz wrote: + attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a)), + CONST_CAST_TREE (a2)); I might use as->name for the name, and change lookup_attribute to take a const_tree rather than use CONST_CAST_TREE. + if (!a) +{ + for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a)) + { + const struct attribute_spec *as; + const_tree attr; + as = lookup_attribute_spec (TREE_PURPOSE (a)); + if (!as || as->affects_type_identity == false) + continue; + attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a)), + CONST_CAST_TREE (a1)); + if (!attr) + break; + + if (TREE_VALUE (a) != NULL_TREE + && TREE_CODE (TREE_VALUE (a)) == TREE_LIST + && TREE_VALUE (attr) != NULL + && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST) + { + if (simple_cst_list_equal (TREE_VALUE (a), +TREE_VALUE (attr)) == 1) + break; + } + else if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (attr)) == 1) + break; + } Once we've walked the first list, we don't need to compare the values of common attributes again; for each attribute in the second list either it does appear in the first list and we've already established that they match, or it doesn't appear in the first list and we're done. Jason
Re: [v3] Regenerate Solaris 2 baselines for GCC 4.6.0 release
Benjamin Kosnik writes: > OK. > > Looks great thanks Ranier. Installed on mainline and 4.6 branch. Thanks for all your help getting this right. Rainer -- - Rainer Orth, Center for Biotechnology, Bielefeld University
Re: [PATCH] Fix simplify_const_unary_operation (PR debug/48204)
On Wed, Mar 23, 2011 at 9:11 PM, Jakub Jelinek wrote: > Hi! > > simplify_const_unary_operation assumes it doesn't have to change anything > in REAL_VALUE_TYPE for FLOAT_EXTEND, which is wrong when FLOAT_EXTENDing > e.g. from SFmode to DDmode or SDmode to DFmode, where the number > needs to be converted from binary to decimal or vice versa. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, > ok for trunk/4.6.1? Ok. Thanks, Richard. > 2011-03-23 Jakub Jelinek > > PR debug/48204 > * simplify-rtx.c (simplify_const_unary_operation): Call > real_convert when changing mode class with FLOAT_EXTEND. > > * gcc.dg/dfp/pr48204.c: New test. > > --- gcc/simplify-rtx.c.jj 2011-03-21 13:00:09.0 +0100 > +++ gcc/simplify-rtx.c 2011-03-23 16:39:13.0 +0100 > @@ -1526,7 +1526,8 @@ simplify_const_unary_operation (enum rtx > } > > else if (GET_CODE (op) == CONST_DOUBLE > - && SCALAR_FLOAT_MODE_P (mode)) > + && SCALAR_FLOAT_MODE_P (mode) > + && SCALAR_FLOAT_MODE_P (GET_MODE (op))) > { > REAL_VALUE_TYPE d, t; > REAL_VALUE_FROM_CONST_DOUBLE (d, op); > @@ -1549,7 +1550,10 @@ simplify_const_unary_operation (enum rtx > d = real_value_truncate (mode, d); > break; > case FLOAT_EXTEND: > - /* All this does is change the mode. */ > + /* All this does is change the mode, unless changing > + mode class. */ > + if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op))) > + real_convert (&d, mode, &d); > break; > case FIX: > real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL); > --- gcc/testsuite/gcc.dg/dfp/pr48204.c.jj 2011-03-23 16:44:09.0 > +0100 > +++ gcc/testsuite/gcc.dg/dfp/pr48204.c 2011-03-23 16:43:35.0 +0100 > @@ -0,0 +1,10 @@ > +/* PR debug/48204 */ > +/* { dg-do compile } */ > +/* { dg-options "-O -fno-tree-ccp -fno-tree-dominator-opts -fno-tree-fre -g" > } */ > + > +void > +foo (void) > +{ > + float cf = 3.0f; > + _Decimal64 d64 = cf; > +} > > Jakub >
Re: [patch] Enhance conditional store sinking
On Tue, Mar 22, 2011 at 6:28 AM, Ira Rosen wrote: > On 17 March 2011 16:48, Richard Guenther wrote: > >>> + then_datarefs = VEC_alloc (data_reference_p, heap, 1); >>> + else_datarefs = VEC_alloc (data_reference_p, heap, 1); >>> + then_ddrs = VEC_alloc (ddr_p, heap, 1); >>> + else_ddrs = VEC_alloc (ddr_p, heap, 1); >>> + if (!compute_data_dependences_for_bb (then_bb, false, &then_datarefs, >>> + &then_ddrs) >> >> Can we avoid computing dependencies if the other BB would have no >> data-refs? Thus, split collecting datarefs and computing dependences? > > Done. > >> >>> + || !compute_data_dependences_for_bb (else_bb, false, &else_datarefs, >>> + &else_ddrs) >>> + || !VEC_length (data_reference_p, then_datarefs) >>> + || !VEC_length (data_reference_p, else_datarefs)) >>> + { >>> + free_data_refs (then_datarefs); >>> + free_data_refs (else_datarefs); >>> + free_dependence_relations (then_ddrs); >>> + free_dependence_relations (else_ddrs); >>> + return false; >>> + } >>> + >>> + /* Check that there are no read-after-write or write-after-write >>> dependencies >>> + in THEN_BB. */ >>> + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) >>> + { >>> + struct data_reference *dra = DDR_A (ddr); >>> + struct data_reference *drb = DDR_B (ddr); >>> + >>> + if (DDR_ARE_DEPENDENT (ddr) != chrec_known >>> + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) >>> + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb))) >>> + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) >>> + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT >>> (dra))) >>> + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb >> >> The gimple_uids are not initialized here, you need to make sure to >> call renumber_gimple_stmt_uids () before starting. Note that phiopt >> incrementally changes the IL, so I'm not sure those uids will stay >> valid as stmts are moved across blocks. > > I added a call to renumber_gimple_stmt_uids_in_blocks() before data > dependence checks, and there are no code changes between that and the > checks, so, I think, it should be OK. > >> >>> + { >>> + free_data_refs (then_datarefs); >>> + free_data_refs (else_datarefs); >>> + free_dependence_relations (then_ddrs); >>> + free_dependence_relations (else_ddrs); >>> + return false; >>> + } >>> + } >>> + >>> + /* Check that there are no read-after-write or write-after-write >>> dependencies >>> + in ELSE_BB. */ >>> + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) >>> + { >>> + struct data_reference *dra = DDR_A (ddr); >>> + struct data_reference *drb = DDR_B (ddr); >>> + >>> + if (DDR_ARE_DEPENDENT (ddr) != chrec_known >>> + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) >>> + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb))) >>> + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) >>> + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT >>> (dra))) >>> + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb >>> + { >>> + free_data_refs (then_datarefs); >>> + free_data_refs (else_datarefs); >>> + free_dependence_relations (then_ddrs); >>> + free_dependence_relations (else_ddrs); >>> + return false; >>> + } >>> + } >>> + >>> + /* Found pairs of stores with equal LHS. */ >>> + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) >>> + { >>> + if (DR_IS_READ (then_dr)) >>> + continue; >>> + >>> + then_store = DR_STMT (then_dr); >>> + then_lhs = gimple_assign_lhs (then_store); >>> + found = false; >>> + >>> + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) >>> + { >>> + if (DR_IS_READ (else_dr)) >>> + continue; >>> + >>> + else_store = DR_STMT (else_dr); >>> + else_lhs = gimple_assign_lhs (else_store); >>> + >>> + if (operand_equal_p (then_lhs, else_lhs, 0)) >>> + { >>> + found = true; >>> + break; >>> + } >>> + } >>> + >>> + if (!found) >>> + continue; >>> + >>> + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, >>> + then_store, else_store); >> >> So you are executing if-else store replacement for common data reference >> pairs only. I think it's cheaper to collect those pairs before computing >> dependences and only if there is at least one pair perform the optimization. > > OK, I changed the order. > >> >> You basically perform store sinking, creating a PHI node for each store >> you sink (that's then probably if-converted by if-conversion later, >> eventually >> redundant with -ftree-loop-if-convert-stores?) >> >> I am concerned
Re: Cleaning up expand optabs code
"Anatoly Sokolov" writes: > This patch casue ICE on H8300 target: This is due to jump_address_operand checking the wrong mode. The predicate is: (define_predicate "jump_address_operand" (match_code "reg,mem") { if (GET_CODE (op) == REG) return mode == Pmode; [...] } but "mode" is the mode passed to the predicate, not the mode of OP. The indirect_jump pattern is: (define_expand "indirect_jump" [(set (pc) (match_operand 0 "jump_address_operand" ""))] "" "") which says that VOIDmode should be passed to jump_address_operand, so all registers end up being rejected. I've applied the following as the obvious fix. You then hit bug 48263 ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48263 ); I'm testing a fix for that now. Richard gcc/ * config/h8300/predicates.md (jump_address_operand): Fix register mode check. Index: gcc/config/h8300/predicates.md === --- gcc/config/h8300/predicates.md 2011-01-05 15:12:08.0 + +++ gcc/config/h8300/predicates.md 2011-03-24 09:20:15.0 + @@ -259,7 +259,7 @@ (define_predicate "jump_address_operand" (match_code "reg,mem") { if (GET_CODE (op) == REG) -return mode == Pmode; +return GET_MODE (op) == Pmode; if (GET_CODE (op) == MEM) {
Re: [patch] Fix invalid GIMPLE out of SRA
On Wed, Mar 23, 2011 at 9:54 PM, Eric Botcazou wrote: > Hi, > > this is a fallout of one of my gimplifier changes. For the attached testcase, > the compiler generates invalid GIMPLE at -O1 or above: > > p.adb: In function 'P.F': > p.adb:24:1: error: invalid operand in unary operation > D.2361_107 = (integer[1:1] *) &*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4}; > > if (!is_gimple_val (rhs1)) > { > error ("invalid operand in unary operation"); > return true; > } > > (gdb) p rhs_code > $6 = NOP_EXPR > (gdb) p debug_generic_expr(rhs1) > &*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4} > > i.e ADDR_EXPR of ARRAY_RANGE_REF with non-constant operand #1. > > The invalid statement is generated by the early SRA pass: > > integer a1[1:1]; > > VIEW_CONVERT_EXPR(*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4}) = > a1; > > is rewritten into: > > Created a replacement for a1 offset: 0, size: 32: a1$1 > > D.2361_107 = (integer[1:1] *) &*S15b.16_56[D.2327_91 ...]{lb: 1 sz: 4}; > MEM[(integer[1:D.2312] *)D.2361_107] = a1$1_92; > > > It turns out that the problematic NOP_EXPR is a useless type conversion > emitted > by build_fold_addr_expr: if you add a call to force_gimple_operand at the hot > spot, it ends up removing the NOP_EXPR and nothing else. So the proposed fix > is just to add a call to STRIP_USELESS_TYPE_CONVERSION there. > > Tested on i586-suse-linux, OK for the mainline? Ok. At some point I hope we get gimple variants for most of the tree building helpers (that build_fold_addr_expr, and also fold_convert). Thanks, Richard. > > 2011-03-23 Eric Botcazou > > * tree-sra.c (build_ref_for_offset): Call STRIP_USELESS_TYPE_CONVERSION > on the address built for a reference with variable offset. > > > 2011-03-23 Eric Botcazou > > * gnat.dg/array15.ad[sb]: New test. > * gnat.dg/array15_pkg.ads: New helper. > > > -- > Eric Botcazou >
Re: [lto] Minor cleanups, export some functions (issue4272068)
On Wed, Mar 23, 2011 at 10:24 PM, Diego Novillo wrote: > > This patch has a few cleanups and exports 5 functions from the LTO streamer > that we are using from PPH. > > - When calling output_string_with_length, every caller would first > write a 0 to indicate that the string is not NULL before writing the > actual string. I moved that into output_string_with_length. > - The functions to read/write raw data blocks was private to > lto-opts.c. I moved it as a general available function into > lto-streamer-*.c. > - Similarly, the functions to read/write strings and the code to emit > decl streams and references were private. I made them extern so > they can be called from pph. > > None of the above changes behaviour in LTO. The patch bootstrap and > tests on x86_64. OK for trunk? > Ok. Thanks, Richard. > Diego. > > > * lto-opts.c (input_data_block): Move to lto-streamer-in.c. > * lto-streamer-in.c (input_string_internal): Add clarifying > comments. > (lto_input_data_block): Move from lto-opts.c. Make extern. > Update all users. > (lto_input_string): Rename from input_string. Make extern. > Update all users. > * lto-streamer-out.c (lto_output_string_with_length): Rename from > output_string_with_length. > Output 0 to indicate a non-NULL string. Update all callers to > not emit 0. > (lto_output_string): Rename from output_string. Make extern. > Update all users. > (lto_output_decl_state_streams): Make extern. > (lto_output_decl_state_refs): Make extern. > * lto-streamer.h (lto_input_string): Declare. > (lto_input_data_block): Declare. > (lto_output_string): Declare. > (lto_output_string_with_length): Declare. > (lto_output_decl_state_streams): Declare. > (lto_output_decl_state_refs): Declare. > > diff --git a/gcc/lto-opts.c b/gcc/lto-opts.c > index ec4e78d..9979e8d 100644 > --- a/gcc/lto-opts.c > +++ b/gcc/lto-opts.c > @@ -162,18 +162,6 @@ output_string_stream (struct lto_output_stream *stream, > const char *string) > output_data_stream (stream, &flag, sizeof (flag)); > } > > -/* Read LENGTH bytes from STREAM to ADDR. */ > - > -static void > -input_data_block (struct lto_input_block *ib, void *addr, size_t length) > -{ > - size_t i; > - unsigned char *const buffer = (unsigned char *const) addr; > - > - for (i = 0; i < length; i++) > - buffer[i] = lto_input_1_unsigned (ib); > -} > - > /* Return a string from IB. The string is allocated, and the caller is > responsible for freeing it. */ > > @@ -182,15 +170,15 @@ input_string_block (struct lto_input_block *ib) > { > bool flag; > > - input_data_block (ib, &flag, sizeof (flag)); > + lto_input_data_block (ib, &flag, sizeof (flag)); > if (flag) > { > size_t length; > char *string; > > - input_data_block (ib, &length, sizeof (length)); > + lto_input_data_block (ib, &length, sizeof (length)); > string = (char *) xcalloc (1, length + 1); > - input_data_block (ib, string, length); > + lto_input_data_block (ib, string, length); > > return string; > } > @@ -336,16 +324,16 @@ input_options (struct lto_input_block *ib) > { > size_t length, i; > > - input_data_block (ib, &length, sizeof (length)); > + lto_input_data_block (ib, &length, sizeof (length)); > > for (i = 0; i < length; i++) > { > opt_t o; > > - input_data_block (ib, &o.type, sizeof (o.type)); > - input_data_block (ib, &o.code, sizeof (o.code)); > + lto_input_data_block (ib, &o.type, sizeof (o.type)); > + lto_input_data_block (ib, &o.code, sizeof (o.code)); > o.arg = input_string_block (ib); > - input_data_block (ib, &o.value, sizeof (o.value)); > + lto_input_data_block (ib, &o.value, sizeof (o.value)); > VEC_safe_push (opt_t, heap, file_options, &o); > } > } > diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c > index a873258..383bfc2 100644 > --- a/gcc/lto-streamer-in.c > +++ b/gcc/lto-streamer-in.c > @@ -140,7 +140,10 @@ input_string_internal (struct data_in *data_in, struct > lto_input_block *ib, > unsigned int loc; > const char *result; > > + /* Read the location of the string from IB. */ > loc = lto_input_uleb128 (ib); > + > + /* Get the string stored at location LOC in DATA_IN->STRINGS. */ > LTO_INIT_INPUT_BLOCK (str_tab, data_in->strings, loc, data_in->strings_len); > len = lto_input_uleb128 (&str_tab); > *rlen = len; > @@ -191,10 +194,24 @@ input_identifier (struct data_in *data_in, struct > lto_input_block *ib) > return get_identifier_with_length (ptr, len); > } > > + > +/* Read LENGTH bytes from STREAM to ADDR. */ > + > +void > +lto_input_data_block (struct lto_input_block *ib, void *addr, size_t length) > +{ > + size_t i; > + unsigned char *const buffer = (unsigned char *const) addr; > + > + for (i = 0; i < length; i++) > + buffer[i] = lto_input_1_unsigned (ib); > +
Re: [doc patch] obvious partial fix for other/48254
On Wed, Mar 23, 2011 at 11:03 PM, Jonathan Wakely wrote: > Committed to 4.4 and 4.5 branches as obvious, will apply to 4.6 after > 4.6.0 is released. The option's gone on the trunk so not relevant > there. If you apply anything to 4.6 it should probably simply change the docs to say "This option does nothing.". Or maybe don't pretend it exists in any useful form and remove it completely. Richard. > 2011-03-23 Jonathan Wakely > > PR other/48254 > * doc/invoke.texi (-fipa-struct-reorg): Fix typo. > > > > Index: doc/invoke.texi > === > --- doc/invoke.texi (revision 171365) > +++ doc/invoke.texi (working copy) > @@ -6121,7 +6121,7 @@ Enabled by default at @option{-O} and hi > @opindex fipa-struct-reorg > Perform structure reorganization optimization, that change C-like structures > layout in order to better utilize spatial locality. This transformation is > -affective for programs containing arrays of structures. Available in two > +effective for programs containing arrays of structures. Available in two > compilation modes: profile-based (enabled with @option{-fprofile-generate}) > or static (which uses built-in heuristics). Require > @option{-fipa-type-escape} > to provide the safety of this transformation. It works only in whole program >
Re: [doc patch] obvious partial fix for other/48254
On 24 March 2011 10:12, Richard Guenther wrote: > On Wed, Mar 23, 2011 at 11:03 PM, Jonathan Wakely > wrote: >> Committed to 4.4 and 4.5 branches as obvious, will apply to 4.6 after >> 4.6.0 is released. The option's gone on the trunk so not relevant >> there. > > If you apply anything to 4.6 it should probably simply change > the docs to say "This option does nothing.". Or maybe don't > pretend it exists in any useful form and remove it completely. Ah, I didn't realise that was the case, thanks!
Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes
2011/3/24 Jason Merrill : > On 03/21/2011 06:36 PM, Kai Tietz wrote: >> >> + attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a)), >> + CONST_CAST_TREE (a2)); > > I might use as->name for the name, and change lookup_attribute to take a > const_tree rather than use CONST_CAST_TREE. I changed patch to use as->name here instead. The CONST_CAST_TREE part - as we discussed on irc - is necessary, as lookup_attribute returns as result a non-const tree. >> + if (!a) >> + { >> + for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a)) >> + { >> + const struct attribute_spec *as; >> + const_tree attr; >> + as = lookup_attribute_spec (TREE_PURPOSE (a)); >> + if (!as || as->affects_type_identity == false) >> + continue; >> + attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a)), >> + CONST_CAST_TREE (a1)); >> + if (!attr) >> + break; >> + >> + if (TREE_VALUE (a) != NULL_TREE >> + && TREE_CODE (TREE_VALUE (a)) == TREE_LIST >> + && TREE_VALUE (attr) != NULL >> + && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST) >> + { >> + if (simple_cst_list_equal (TREE_VALUE (a), >> + TREE_VALUE (attr)) == 1) >> + break; >> + } >> + else if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (attr)) == >> 1) >> + break; >> + } > > Once we've walked the first list, we don't need to compare the values of > common attributes again; for each attribute in the second list either it > does appear in the first list and we've already established that they match, > or it doesn't appear in the first list and we're done. Yes Updated patch attached. Ok for apply to trunk? Regards, Kai -- | (\_/) This is Bunny. Copy and paste | (='.'=) Bunny into your signature to help | (")_(") him gain world domination Index: gcc/gcc/c-typeck.c === --- gcc.orig/gcc/c-typeck.c 2011-03-24 08:23:42.441173500 +0100 +++ gcc/gcc/c-typeck.c 2011-03-24 09:24:53.445892300 +0100 @@ -1079,7 +1079,7 @@ comptypes_internal (const_tree type1, co return 1; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - if (!(attrval = targetm.comp_type_attributes (t1, t2))) + if (!(attrval = comp_type_attributes (t1, t2))) return 0; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ Index: gcc/gcc/cp/decl.c === --- gcc.orig/gcc/cp/decl.c 2011-03-24 08:23:42.443173500 +0100 +++ gcc/gcc/cp/decl.c 2011-03-24 09:24:53.573408500 +0100 @@ -1012,8 +1012,8 @@ decls_match (tree newdecl, tree olddecl) types_match = compparms (p1, p2) && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE - || targetm.comp_type_attributes (TREE_TYPE (newdecl), - TREE_TYPE (olddecl)) != 0); + || comp_type_attributes (TREE_TYPE (newdecl), + TREE_TYPE (olddecl)) != 0); } else types_match = 0; Index: gcc/gcc/cp/search.c === --- gcc.orig/gcc/cp/search.c2011-03-24 08:23:42.444173500 +0100 +++ gcc/gcc/cp/search.c 2011-03-24 09:24:53.645417600 +0100 @@ -1897,7 +1897,7 @@ check_final_overrider (tree overrider, t } /* Check for conflicting type attributes. */ - if (!targetm.comp_type_attributes (over_type, base_type)) + if (!comp_type_attributes (over_type, base_type)) { error ("conflicting type attributes specified for %q+#D", overrider); error (" overriding %q+#D", basefn); Index: gcc/gcc/cp/typeck.c === --- gcc.orig/gcc/cp/typeck.c2011-03-24 08:23:42.495173500 +0100 +++ gcc/gcc/cp/typeck.c 2011-03-24 09:24:53.697424200 +0100 @@ -1338,7 +1338,7 @@ structural_comptypes (tree t1, tree t2, /* If we get here, we know that from a target independent POV the types are the same. Make sure the target attributes are also the same. */ - return targetm.comp_type_attributes (t1, t2); + return comp_type_attributes (t1, t2); } /* Return true if T1 and T2 are related as allowed by STRICT. STRICT Index: gcc/gcc/gimple.c === --- gcc.orig/gcc/gimple.c 2011-03-24 08:23:42.496173500 +0100 +++ gcc/gcc/gimple.c2011-03-24 09:24:53.793936500 +0100 @@ -3615,7 +3615,7 @@ gimple_types_compatible_p_1 (tree t1, tr state, sccstack, sccstate, sccstate_obstack)) goto different_types; - if (!targetm.comp_type_attributes (t1, t2)) + if (!comp_type_attributes (t1,
Re: [PATCH 3/6] Allow jumps in epilogues
On 03/23/2011 06:27 PM, Richard Henderson wrote: > On 03/23/2011 10:22 AM, Bernd Schmidt wrote: >> On 03/23/2011 06:19 PM, Richard Henderson wrote: >>> body >>> body >>> restore r1 XXX >>> restore r2 XXX >>> jmp L2 XXX >>> >>> L1: bodyYYY >>> bodyYYY >>> restore r2 >>> >>> L2: restore r3 >>> return >> >>> In general, with shrink-wrapping, we can have essentially arbitrary >>> differences in unwind info between blocks that are sequential. >> >> I don't think this can actually happen with the current implementation. >> There is only one prologue, and all epilogues (the normal one and the >> sibcall epilogues) match it exactly. I don't believe we can generate >> code as in the example above, both before and after my patch. > > Um.. then what's this "allow jumps in epilogues" thing of which you speak? > If there's a jump, then it goes somewhere, and branches over something. > I see no constraints on what that something might be. > > Could you give an example of a transformation that is allowed by this? The idea was to be able to share a single return instruction between epilogue/non-epilogue return paths, so that e.g. on i686 a conditional return could be implemented as a conditional jump to a common return insn. The allow-jumps patch then becomes necessary because bbro can move the blocks around. It does seem, however, that bbro can in fact cause problems for the unwind information when the prologue is no longer in the first block. Let me try to come up with a solution for that. Bernd
[Patch] New bfin divsi/udivsi implementations
The attached patch updates the blackfin ___divsi3 and ___udivsi3 implementations (and updates ___umodsi3 to match), as well as adding .size directives to all functions in the file. 2011-03-24 Stuart Henderson * gcc/config/bfin/lib1funcs.asm (___divsi3): New implementation, add .size directive and unguard .text directive. (___udivsi3): New implementation and add .size directive. (___umodsi3): Update to match new ___divsi3/___udivsi3 implementations and add .size directive. (___modsi3): Add .size directive. (___umulsi3_highpart): Likewise. (___smulsi3_highpart): Likewise. I don't have write permissions. Thanks, Stu upstream.patch Description: upstream.patch
[PATCH] Fix PR 48144
Hello, As noted in the PR audit trail, this is a case when we fail to find a transformed insn due to incomplete transformation history attached to it. The earlier fixes of this issue worked only for bookkeeping copies, but now we need a more general mechanism. Fixed by simply picking up additional transformation history from the av sets of basic blocks on the way. The problem can only happen on the bookkeeping blocks which have somewhat newer av sets available. Bootstrapping and testing on x86-64 and ia64 is in progress, ok if it succeeds? Andrey 2011-03-24 Andrey Belevantsev gcc/ PR rtl-optimization/48144 * sel-sched-ir.c (merge_history_vect): Factor out from ... (merge_expr_data): ... here. (av_set_intersect): Rename to av_set_code_motion_filter. Update all callers. Call merge_history_vect when an expression is found in both sets. * sel-sched-ir.h (av_set_code_motion_filter): Add prototype. gcc/testsuite PR rtl-optimization/48144 * gcc.dg/pr48144.c: New test. diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index b88dad1..61f3ffb 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -1564,6 +1564,20 @@ free_history_vect (VEC (expr_history_def, heap) **pvect) *pvect = NULL; } +/* Merge vector FROM to PVECT. */ +static void +merge_history_vect (VEC (expr_history_def, heap) **pvect, + VEC (expr_history_def, heap) *from) +{ + expr_history_def *phist; + int i; + + /* We keep this vector sorted. */ + for (i = 0; VEC_iterate (expr_history_def, from, i, phist); i++) +insert_in_history_vect (pvect, phist->uid, phist->type, +phist->old_expr_vinsn, phist->new_expr_vinsn, +phist->spec_ds); +} /* Compare two vinsns as rhses if possible and as vinsns otherwise. */ bool @@ -1796,9 +1810,6 @@ update_speculative_bits (expr_t to, expr_t from, insn_t split_point) void merge_expr_data (expr_t to, expr_t from, insn_t split_point) { - int i; - expr_history_def *phist; - /* For now, we just set the spec of resulting expr to be minimum of the specs of merged exprs. */ if (EXPR_SPEC (to) > EXPR_SPEC (from)) @@ -1822,20 +1833,12 @@ merge_expr_data (expr_t to, expr_t from, insn_t split_point) EXPR_ORIG_SCHED_CYCLE (to) = MIN (EXPR_ORIG_SCHED_CYCLE (to), EXPR_ORIG_SCHED_CYCLE (from)); - /* We keep this vector sorted. */ - for (i = 0; - VEC_iterate (expr_history_def, EXPR_HISTORY_OF_CHANGES (from), -i, phist); - i++) -insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to), -phist->uid, phist->type, -phist->old_expr_vinsn, phist->new_expr_vinsn, -phist->spec_ds); - EXPR_WAS_SUBSTITUTED (to) |= EXPR_WAS_SUBSTITUTED (from); EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from); EXPR_CANT_MOVE (to) |= EXPR_CANT_MOVE (from); + merge_history_vect (&EXPR_HISTORY_OF_CHANGES (to), + EXPR_HISTORY_OF_CHANGES (from)); update_target_availability (to, from, split_point); update_speculative_bits (to, from, split_point); } @@ -2328,16 +2331,24 @@ av_set_split_usefulness (av_set_t av, int prob, int all_prob) } /* Leave in AVP only those expressions, which are present in AV, - and return it. */ + and return it, merging history expressions. */ void -av_set_intersect (av_set_t *avp, av_set_t av) +av_set_code_motion_filter (av_set_t *avp, av_set_t av) { av_set_iterator i; - expr_t expr; + expr_t expr, expr2; FOR_EACH_EXPR_1 (expr, i, avp) -if (av_set_lookup (av, EXPR_VINSN (expr)) == NULL) +if ((expr2 = av_set_lookup (av, EXPR_VINSN (expr))) == NULL) av_set_iter_remove (&i); +else + /* When updating av sets in bookkeeping blocks, we can add more insns + there which will be transformed but the upper av sets will not + reflect those transformations. We then fail to undo those + when searching for such insns. So merge the history saved + in the av set of the block we are processing. */ + merge_history_vect (&EXPR_HISTORY_OF_CHANGES (expr), + EXPR_HISTORY_OF_CHANGES (expr2)); } diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h index 1f3dec4..5516da9 100644 --- a/gcc/sel-sched-ir.h +++ b/gcc/sel-sched-ir.h @@ -1565,7 +1565,7 @@ extern void av_set_leave_one_nonspec (av_set_t *); extern expr_t av_set_element (av_set_t, int); extern void av_set_substract_cond_branches (av_set_t *); extern void av_set_split_usefulness (av_set_t, int, int); -extern void av_set_intersect (av_set_t *, av_set_t); +extern void av_set_code_motion_filter (av_set_t *, av_set_t); extern void sel_save_haifa_priorities (void); diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index e26ddac..9179249 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -6481,7 +6481,7 @@ code_motion_path_driver (insn_t insn, a
Re: [patch, ARM] Fix PR48250, adjust DImode reload address legitimizing
On Thu, 2011-03-24 at 12:56 +0900, Chung-Lin Tang wrote: > Hi, > PR48250 happens under TARGET_NEON, where DImode is included within the > valid NEON modes. This turns the range of legitimate constant indexes to > step-4 (coproc load/store), thus arm_legitimize_reload_address() when > trying to decompose the [reg+index] reload address into > [(reg+index_high)+index_low], can cause an ICE later when 'index_low' > part is not aligned to 4. > > I'm not sure why the current DImode index is computed as: > low = ((val & 0xf) ^ 0x8) - 0x8; the sign-extending into negative > values, then subtracting back, actually creates further off indexes. > e.g. in the supplied testcase, [sp+13] was turned into [(sp+16)-3]. > Hysterical Raisins... the code there was clearly written for the days before we had LDRD in the architecture. At that time the most efficient way to load a 64-bit object was to use the LDM{ia,ib,da,db} instructions. The computation here was (I think), intended to try and make the most efficient use of an add/sub instruction followed by LDM/STM offsetting. At that time the architecture had no unaligned access either, so dealing with 64-bit that were less than 32-bit aligned (in those days 32-bit was the maximum alignment) probably wasn't considered, or couldn't even get through to reload. > My patch changes the index decomposing to a more straightforward way; it > also sort of outlines the way the other reload address indexes are > broken by using and-masks, is not the most effective. The address is > computed by addition, subtracting away the parts to obtain low+high > should be the optimal way of giving the largest computable index range. > > I have included a few Thumb-2 bits in the patch; I know currently > arm_legitimize_reload_address() is only used under TARGET_ARM, but I > guess it might eventually be turned into TARGET_32BIT. > I think this needs to be looked at carefully on ARMv4/ARMv4T to check that it doesn't cause regressions there when we don't have LDRD in the instruction set. > Cross-tested on QEMU without regressions, is this okay? > > Thanks, > Chung-Lin > > 2011-03-24 Chung-Lin Tang > > PR target/48250 > * config/arm/arm.c (arm_legitimize_reload_address): Adjust > DImode constant index decomposing. Mask out lower 2-bits for > NEON and Thumb-2. > > testsuite/ > * gcc.target/arm/pr48250.c: New. R.
Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes
Sorry, but I found some commenting issues and reworked them a bit. Attached is the updated patch. Kai Index: gcc/gcc/c-typeck.c === --- gcc.orig/gcc/c-typeck.c 2011-03-24 08:23:42.441173500 +0100 +++ gcc/gcc/c-typeck.c 2011-03-24 09:24:53.445892300 +0100 @@ -1079,7 +1079,7 @@ comptypes_internal (const_tree type1, co return 1; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - if (!(attrval = targetm.comp_type_attributes (t1, t2))) + if (!(attrval = comp_type_attributes (t1, t2))) return 0; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ Index: gcc/gcc/cp/decl.c === --- gcc.orig/gcc/cp/decl.c 2011-03-24 08:23:42.443173500 +0100 +++ gcc/gcc/cp/decl.c 2011-03-24 09:24:53.573408500 +0100 @@ -1012,8 +1012,8 @@ decls_match (tree newdecl, tree olddecl) types_match = compparms (p1, p2) && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE - || targetm.comp_type_attributes (TREE_TYPE (newdecl), - TREE_TYPE (olddecl)) != 0); + || comp_type_attributes (TREE_TYPE (newdecl), + TREE_TYPE (olddecl)) != 0); } else types_match = 0; Index: gcc/gcc/cp/search.c === --- gcc.orig/gcc/cp/search.c2011-03-24 08:23:42.444173500 +0100 +++ gcc/gcc/cp/search.c 2011-03-24 09:24:53.645417600 +0100 @@ -1897,7 +1897,7 @@ check_final_overrider (tree overrider, t } /* Check for conflicting type attributes. */ - if (!targetm.comp_type_attributes (over_type, base_type)) + if (!comp_type_attributes (over_type, base_type)) { error ("conflicting type attributes specified for %q+#D", overrider); error (" overriding %q+#D", basefn); Index: gcc/gcc/cp/typeck.c === --- gcc.orig/gcc/cp/typeck.c2011-03-24 08:23:42.495173500 +0100 +++ gcc/gcc/cp/typeck.c 2011-03-24 09:24:53.697424200 +0100 @@ -1338,7 +1338,7 @@ structural_comptypes (tree t1, tree t2, /* If we get here, we know that from a target independent POV the types are the same. Make sure the target attributes are also the same. */ - return targetm.comp_type_attributes (t1, t2); + return comp_type_attributes (t1, t2); } /* Return true if T1 and T2 are related as allowed by STRICT. STRICT Index: gcc/gcc/gimple.c === --- gcc.orig/gcc/gimple.c 2011-03-24 08:23:42.496173500 +0100 +++ gcc/gcc/gimple.c2011-03-24 09:24:53.793936500 +0100 @@ -3615,7 +3615,7 @@ gimple_types_compatible_p_1 (tree t1, tr state, sccstack, sccstate, sccstate_obstack)) goto different_types; - if (!targetm.comp_type_attributes (t1, t2)) + if (!comp_type_attributes (t1, t2)) goto different_types; if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2)) Index: gcc/gcc/tree-ssa.c === --- gcc.orig/gcc/tree-ssa.c 2011-03-24 08:23:42.498173500 +0100 +++ gcc/gcc/tree-ssa.c 2011-03-24 09:24:53.831441200 +0100 @@ -1438,7 +1438,7 @@ useless_type_conversion_p (tree outer_ty /* Defer to the target if necessary. */ if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type)) - return targetm.comp_type_attributes (outer_type, inner_type) != 0; + return comp_type_attributes (outer_type, inner_type) != 0; return true; } Index: gcc/gcc/tree.c === --- gcc.orig/gcc/tree.c 2011-03-24 08:23:42.499173500 +0100 +++ gcc/gcc/tree.c 2011-03-24 11:54:43.225949400 +0100 @@ -4283,7 +4283,7 @@ build_type_attribute_qual_variant (tree its canonical type, we will need to use structural equality checks for this type. */ if (TYPE_STRUCTURAL_EQUALITY_P (ttype) - || !targetm.comp_type_attributes (ntype, ttype)) + || !comp_type_attributes (ntype, ttype)) SET_TYPE_STRUCTURAL_EQUALITY (ntype); else if (TYPE_CANONICAL (ntype) == ntype) TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype); @@ -4296,6 +4296,67 @@ build_type_attribute_qual_variant (tree return ttype; } +/* Return 0 if the attributes for two types are incompatible, 1 if they + are compatible, and 2 if they are nearly compatible (which causes a + warning to be generated). */ +int +comp_type_attributes (const_tree type1, const_tree type2) +{ + const_tree a1 = TYPE_ATTRIBUTES (type1); + const_tree a2 = TYPE_ATTRIBUTES (type2); + const_tree a; + + if (a1 == a2) +return 1; + for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a)) +{ + const struc
Re: [patch] Fix PR48183, NEON ICE in emit-rtl.c:immed_double_const() under -g
Chung-Lin Tang writes: > PR48183 is a case where ARM NEON instrinsics, under -O -g, produce debug > insns that tries to expand OImode (32-byte integer) zero constants, much > too large to represent as two HOST_WIDE_INTs; as the internals manual > indicates, such large constants are not supported in general, and ICEs > on the GET_MODE_BITSIZE(mode) == 2*HOST_BITS_PER_WIDE_INT assertion. > > This patch allows the cases where the large integer constant is still > representable using a single CONST_INT, such as zero(0). Bootstrapped > and tested on i686 and x86_64, cross-tested on ARM, all without > regressions. Okay for trunk? > > Thanks, > Chung-Lin > > 2011-03-20 Chung-Lin Tang > > * emit-rtl.c (immed_double_const): Allow wider than > 2*HOST_BITS_PER_WIDE_INT mode constants when they are > representable as a single const_int RTX. I realise this might be seen as a good expedient fix, but it makes me a bit uneasy. Not a very constructive rationale, sorry. For this particular case, the problem is that vst2q_s32 and the like initialise a union directly: union { int32x4x2_t __i; __builtin_neon_oi __o; } __bu = { __b; }; and this gets translated into a zeroing of the whole union followed by an assignment to __i: __bu = {}; __bu.__i = __b; We later optimise away the first assignment, but it still exists in the debug info. Another expedient fix might be to replace these initialisations with: union { int32x4x2_t __i; __builtin_neon_oi __o; } __bu; __bu.__i = __b; so that we never get a zeroing statement. I realise both "fixes" are papering over the real problem. What we really need is arbitrary-length constant integers, like we already have for vectors. But that's going to be a much bigger patch. It just seems to me that, if we're going for a work-around, the arm_neon.h change is neutral, while changing immed_double_const feels more risky. Richard
Re: [patch, ARM] Enable auto-detection of vector size for NEON
On Thu, 24 Mar 2011, Ira Rosen wrote: > Hi, > > This patch implements TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES for ARM > NEON. Given the multiple vector sizes support, is there a reason not to enable -mvectorize-with-neon-quad by default? -- Joseph S. Myers jos...@codesourcery.com
Re: [patch, ARM] Enable auto-detection of vector size for NEON
On 24 March 2011 13:03, Joseph S. Myers wrote: > On Thu, 24 Mar 2011, Ira Rosen wrote: > >> Hi, >> >> This patch implements TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES for ARM >> NEON. > > Given the multiple vector sizes support, is there a reason not to enable > -mvectorize-with-neon-quad by default? I don't see any reason, and I am going to submit a follow-up patch that does that. Ira > > -- > Joseph S. Myers > jos...@codesourcery.com >
Update config.sub
I've updated config.sub to the latest version from config.git. This will facilitate further cleanups by ensuring that certain obsolete triplets can never appear as canonical hosts or targets in gcc or src builds. Index: ChangeLog === --- ChangeLog (revision 171384) +++ ChangeLog (working copy) @@ -1,3 +1,7 @@ +2011-03-24 Joseph Myers + + * config.sub: Update to version 2011-03-23. + 2011-03-22 Joseph Myers * configure.ac (arm-semi-aof, crx-*-*, parisc*-*-linux*, Index: config.sub === --- config.sub (revision 171384) +++ config.sub (working copy) @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011 Free Software Foundation, Inc. -timestamp='2011-02-24' +timestamp='2011-03-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -288,7 +288,7 @@ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rx \ | score \ @@ -296,12 +296,12 @@ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e \ | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; @@ -325,6 +325,18 @@ basic_machine=mt-unknown ;; + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. @@ -384,22 +396,22 @@ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) @@ -950,9 +962,10 @@ ;; power) basic_machine=power-ibm ;; - ppc)basic_machine=powerpc-unknown + ppc | ppcbe)basic_machine=powerpc-unknown ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown @@ -1046,6 +1059,9 @@ basic_machine=i860-stratus os=-sysv4 ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; sun2) basic_machine=m68000-sun ;; @@ -1178,6 +1194,9 @@ xps | xps100) basic_machine=xps100-honeywell ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; ymp) basic_machine=ymp-cray os=-unicos -- Joseph S. Myers jos...@codesourcery.com
Remove dead cases from toplevel configure.ac
This patch removes various dead cases from the toplevel configure.ac. Target ep9312-* isn't known to config.sub at all so those cases have been dead for a long time; likewise parisc*64*-* (those parisc cases it does know have also been handled by config.sub as aliases for hppa-* for a long time). With my recent config.sub changes, strongarm-*, xscale*-*, thumb-* and ppc*-* will always be converted by config.sub to arm*-* or powerpc*-* when accepted at all (most ppc*-* cases were already so converted before my changes). OK to commit? 2011-03-24 Joseph Myers * configure.ac (ppc*-*-pe): Remove host case. (strongarm-*-coff | xscale-*-coff, strongarm-*-elf* | xscale-*-elf*, thumb-*-coff, thumb-*-elf, thumb-*-pe, ep9312-*-elf | ep9312-*-coff, parisc*64*-*-linux*, ppc*-*-pe): Remove target cases. * configure: Regenerate. Index: configure.ac === --- configure.ac(revision 171384) +++ configure.ac(working copy) @@ -451,9 +451,6 @@ *-*-netbsd*) noconfigdirs="$noconfigdirs rcs" ;; - ppc*-*-pe) -noconfigdirs="$noconfigdirs patch diff make tk tcl expect dejagnu autoconf automake texinfo bison send-pr gprof rcs guile perl itcl gnuserv" -;; powerpc-*-beos*) noconfigdirs="$noconfigdirs tk itcl libgui gdb dejagnu readline" ;; @@ -672,11 +669,11 @@ arc-*-*) noconfigdirs="$noconfigdirs target-libgloss" ;; - arm-*-coff | strongarm-*-coff | xscale-*-coff) + arm-*-coff) noconfigdirs="$noconfigdirs ${libgcj}" libgloss_dir=arm ;; - arm-*-elf* | strongarm-*-elf* | xscale-*-elf* | arm*-*-eabi* ) + arm-*-elf* | arm*-*-eabi* ) noconfigdirs="$noconfigdirs target-libffi target-qthreads" libgloss_dir=arm ;; @@ -694,15 +691,6 @@ arm-*-pe*) noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" ;; - thumb-*-coff) -noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" -;; - thumb-*-elf) -noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" -;; - thumb-*-pe) -noconfigdirs="$noconfigdirs target-libgloss ${libgcj}" -;; arm-*-riscix*) noconfigdirs="$noconfigdirs ld target-libgloss ${libgcj}" ;; @@ -747,9 +735,6 @@ d30v-*-*) noconfigdirs="$noconfigdirs ${libgcj} gdb" ;; - ep9312-*-elf | ep9312-*-coff) -libgloss_dir=arm -;; fr30-*-elf*) noconfigdirs="$noconfigdirs ${libgcj} gdb" ;; @@ -768,7 +753,7 @@ ;; hppa1.1-*-osf* | hppa1.1-*-bsd* ) ;; - hppa*64*-*-linux* | parisc*64*-*-linux*) + hppa*64*-*-linux*) # In this case, it's because the hppa64-linux target is for # the kernel only at this point and has no libc, and thus no # headers, crt*.o, etc., all of which are needed by these. @@ -912,7 +897,7 @@ # copied from rs6000-*-* entry noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp target-newlib ${libgcj}" ;; - powerpc*-*-winnt* | powerpc*-*-pe* | ppc*-*-pe) + powerpc*-*-winnt* | powerpc*-*-pe*) target_configdirs="$target_configdirs target-winsup" noconfigdirs="$noconfigdirs gdb tcl tk make expect target-libgloss itcl gnuserv ${libgcj}" # always build newlib. -- Joseph S. Myers jos...@codesourcery.com
Re: [patch, ARM] Enable auto-detection of vector size for NEON
On 24/03/11 09:06, Ira Rosen wrote: Hi, This patch implements TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES for ARM NEON. Regtested on arm-linux-gnueabi. OK for trunk? This is OK for trunk if there are no regressions. cheers Ramana Thanks, Ira ChangeLog: * config/arm/arm.c (arm_autovectorize_vector_sizes): New function. (TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Define. testsuite/ChangeLog: * gcc.dg/vect/vect-outer-5.c: Reduce the distance between data accesses to preserve the meaning of the test for doubleword vectors. * gcc.dg/vect/no-vfa-pr29145.c: Likewise. * gcc.dg/vect/slp-3.c: Reduce the loop bound for the same reason. Index: config/arm/arm.c === --- config/arm/arm.c(revision 171339) +++ config/arm/arm.c(working copy) @@ -252,6 +252,7 @@ static bool arm_builtin_support_vector_misalignmen bool is_packed); static void arm_conditional_register_usage (void); static reg_class_t arm_preferred_rename_class (reg_class_t rclass); +static unsigned int arm_autovectorize_vector_sizes (void); ^L /* Table of machine attributes. */ @@ -404,6 +405,9 @@ static const struct default_options arm_option_opt #define TARGET_VECTOR_MODE_SUPPORTED_P arm_vector_mode_supported_p #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arm_preferred_simd_mode +#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES +#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \ + arm_autovectorize_vector_sizes #undef TARGET_MACHINE_DEPENDENT_REORG #define TARGET_MACHINE_DEPENDENT_REORG arm_reorg @@ -23528,6 +23532,12 @@ arm_expand_sync (enum machine_mode mode, } } +static unsigned int +arm_autovectorize_vector_sizes (void) +{ + return TARGET_NEON_VECTORIZE_QUAD ? 16 | 8 : 0; +} + static bool arm_vector_alignment_reachable (const_tree type, bool is_packed) { Index: testsuite/gcc.dg/vect/vect-outer-5.c === --- testsuite/gcc.dg/vect/vect-outer-5.c(revision 171339) +++ testsuite/gcc.dg/vect/vect-outer-5.c(working copy) @@ -17,7 +17,7 @@ int main1 () float B[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); float C[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); float D[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); - float E[4] = {0,1,2,480}; + float E[4] = {0,480,960,1440}; float s; int i, j; @@ -55,7 +55,7 @@ int main1 () s = 0; for (j=0; j
[PATCH] use cfglayout mode for instatiate_virtual_regs
As $SUBJECT suggests. The patch looks much bigger than it actually is due to re-indentation. Tested on x86_64-unknown-linux-gnu. OK to commit? -Nathan * function.c (instantiate_virtual_regs): Use FOR_EACH_BB and FOR_BB_INSNS_SAFE to iterate through insns. Re-indent. * passes.c (init_optimization_passes): Move pass_instantiate_virtual_regs after pass_into_cfg_layout_mode. diff --git a/gcc/function.c b/gcc/function.c index a1ea482..49404c8 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1883,7 +1883,7 @@ instantiate_decls (tree fndecl) static unsigned int instantiate_virtual_regs (void) { - rtx insn; + basic_block bb; /* Compute the offsets to use for this function. */ in_arg_offset = FIRST_PARM_OFFSET (current_function_decl); @@ -1901,33 +1901,40 @@ instantiate_virtual_regs (void) /* Scan through all the insns, instantiating every virtual register still present. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) -if (INSN_P (insn)) - { - /* These patterns in the instruction stream can never be recognized. - Fortunately, they shouldn't contain virtual registers either. */ - if (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER - || GET_CODE (PATTERN (insn)) == ADDR_VEC - || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC - || GET_CODE (PATTERN (insn)) == ASM_INPUT) - continue; - else if (DEBUG_INSN_P (insn)) - for_each_rtx (&INSN_VAR_LOCATION (insn), - instantiate_virtual_regs_in_rtx, NULL); - else - instantiate_virtual_regs_in_insn (insn); + FOR_EACH_BB (bb) +{ + rtx insn, curr; - if (INSN_DELETED_P (insn)) - continue; + FOR_BB_INSNS_SAFE (bb, insn, curr) + { + if (INSN_P (insn)) + { + /* These patterns in the instruction stream can never be recognized. +Fortunately, they shouldn't contain virtual registers either. */ + if (GET_CODE (PATTERN (insn)) == USE + || GET_CODE (PATTERN (insn)) == CLOBBER + || GET_CODE (PATTERN (insn)) == ADDR_VEC + || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC + || GET_CODE (PATTERN (insn)) == ASM_INPUT) + continue; + else if (DEBUG_INSN_P (insn)) + for_each_rtx (&INSN_VAR_LOCATION (insn), + instantiate_virtual_regs_in_rtx, NULL); + else + instantiate_virtual_regs_in_insn (insn); - for_each_rtx (®_NOTES (insn), instantiate_virtual_regs_in_rtx, NULL); + if (INSN_DELETED_P (insn)) + continue; - /* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE. */ - if (CALL_P (insn)) - for_each_rtx (&CALL_INSN_FUNCTION_USAGE (insn), - instantiate_virtual_regs_in_rtx, NULL); - } + for_each_rtx (®_NOTES (insn), instantiate_virtual_regs_in_rtx, NULL); + + /* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE. */ + if (CALL_P (insn)) + for_each_rtx (&CALL_INSN_FUNCTION_USAGE (insn), + instantiate_virtual_regs_in_rtx, NULL); + } + } +} /* Instantiate the virtual registers in the DECLs for debugging purposes. */ instantiate_decls (current_function_decl); @@ -1963,7 +1970,7 @@ struct rtl_opt_pass pass_instantiate_virtual_regs = NULL, /* next */ 0,/* static_pass_number */ TV_NONE, /* tv_id */ - 0,/* properties_required */ + PROP_cfglayout, /* properties_required */ 0,/* properties_provided */ 0,/* properties_destroyed */ 0,/* todo_flags_start */ diff --git a/gcc/passes.c b/gcc/passes.c index 42a3239..3353557 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -956,8 +956,8 @@ init_optimization_passes (void) NEXT_PASS (pass_rtl_eh); NEXT_PASS (pass_initial_value_sets); NEXT_PASS (pass_unshare_all_rtl); - NEXT_PASS (pass_instantiate_virtual_regs); NEXT_PASS (pass_into_cfg_layout_mode); + NEXT_PASS (pass_instantiate_virtual_regs); NEXT_PASS (pass_jump2); NEXT_PASS (pass_lower_subreg); NEXT_PASS (pass_df_initialize_opt);
Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes
On 03/24/2011 11:56 AM, Kai Tietz wrote: + if (TREE_VALUE (a) != NULL_TREE + && TREE_CODE (TREE_VALUE (a)) == TREE_LIST + && TREE_VALUE (attr) != NULL + && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST) + { + if (simple_cst_list_equal (TREE_VALUE (a), +TREE_VALUE (attr)) == 1) + break; + } + else if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (attr)) == 1) How about splitting this out into a separate function that can compare either list or expression arguments? That would also be useful for merge_attributes and attribute_list_contained. Jason
Re: Cleaning up expand optabs code
On 03/22/2011 06:48 PM, Richard Henderson wrote: > Ok. Watch out for other target problems this week. This unfortunately broke bootstrap on s390. An unrecognizable insns is generated: (insn 22 21 23 4 (set (reg/v:DI 44 [ end]) (mult:DI (sign_extend:DI (mem/s/j:SI (plus:SI (reg/v/f:SI 47 [ foo]) (const_int 4 [0x4])) [0 foo_5(D)->incr_ull+4 S4 A32])) (sign_extend:DI (subreg:SI (reg:DI 49) 4 t.c:12 -1 (nil)) The problem is that expand_binop_directly swaps the operands without rechecking the predicates afterwards. The old code did: /* Now, if insn's predicates don't allow our operands, put them into pseudo regs. */ if (!insn_data[icode].operand[1].predicate (xop0, mode0) && mode0 != VOIDmode) xop0 = copy_to_mode_reg (mode0, xop0); if (!insn_data[icode].operand[2].predicate (xop1, mode1) && mode1 != VOIDmode) xop1 = copy_to_mode_reg (mode1, xop1); Right after swapping the operands. Unfortunately it cannot be simply fixed by swapping the operands in the back end pattern. Since subreg and reg have different operand precedences. A subreg usually will be second after a mem while a reg (having same precedence as mem) might be first operand before a mem. Just copying the pre-patch behaviour fixes the problem for me: Index: gcc/optabs.c === *** gcc/optabs.c.orig 2011-03-24 12:54:31.0 +0100 --- gcc/optabs.c2011-03-24 12:54:43.0 +0100 *** expand_binop_directly (enum machine_mode *** 1308,1313 --- 1308,1322 ops[1].value = swap; } + /* Now, if insn's predicates don't allow our operands, put them into +pseudo regs. */ + + if (!insn_operand_matches (icode, 1, ops[1].value)) + ops[1].value = copy_to_mode_reg (mode0, ops[1].value); + + if (!insn_operand_matches (icode, 2, ops[2].value)) + ops[2].value = copy_to_mode_reg (mode1, ops[2].value); + pat = GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value); if (pat) { Ok? Bye, -Andreas-
Re: Remove dead cases from toplevel configure.ac
On 03/24/2011 12:26 PM, Joseph S. Myers wrote: This patch removes various dead cases from the toplevel configure.ac. Target ep9312-* isn't known to config.sub at all so those cases have been dead for a long time; likewise parisc*64*-* (those parisc cases it does know have also been handled by config.sub as aliases for hppa-* for a long time). With my recent config.sub changes, strongarm-*, xscale*-*, thumb-* and ppc*-* will always be converted by config.sub to arm*-* or powerpc*-* when accepted at all (most ppc*-* cases were already so converted before my changes). OK to commit? Ok. Paolo
Re: Cleaning up expand optabs code
Andreas Krebbel writes: > On 03/22/2011 06:48 PM, Richard Henderson wrote: > >> Ok. Watch out for other target problems this week. > > This unfortunately broke bootstrap on s390. This is PR 48263. Since it seems to be affecting several targets, and since my bootstrap seems to be taking a looong time, I'll post the patch here before testing has finished. > Just copying the pre-patch behaviour fixes the problem for me: I think we need to undo more of the patch, and leave the conversion outside of the new interface. Sorry for the breakage. Richard gcc/ PR rtl-optimization/48263 * optabs.c (expand_binop_directly): Reinstate convert_modes code and original commutative_p handling. Use maybe_gen_insn. Index: gcc/optabs.c === --- gcc/optabs.c2011-03-24 09:18:00.0 + +++ gcc/optabs.c2011-03-24 09:36:46.0 + @@ -1269,6 +1269,38 @@ expand_binop_directly (enum machine_mode if (!shift_optab_p (binoptab)) xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp); + /* In case the insn wants input operands in modes different from + those of the actual operands, convert the operands. It would + seem that we don't need to convert CONST_INTs, but we do, so + that they're properly zero-extended, sign-extended or truncated + for their mode. */ + + if (GET_MODE (xop0) != mode0 && mode0 != VOIDmode) +xop0 = convert_modes (mode0, + GET_MODE (xop0) != VOIDmode + ? GET_MODE (xop0) + : mode, + xop0, unsignedp); + + if (GET_MODE (xop1) != mode1 && mode1 != VOIDmode) +xop1 = convert_modes (mode1, + GET_MODE (xop1) != VOIDmode + ? GET_MODE (xop1) + : mode, + xop1, unsignedp); + + /* If operation is commutative, + try to make the first operand a register. + Even better, try to make it the same as the target. + Also try to make the last operand a constant. */ + if (commutative_p + && swap_commutative_operands_with_target (target, xop0, xop1)) +{ + swap = xop1; + xop1 = xop0; + xop0 = swap; +} + /* Now, if insn's predicates don't allow our operands, put them into pseudo regs. */ @@ -1291,41 +1323,25 @@ expand_binop_directly (enum machine_mode tmp_mode = mode; create_output_operand (&ops[0], target, tmp_mode); - create_convert_operand_from (&ops[1], xop0, mode, unsignedp); - create_convert_operand_from (&ops[2], xop1, mode, unsignedp); - if (maybe_legitimize_operands (icode, 0, 3, ops)) -{ - /* If operation is commutative, -try to make the first operand a register. -Even better, try to make it the same as the target. -Also try to make the last operand a constant. */ - if (commutative_p - && swap_commutative_operands_with_target (ops[0].value, ops[1].value, - ops[2].value)) - { - swap = ops[2].value; - ops[2].value = ops[1].value; - ops[1].value = swap; - } - - pat = GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value); - if (pat) + create_input_operand (&ops[1], xop0, mode0); + create_input_operand (&ops[2], xop1, mode1); + pat = maybe_gen_insn (icode, 3, ops); + if (pat) +{ + /* If PAT is composed of more than one insn, try to add an appropriate +REG_EQUAL note to it. If we can't because TEMP conflicts with an +operand, call expand_binop again, this time without a target. */ + if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX + && ! add_equal_note (pat, ops[0].value, binoptab->code, + ops[1].value, ops[2].value)) { - /* If PAT is composed of more than one insn, try to add an appropriate -REG_EQUAL note to it. If we can't because TEMP conflicts with an -operand, call expand_binop again, this time without a target. */ - if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX - && ! add_equal_note (pat, ops[0].value, binoptab->code, - ops[1].value, ops[2].value)) - { - delete_insns_since (last); - return expand_binop (mode, binoptab, op0, op1, NULL_RTX, - unsignedp, methods); - } - - emit_insn (pat); - return ops[0].value; + delete_insns_since (last); + return expand_binop (mode, binoptab, op0, op1, NULL_RTX, + unsignedp, methods); } + + emit_insn (pat); + return ops[0].value; } delete_insns_since (last); return NULL_RTX;
Re: [patch] Enhance conditional store sinking
On Thu, Mar 24, 2011 at 11:03 AM, H.J. Lu wrote: > On Tue, Mar 22, 2011 at 6:28 AM, Ira Rosen wrote: >> On 17 March 2011 16:48, Richard Guenther wrote: >> + then_datarefs = VEC_alloc (data_reference_p, heap, 1); + else_datarefs = VEC_alloc (data_reference_p, heap, 1); + then_ddrs = VEC_alloc (ddr_p, heap, 1); + else_ddrs = VEC_alloc (ddr_p, heap, 1); + if (!compute_data_dependences_for_bb (then_bb, false, &then_datarefs, + &then_ddrs) >>> >>> Can we avoid computing dependencies if the other BB would have no >>> data-refs? Thus, split collecting datarefs and computing dependences? >> >> Done. >> >>> + || !compute_data_dependences_for_bb (else_bb, false, &else_datarefs, + &else_ddrs) + || !VEC_length (data_reference_p, then_datarefs) + || !VEC_length (data_reference_p, else_datarefs)) + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + + /* Check that there are no read-after-write or write-after-write dependencies + in THEN_BB. */ + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb >>> >>> The gimple_uids are not initialized here, you need to make sure to >>> call renumber_gimple_stmt_uids () before starting. Note that phiopt >>> incrementally changes the IL, so I'm not sure those uids will stay >>> valid as stmts are moved across blocks. >> >> I added a call to renumber_gimple_stmt_uids_in_blocks() before data >> dependence checks, and there are no code changes between that and the >> checks, so, I think, it should be OK. >> >>> + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Check that there are no read-after-write or write-after-write dependencies + in ELSE_BB. */ + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) + { + struct data_reference *dra = DDR_A (ddr); + struct data_reference *drb = DDR_B (ddr); + + if (DDR_ARE_DEPENDENT (ddr) != chrec_known + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb))) + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra))) + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb + { + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); + free_dependence_relations (then_ddrs); + free_dependence_relations (else_ddrs); + return false; + } + } + + /* Found pairs of stores with equal LHS. */ + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) + { + if (DR_IS_READ (then_dr)) + continue; + + then_store = DR_STMT (then_dr); + then_lhs = gimple_assign_lhs (then_store); + found = false; + + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) + { + if (DR_IS_READ (else_dr)) + continue; + + else_store = DR_STMT (else_dr); + else_lhs = gimple_assign_lhs (else_store); + + if (operand_equal_p (then_lhs, else_lhs, 0)) + { + found = true; + break; + } + } + + if (!found) + continue; + + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, + then_store, else_store); >>> >>> So you are executing if-else store replacement for common data reference >>> pairs only. I think it's cheaper to collect those pairs before computing >>> dependences and only if there is at least one pair perform the optimization. >> >> OK, I changed the order. >> >>> >>> You basically perform store sinking, creating a PHI
Re: [patch] Enhance conditional store sinking
On Thu, Mar 24, 2011 at 1:39 PM, Richard Guenther wrote: > On Thu, Mar 24, 2011 at 11:03 AM, H.J. Lu wrote: >> On Tue, Mar 22, 2011 at 6:28 AM, Ira Rosen wrote: >>> On 17 March 2011 16:48, Richard Guenther wrote: >>> > + then_datarefs = VEC_alloc (data_reference_p, heap, 1); > + else_datarefs = VEC_alloc (data_reference_p, heap, 1); > + then_ddrs = VEC_alloc (ddr_p, heap, 1); > + else_ddrs = VEC_alloc (ddr_p, heap, 1); > + if (!compute_data_dependences_for_bb (then_bb, false, &then_datarefs, > + &then_ddrs) Can we avoid computing dependencies if the other BB would have no data-refs? Thus, split collecting datarefs and computing dependences? >>> >>> Done. >>> > + || !compute_data_dependences_for_bb (else_bb, false, > &else_datarefs, > + &else_ddrs) > + || !VEC_length (data_reference_p, then_datarefs) > + || !VEC_length (data_reference_p, else_datarefs)) > + { > + free_data_refs (then_datarefs); > + free_data_refs (else_datarefs); > + free_dependence_relations (then_ddrs); > + free_dependence_relations (else_ddrs); > + return false; > + } > + > + /* Check that there are no read-after-write or write-after-write > dependencies > + in THEN_BB. */ > + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) > + { > + struct data_reference *dra = DDR_A (ddr); > + struct data_reference *drb = DDR_B (ddr); > + > + if (DDR_ARE_DEPENDENT (ddr) != chrec_known > + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) > + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT > (drb))) > + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) > + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT > (dra))) > + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb The gimple_uids are not initialized here, you need to make sure to call renumber_gimple_stmt_uids () before starting. Note that phiopt incrementally changes the IL, so I'm not sure those uids will stay valid as stmts are moved across blocks. >>> >>> I added a call to renumber_gimple_stmt_uids_in_blocks() before data >>> dependence checks, and there are no code changes between that and the >>> checks, so, I think, it should be OK. >>> > + { > + free_data_refs (then_datarefs); > + free_data_refs (else_datarefs); > + free_dependence_relations (then_ddrs); > + free_dependence_relations (else_ddrs); > + return false; > + } > + } > + > + /* Check that there are no read-after-write or write-after-write > dependencies > + in ELSE_BB. */ > + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) > + { > + struct data_reference *dra = DDR_A (ddr); > + struct data_reference *drb = DDR_B (ddr); > + > + if (DDR_ARE_DEPENDENT (ddr) != chrec_known > + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) > + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT > (drb))) > + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) > + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT > (dra))) > + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb > + { > + free_data_refs (then_datarefs); > + free_data_refs (else_datarefs); > + free_dependence_relations (then_ddrs); > + free_dependence_relations (else_ddrs); > + return false; > + } > + } > + > + /* Found pairs of stores with equal LHS. */ > + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) > + { > + if (DR_IS_READ (then_dr)) > + continue; > + > + then_store = DR_STMT (then_dr); > + then_lhs = gimple_assign_lhs (then_store); > + found = false; > + > + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) > + { > + if (DR_IS_READ (else_dr)) > + continue; > + > + else_store = DR_STMT (else_dr); > + else_lhs = gimple_assign_lhs (else_store); > + > + if (operand_equal_p (then_lhs, else_lhs, 0)) > + { > + found = true; > + break; > + } > + } > + > + if (!found) > + continue; > + > + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, > + then_store, else_store); So you are executing if-else store replacement for common data reference pairs only. I think it's cheaper to collect th
[PATCH] Fix PR48269
This removes a double-accounting for MEM_REF offsets. The code still looks somewhat fishy, but at least is consistent in what it does now ;) Bootstrapped and tested on x86_64-unknonw-linux-gnu, applied to trunk. Richard. 2011-03-24 Richard Guenther PR middle-end/48269 * tree-object-size.c (addr_object_size): Do not double-account for MEM_REF offsets. * gcc.dg/builtin-object-size-10.c: New testcase. Index: gcc/tree-object-size.c === *** gcc/tree-object-size.c (revision 171384) --- gcc/tree-object-size.c (working copy) *** addr_object_size (struct object_size_inf *** 348,355 tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var); if (bytes2 != error_mark_node) { - bytes2 = size_binop (PLUS_EXPR, bytes2, - TREE_OPERAND (pt_var, 1)); if (TREE_CODE (bytes2) == INTEGER_CST && tree_int_cst_lt (pt_var_size, bytes2)) bytes2 = size_zero_node; --- 348,353 Index: gcc/testsuite/gcc.dg/builtin-object-size-10.c === *** gcc/testsuite/gcc.dg/builtin-object-size-10.c (revision 0) --- gcc/testsuite/gcc.dg/builtin-object-size-10.c (revision 0) *** *** 0 --- 1,26 + /* { dg-do compile } */ + /* { dg-options "-O2 -fdump-tree-objsz-details" } */ + + typedef struct { + char sentinel[4]; + char data[0]; + } drone_packet; + typedef struct { + char type_str[16]; + char channel_hop; + } drone_source_packet; + drone_packet * + foo(char *x) + { + drone_packet *dpkt = __builtin_malloc(sizeof(drone_packet) + + sizeof(drone_source_packet)); + drone_source_packet *spkt = (drone_source_packet *) dpkt->data; + __builtin___snprintf_chk (spkt->type_str, 16, + 1, __builtin_object_size (spkt->type_str, 1), + "%s", x); + return dpkt; + } + + /* { dg-final { scan-tree-dump "maximum object size 21" "objsz" } } */ + /* { dg-final { scan-tree-dump "maximum subobject size 16" "objsz" } } */ + /* { dg-final { cleanup-tree-dump "objsz" } } */
Re: [patch] Enhance conditional store sinking
On 24 March 2011 14:40, Richard Guenther wrote: > On Thu, Mar 24, 2011 at 1:39 PM, Richard Guenther > wrote: >> On Thu, Mar 24, 2011 at 11:03 AM, H.J. Lu wrote: >>> On Tue, Mar 22, 2011 at 6:28 AM, Ira Rosen wrote: On 17 March 2011 16:48, Richard Guenther wrote: >> + then_datarefs = VEC_alloc (data_reference_p, heap, 1); >> + else_datarefs = VEC_alloc (data_reference_p, heap, 1); >> + then_ddrs = VEC_alloc (ddr_p, heap, 1); >> + else_ddrs = VEC_alloc (ddr_p, heap, 1); >> + if (!compute_data_dependences_for_bb (then_bb, false, &then_datarefs, >> + &then_ddrs) > > Can we avoid computing dependencies if the other BB would have no > data-refs? Thus, split collecting datarefs and computing dependences? Done. > >> + || !compute_data_dependences_for_bb (else_bb, false, >> &else_datarefs, >> + &else_ddrs) >> + || !VEC_length (data_reference_p, then_datarefs) >> + || !VEC_length (data_reference_p, else_datarefs)) >> + { >> + free_data_refs (then_datarefs); >> + free_data_refs (else_datarefs); >> + free_dependence_relations (then_ddrs); >> + free_dependence_relations (else_ddrs); >> + return false; >> + } >> + >> + /* Check that there are no read-after-write or write-after-write >> dependencies >> + in THEN_BB. */ >> + FOR_EACH_VEC_ELT (ddr_p, then_ddrs, i, ddr) >> + { >> + struct data_reference *dra = DDR_A (ddr); >> + struct data_reference *drb = DDR_B (ddr); >> + >> + if (DDR_ARE_DEPENDENT (ddr) != chrec_known >> + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) >> + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT >> (drb))) >> + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) >> + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT >> (dra))) >> + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb > > The gimple_uids are not initialized here, you need to make sure to > call renumber_gimple_stmt_uids () before starting. Note that phiopt > incrementally changes the IL, so I'm not sure those uids will stay > valid as stmts are moved across blocks. I added a call to renumber_gimple_stmt_uids_in_blocks() before data dependence checks, and there are no code changes between that and the checks, so, I think, it should be OK. > >> + { >> + free_data_refs (then_datarefs); >> + free_data_refs (else_datarefs); >> + free_dependence_relations (then_ddrs); >> + free_dependence_relations (else_ddrs); >> + return false; >> + } >> + } >> + >> + /* Check that there are no read-after-write or write-after-write >> dependencies >> + in ELSE_BB. */ >> + FOR_EACH_VEC_ELT (ddr_p, else_ddrs, i, ddr) >> + { >> + struct data_reference *dra = DDR_A (ddr); >> + struct data_reference *drb = DDR_B (ddr); >> + >> + if (DDR_ARE_DEPENDENT (ddr) != chrec_known >> + && ((DR_IS_READ (dra) && DR_IS_WRITE (drb) >> + && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT >> (drb))) >> + || (DR_IS_READ (drb) && DR_IS_WRITE (dra) >> + && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT >> (dra))) >> + || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb >> + { >> + free_data_refs (then_datarefs); >> + free_data_refs (else_datarefs); >> + free_dependence_relations (then_ddrs); >> + free_dependence_relations (else_ddrs); >> + return false; >> + } >> + } >> + >> + /* Found pairs of stores with equal LHS. */ >> + FOR_EACH_VEC_ELT (data_reference_p, then_datarefs, i, then_dr) >> + { >> + if (DR_IS_READ (then_dr)) >> + continue; >> + >> + then_store = DR_STMT (then_dr); >> + then_lhs = gimple_assign_lhs (then_store); >> + found = false; >> + >> + FOR_EACH_VEC_ELT (data_reference_p, else_datarefs, j, else_dr) >> + { >> + if (DR_IS_READ (else_dr)) >> + continue; >> + >> + else_store = DR_STMT (else_dr); >> + else_lhs = gimple_assign_lhs (else_store); >> + >> + if (operand_equal_p (then_lhs, else_lhs, 0)) >> + { >> + found = true; >> + break; >> + } >> + } >> + >> + if (!found) >> + continue; >> + >> + res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, >> +
gcc-patches@gcc.gnu.org
On Sun, Nov 21, 2010 at 21:52, Nathan Froyd wrote: > * system.h (FUNCTION_ARG, FUNCTION_INCOMING_ARG): Poison. > (FUNCTION_ARG_ADVANCE): Likewise. > * tm.texi.in: Change references to them to hook references. > * tm.texi: Regenerate. > * targhooks.c (default_function_arg): Eliminate check for target > macro. > (default_function_incoming_arg): Likewise. > (default_function_arg_advance): Likewise. > * target.def (function_arg, function_incoming_arg): Change to > DEFHOOK. > (function_arg_advance): Likewise. > * target-def.h: Eliminate FUNCTION_INCOMING_ARG check. OK. Diego.
Re: [PATCH][RFC] Add gimple_fold
On Tue, Mar 22, 2011 at 04:59, Richard Guenther wrote: > I simply put it in place as a possibility, I currently don't plan > to implement any GF_KIND_COMPLEX folders (the caller would need to > re-gimplify them which doesn't sound too useful). Maybe I should > simply drop it. Perhaps. Not supporting an "everything else" bucket would help us not fall into the usual trap of having to support too many weird cases. Though I'm sure we can find other ways of falling into that ;) >> For instance, if folding ends up producing a complex tree, would it need to >> be >> gimplified? Maybe we could generate the gimplified statement and return the >> SSA name on the LHS? Though I'm not sure I like even this. > > Hm, I tried to avoid making the folder rewrite existing or emit new > stmts - the idea was to make the interface cheap, not allocating GC > memory for expressions or statements. Sounds reasonable. Perhaps this could be done by a wrapper, if needed. Diego.
Scheduler cleanups, 1/N
I have a number of patches that will be necessary for a new target. Some of these can be applied now as cleanups, so I'm submit them now. This changes the schedule_block main loop not to move instructions while computing the schedule. Instead, we collect them in a VEC and modify the RTL afterwards. The real motivation for this is to add support for backtracking later. Bootstrapped and tested on i686-linux. No changes in generated code on any of my testcases. Bernd * sched-ebb.c (begin_schedule_ready): Remove second argument. Split most of the code into... (begin_move_insn): ... here. New function. (ebb_sched_info): Add a pointer to it. * haifa-sched.c (scheduled_insns): New static variable. (sched_extend_ready_list): Allocate it. (schedule_block): Use it to record the order of scheduled insns. Perform RTL changes to move insns only after all scheduling decisions have been made. * modulo-sched.c (sms_sched_haifa_sched_info): Add NULL entry for the begin_move_insn field. * sel-sched-ir.c (sched_sel_haifa_sched_info): Likewise. * sched-int.h (struct haifa_sched_info): Remove second argument from begin_schedule_ready hook. Add new member begin_move_insn. * sched-rgn.c (begin_schedule_ready): Remove second argument. (rgn_const_sched_info): Add NULL entry for the begin_move_insn field. Index: gcc/sched-ebb.c === --- gcc/sched-ebb.c.orig +++ gcc/sched-ebb.c @@ -59,7 +59,7 @@ static basic_block last_bb; /* Implementations of the sched_info functions for region scheduling. */ static void init_ready_list (void); -static void begin_schedule_ready (rtx, rtx); +static void begin_schedule_ready (rtx); static int schedule_more_p (void); static const char *ebb_print_insn (const_rtx, int); static int rank (rtx, rtx); @@ -125,10 +125,15 @@ init_ready_list (void) /* INSN is being scheduled after LAST. Update counters. */ static void -begin_schedule_ready (rtx insn, rtx last) +begin_schedule_ready (rtx insn ATTRIBUTE_UNUSED) { sched_rgn_n_insns++; +} +/* INSN is being moved to its place in the schedule, after LAST. */ +static void +begin_move_insn (rtx insn, rtx last) +{ if (BLOCK_FOR_INSN (insn) == last_bb /* INSN is a jump in the last block, ... */ && control_flow_insn_p (insn) @@ -288,6 +293,7 @@ static struct haifa_sched_info ebb_sched ebb_add_remove_insn, begin_schedule_ready, + begin_move_insn, advance_target_bb, SCHED_EBB /* We can create new blocks in begin_schedule_ready (). */ Index: gcc/haifa-sched.c === --- gcc/haifa-sched.c.orig +++ gcc/haifa-sched.c @@ -302,6 +302,10 @@ static struct ready_list *readyp = &read /* Scheduling clock. */ static int clock_var; +/* This records the actual schedule. It is built up during the main phase + of schedule_block, and afterwards used to reorder the insns in the RTL. */ +static VEC(rtx, heap) *scheduled_insns; + static int may_trap_exp (const_rtx, int); /* Nonzero iff the address is comprised from at most 1 register. */ @@ -2813,6 +2817,51 @@ choose_ready (struct ready_list *ready, } } +/* This function is called when we have successfully scheduled a + block. It uses the schedule stored in the scheduled_insns vector + to rearrange the RTL. PREV_HEAD is used as the anchor to which we + append the scheduled insns; TAIL is the insn after the scheduled + block. TARGET_BB is the argument passed to schedule_block. */ + +static void +commit_schedule (rtx prev_head, rtx tail, basic_block *target_bb) +{ + int i; + + last_scheduled_insn = prev_head; + for (i = 0; i < (int)VEC_length (rtx, scheduled_insns); i++) +{ + rtx insn = VEC_index (rtx, scheduled_insns, i); + + if (control_flow_insn_p (last_scheduled_insn) + || current_sched_info->advance_target_bb (*target_bb, insn)) + { + *target_bb = current_sched_info->advance_target_bb (*target_bb, 0); + + if (sched_verbose) + { + rtx x; + + x = next_real_insn (last_scheduled_insn); + gcc_assert (x); + dump_new_block_header (1, *target_bb, x, tail); + } + + last_scheduled_insn = bb_note (*target_bb); + } + + if (current_sched_info->begin_move_insn) + (*current_sched_info->begin_move_insn) (insn, last_scheduled_insn); + move_insn (insn, last_scheduled_insn, +current_sched_info->next_tail); + if (!DEBUG_INSN_P (insn)) + reemit_notes (insn); + last_scheduled_insn = insn; +} + + VEC_truncate (rtx, scheduled_insns, 0); +} + /* Use forward list scheduling to rearrange insns of block pointed to by TARGET_BB, possibly bringing insns from subsequent blocks in the same region. */ @@ -2934,6 +2983,7 @@ schedule_block
Scheduler cleanups, 2/N
This prints a bit more information in debugging dumps. Bootstrapped and tested on i686-linux. Bernd * haifa-sched.c (queue_insn): New arg REASON. All callers changed. Print it in debugging output. Index: gcc/haifa-sched.c === --- gcc/haifa-sched.c.orig +++ gcc/haifa-sched.c @@ -493,7 +493,7 @@ haifa_classify_insn (const_rtx insn) static int priority (rtx); static int rank_for_schedule (const void *, const void *); static void swap_sort (rtx *, int); -static void queue_insn (rtx, int); +static void queue_insn (rtx, int, const char *); static int schedule_insn (rtx); static void adjust_priority (rtx); static void advance_one_cycle (void); @@ -1318,10 +1318,11 @@ swap_sort (rtx *a, int n) /* Add INSN to the insn queue so that it can be executed at least N_CYCLES after the currently executing insn. Preserve insns - chain for debugging purposes. */ + chain for debugging purposes. REASON will be printed in debugging + output. */ HAIFA_INLINE static void -queue_insn (rtx insn, int n_cycles) +queue_insn (rtx insn, int n_cycles, const char *reason) { int next_q = NEXT_Q_AFTER (q_ptr, n_cycles); rtx link = alloc_INSN_LIST (insn, insn_queue[next_q]); @@ -1337,7 +1338,7 @@ queue_insn (rtx insn, int n_cycles) fprintf (sched_dump, ";;\t\tReady-->Q: insn %s: ", (*current_sched_info->print_insn) (insn, 0)); - fprintf (sched_dump, "queued for %d cycles.\n", n_cycles); + fprintf (sched_dump, "queued for %d cycles (%s).\n", n_cycles, reason); } QUEUE_INDEX (insn) = next_q; @@ -2067,11 +2068,7 @@ queue_to_ready (struct ready_list *ready && ready->n_ready - ready->n_debug > MAX_SCHED_READY_INSNS && !SCHED_GROUP_P (insn) && insn != skip_insn) - { - if (sched_verbose >= 2) - fprintf (sched_dump, "requeued because ready full\n"); - queue_insn (insn, 1); - } + queue_insn (insn, 1, "ready full"); else { ready_add (ready, insn, false); @@ -2975,7 +2972,7 @@ schedule_block (basic_block *target_bb) insn = ready_remove (&ready, i); if (insn != skip_insn) - queue_insn (insn, 1); + queue_insn (insn, 1, "list truncated"); } } } @@ -3176,7 +3173,7 @@ schedule_block (basic_block *target_bb) if (cost >= 1) { - queue_insn (insn, cost); + queue_insn (insn, cost, "resource conflict"); if (SCHED_GROUP_P (insn)) { advance = cost; @@ -3961,7 +3958,7 @@ change_queue_index (rtx next, int delay) if (delay == QUEUE_READY) ready_add (readyp, next, false); else if (delay >= 1) -queue_insn (next, delay); +queue_insn (next, delay, "change queue index"); if (sched_verbose >= 2) {
[PATCH PING] fortran-specific bits of tree-slimming patches
The Fortran-specific bits of these patches: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00565.html [PATCH 07/18] generalize build_case_label to the rest of the compiler http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00557.html [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00566.html are still pending review. -Nathan
Scheduler cleanups, 3/N
This caches dependency costs. The target adjust_cost macro can be quite expensive. This may not make much of a difference now, but in the final backtracking scheduler patches (which I'm omitting for the moment) we look at these costs a bit more often. Bernd gcc/ * sched-int.h (struct _dep): New member COST. (DEP_COST): New macro. (UNKNOWN_DEP_COST): Define. * sched-deps.c (init_dep_1): Initialize cost member. * haifa-sched.c (dep_cost_1): Use precomputed cost if available, compute and set it otherwise. (sched_change_pattern): Reset costs of dependencies. Index: gcc/haifa-sched.c === --- gcc/haifa-sched.c.orig +++ gcc/haifa-sched.c @@ -845,6 +845,9 @@ dep_cost_1 (dep_t link, dw_t dw) rtx used = DEP_CON (link); int cost; + if (DEP_COST (link) != UNKNOWN_DEP_COST) +return DEP_COST (link); + /* A USE insn should never require the value used to be computed. This allows the computation of a function's result and parameter values to overlap the return and call. We don't care about the @@ -902,6 +905,7 @@ dep_cost_1 (dep_t link, dw_t dw) cost = 0; } + DEP_COST (link) = cost; return cost; } @@ -4854,11 +4858,20 @@ fix_recovery_deps (basic_block rec) void sched_change_pattern (rtx insn, rtx new_pat) { + sd_iterator_def sd_it; + dep_t dep; int t; t = validate_change (insn, &PATTERN (insn), new_pat, 0); gcc_assert (t); dfa_clear_single_insn_cache (insn); + + for (sd_it = sd_iterator_start (insn, SD_LIST_FORW | SD_LIST_BACK); + sd_iterator_cond (&sd_it, &dep);) +{ + DEP_COST (dep) = UNKNOWN_DEP_COST; + sd_iterator_next (&sd_it); +} } /* Change pattern of INSN to NEW_PAT. Invalidate cached haifa Index: gcc/sched-deps.c === --- gcc/sched-deps.c.orig +++ gcc/sched-deps.c @@ -106,6 +106,7 @@ init_dep_1 (dep_t dep, rtx pro, rtx con, DEP_CON (dep) = con; DEP_TYPE (dep) = type; DEP_STATUS (dep) = ds; + DEP_COST (dep) = UNKNOWN_DEP_COST; } /* Init DEP with the arguments. Index: gcc/sched-int.h === --- gcc/sched-int.h.orig +++ gcc/sched-int.h @@ -239,6 +239,9 @@ struct _dep /* Dependency status. This field holds all dependency types and additional information for speculative dependencies. */ ds_t status; + + /* Cached cost of the dependency. */ + int cost; }; typedef struct _dep dep_def; @@ -248,6 +251,9 @@ typedef dep_def *dep_t; #define DEP_CON(D) ((D)->con) #define DEP_TYPE(D) ((D)->type) #define DEP_STATUS(D) ((D)->status) +#define DEP_COST(D) ((D)->cost) + +#define UNKNOWN_DEP_COST INT_MIN /* Functions to work with dep. */
[PATCH PING] c++-specific bits of tree-slimming patches
The C++-specific bits of these patches: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00557.html [PATCH 07/18] generalize build_case_label to the rest of the compiler http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00557.html [PATCH 08/18] convert cp *FOR_STMTs to use private scope fields http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00553.html [PATCH 09/18] convert cp IF_STMTs to use private scope fields http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00562.html [PATCH 10/18] convert cp SWITCH_STMTs to use private scope fields http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00552.html [PATCH 11/18] mark EXPR_PACK_EXPANSION as typed only http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00563.html [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00566.html are still pending review. -Nathan
Scheduler cleanups, 4/N
We have a mechanism to prevent the scheduler from touching certain blocks; this is used by modulo scheduling. sched-ebb does not honor this flag currently; this patch fixes it. Bootstrapped and tested on i686-linux (pointlessly... but it's also used in our local tree for a new target, TI C6X). Bernd * sched-ebb.c (schedule_ebbs): Honor the BB_DISABLE_SCHEDULE_FLAG. Index: gcc/sched-ebb.c === --- gcc/sched-ebb.c.orig +++ gcc/sched-ebb.c @@ -585,6 +585,9 @@ schedule_ebbs (void) { rtx head = BB_HEAD (bb); + if (bb->flags & BB_DISABLE_SCHEDULE) + continue; + for (;;) { edge e; @@ -597,6 +600,8 @@ schedule_ebbs (void) break; if (e->probability <= probability_cutoff) break; + if (e->dest->flags & BB_DISABLE_SCHEDULE) + break; bb = bb->next_bb; }
Scheduler cleanups, 5/5
We can currently select an insn to be scheduled, only to find out that it's not actually valid at the current time, either due to state conflicts or being an asm with something else already scheduled in the same cycle. Not only is this pointless, it causes problem with the sched_reorder logic in the TI C6X port (which will be submitted later). The solution is to prune the ready list earlier. More code is moved out of the schedule_block main loop, which is IMO always a good thing. Bootstrapped and tested (a slightly earlier version with an unused variable) on i686-linux; I also verified that there are no changes in code generation on any of my testcases. Bernd * haifa-sched.c (prune_ready_list): New function, broken out of schedule_block. (schedule_block): Use it. Index: gcc/haifa-sched.c === --- gcc/haifa-sched.c.orig +++ gcc/haifa-sched.c @@ -2614,8 +2614,8 @@ max_issue (struct ready_list *ready, int { if (state_dead_lock_p (state) || insn_finishes_cycle_p (insn)) - /* We won't issue any more instructions in the next - choice_state. */ + /* We won't issue any more instructions in the next + choice_state. */ top->rest = 0; else top->rest--; @@ -2863,6 +2863,52 @@ commit_schedule (rtx prev_head, rtx tail VEC_truncate (rtx, scheduled_insns, 0); } +/* Examine all insns on the ready list and queue those which can't be + issued in this cycle. TEMP_STATE is temporary scheduler state we + can use as scratch space. If FIRST_CYCLE_INSN_P is true, no insns + have been issued for the current cycle, which means it is valid to + issue an asm statement. */ + +static void +prune_ready_list (state_t temp_state, bool first_cycle_insn_p) +{ + int i; + + restart: + for (i = 0; i < ready.n_ready; i++) +{ + rtx insn = ready_element (&ready, i); + int cost = 0; + const char *reason = "resource conflict"; + + if (recog_memoized (insn) < 0) + { + if (!first_cycle_insn_p + && (GET_CODE (PATTERN (insn)) == ASM_INPUT + || asm_noperands (PATTERN (insn)) >= 0)) + cost = 1; + reason = "asm"; + } + else if (flag_sched_pressure) + cost = 0; + else + { + memcpy (temp_state, curr_state, dfa_state_size); + cost = state_transition (temp_state, insn); + if (cost < 0) + cost = 0; + else if (cost == 0) + cost = 1; + } + if (cost >= 1) + { + ready_remove (&ready, i); + queue_insn (insn, cost, reason); + goto restart; + } +} +} + /* Use forward list scheduling to rearrange insns of block pointed to by TARGET_BB, possibly bringing insns from subsequent blocks in the same region. */ @@ -3014,6 +3060,10 @@ schedule_block (basic_block *target_bb) } while (advance > 0); + prune_ready_list (temp_state, true); + if (ready.n_ready == 0) +continue; + if (sort_p) { /* Sort the ready list based on priority. */ @@ -3144,44 +3194,6 @@ schedule_block (basic_block *target_bb) } sort_p = TRUE; - memcpy (temp_state, curr_state, dfa_state_size); - if (recog_memoized (insn) < 0) - { - asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT - || asm_noperands (PATTERN (insn)) >= 0); - if (!first_cycle_insn_p && asm_p) - /* This is asm insn which is tried to be issued on the - cycle not first. Issue it on the next cycle. */ - cost = 1; - else - /* A USE insn, or something else we don't need to - understand. We can't pass these directly to - state_transition because it will trigger a - fatal error for unrecognizable insns. */ - cost = 0; - } - else if (sched_pressure_p) - cost = 0; - else - { - cost = state_transition (temp_state, insn); - if (cost < 0) - cost = 0; - else if (cost == 0) - cost = 1; - } - - if (cost >= 1) - { - queue_insn (insn, cost, "resource conflict"); - if (SCHED_GROUP_P (insn)) - { - advance = cost; - break; - } - - continue; - } if (current_sched_info->can_schedule_ready_p && ! (*current_sched_info->can_schedule_ready_p) (insn)) @@ -3202,14 +3214,20 @@ schedule_block (basic_block *target_bb) /* Update counters, etc in the scheduler's front end. */ (*current_sched_info->begin_schedule_ready) (ins
Re: [PATCH][ARM] Discourage use of NEON on Cortex-A8
On Tue, 2011-03-22 at 14:08 +, Andrew Stubbs wrote: > And again, with the patch ... > > On 22/03/11 14:05, Andrew Stubbs wrote: > > On 14/03/11 18:17, Richard Earnshaw wrote: > > > I think the order should be: not-a8, core-regs, core-regs, only-a8. > > > > Ok, how about this? > > > > I've tested that it still builds spec2k crafty. > > > > Andrew OK
Re: [RFC] Add a new argument to SELECT_CC_MODE
On Tue, 2011-03-22 at 21:00 +0100, Eric Botcazou wrote: > > Like in the attached patch. > > Sandra expressed an interest for it so I've installed it on the mainline > after > bootstrapping and regtesting on x86_64-suse-linux. > > > 2011-03-22 Eric Botcazou > > * combine.c (simplify_set): Try harder to find the best CC mode when > simplifying a nested COMPARE on the RHS. > > So I've always suspected that the way the ARM port handles this is broken. I think this now confirms that suspicion. Taking a look at the x86 backend the code there looks far more sensible and more in-line with what I think ARM should be doing. For a floating point operation the code is: TARGET_IEEE_FP ? CCFPUmode : CCFPmode; That is, if generating IEEE compliant code, then use non-excepting comparisions, otherwise use exception raising ones. R.
Re: [patch] Fix PR48183, NEON ICE in emit-rtl.c:immed_double_const() under -g
On Thu, 24 Mar 2011 10:57:06 + Richard Sandiford wrote: > Chung-Lin Tang writes: > > PR48183 is a case where ARM NEON instrinsics, under -O -g, produce > > debug insns that tries to expand OImode (32-byte integer) zero > > constants, much too large to represent as two HOST_WIDE_INTs; as > > the internals manual indicates, such large constants are not > > supported in general, and ICEs on the GET_MODE_BITSIZE(mode) == > > 2*HOST_BITS_PER_WIDE_INT assertion. > > > > This patch allows the cases where the large integer constant is > > still representable using a single CONST_INT, such as zero(0). > > Bootstrapped and tested on i686 and x86_64, cross-tested on ARM, > > all without regressions. Okay for trunk? > > > > Thanks, > > Chung-Lin > > > > 2011-03-20 Chung-Lin Tang > > > > * emit-rtl.c (immed_double_const): Allow wider than > > 2*HOST_BITS_PER_WIDE_INT mode constants when they are > > representable as a single const_int RTX. > > I realise this might be seen as a good expedient fix, but it makes > me a bit uneasy. Not a very constructive rationale, sorry. FWIW I also had a "fix" for this issue, which is equivalent to Chung-Lin's patch apart from only allowing constant-zero (attached). That's not really a vote from me for this approach, but maybe limiting the extent to which we pretend to support wide-integer constants like this is sensible, if we do go that way. Julian--- gcc/expr.c (revision 314639) +++ gcc/expr.c (working copy) @@ -8458,6 +8458,18 @@ expand_expr_real_1 (tree exp, rtx target return decl_rtl; case INTEGER_CST: + if (GET_MODE_BITSIZE (mode) > 2 * HOST_BITS_PER_WIDE_INT) + { + /* FIXME: We can't generally represent wide integer constants, + but GCC sometimes tries to initialise wide integer values (such + as used by the ARM NEON support) with zero. Handle that as a + special case here. */ + if (initializer_zerop (exp)) + return CONST0_RTX (mode); + + gcc_unreachable (); + } + temp = immed_double_const (TREE_INT_CST_LOW (exp), TREE_INT_CST_HIGH (exp), mode);
Remove old host cases from toplevel configure
This patch removes cases for a range of old hosts from the toplevel configure.ac, as I think those cases are no longer useful. All the removed code comes from Cygnus configure before the toplevel configure was converted to be an autoconf-generated script. In general those hosts, if ever supported as targets by GCC at all, had their GCC target support obsoleted in GCC 4.3 or earlier. It is of course theoretically possible to build cross tools hosted on a system not supported as a target by GCC, using a non-GCC compiler, but it's much more of a niche than building native tools there and these targets all became unsupported for native tools a long time ago for lack of interest in maintaining support for them. Thus I don't think it's useful any more to maintain cases for these hosts in toplevel configure. Furthermore, the whole idea of the toplevel configure tentative_cc setting code is dubious since this is an autoconf-generated script and it's autoconf's job to deal with finding a working compiler, putting it in ANSI C mode, etc. - so if someone did wish to resupport one of these hosts (and in the unlikely event that building current tools using the old system compiler is at all possible) it would be better to put system-specific pieces in autoconf and make toolchain configure code work using features not host triplet tests as far as possible. OK to commit? 2011-03-24 Joseph Myers * configure.ac (i[[3456789]]86-*-vsta, i[[3456789]]86-*-go32*, i[[3456789]]86-*-beos*, powerpc-*-beos*, m68k-hp-hpux*, m68k-apollo-sysv*, m68k-apollo-bsd*, m88k-dg-dgux*, m88k-harris-cxux*, m88k-motorola-sysv*, mips*-dec-ultrix*, mips*-nec-sysv4*, mips*-sgi-irix4*, mips*-*-sysv4*, mips*-*-sysv*, i370-ibm-opened*, i[[3456789]]86-*-sysv5*, i[[3456789]]86-*-dgux*, i[[3456789]]86-ncr-sysv4.3*, i[[3456789]]86-ncr-sysv4*, i[[3456789]]86-*-sco3.2v5*, i[[3456789]]86-*-sco*, i[[3456789]]86-*-udk*, vax-*-ultrix2*, m68k-sun-sunos*, hppa*-*-hiux*, *-*-hiux*, rs6000-*-lynxos*, *-*-sysv4*, *-*-rhapsody*): Remove host cases. * configure: Regenerate. config: 2011-03-24 Joseph Myers * mh-cxux, mh-decstation, mh-dgux386, mh-lynxrs6k, mh-ncr3000, mh-necv4, mh-sco, mh-sysv5: Remove. Index: configure.ac === --- configure.ac(revision 171390) +++ configure.ac(working copy) @@ -429,10 +429,7 @@ hppa*64*-*-*) noconfigdirs="$noconfigdirs byacc" ;; - i[[3456789]]86-*-vsta) -noconfigdirs="$noconfigdirs tcl expect dejagnu make texinfo bison patch flex byacc send-pr gprof uudecode dejagnu diff guile perl itcl gnuserv gettext" -;; - i[[3456789]]86-*-go32* | i[[3456789]]86-*-msdosdjgpp*) + i[[3456789]]86-*-msdosdjgpp*) noconfigdirs="$noconfigdirs tcl tk expect dejagnu send-pr uudecode guile itcl gnuserv libffi" ;; x86_64-*-mingw*) @@ -442,18 +439,12 @@ # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv" noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib" ;; - i[[3456789]]86-*-beos*) -noconfigdirs="$noconfigdirs tk itcl libgui gdb" -;; *-*-cygwin*) noconfigdirs="$noconfigdirs autoconf automake send-pr rcs guile perl" ;; *-*-netbsd*) noconfigdirs="$noconfigdirs rcs" ;; - powerpc-*-beos*) -noconfigdirs="$noconfigdirs tk itcl libgui gdb dejagnu readline" -;; esac @@ -966,8 +957,6 @@ ;; sh-*-* | sh64-*-*) case "${host}" in - i[[3456789]]86-*-vsta) ;; # don't add gprof back in - i[[3456789]]86-*-go32*) ;; # don't add gprof back in i[[3456789]]86-*-msdosdjgpp*) ;; # don't add gprof back in *) skipdirs=`echo " ${skipdirs} " | sed -e 's/ gprof / /'` ;; esac @@ -1049,104 +1038,6 @@ host_makefile_frag=/dev/null if test -d ${srcdir}/config ; then case "${host}" in - m68k-hp-hpux*) -# Avoid "too much defining" errors from HPUX compiler. -tentative_cc="cc -Wp,-H256000" -# If "ar" in $PATH is GNU ar, the symbol table may need rebuilding. -# If it's HP/UX ar, this should be harmless. -RANLIB="ar ts" -;; - m68k-apollo-sysv*) -tentative_cc="cc -A ansi -A runtype,any -A systype,any -U__STDC__ -DUSG" -;; - m68k-apollo-bsd*) -#None of the Apollo compilers can compile gas or binutils. The preprocessor -# chokes on bfd, the compiler won't let you assign integers to enums, and -# other problems. Defining CC to gcc is a questionable way to say "don't use -# the apollo compiler" (the preferred version of GCC could be called cc, -# or whatever), but I'm not sure leaving CC as cc is any better... -#CC=cc -A ansi -A runtype,any -A systype,any -U__STDC__ -DNO_STDARG -# Used to have BISON=yacc. -tentative_cc=gcc -;; - m88k-dg-dgux*) -
Re: Problem with ARM longcalls
On Wed, 2011-03-23 at 16:46 +0100, Bernd Schmidt wrote: > I've discovered a problem with -mlong-calls on ARM. The bug was first > reported against a new target, but I'd copied the relevant code from the > ARM backend. > > We use current_function_section in arm_is_long_call_p to decide whether > we're calling something that goes into the same section. The problem > with this is that current_function_section can only be used during > final, since it relies on the global variable in_cold_section_p which is > set up only in assemble_start_function. On ARM, this problem manifests > as short-calls when a long-call would be required; in the other port it > was an "insn doesn't satisfy its constraints" error. > > The following patch is against 4.5, since the problem appears hidden in > mainline (the initialization of first_function_block_is_cold has > changed). Ok for trunk and branches after arm-linux tests complete? > > > Bernd The ARM port currently doesn't support hot/cold partitioning of code (and can't until the constant pool code is rewritten to deal with it), so how is this a problem? R.
Re: Problem with ARM longcalls
On 03/24/2011 03:24 PM, Richard Earnshaw wrote: > > On Wed, 2011-03-23 at 16:46 +0100, Bernd Schmidt wrote: >> I've discovered a problem with -mlong-calls on ARM. The bug was first >> reported against a new target, but I'd copied the relevant code from the >> ARM backend. >> >> We use current_function_section in arm_is_long_call_p to decide whether >> we're calling something that goes into the same section. The problem >> with this is that current_function_section can only be used during >> final, since it relies on the global variable in_cold_section_p which is >> set up only in assemble_start_function. On ARM, this problem manifests >> as short-calls when a long-call would be required; in the other port it >> was an "insn doesn't satisfy its constraints" error. >> >> The following patch is against 4.5, since the problem appears hidden in >> mainline (the initialization of first_function_block_is_cold has >> changed). Ok for trunk and branches after arm-linux tests complete? >> >> >> Bernd > > The ARM port currently doesn't support hot/cold partitioning of code > (and can't until the constant pool code is rewritten to deal with it), > so how is this a problem? Different functions can still go into different sections. When we start expanding a function, in_cold_section_p still contains the value that was correct for the previous one. It will change at the start of final, which means that current_function_section can return different values while compiling a function. See the included testcase. Bernd
Fix more minor issues from static checkers
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 First in tree-ssa-live.c, "ann" is set, but never used in a couple places. Second, in tree-ssa-copy.c we set "stmt" in propagate_tree_value_into_stmt, but never use it. Removing the assignment is obviously trivial. Finally, in cfglayout force_nonfallthru may delete its argument (E_FALL) which we then use. The fix is to save E_FALL->src prior to the call to force_nonfallthru. Bootstrapped and regression tested on x86_64-unknown-linux-gnu. OK for trunk? Thanks, Jeff -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJNi1dDAAoJEBRtltQi2kC7b8kIAIsiwpn3FieHNWhn5RGFdn85 mXoknFh9Ybc71XOKU80UAWCxX61iCImJoqKJNdAEi1S4KLRboKIzEv2OrNjNbt4r c8EO8K8Q42NJ3IcinbHuqWK9KxhRuWso2w4VEMVS8gOHgSl12PA2C2LYMWLXa0l5 EgNNta6HWCD1uC8EL7Zt+3vMLRY7Ru+bVbR1T58miRe9CatK5Iz85T3FZ0qfPr4z Lp8aHCPcRQlabqgk2Thr/cexK3ZdTFXdHP+F3e60GlPEB7Y0nbwrZIvHW+RWj2z0 Et4wEEUnrCXbqJMaZgrHaOl5lierXKMy2FPc/tMSrUO6kw920Y8PzNMQweP4QSE= =cYgV -END PGP SIGNATURE- * tree-ssa-live.c (remove_unused_scope_block_p): Remove set but unused variable "ann". (remove_unused_locals): Likewise. * tree-ssa-copy.c (propagate_tree_value_into_stmt): Remove useless statement. * cfglayout.c (fixup_reorder_chain): Do not dereference E_FALL after it is freed. Index: tree-ssa-live.c === *** tree-ssa-live.c (revision 171351) --- tree-ssa-live.c (working copy) *** remove_unused_scope_block_p (tree scope) *** 427,433 { tree *t, *next; bool unused = !TREE_USED (scope); - var_ann_t ann; int nsubblocks = 0; for (t = &BLOCK_VARS (scope); *t; t = next) --- 427,432 *** remove_unused_scope_block_p (tree scope) *** 467,474 info about optimized-out variables in the scope blocks. Exception are the scope blocks not containing any instructions at all so user can't get into the scopes at first place. */ ! else if ((ann = var_ann (*t)) != NULL ! && is_used_p (*t)) unused = false; else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t)) /* For labels that are still used in the IL, the decision to --- 466,472 info about optimized-out variables in the scope blocks. Exception are the scope blocks not containing any instructions at all so user can't get into the scopes at first place. */ ! else if (var_ann (*t) != NULL && is_used_p (*t)) unused = false; else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t)) /* For labels that are still used in the IL, the decision to *** remove_unused_locals (void) *** 690,696 basic_block bb; tree var, t; referenced_var_iterator rvi; - var_ann_t ann; bitmap global_unused_vars = NULL; unsigned srcidx, dstidx, num; --- 688,693 *** remove_unused_locals (void) *** 766,772 { var = VEC_index (tree, cfun->local_decls, srcidx); if (TREE_CODE (var) != FUNCTION_DECL ! && (!(ann = var_ann (var)) || !is_used_p (var))) { if (is_global_var (var)) --- 763,769 { var = VEC_index (tree, cfun->local_decls, srcidx); if (TREE_CODE (var) != FUNCTION_DECL ! && (!var_ann (var) || !is_used_p (var))) { if (is_global_var (var)) *** remove_unused_locals (void) *** 798,804 FOR_EACH_LOCAL_DECL (cfun, ix, var) if (TREE_CODE (var) == VAR_DECL && is_global_var (var) ! && (ann = var_ann (var)) != NULL && is_used_p (var)) mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars); --- 795,801 FOR_EACH_LOCAL_DECL (cfun, ix, var) if (TREE_CODE (var) == VAR_DECL && is_global_var (var) ! && var_ann (var) != NULL && is_used_p (var)) mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars); Index: tree-ssa-copy.c === *** tree-ssa-copy.c (revision 171351) --- tree-ssa-copy.c (working copy) *** propagate_tree_value_into_stmt (gimple_s *** 244,250 expr = gimple_assign_rhs1 (stmt); propagate_tree_value (&expr, val); gimple_assign_set_rhs_from_tree (gsi, expr); - stmt = gsi_stmt (*gsi); } else if (gimple_code (stmt) == GIMPLE_COND) { --- 244,249 Index: cfglayout.c === *** cfglayout.c (revision 171351) --- cfglayout.c (working copy) *** fixup_reorder_chain (void) *** 766,772 { edge e_fall, e_taken, e; rtx bb_end_insn; ! basic_block nb; edge_iterato
[PATCH] Fix PR48270
Bootstrapped and tested on x86_64-unknonw-linux-gnu, applied. Richard. 2011-03-24 Richard Guenther PR tree-optimization/48270 * tree-ssa-phiopt.c (cond_if_else_store_replacement): Do not free datarefs before ddrs. Index: gcc/tree-ssa-phiopt.c === --- gcc/tree-ssa-phiopt.c (revision 171388) +++ gcc/tree-ssa-phiopt.c (working copy) @@ -1494,8 +1494,6 @@ cond_if_else_store_replacement (basic_bl else_ddrs = VEC_alloc (ddr_p, heap, 1); compute_all_dependences (then_datarefs, &then_ddrs, NULL, false); compute_all_dependences (else_datarefs, &else_ddrs, NULL, false); - free_data_refs (then_datarefs); - free_data_refs (else_datarefs); blocks[0] = then_bb; blocks[1] = else_bb; blocks[2] = join_bb; @@ -1517,6 +1515,8 @@ cond_if_else_store_replacement (basic_bl { free_dependence_relations (then_ddrs); free_dependence_relations (else_ddrs); + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); VEC_free (gimple, heap, then_stores); VEC_free (gimple, heap, else_stores); return false; @@ -1539,6 +1539,8 @@ cond_if_else_store_replacement (basic_bl { free_dependence_relations (then_ddrs); free_dependence_relations (else_ddrs); + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); VEC_free (gimple, heap, then_stores); VEC_free (gimple, heap, else_stores); return false; @@ -1556,6 +1558,8 @@ cond_if_else_store_replacement (basic_bl free_dependence_relations (then_ddrs); free_dependence_relations (else_ddrs); + free_data_refs (then_datarefs); + free_data_refs (else_datarefs); VEC_free (gimple, heap, then_stores); VEC_free (gimple, heap, else_stores);
[PATCH] Paper over(?) PR48271
This maybe papers over PR48271, we're modifying the CFG and yet marking some BBs for cleanup. Well, at least the jump-threading case is supposed to work this way. DOM doesn't deserve too much love, so ... Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-03-24 Richard Guenther PR tree-optimization/48271 * tree-ssa-dom.c (tree_ssa_dominator_optimize): Only cleanup blocks that still exist. * g++.dg/torture/pr48271.C: New testcase. Index: gcc/tree-ssa-dom.c === *** gcc/tree-ssa-dom.c (revision 171387) --- gcc/tree-ssa-dom.c (working copy) *** tree_ssa_dominator_optimize (void) *** 701,707 gimple_stmt_iterator gsi; basic_block bb; FOR_EACH_BB (bb) ! {for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) update_stmt_if_modified (gsi_stmt (gsi)); } } --- 701,708 gimple_stmt_iterator gsi; basic_block bb; FOR_EACH_BB (bb) ! { ! for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) update_stmt_if_modified (gsi_stmt (gsi)); } } *** tree_ssa_dominator_optimize (void) *** 734,740 EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi) { basic_block bb = BASIC_BLOCK (i); ! if (single_succ_p (bb) == 1 && (single_succ_edge (bb)->flags & EDGE_EH) == 0) { bitmap_clear_bit (need_eh_cleanup, i); --- 735,742 EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi) { basic_block bb = BASIC_BLOCK (i); ! if (bb ! && single_succ_p (bb) && (single_succ_edge (bb)->flags & EDGE_EH) == 0) { bitmap_clear_bit (need_eh_cleanup, i); Index: gcc/testsuite/g++.dg/torture/pr48271.C === *** gcc/testsuite/g++.dg/torture/pr48271.C (revision 0) --- gcc/testsuite/g++.dg/torture/pr48271.C (revision 0) *** *** 0 --- 1,119 + // { dg-do compile } + // { dg-options "-ftree-vrp -fno-guess-branch-probability -fnon-call-exceptions" } + + void *xalloc (); + void xfree (void *); + void error (); + + static inline void * + MallocT () + { + void *p = xalloc (); + if (!p) + error (); + return p; + } + + + struct ByteBlob + { + int *header; + + ByteBlob(); + + ~ByteBlob () + { + Free (); + } + + int RawFree (int * p) + { + if (!p) + error (); + xfree (p); + } + + int *LengthRef (); + + void Free () + { + if (*header) + RawFree (header); + } + + int Append (int num_ints) + { + if (*header) + MallocT (); + *LengthRef () += num_ints; + } + }; + + struct CBlobT:ByteBlob + { + ~CBlobT () + { + Free (); + } + }; + + template < class T > struct FixedSizeArray + { + int HeaderSize; + T *data; + FixedSizeArray (); + int RefCnt () + { + return *(int *) MallocT (); + } +~FixedSizeArray () + { + if (RefCnt ()) + for (T * pItem = data + Length (); pItem != data; pItem--) + T (); + } + int Length (); + }; + + class SmallArray + { + typedef FixedSizeArray < int > SubArray; + typedef FixedSizeArray < SubArray > SuperArray; + SuperArray data; + }; + + struct CHashTableT + { + int *m_slots; + ~CHashTableT () + { + delete m_slots; + } + }; + + struct CYapfBaseT + { + int *PfGetSettings (); + SmallArray m_arr; + CHashTableT m_closed; + CYapfBaseT () + { + MallocT (); + } + }; + + struct CYapfCostRailT:CYapfBaseT + { + CBlobT m_sig_look_ahead_costs; + CYapfCostRailT () + { + m_sig_look_ahead_costs.Append (*Yapf ()->PfGetSettings ()); + Yapf ()->PfGetSettings (); + } + CYapfBaseT *Yapf (); + }; + + void stCheckReverseTrain () + { + CYapfCostRailT pf1; + }
[patch] Preserve source location in folder
Hi, when fold_ternary_loc is attempting to make the tree prettier, e.g. by swapping the arguments of a COND_EXPR, it does: tem = fold_truth_not_expr (loc, arg0); Now LOC is the location that will be put on the whole expression and there is no reason it should override the location of ARG0, if any, when inverting it. The attached patch only ensures that - this gives more precise coverage info. Bootstrapped/regtested on x86_64-suse-linux, OK for the mainline? 2011-03-24 Eric Botcazou * fold-const.c (fold_ternary_loc): Preserve the location (if any) of the argument in calls to fold_truth_not_expr. -- Eric Botcazou Index: fold-const.c === --- fold-const.c (revision 171345) +++ fold-const.c (working copy) @@ -13327,7 +13327,10 @@ fold_ternary_loc (location_t loc, enum t TREE_OPERAND (arg0, 1)) && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2 { - tem = fold_truth_not_expr (loc, arg0); + location_t loc0 = EXPR_LOCATION (arg0); + if (loc0 == UNKNOWN_LOCATION) + loc0 = loc; + tem = fold_truth_not_expr (loc0, arg0); if (tem && COMPARISON_CLASS_P (tem)) { tem = fold_cond_expr_with_comparison (loc, type, tem, op2, op1); @@ -13341,10 +13344,13 @@ fold_ternary_loc (location_t loc, enum t if (truth_value_p (TREE_CODE (arg0)) && tree_swap_operands_p (op1, op2, false)) { + location_t loc0 = EXPR_LOCATION (arg0); + if (loc0 == UNKNOWN_LOCATION) + loc0 = loc; /* See if this can be inverted. If it can't, possibly because it was a floating-point inequality comparison, don't do anything. */ - tem = fold_truth_not_expr (loc, arg0); + tem = fold_truth_not_expr (loc0, arg0); if (tem) return fold_build3_loc (loc, code, type, tem, op2, op1); } @@ -13489,8 +13495,11 @@ fold_ternary_loc (location_t loc, enum t && truth_value_p (TREE_CODE (arg0)) && truth_value_p (TREE_CODE (arg1))) { + location_t loc0 = EXPR_LOCATION (arg0); + if (loc0 == UNKNOWN_LOCATION) + loc0 = loc; /* Only perform transformation if ARG0 is easily inverted. */ - tem = fold_truth_not_expr (loc, arg0); + tem = fold_truth_not_expr (loc0, arg0); if (tem) return fold_build2_loc (loc, TRUTH_ORIF_EXPR, type, fold_convert_loc (loc, type, tem), @@ -13502,8 +13511,11 @@ fold_ternary_loc (location_t loc, enum t && truth_value_p (TREE_CODE (arg0)) && truth_value_p (TREE_CODE (op2))) { + location_t loc0 = EXPR_LOCATION (arg0); + if (loc0 == UNKNOWN_LOCATION) + loc0 = loc; /* Only perform transformation if ARG0 is easily inverted. */ - tem = fold_truth_not_expr (loc, arg0); + tem = fold_truth_not_expr (loc0, arg0); if (tem) return fold_build2_loc (loc, TRUTH_ANDIF_EXPR, type, fold_convert_loc (loc, type, tem),
[patch] Do not generate useless branches for multi-word comparison
Hi, this improves the RTL generated for multi-word comparison to avoid generating useless branches. In do_jump_by_parts_greater_rtx: 1) do not generate the last cond jump, 2) do not generate the uncond branch to the drop-through label, if any, 3) generate only one comparison for the special (0 > x) case. Tested on i586-suse-linux, OK for the mainline? 2011-03-24 Eric Botcazou * dojump.c (do_jump_by_parts_greater_rtx): Optimize in specific cases. -- Eric Botcazou Index: dojump.c === --- dojump.c (revision 171345) +++ dojump.c (working copy) @@ -637,14 +637,32 @@ do_jump_by_parts_greater_rtx (enum machi { int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); rtx drop_through_label = 0; + bool drop_through_if_true = false, drop_through_if_false = false; + enum rtx_code code = GT; int i; if (! if_true_label || ! if_false_label) drop_through_label = gen_label_rtx (); if (! if_true_label) -if_true_label = drop_through_label; +{ + if_true_label = drop_through_label; + drop_through_if_true = true; +} if (! if_false_label) -if_false_label = drop_through_label; +{ + if_false_label = drop_through_label; + drop_through_if_false = true; +} + + /* Deal with the special case 0 > x: only one comparison is necessary and + we reverse it to avoid jumping to the drop-through label. */ + if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false) +{ + code = LE; + if_true_label = if_false_label; + if_false_label = drop_through_label; + drop_through_if_false = true; +} /* Compare a word at a time, high order first. */ for (i = 0; i < nwords; i++) @@ -663,17 +681,20 @@ do_jump_by_parts_greater_rtx (enum machi } /* All but high-order word must be compared as unsigned. */ - do_compare_rtx_and_jump (op0_word, op1_word, GT, - (unsignedp || i > 0), word_mode, NULL_RTX, - NULL_RTX, if_true_label, prob); + do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0), + word_mode, NULL_RTX, NULL_RTX, if_true_label, + prob); + + /* Emit only one comparison for 0. Do not emit the last cond jump. */ + if (op0 == const0_rtx || i == nwords - 1) + break; /* Consider lower words only if these are equal. */ do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, - NULL_RTX, NULL_RTX, if_false_label, - inv (prob)); + NULL_RTX, NULL_RTX, if_false_label, inv (prob)); } - if (if_false_label) + if (!drop_through_if_false) emit_jump (if_false_label); if (drop_through_label) emit_label (drop_through_label);
[PATCH] fix memory accounting for copying nodes
tree.c can gather optionally statistics--counts and total bytes allocated--when tree nodes are created. Due to an oversight, however, this accounting is not performed when nodes are copied. The patch below corrects this oversight and moves things around so the accounting is done in (almost) only one place. (The "almost" is due to special decrementing when we reuse types, which is arguably bogus, since we've created a node already, so we shouldn't be playing games to pretend we didn't touch memory.) Tested on x86_64-unknown-linux-gnu, with and without --enable-gather-detailed-mem-stats. OK to commit? -Nathan * tree.c (record_node_allocation_statistics): New function. (make_node_stat, copy_node_stat, build_string): Call it. (make_tree_binfo_stat, make_tree_vec_stat, tree_cons_stat): Likewise. (build1_stat, build_omp_clause): Likewise. diff --git a/gcc/tree.c b/gcc/tree.c index efa51bd..2066c84 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -769,20 +769,15 @@ tree_size (const_tree node) } } -/* Return a newly allocated node of code CODE. For decl and type - nodes, some other fields are initialized. The rest of the node is - initialized to zero. This function cannot be used for TREE_VEC or - OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size. +/* Record interesting allocation statistics for a tree node with CODE + and LENGTH. */ - Achoo! I got a code in the node. */ - -tree -make_node_stat (enum tree_code code MEM_STAT_DECL) +static void +record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED, + size_t length ATTRIBUTE_UNUSED) { - tree t; - enum tree_code_class type = TREE_CODE_CLASS (code); - size_t length = tree_code_size (code); #ifdef GATHER_STATISTICS + enum tree_code_class type = TREE_CODE_CLASS (code); tree_node_kind kind; switch (type) @@ -841,12 +836,20 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) kind = constr_kind; break; + case OMP_CLAUSE: + kind = omp_clause_kind; + break; + default: kind = x_kind; break; } break; +case tcc_vl_exp: + kind = e_kind; + break; + default: gcc_unreachable (); } @@ -854,6 +857,23 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) tree_node_counts[(int) kind]++; tree_node_sizes[(int) kind] += length; #endif +} + +/* Return a newly allocated node of code CODE. For decl and type + nodes, some other fields are initialized. The rest of the node is + initialized to zero. This function cannot be used for TREE_VEC or + OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size. + + Achoo! I got a code in the node. */ + +tree +make_node_stat (enum tree_code code MEM_STAT_DECL) +{ + tree t; + enum tree_code_class type = TREE_CODE_CLASS (code); + size_t length = tree_code_size (code); + + record_node_allocation_statistics (code, length); t = ggc_alloc_zone_cleared_tree_node_stat ( (code == IDENTIFIER_NODE) ? &tree_id_zone : &tree_zone, @@ -950,6 +970,7 @@ copy_node_stat (tree node MEM_STAT_DECL) gcc_assert (code != STATEMENT_LIST); length = tree_size (node); + record_node_allocation_statistics (code, length); t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT); memcpy (t, node, length); @@ -1540,10 +1561,7 @@ build_string (int len, const char *str) /* Do not waste bytes provided by padding of struct tree_string. */ length = len + offsetof (struct tree_string, str) + 1; -#ifdef GATHER_STATISTICS - tree_node_counts[(int) c_kind]++; - tree_node_sizes[(int) c_kind] += length; -#endif + record_node_allocation_statistics (STRING_CST, length); s = ggc_alloc_tree_node (length); @@ -1663,10 +1681,7 @@ make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL) size_t length = (offsetof (struct tree_binfo, base_binfos) + VEC_embedded_size (tree, base_binfos)); -#ifdef GATHER_STATISTICS - tree_node_counts[(int) binfo_kind]++; - tree_node_sizes[(int) binfo_kind] += length; -#endif + record_node_allocation_statistics (TREE_BINFO, length); t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT); @@ -1688,10 +1703,7 @@ make_tree_vec_stat (int len MEM_STAT_DECL) tree t; int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec); -#ifdef GATHER_STATISTICS - tree_node_counts[(int) vec_kind]++; - tree_node_sizes[(int) vec_kind] += length; -#endif + record_node_allocation_statistics (TREE_VEC, length); t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length PASS_MEM_STAT); @@ -2229,10 +2241,7 @@ tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL) PASS_MEM_STAT); memset (node, 0, sizeof (struct tree_common)); -#ifdef GATHER_STATISTICS - tree_node_counts[(int) x_kind]++; - tree_node_sizes[(int)
Re: Fix more minor issues from static checkers
On Thu, Mar 24, 2011 at 10:37, Jeff Law wrote: > Bootstrapped and regression tested on x86_64-unknown-linux-gnu. OK for > trunk? OK. Diego.
Re: [patch] Preserve source location in folder
On Thu, Mar 24, 2011 at 3:38 PM, Eric Botcazou wrote: > Hi, > > when fold_ternary_loc is attempting to make the tree prettier, e.g. by > swapping > the arguments of a COND_EXPR, it does: > > tem = fold_truth_not_expr (loc, arg0); > > Now LOC is the location that will be put on the whole expression and there is > no reason it should override the location of ARG0, if any, when inverting it. > The attached patch only ensures that - this gives more precise coverage info. > > Bootstrapped/regtested on x86_64-suse-linux, OK for the mainline? Ok. (I shortly thought about a PREFER_OVER_UNKNOWN_LOCATION (maybe_unknown, loc) macro, but well ...) Thanks, Richard. > > 2011-03-24 Eric Botcazou > > * fold-const.c (fold_ternary_loc): Preserve the location (if any) of > the argument in calls to fold_truth_not_expr. > > > -- > Eric Botcazou >
Re: [PATCH] fix memory accounting for copying nodes
On Thu, Mar 24, 2011 at 3:46 PM, Nathan Froyd wrote: > tree.c can gather optionally statistics--counts and total bytes > allocated--when tree nodes are created. Due to an oversight, however, > this accounting is not performed when nodes are copied. The patch below > corrects this oversight and moves things around so the accounting is > done in (almost) only one place. (The "almost" is due to special > decrementing when we reuse types, which is arguably bogus, since we've > created a node already, so we shouldn't be playing games to pretend we > didn't touch memory.) > > Tested on x86_64-unknown-linux-gnu, with and without > --enable-gather-detailed-mem-stats. OK to commit? Ok. Thanks, Richard. > -Nathan > > * tree.c (record_node_allocation_statistics): New function. > (make_node_stat, copy_node_stat, build_string): Call it. > (make_tree_binfo_stat, make_tree_vec_stat, tree_cons_stat): Likewise. > (build1_stat, build_omp_clause): Likewise. > > diff --git a/gcc/tree.c b/gcc/tree.c > index efa51bd..2066c84 100644 > --- a/gcc/tree.c > +++ b/gcc/tree.c > @@ -769,20 +769,15 @@ tree_size (const_tree node) > } > } > > -/* Return a newly allocated node of code CODE. For decl and type > - nodes, some other fields are initialized. The rest of the node is > - initialized to zero. This function cannot be used for TREE_VEC or > - OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size. > +/* Record interesting allocation statistics for a tree node with CODE > + and LENGTH. */ > > - Achoo! I got a code in the node. */ > - > -tree > -make_node_stat (enum tree_code code MEM_STAT_DECL) > +static void > +record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED, > + size_t length ATTRIBUTE_UNUSED) > { > - tree t; > - enum tree_code_class type = TREE_CODE_CLASS (code); > - size_t length = tree_code_size (code); > #ifdef GATHER_STATISTICS > + enum tree_code_class type = TREE_CODE_CLASS (code); > tree_node_kind kind; > > switch (type) > @@ -841,12 +836,20 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) > kind = constr_kind; > break; > > + case OMP_CLAUSE: > + kind = omp_clause_kind; > + break; > + > default: > kind = x_kind; > break; > } > break; > > + case tcc_vl_exp: > + kind = e_kind; > + break; > + > default: > gcc_unreachable (); > } > @@ -854,6 +857,23 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) > tree_node_counts[(int) kind]++; > tree_node_sizes[(int) kind] += length; > #endif > +} > + > +/* Return a newly allocated node of code CODE. For decl and type > + nodes, some other fields are initialized. The rest of the node is > + initialized to zero. This function cannot be used for TREE_VEC or > + OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size. > + > + Achoo! I got a code in the node. */ > + > +tree > +make_node_stat (enum tree_code code MEM_STAT_DECL) > +{ > + tree t; > + enum tree_code_class type = TREE_CODE_CLASS (code); > + size_t length = tree_code_size (code); > + > + record_node_allocation_statistics (code, length); > > t = ggc_alloc_zone_cleared_tree_node_stat ( > (code == IDENTIFIER_NODE) ? &tree_id_zone : &tree_zone, > @@ -950,6 +970,7 @@ copy_node_stat (tree node MEM_STAT_DECL) > gcc_assert (code != STATEMENT_LIST); > > length = tree_size (node); > + record_node_allocation_statistics (code, length); > t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT); > memcpy (t, node, length); > > @@ -1540,10 +1561,7 @@ build_string (int len, const char *str) > /* Do not waste bytes provided by padding of struct tree_string. */ > length = len + offsetof (struct tree_string, str) + 1; > > -#ifdef GATHER_STATISTICS > - tree_node_counts[(int) c_kind]++; > - tree_node_sizes[(int) c_kind] += length; > -#endif > + record_node_allocation_statistics (STRING_CST, length); > > s = ggc_alloc_tree_node (length); > > @@ -1663,10 +1681,7 @@ make_tree_binfo_stat (unsigned base_binfos > MEM_STAT_DECL) > size_t length = (offsetof (struct tree_binfo, base_binfos) > + VEC_embedded_size (tree, base_binfos)); > > -#ifdef GATHER_STATISTICS > - tree_node_counts[(int) binfo_kind]++; > - tree_node_sizes[(int) binfo_kind] += length; > -#endif > + record_node_allocation_statistics (TREE_BINFO, length); > > t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT); > > @@ -1688,10 +1703,7 @@ make_tree_vec_stat (int len MEM_STAT_DECL) > tree t; > int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec); > > -#ifdef GATHER_STATISTICS > - tree_node_counts[(int) vec_kind]++; > - tree_node_sizes[(int) vec_kind] += length; > -#endif > + record_node_allocation_statistics (TREE_VEC, length); > > t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length > PASS_MEM_STAT); >
[rs6000] Fix thinko in output_profile_hook
Hi, the problematic line is: label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf)); On AIX, rs6000_xcoff_strip_name_encoding can return NAME + 1: static const char * rs6000_xcoff_strip_name_encoding (const char *name) { size_t len; if (*name == '*') name++; len = strlen (name); if (name[len - 1] == ']') return ggc_alloc_string (name, len - 4); else return name; } which means that you can have (ADDR + 1) in some GC tree and gt_ggc_m_S choke: if (offset) { /* Here we've seen a char* which does not point to the beginning of an allocated object. We assume it points to the middle of a STRING_CST. */ gcc_assert (offset == offsetof (struct tree_string, str)); p = ((const char *) p) - offset; gt_ggc_mx_lang_tree_node (CONST_CAST (void *, p)); return; } Tested on AIX, OK for the mainline? 2011-03-24 Eric Botcazou * config/rs6000/rs6000.c (output_profile_hook): Fix thinko. -- Eric Botcazou Index: config/rs6000/rs6000.c === --- config/rs6000/rs6000.c (revision 171345) +++ config/rs6000/rs6000.c (working copy) @@ -23002,7 +23002,7 @@ output_profile_hook (int labelno ATTRIBU rtx fun; ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); - label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf)); + label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf)); fun = gen_rtx_SYMBOL_REF (Pmode, label_name); emit_library_call (init_one_libfunc (RS6000_MCOUNT),
Re: Cleaning up expand optabs code
Richard Sandiford writes: > Andreas Krebbel writes: >> On 03/22/2011 06:48 PM, Richard Henderson wrote: >> >>> Ok. Watch out for other target problems this week. >> >> This unfortunately broke bootstrap on s390. > > This is PR 48263. Since it seems to be affecting several targets, > and since my bootstrap seems to be taking a looong time, I'll post > the patch here before testing has finished. Bootstrap & regression-test on x86_64-linux-gnu now finished. OK to install? >> Just copying the pre-patch behaviour fixes the problem for me: > > I think we need to undo more of the patch, and leave the conversion > outside of the new interface. > > Sorry for the breakage. > > Richard > > > gcc/ > PR rtl-optimization/48263 > * optabs.c (expand_binop_directly): Reinstate convert_modes code > and original commutative_p handling. Use maybe_gen_insn. > > Index: gcc/optabs.c > === > --- gcc/optabs.c 2011-03-24 09:18:00.0 + > +++ gcc/optabs.c 2011-03-24 09:36:46.0 + > @@ -1269,6 +1269,38 @@ expand_binop_directly (enum machine_mode >if (!shift_optab_p (binoptab)) > xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp); > > + /* In case the insn wants input operands in modes different from > + those of the actual operands, convert the operands. It would > + seem that we don't need to convert CONST_INTs, but we do, so > + that they're properly zero-extended, sign-extended or truncated > + for their mode. */ > + > + if (GET_MODE (xop0) != mode0 && mode0 != VOIDmode) > +xop0 = convert_modes (mode0, > + GET_MODE (xop0) != VOIDmode > + ? GET_MODE (xop0) > + : mode, > + xop0, unsignedp); > + > + if (GET_MODE (xop1) != mode1 && mode1 != VOIDmode) > +xop1 = convert_modes (mode1, > + GET_MODE (xop1) != VOIDmode > + ? GET_MODE (xop1) > + : mode, > + xop1, unsignedp); > + > + /* If operation is commutative, > + try to make the first operand a register. > + Even better, try to make it the same as the target. > + Also try to make the last operand a constant. */ > + if (commutative_p > + && swap_commutative_operands_with_target (target, xop0, xop1)) > +{ > + swap = xop1; > + xop1 = xop0; > + xop0 = swap; > +} > + >/* Now, if insn's predicates don't allow our operands, put them into > pseudo regs. */ > > @@ -1291,41 +1323,25 @@ expand_binop_directly (enum machine_mode > tmp_mode = mode; > >create_output_operand (&ops[0], target, tmp_mode); > - create_convert_operand_from (&ops[1], xop0, mode, unsignedp); > - create_convert_operand_from (&ops[2], xop1, mode, unsignedp); > - if (maybe_legitimize_operands (icode, 0, 3, ops)) > -{ > - /* If operation is commutative, > - try to make the first operand a register. > - Even better, try to make it the same as the target. > - Also try to make the last operand a constant. */ > - if (commutative_p > - && swap_commutative_operands_with_target (ops[0].value, ops[1].value, > - ops[2].value)) > - { > - swap = ops[2].value; > - ops[2].value = ops[1].value; > - ops[1].value = swap; > - } > - > - pat = GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value); > - if (pat) > + create_input_operand (&ops[1], xop0, mode0); > + create_input_operand (&ops[2], xop1, mode1); > + pat = maybe_gen_insn (icode, 3, ops); > + if (pat) > +{ > + /* If PAT is composed of more than one insn, try to add an appropriate > + REG_EQUAL note to it. If we can't because TEMP conflicts with an > + operand, call expand_binop again, this time without a target. */ > + if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX > + && ! add_equal_note (pat, ops[0].value, binoptab->code, > +ops[1].value, ops[2].value)) > { > - /* If PAT is composed of more than one insn, try to add an appropriate > - REG_EQUAL note to it. If we can't because TEMP conflicts with an > - operand, call expand_binop again, this time without a target. */ > - if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX > - && ! add_equal_note (pat, ops[0].value, binoptab->code, > -ops[1].value, ops[2].value)) > - { > - delete_insns_since (last); > - return expand_binop (mode, binoptab, op0, op1, NULL_RTX, > -unsignedp, methods); > - } > - > - emit_insn (pat); > - return ops[0].value; > + delete_insns_since (last); > + return expand_binop (mode, binoptab, op0, op1, NULL_RTX, > +unsignedp, meth
Re: [Patch ARM] PR47930 Fix documentation for marm / mthumb
On Sun, 2011-03-20 at 15:19 +, Ramana Radhakrishnan wrote: > Hi, > > This fixes up documentation for the -marm option and changes the > behaviour of mthumb to reject the negative options to bring this to > behave similar to the marm option. The option needs to be documented > since we now have situations where toolchains default to Thumb state and > folks need a way of overriding this. I would like a review of this > before committing it since this is a change to the command line options. > > Tested by building a cross toolchain to arm-linux-gnueabi and verified > that -mno-thumb is rejected and looking up the documentation after it > was rebuilt. > > Ok ? > > cheers > Ramana > > > 2011-03-20 Ramana Radhakrishnan > > PR target/47930 > * config/arm/arm.opt (marm): Document it. > (mthumb): Reject negative variant. +@item -marm +@opindex marm +Generate code for the 32 bit ARM instruction set. This is used to +override and generate code in ARM state if the compiler has been +configured to be built in Thumb state. This option is not passed to the +assembler. I'd suggest @item -mthumb @itemx -marm @opindex marm @opindex mthumb Select between generating code that executes in ARM and Thumb states. The default for most configurations is to generate code that executes in ARM state, but the default can be changed by configuring GCC with the @option{--with-mode=}@var{state} configure option. I don't see any need to talk about the Thumb1/Thumb2 behaviour here any more than we do about other ISA variants in ARM state. Nor do I think it's relevant to talk about this option in relation to the assembler. The arm.opt change is OK, but 'Report' should stay; and it should also be added to the -marm case. R.
Re: Cleaning up expand optabs code
This showed up as a warning during the h8300 build I did this morning. I've no idea why it wasn't caught during the x86_64, ARM and MIPS testing. Bootstrapped & regression-tested on x86_64-linux-gnu. Installed as obvious. Richard gcc/ * builtins.c (expand_movstr): Fix endp == 1 adjustment after last commit. Index: gcc/builtins.c === --- gcc/builtins.c 2011-03-23 09:30:17.0 + +++ gcc/builtins.c 2011-03-24 09:08:05.0 + @@ -3655,7 +3655,6 @@ expand_builtin_mempcpy_args (tree dest, expand_movstr (tree dest, tree src, rtx target, int endp) { struct expand_operand ops[3]; - rtx end; rtx dest_mem; rtx src_mem; @@ -3683,7 +3682,7 @@ expand_movstr (tree dest, tree src, rtx adjust it. */ if (endp == 1) { - rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1); + rtx tem = plus_constant (gen_lowpart (GET_MODE (target), target), 1); emit_move_insn (target, force_operand (tem, NULL_RTX)); } }
[Ada] Fix bogus CE raised on call to overloaded function
The attached code (derived from ACATS c34006d) raises a bogus Constraint_Error since at least GCC 3.4: raised CONSTRAINT_ERROR : p.adb:33 discriminant check failed This is related to the overloading of function Create. Tested on i586-suse-linux, applied on the mainline. 2011-03-24 Eric Botcazou * gcc-interface/trans.c (gnat_to_gnu): Remove obsolete case of non-conversion to the nominal result type at the end. 2011-03-24 Eric Botcazou * gnat.dg/derived_type2.adb: New test. -- Eric Botcazou Index: gcc-interface/trans.c === --- gcc-interface/trans.c (revision 171345) +++ gcc-interface/trans.c (working copy) @@ -5879,15 +5879,11 @@ gnat_to_gnu (Node_Id gnat_node) since we need to ignore those conversions (for 'Valid). 2. If we have a label (which doesn't have any well-defined type), a - field or an error, return the result almost unmodified. Also don't - do the conversion if the result type involves a PLACEHOLDER_EXPR in - its size since those are the cases where the front end may have the - type wrong due to "instantiating" the unconstrained record with - discriminant values. Similarly, if the two types are record types - with the same name don't convert. This will be the case when we are - converting from a packable version of a type to its original type and - we need those conversions to be NOPs in order for assignments into - these types to work properly. + field or an error, return the result almost unmodified. Similarly, + if the two types are record types with the same name, don't convert. + This will be the case when we are converting from a packable version + of a type to its original type and we need those conversions to be + NOPs in order for assignments into these types to work properly. 3. If the type is void or if we have no result, return error_mark_node to show we have no result. @@ -5933,12 +5929,8 @@ gnat_to_gnu (Node_Id gnat_node) else if (TREE_CODE (gnu_result) == LABEL_DECL || TREE_CODE (gnu_result) == FIELD_DECL || TREE_CODE (gnu_result) == ERROR_MARK - || (TYPE_SIZE (gnu_result_type) - && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST - && TREE_CODE (gnu_result) != INDIRECT_REF - && CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))) - || ((TYPE_NAME (gnu_result_type) - == TYPE_NAME (TREE_TYPE (gnu_result))) + || (TYPE_NAME (gnu_result_type) + == TYPE_NAME (TREE_TYPE (gnu_result)) && TREE_CODE (gnu_result_type) == RECORD_TYPE && TREE_CODE (TREE_TYPE (gnu_result)) == RECORD_TYPE)) { -- { dg-do run } -- { dg-options "-gnatws" } procedure Derived_Type2 is package Pkg is type Parent (B : Boolean := True) is record case B is when True => S : String (1 .. 5); when False => F : Float; end case; end record; function Create (X : Parent) return Parent; end Pkg; package body Pkg is function Create (X : Parent) return Parent is begin return (True, "12345"); end; end Pkg; use Pkg; type T is new Parent (True); X : T; begin if Create (X).B /= True then raise Program_Error; end if; end;
Re: [PATCH PING] fortran-specific bits of tree-slimming patches
On 03/24/2011 06:10 AM, Nathan Froyd wrote: The Fortran-specific bits of these patches: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00565.html [PATCH 07/18] generalize build_case_label to the rest of the compiler http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00557.html [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00566.html are still pending review. -Nathan gfortran parts OK. Jerry
[debug] Remove deprecated DW_FORM_sig8 define
Hi, While reading through the unit type support I noticed some parts were still using the old DW_FORM_sig8 while others used the actual DW_FORM_ref_sig8 as used in the dwarf spec. I missed some things in a first scan because of this, so I thought I just clean it up. 2010-03-24 Mark Wielaard * dwarf2.h (dwarf_form): Remove deprecated DW_FORM_sig8 define. 2011-03-24 Mark Wielaard * dwarf2out.c (size_of_die): Modify comment to say DW_FORM_ref_sig8. (value_format): Use DW_FORM_ref_sig8, not DW_FORM_sig8. binutils already only uses the new definition. I have a similar cleanup patch for gdb. OK, to commit? Thanks, Mark diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9dec3e4..41d55bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2011-03-24 Mark Wielaard + + * dwarf2out.c (size_of_die): Modify comment to say DW_FORM_ref_sig8. + (value_format): Use DW_FORM_ref_sig8, not DW_FORM_sig8. + 2011-03-24 Richard Guenther PR tree-optimization/46562 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index aa6f6b6..bc05982 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -10729,7 +10729,7 @@ size_of_die (dw_die_ref die) case dw_val_class_die_ref: if (AT_ref_external (a)) { - /* In DWARF4, we use DW_FORM_sig8; for earlier versions + /* In DWARF4, we use DW_FORM_ref_sig8; for earlier versions we use DW_FORM_ref_addr. In DWARF2, DW_FORM_ref_addr is sized by target address length, whereas in DWARF3 it's always sized as an offset. */ @@ -11005,7 +11005,7 @@ value_format (dw_attr_ref a) return DW_FORM_flag; case dw_val_class_die_ref: if (AT_ref_external (a)) - return dwarf_version >= 4 ? DW_FORM_sig8 : DW_FORM_ref_addr; + return dwarf_version >= 4 ? DW_FORM_ref_sig8 : DW_FORM_ref_addr; else return DW_FORM_ref; case dw_val_class_fde_ref: diff --git a/include/ChangeLog b/include/ChangeLog index a0585b0..4a09ab6 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2010-03-24 Mark Wielaard + + * dwarf2.h (dwarf_form): Remove deprecated DW_FORM_sig8 define. + 2010-03-23 Rafael Ávila de Espíndola * plugin-api.h (ld_plugin_get_view): New. diff --git a/include/dwarf2.h b/include/dwarf2.h index 46f2291..ef0fa5f 100644 --- a/include/dwarf2.h +++ b/include/dwarf2.h @@ -189,7 +189,6 @@ enum dwarf_form DW_FORM_exprloc = 0x18, DW_FORM_flag_present = 0x19, DW_FORM_ref_sig8 = 0x20 -#define DW_FORM_sig8 DW_FORM_ref_sig8 /* Note: The use of DW_FORM_sig8 is deprecated. */ }; /* Attribute names and codes. */
Tighten ARM's CANNOT_CHANGE_MODE_CLASS
We currently generate very poor code for tests like: #include void foo (uint32_t *a, uint32_t *b, uint32_t *c) { uint32x4x3_t x, y; x = vld3q_u32 (a); y = vld3q_u32 (b); x.val[0] = vaddq_u32 (x.val[0], y.val[0]); x.val[1] = vaddq_u32 (x.val[1], y.val[1]); x.val[2] = vaddq_u32 (x.val[2], y.val[2]); vst3q_u32 (a, x); } This is because we force the uint32x4x3_t values to the stack and then load and store the individual vectors. What we actually want is for the uint32x4x3_t values to be stored in registers, and for the individual vectors to be accessed as subregs of those registers. The first part involves some middle-end mode changes (see recent gcc@ thread), while the second part requires a change to ARM's CANNOT_CHANGE_MODE_CLASS. CANNOT_CHANGE_MODE_CLASS is defined as: /* FPA registers can't do subreg as all values are reformatted to internal precision. VFP registers may only be accessed in the mode they were set. */ #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ ? reg_classes_intersect_p (FPA_REGS, (CLASS))\ || reg_classes_intersect_p (VFP_REGS, (CLASS)) \ : 0) But this VFP restriction appears to apply only to VFPv1; thanks to Peter Maydell for the archaeology. Tested on arm-linux-gnueabi. OK to install? This doesn't have any direct benefit without the middle-end mode change, but it needs to go in first in order for that change not to regress. Richard gcc/ * config/arm/arm.h (CANNOT_CHANGE_MODE_CLASS): Restrict FPA_REGS case to VFPv1. Index: gcc/config/arm/arm.h === --- gcc/config/arm/arm.h2011-03-24 13:47:14.0 + +++ gcc/config/arm/arm.h2011-03-24 15:26:19.0 + @@ -1167,12 +1167,14 @@ #define IRA_COVER_CLASSES \ } /* FPA registers can't do subreg as all values are reformatted to internal - precision. VFP registers may only be accessed in the mode they + precision. VFPv1 registers may only be accessed in the mode they were set. */ -#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ - (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ - ? reg_classes_intersect_p (FPA_REGS, (CLASS)) \ - || reg_classes_intersect_p (VFP_REGS, (CLASS))\ +#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ + (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ + ? (reg_classes_intersect_p (FPA_REGS, (CLASS)) \ + || (TARGET_VFP \ + && arm_fpu_desc->rev == 1 \ + && reg_classes_intersect_p (VFP_REGS, (CLASS \ : 0) /* The class value for index registers, and the one for base regs. */
*ping* Re: [Patch, Fortran, 4.7] PR 18918 - Add initial support for a coarray communication library
*ping* http://gcc.gnu.org/ml/fortran/2011-03/msg00162.html (RFC patch: http://gcc.gnu.org/ml/fortran/2011-03/msg3.html) Tobias PS: I will come back to the other emails of this week tomorrow; I am still recovering from a cold, which started with fever last Sunday :-( On 19.03.2011 17:23, Tobias Burnus wrote: Build and regtested on x86-64-linux. (a) Is the patch OK for the 4.7 trunk? (b) Are the libgfortrancaf.h, libgfortrancaf_mpi.c and libgfortrancaf_single.c OK for inclusion at libgfortran/caf?
Re: [x32] PATCH: PR middle-end/47725: [x32] error: unable to find a register to spill in class DIREG
> Pointer is promoted to Pmode from ptr_mode. Indeed. However the problem is the 2 in assign_parm_setup_reg: /* Store the parm in a pseudoregister during the function, but we may need to do it in a wider mode. Using 2 here makes the result consistent with promote_decl_mode and thus expand_expr_real_1. */ promoted_nominal_mode = promote_function_mode (data->nominal_type, data->nominal_mode, &unsignedp, TREE_TYPE (current_function_decl), 2); which is supposed to match the 2 in promote_decl_mode: if (TREE_CODE (decl) == RESULT_DECL || TREE_CODE (decl) == PARM_DECL) pmode = promote_function_mode (type, mode, &unsignedp, TREE_TYPE (current_function_decl), 2); else pmode = promote_mode (type, mode, &unsignedp); but doesn't match the 0 in assign_parm_find_data_types: promoted_mode = promote_function_mode (passed_type, passed_mode, &unsignedp, TREE_TYPE (current_function_decl), 0); so you get the redundant extension in the callee. The solution is to define the promote_function_mode hook for x86 to something like: static enum machine_mode ix86_promote_function_mode (const_tree type, enum machine_mode mode, int *punsignedp, const_tree fntype ATTRIBUTE_UNUSED, int for_return ATTRIBUTE_UNUSED) { if (POINTER_TYPE_P (type)) { *punsignedp = POINTERS_EXTEND_UNSIGNED; return Pmode; } return mode; } -- Eric Botcazou
Tweak ARM vld3q and vld4q patterns
The ARM vld3q and vld4q .md patterns expand into two individual vld3/vld4 instructions. Each instruction loads half of the total elements. The problem is that this is implemented as: array = vld3a (array, mem1) array = vld3b (array, mem2) with "array" being an input to the _first_ load as well as the second. This input is dead, but results in unnecessary loads from the stack. E.g. for: #include void foo (uint32_t *a, uint32_t *b, uint32_t *c) { uint32x4x3_t x, y; x = vld3q_u32 (a); y = vld3q_u32 (b); x.val[0] = vaddq_u32 (x.val[0], y.val[0]); x.val[1] = vaddq_u32 (x.val[1], y.val[1]); x.val[2] = vaddq_u32 (x.val[2], y.val[2]); vst3q_u32 (a, x); } we get: stmfd sp!, {r3, fp} ldr r2, .L2 add fp, sp, #4 vldmia r2, {d16-d21} sub sp, sp, #112 vmovq11, q8 @ ti vmovq12, q9 @ ti vmovq13, q10 @ ti ... where the vldmia is loading the x and y "inputs" to the two vld3q_u32s from the corresponding stack slots. It's true that vld?a doesn't _change_ the whole of the array, but that doesn't matter; we no longer care what values the other elements have. Tested on arm-linux-gnueabi. OK to install? Richard gcc/ * config/arm/neon.md (neon_vld3qa, neon_vld4qa): Remove operand 1 and reshuffle the operands to match. (neon_vld3, neon_vld4): Update accordingly. Index: gcc/config/arm/neon.md === --- gcc/config/arm/neon.md 2011-03-24 13:47:13.0 + +++ gcc/config/arm/neon.md 2011-03-24 15:51:59.0 + @@ -4605,8 +4605,7 @@ (define_expand "neon_vld3" (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] "TARGET_NEON" { - emit_insn (gen_neon_vld3qa (operands[0], operands[0], -operands[1], operands[1])); + emit_insn (gen_neon_vld3qa (operands[0], operands[1], operands[1])); emit_insn (gen_neon_vld3qb (operands[0], operands[0], operands[1], operands[1])); DONE; @@ -4614,12 +4613,11 @@ (define_expand "neon_vld3" (define_insn "neon_vld3qa" [(set (match_operand:CI 0 "s_register_operand" "=w") -(unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2")) -(match_operand:CI 1 "s_register_operand" "0") +(unspec:CI [(mem:CI (match_operand:SI 2 "s_register_operand" "1")) (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] UNSPEC_VLD3A)) - (set (match_operand:SI 2 "s_register_operand" "=r") -(plus:SI (match_dup 3) + (set (match_operand:SI 1 "s_register_operand" "=r") +(plus:SI (match_dup 2) (const_int 24)))] "TARGET_NEON" { @@ -4628,7 +4626,7 @@ (define_insn "neon_vld3qa" ops[0] = gen_rtx_REG (DImode, regno); ops[1] = gen_rtx_REG (DImode, regno + 4); ops[2] = gen_rtx_REG (DImode, regno + 8); - ops[3] = operands[2]; + ops[3] = operands[1]; output_asm_insn ("vld3.\t{%P0, %P1, %P2}, [%3]!", ops); return ""; } @@ -4897,8 +4895,7 @@ (define_expand "neon_vld4" (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] "TARGET_NEON" { - emit_insn (gen_neon_vld4qa (operands[0], operands[0], -operands[1], operands[1])); + emit_insn (gen_neon_vld4qa (operands[0], operands[1], operands[1])); emit_insn (gen_neon_vld4qb (operands[0], operands[0], operands[1], operands[1])); DONE; @@ -4906,12 +4903,11 @@ (define_expand "neon_vld4" (define_insn "neon_vld4qa" [(set (match_operand:XI 0 "s_register_operand" "=w") -(unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2")) -(match_operand:XI 1 "s_register_operand" "0") +(unspec:XI [(mem:XI (match_operand:SI 2 "s_register_operand" "1")) (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] UNSPEC_VLD4A)) - (set (match_operand:SI 2 "s_register_operand" "=r") -(plus:SI (match_dup 3) + (set (match_operand:SI 1 "s_register_operand" "=r") +(plus:SI (match_dup 2) (const_int 32)))] "TARGET_NEON" { @@ -4921,7 +4917,7 @@ (define_insn "neon_vld4qa" ops[1] = gen_rtx_REG (DImode, regno + 4); ops[2] = gen_rtx_REG (DImode, regno + 8); ops[3] = gen_rtx_REG (DImode, regno + 12); - ops[4] = operands[2]; + ops[4] = operands[1]; output_asm_insn ("vld4.\t{%P0, %P1, %P2, %P3}, [%4]!", ops); return ""; }
[Ada] Change return mechanism for variable-sized constrained array types
This changes the return mechanism for variable-sized constrained array types. They used to be returned on the secondary stack, they are now returned on the primary stack. This is generally more efficient and, in particular, makes it possible for the back-end to elide copies. Tested on i586-suse-linux, applied on the mainline. 2011-03-24 Eric Botcazou * einfo.ads (Size_Depends_On_Discriminant): Adjust description. * layout.adb (Compute_Size_Depends_On_Discriminant): New procedure to compute Set_Size_Depends_On_Discriminant. (Layout_Type): Call it on array types in back-end layout mode. * sem_util.adb (Requires_Transient_Scope): Return true for array types only if the size depends on the value of discriminants. * gcc-interface/utils2.c (build_binary_op) : Use the RHS type if the RHS is a call to a function that returns an unconstrained type with default discriminant. 2011-03-24 Eric Botcazou * gnat.dg/array16.ad[sb]: New test. * gnat.dg/array16.ads: New helper. -- Eric Botcazou Index: layout.adb === --- layout.adb (revision 171345) +++ layout.adb (working copy) @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2001-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 2001-2011, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -109,6 +109,12 @@ package body Layout is -- are of an enumeration type (so that the subtraction cannot be -- done directly) by applying the Pos operator to Hi/Lo first. + procedure Compute_Size_Depends_On_Discriminant (E : Entity_Id); + -- Given an array type or an array subtype E, compute whether its size + -- depends on the value of one or more discriminants and set the flag + -- Size_Depends_On_Discriminant accordingly. This need not be called + -- in front end layout mode since it does the computation on its own. + function Expr_From_SO_Ref (Loc : Source_Ptr; D: SO_Ref; @@ -1289,6 +1295,49 @@ package body Layout is end if; end Layout_Array_Type; + -- + -- Compute_Size_Depends_On_Discriminant -- + -- + + procedure Compute_Size_Depends_On_Discriminant (E : Entity_Id) is + Indx : Node_Id; + Ityp : Entity_Id; + Lo : Node_Id; + Hi : Node_Id; + Res : Boolean := False; + begin + -- Loop to process array indexes + + Indx := First_Index (E); + while Present (Indx) loop + Ityp := Etype (Indx); + + -- If an index of the array is a generic formal type then there is + -- no point in determining a size for the array type. + + if Is_Generic_Type (Ityp) then +return; + end if; + + Lo := Type_Low_Bound (Ityp); + Hi := Type_High_Bound (Ityp); + + if (Nkind (Lo) = N_Identifier + and then Ekind (Entity (Lo)) = E_Discriminant) + or else (Nkind (Hi) = N_Identifier + and then Ekind (Entity (Hi)) = E_Discriminant) + then +Res := True; + end if; + + Next_Index (Indx); + end loop; + + if Res then + Set_Size_Depends_On_Discriminant (E); + end if; + end Compute_Size_Depends_On_Discriminant; + --- -- Layout_Object -- --- @@ -2631,6 +2680,15 @@ package body Layout is Set_Alignment (E, Uint_1); end if; end if; + +-- We need to know whether the size depends on the value of one +-- or more discriminants to select the return mechanism. Skip if +-- errors are present, to prevent cascaded messages. + +if Serious_Errors_Detected = 0 then + Compute_Size_Depends_On_Discriminant (E); +end if; + end if; end if; Index: einfo.ads === --- einfo.ads (revision 171345) +++ einfo.ads (working copy) @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 1992-20
[debug] dwarf2out emits unnecessary null byte in empty .debug_abbrev section
Hi, Detected by the elfutils dwarflint tool. Example: $ echo > empty.c $ gcc -g -c empty.c $ readelf -x .debug_abbrev empty.o Hex dump of section '.debug_abbrev': 0x 00 . Although harmless it might add up if a project has a lot of objects without any real debuginfo in them. There might not actually be many such projects though. 2011-03-24 Mark Wielaard PR debug/48041 * dwarf2out.c (output_abbrev_section): Only terminate table when abbrev_die_table_in_use > 1. Bootstraps fine on x86_64-gnu-linux and no regressions seen with make check -k OK, to commit? Thanks, Mark --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -11084,7 +11084,8 @@ output_abbrev_section (void) } /* Terminate the table. */ - dw2_asm_output_data (1, 0, NULL); + if (abbrev_die_table_in_use > 1) +dw2_asm_output_data (1, 0, NULL); } /* Output a symbol we can use to refer to this DIE from another CU. */
Re: [PATCH, C++ testsuite] Fix g++.dg/abi/arm_cxa_vec1.C
On Thu, 2011-03-03 at 11:35 +, Yufeng Zhang wrote: > Hi, > > Here is a patch that fixes a problem in one g++ test case. A typo (of > using the macro ___ARM_EABI__ rather than __ARM_EABI__) has made the > original test case almost a NOP. > > Also with a few other changes that make the test work properly. > > I have already tested the updated test case that it still passes with > arm-eabi as an expected pass and passes with x86 as an unsupported test. > > OK for the trunk? > > Thanks, > Yufeng > > > 2011-03-03 Yufeng Zhang > > * g++.dg/abi/arm_cxa_vec1.C: Correct the typos/errors in the > test case. > OK. R.
[libgo] Improve Solaris 2/SPARC support
In order to improve Go test results on Solaris 2/SPARC, I need the following patch. * go-test.exp wasn't updated for the change from sparcv9 to sparc64. While I still don't agree with the new name, at least the two should be consistent. * env.go needs to accept sparc and sparc64. * Just like 32-bit Solaris 2/x86, 32-bit Solaris 2/SPARC needs to use the largefile variants of several functions. I've not introduced a new LIBGO_IS_SOLARIS32 conditional for that, but perhaps one should? With this patch, results are considerably improved, though still not good: the rpc and websocket tests hang indefinitely, as reported in PR go/48242, so one cannot include Go in a default bootstrap. I'll investigate those shortly. Apart from that, many tests fail, cf. PR go/48243. I'll have a look at them in the future, but wanted the get the low-hanging fruit out of the door. Rainer 2011-03-24 Rainer Orth go: * go.test/go-test.exp (go-set-goarch): Use sparc64 for 64-bit SPARC. * go.test/test/env.go (main): Handle sparc, sparc64. libgo: * Makefile.am (go_os_dir_file) [LIBGO_IS_SPARC]: Use go/os/dir_largefile.go. (syscall_filesize_file) [LIBGO_IS_SPARC]: Use syscalls/sysfile_largefile.go. (syscall_stat_file) [LIBGO_IS_SPARC]: Use syscalls/sysfile_stat_largefile.go. * Makefile.in: Regenerate. diff -r de1b3baf021b gcc/testsuite/go.test/go-test.exp --- a/gcc/testsuite/go.test/go-test.exp Thu Mar 24 13:19:30 2011 +0100 +++ b/gcc/testsuite/go.test/go-test.exp Thu Mar 24 13:22:43 2011 +0100 @@ -129,7 +129,7 @@ if [check_effective_target_ilp32] { set goarch "sparc" } else { - set goarch "sparcv9" + set goarch "sparc64" } } default { diff -r de1b3baf021b gcc/testsuite/go.test/test/env.go --- a/gcc/testsuite/go.test/test/env.go Thu Mar 24 13:19:30 2011 +0100 +++ b/gcc/testsuite/go.test/test/env.go Thu Mar 24 13:22:43 2011 +0100 @@ -1,7 +1,7 @@ // [ $GOOS != nacl ] || exit 0 # NaCl runner does not expose environment // $G $F.go && $L $F.$A && ./$A.out -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2009, 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -15,7 +15,8 @@ print("$GOARCH: ", e0.String(), "\n") os.Exit(1) } - if ga != "amd64" && ga != "386" && ga != "arm" { + if ga != "386" && ga != "amd64" && ga != "arm" && ga != "sparc" && + ga != "sparc64" { print("$GOARCH=", ga, "\n") os.Exit(1) } diff -r de1b3baf021b libgo/Makefile.am --- a/libgo/Makefile.am Thu Mar 24 13:19:30 2011 +0100 +++ b/libgo/Makefile.am Thu Mar 24 13:22:43 2011 +0100 @@ -676,8 +676,12 @@ if LIBGO_IS_386 go_os_dir_file = go/os/dir_largefile.go else +if LIBGO_IS_SPARC +go_os_dir_file = go/os/dir_largefile.go +else go_os_dir_file = go/os/dir_regfile.go endif +endif else if LIBGO_IS_LINUX go_os_dir_file = go/os/dir_largefile.go @@ -1188,16 +1192,21 @@ syscall_stat_file = syscalls/sysfile_stat_largefile.go else # !LIBGO_IS_LINUX if LIBGO_IS_SOLARIS -# FIXME: Same for sparc vs. sparc64. Introduce new/additional conditional? if LIBGO_IS_386 -# Use lseek64 on 386 Solaris. +# Use lseek64 on 32-bit Solaris/x86. syscall_filesize_file = syscalls/sysfile_largefile.go syscall_stat_file = syscalls/sysfile_stat_largefile.go -else # !LIBGO_IS_LINUX && LIBGO_IS_SOLARIS && !LIBGO_IS_386 -# Use lseek on amd64 Solaris. +else # !LIBGO_IS_386 +if LIBGO_IS_SPARC +# Use lseek64 on 32-bit Solaris/SPARC. +syscall_filesize_file = syscalls/sysfile_largefile.go +syscall_stat_file = syscalls/sysfile_stat_largefile.go +else # !LIBGO_IS_386 && !LIBGO_IS_SPARC +# Use lseek on 64-bit Solaris. syscall_filesize_file = syscalls/sysfile_regfile.go syscall_stat_file = syscalls/sysfile_stat_regfile.go -endif # !LIBGO_IS_386 +endif # !LIBGO_IS_386 && !LIBGO_IS_SPARC +endif # !LIBGO_IS_SOLARIS else # !LIBGO_IS_LINUX && !LIBGO_IS_SOLARIS # Use lseek by default. syscall_filesize_file = syscalls/sysfile_regfile.go -- - Rainer Orth, Center for Biotechnology, Bielefeld University
[PATCH] S/390: Fix reject malformed symbolic addresses in preferred_reload_class
Hi, reloads of symbolic addresses are done using larl (if possible) which allows to load a symbol_ref or label_ref plus an even addend. Since these addresses are constants special care has to be taken in preferred_reload class. We have to return NO_REGS in case of a malformed address like symref + odd addend. Otherwise reload assumes that these can be directly reloaded into a register. Fixed with the attached patch. Bootstrapped an regtested on s390, s390x with mainline and 4.6. Committed to mainline. Ok for 4.6? Bye, -Andreas- 2011-03-24 Andreas Krebbel * config/s390/s390.c (s390_preferred_reload_class): Return NO_REGS for invalid symbolic addresses. (s390_secondary_reload): Don't use s390_check_symref_alignment for larl operands. Index: gcc/config/s390/s390.c === *** gcc/config/s390/s390.c.orig --- gcc/config/s390/s390.c *** s390_preferred_reload_class (rtx op, reg *** 3003,3014 it is most likely being used as an address, so prefer ADDR_REGS. If 'class' is not a superset of ADDR_REGS, e.g. FP_REGS, reject this reload. */ - case PLUS: case LABEL_REF: case SYMBOL_REF: case CONST: if (reg_class_subset_p (ADDR_REGS, rclass)) ! return ADDR_REGS; else return NO_REGS; --- 3003,3018 it is most likely being used as an address, so prefer ADDR_REGS. If 'class' is not a superset of ADDR_REGS, e.g. FP_REGS, reject this reload. */ case LABEL_REF: case SYMBOL_REF: case CONST: + if (!legitimate_reload_constant_p (op)) + return NO_REGS; + /* fallthrough */ + case PLUS: + /* load address will be used. */ if (reg_class_subset_p (ADDR_REGS, rclass)) ! return ADDR_REGS; else return NO_REGS; *** s390_secondary_reload (bool in_p, rtx x, *** 3126,3137 if (TARGET_Z10) { /* On z10 several optimizer steps may generate larl operands with an odd addend. */ if (in_p ! && s390_symref_operand_p (x, NULL, NULL) && mode == Pmode ! && !s390_check_symref_alignment (x, 2)) sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10 : CODE_FOR_reloadsi_larl_odd_addend_z10); --- 3130,3145 if (TARGET_Z10) { + HOST_WIDE_INT offset; + rtx symref; + /* On z10 several optimizer steps may generate larl operands with an odd addend. */ if (in_p ! && s390_symref_operand_p (x, &symref, &offset) && mode == Pmode ! && !SYMBOL_REF_ALIGN1_P (symref) ! && (offset & 1) == 1) sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10 : CODE_FOR_reloadsi_larl_odd_addend_z10);
Re: Remove old host cases from toplevel configure
On 03/24/2011 03:11 PM, Joseph S. Myers wrote: Furthermore, the whole idea of the toplevel configure tentative_cc setting code is dubious since this is an autoconf-generated script and it's autoconf's job to deal with finding a working compiler, putting it in ANSI C mode, etc. - so if someone did wish to resupport one of these hosts (and in the unlikely event that building current tools using the old system compiler is at all possible) it would be better to put system-specific pieces in autoconf and make toolchain configure code work using features not host triplet tests as far as possible. 100% agreed, I've meant to clean this up for a long time. OK to commit? Yes, thank you very much. Paolo
[libgo] Support Solaris 8/9
When I tried to build libgo on Solaris 9/x86 with native tools, I ran into a couple of issues: * To correctly build sysinfo.go, one needs a different set of flags to compile sysinfo.c that conflict with the onces needed on Solaris 10+. Since there seems to be no easy way to autoconf this knowledge, I'm hardcoding it in configure.ac (OSCFLAGS) and pass it to mksysinfo.sh. * As documented in the Autoconf manual, the native grep cannot handle \|. One needs to use egrep for that instead. I've only updated the affected invocations, but one may want (or need) to either do this wholesale and/or replace the hardcoded egrep by autoconfed $EGREP. * Similarly, native sed cannot handle \?, so I'm substituting both alternatives in sequence. * For native TLS to work, libgo needs to be linked with -pthread, so libthread.so is included in the link. On Solaris 8, -pthread takes care of even more contortions necessary to get the proper thread library. In order for that to happen, I've introduced libgo_la_LDFLAGS. With those changes (and the strerror_r replacement since Solaris 8 and 9 also lack that function), I could successfully build and test libgo, with relatively decent results: FAIL: fmt Can't open -n grep: can't open -n grep: can't open -n mallocs per Sprintf(""): 1 mallocs per Sprintf("xxx"): 1 mallocs per Sprintf("%x"): 3 mallocs per Sprintf("%x %x"): 4 /vol/gcc/src/hg/trunk/local/libgo/testsuite/gotest[325]: 22734 Segmentation Fault make: *** [fmt/check] Error 1 FAIL: archive/zip Can't open -n grep: can't open -n grep: can't open -n --- FAIL: zip.TestReader (0.0 seconds) error=open testdata/dd.zip: No such file or directory, want FAIL make: *** [archive/zip/check] Error 1 FAIL: crypto/rand Can't open -n grep: can't open -n grep: can't open -n --- FAIL: rand.TestRead (0.0 seconds) Read(buf) = 1040, %!s() FAIL make: *** [crypto/rand/check] Error 1 FAIL: image/png Can't open -n grep: can't open -n grep: can't open -n --- FAIL: png.TestReader (1.0 seconds) basn0g01-30 open testdata/pngsuite/basn0g01-30.png: No such file or directory basn0g02-29 open testdata/pngsuite/basn0g02-29.png: No such file or directory basn0g04-31 open testdata/pngsuite/basn0g04-31.png: No such file or directory --- FAIL: png.TestWriter (0.2 seconds) basn0g01-30 open testdata/pngsuite/basn0g01-30.png: No such file or directory basn0g02-29 open testdata/pngsuite/basn0g02-29.png: No such file or directory basn0g04-31 open testdata/pngsuite/basn0g04-31.png: No such file or directory FAIL make: *** [image/png/check] Error 1 I'll be running make check-go shortly. Rainer 2011-03-24 Rainer Orth * configure.ac (OSCFLAGS): Define. * Makefile.am (s-sysinfo): Use it. (libgo_la_LDFLAGS): Define. * mksysinfo.sh (sysinfo.c) [__sun__ && __svr4__]: Remove. Replace \| in grep REs with egrep and |. Replace \? in sed REs with two variants. * Makefile.in: Regenerate. * configure: Regenerate. diff -r 75d0e839ffe1 libgo/Makefile.am --- a/libgo/Makefile.am Thu Mar 24 13:22:54 2011 +0100 +++ b/libgo/Makefile.am Thu Mar 24 16:45:53 2011 +0100 @@ -1459,6 +1459,8 @@ libgo_la_SOURCES = $(runtime_files) +libgo_la_LDFLAGS = $(PTHREAD_CFLAGS) + libgo_la_LIBADD = \ $(libgo_go_objs) $(LIBFFI) $(PTHREAD_LIBS) $(MATH_LIBS) $(NET_LIBS) @@ -2512,7 +2514,7 @@ sysinfo.go: s-sysinfo; @true s-sysinfo: $(srcdir)/mksysinfo.sh config.h - CC="$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS)" $(SHELL) $(srcdir)/mksysinfo.sh + CC="$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(OSCFLAGS)" $(SHELL) $(srcdir)/mksysinfo.sh $(SHELL) $(srcdir)/../move-if-change tmp-sysinfo.go sysinfo.go $(STAMP) $@ diff -r 75d0e839ffe1 libgo/configure.ac --- a/libgo/configure.acThu Mar 24 13:22:54 2011 +0100 +++ b/libgo/configure.acThu Mar 24 16:45:53 2011 +0100 @@ -229,6 +229,22 @@ fi AC_SUBST(GO_DEBUG_PROC_REGS_OS_ARCH_FILE) +dnl Some targets need special flags to build sysinfo.go. +case "$target" in +*-*-solaris2.[[89]]) + # Solaris 8/9 need this so struct msghdr gets the msg_control + # etc. fields in (_XPG4_2). + OSCFLAGS='-D_XOPEN_SOURCE=500 -D_XOPEN_SOURCE_EXTENDED -D__EXTENSIONS__' + ;; +*-*-solaris2.1[[01]]) + # Solaris 10+ needs this so struct msghdr gets the msg_control + # etc. fields in (_XPG4_2). _XOPEN_SOURCE=500 as + # above doesn't work with C99. + OSCFLAGS='-D_XOPEN_SOURCE=600 -D__EXTENSIONS__' + ;; +esac +AC_SUBST(OSCFLAGS) + dnl Use -fsplit-stack when compiling C code if available. AC_CACHE_CHECK([whether -fsplit-stack is supported], [libgo_cv_c_split_stack_supported], diff -r 75d0e839ffe1 libgo/mksysinfo.sh --- a/libgo/mksysinfo.shThu Mar 24 13:22:54 2011 +0100 +++ b/libgo/mksysinfo.shThu Mar 24 16:45:53
Re: Tighten ARM's CANNOT_CHANGE_MODE_CLASS
On Thu, 2011-03-24 at 15:40 +, Richard Sandiford wrote: > We currently generate very poor code for tests like: > > #include > > void > foo (uint32_t *a, uint32_t *b, uint32_t *c) > { > uint32x4x3_t x, y; > > x = vld3q_u32 (a); > y = vld3q_u32 (b); > x.val[0] = vaddq_u32 (x.val[0], y.val[0]); > x.val[1] = vaddq_u32 (x.val[1], y.val[1]); > x.val[2] = vaddq_u32 (x.val[2], y.val[2]); > vst3q_u32 (a, x); > } > > This is because we force the uint32x4x3_t values to the stack and > then load and store the individual vectors. > > What we actually want is for the uint32x4x3_t values to be stored > in registers, and for the individual vectors to be accessed as > subregs of those registers. The first part involves some middle-end > mode changes (see recent gcc@ thread), while the second part requires > a change to ARM's CANNOT_CHANGE_MODE_CLASS. > > CANNOT_CHANGE_MODE_CLASS is defined as: > > /* FPA registers can't do subreg as all values are reformatted to internal >precision. VFP registers may only be accessed in the mode they >were set. */ > #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ > (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \ >? reg_classes_intersect_p (FPA_REGS, (CLASS)) \ > || reg_classes_intersect_p (VFP_REGS, (CLASS)) \ >: 0) > > But this VFP restriction appears to apply only to VFPv1; thanks to > Peter Maydell for the archaeology. > > Tested on arm-linux-gnueabi. OK to install? > > This doesn't have any direct benefit without the middle-end mode change, > but it needs to go in first in order for that change not to regress. > > Richard > > > gcc/ > * config/arm/arm.h (CANNOT_CHANGE_MODE_CLASS): Restrict FPA_REGS > case to VFPv1. > GCC doesn't support VFPv1 (see the all_fpus table), and I don't think many chips based on that ever escaped into the wild world, so I'm not worried about trying to add that now. So it's probably safe to just kill that check for VFP entirely. R.
Re: [PATCH] reload: Avoid superfluous reloads after find_reloads_subreg_address
Andreas Krebbel wrote: > 2011-03-23 Andreas Krebbel > > * reload.c (find_reloads_subreg_address): Add address_reloaded > parameter and return true there if the full address has been > reloaded. > (find_reloads_toplev): Pass address_reloaded flag. > (find_reloads_address_1): Don't use address_reloaded parameter. This is OK. Thanks, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com
Re: [PATCH v3] Re: avoid useless if-before-free tests
Janne Blomqvist wrote: > On Tue, Mar 8, 2011 at 19:53, Jim Meyering wrote: >> Relative to v2, I've added libgo/ to the list of exempt directories and added >> this recently discussed gfc_free patch, at the request of Tobias Burnus. >> Also, I corrected an error in fortran's ChangeLog and removed all >> whitespace changes from all ChangeLog files. > > The libgfortran changes are Ok for 4.7. > > For the gfortran frontend (gcc/fortran/*) I'd prefer if you'd > > - Replace all calls to "gfc_free (x)" with "free (x)". > - Remove the gfc_free() function and prototype. > - Remove the free() macro which currently prevents calling free() directly. Following up, I've refreshed the series but hit a minor snag while converting new uses of gfc_free, removing new tests-before-free and merging/reordering changes. Applying this fix first makes my problem go away: >From 77142dc7da9e1e11ef8b0c554df4ff5c1bbdda39 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Thu, 24 Mar 2011 17:45:42 +0100 Subject: [PATCH] gfortran: remove unneeded test-before-gfc_free * trans-openmp.c (gfc_trans_omp_reduction_list): Do not guard use of gfc_free; it can handle a NULL argument. --- gcc/fortran/ChangeLog |5 + gcc/fortran/trans-openmp.c |3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 4e0a792..c532986 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2011-03-24 Jim Meyering + + * trans-openmp.c (gfc_trans_omp_reduction_list): Do not guard + use of gfc_free; it can handle a NULL argument. + 2010-03-21 Thomas Koenig PR fortran/22572 diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 53eb999..77ed3bb 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -714,8 +714,7 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where) gfc_free (symtree1); gfc_free (symtree2); gfc_free (symtree3); - if (symtree4) -gfc_free (symtree4); + gfc_free (symtree4); gfc_free_array_spec (outer_sym.as); } -- 1.7.4.1.686.g46300
cleanup host fragments more 1/n
AR_CFLAGS = cr is already the default. Committed to gcc and src. Paolo 2011-03-24 Paolo Bonzini * mh-sysv4: Remove AR_CFLAGS. Index: mh-sysv4 === --- mh-sysv4(revision 171413) +++ mh-sysv4(working copy) @@ -1,4 +1 @@ -# The l flag generates a warning from the SVR4 archiver, remove it. -AR_FLAGS = cr - X11_EXTRA_LIBS = -lnsl
[v3] Fix negative_binomial_distribution
Hi, this does fix a bad thinko of mine in negative_binomial_distribution (the fix will certainly go in 4.6.1, unless Jakub wants it now) + I'm adding basic statistical tests (adapted from GSL) for all the other discrete distributions. Thanks, Paolo. // 2011-03-24 Paolo Carlini * include/bits/random.h (negative_binomial_distribution<>:: negative_binomial_distribution(_IntType, double), negative_binomial_distribution<>:: negative_binomial_distribution(const param_type&)): Fix construction of _M_gd. * include/bits/random.tcc (negative_binomial_distribution<>:: operator()): Fix computation, per Leger's algorithm. * testsuite/util/testsuite_random.h (discrete_pdf, negative_binomial_pdf, poisson_pdf, uniform_int_pdf): New. (binomial_pdf): Swap last two parameters. * testsuite/26_numerics/random/discrete_distribution/ operators/values.cc: New. * testsuite/26_numerics/random/negative_binomial_distribution/ operators/values.cc: Likewise. * testsuite/26_numerics/random/poisson_distribution/ operators/values.cc: Likewise. * testsuite/26_numerics/random/uniform_int_distribution/ operators/values.cc: Likewise. * testsuite/26_numerics/random/binomial_distribution/ operators/values.cc: Adjust.Index: include/bits/random.tcc === --- include/bits/random.tcc (revision 171401) +++ include/bits/random.tcc (working copy) @@ -1075,7 +1075,7 @@ return __is; } - + // This is Leger's algorithm. template template typename negative_binomial_distribution<_IntType>::result_type @@ -1085,7 +1085,8 @@ const double __y = _M_gd(__urng); // XXX Is the constructor too slow? - std::poisson_distribution __poisson(__y); + std::poisson_distribution __poisson(__y * (1.0 - p()) +/ p()); return __poisson(__urng); } @@ -1099,10 +1100,10 @@ typedef typename std::gamma_distribution::param_type param_type; - const double __y = - _M_gd(__urng, param_type(__p.k(), __p.p() / (1.0 - __p.p(; + const double __y = _M_gd(__urng, param_type(__p.k(), 1.0)); - std::poisson_distribution __poisson(__y); + std::poisson_distribution __poisson(__y * (1.0 - __p.p()) +/ __p.p() ); return __poisson(__urng); } Index: include/bits/random.h === --- include/bits/random.h (revision 171401) +++ include/bits/random.h (working copy) @@ -3611,8 +3611,7 @@ param_type(double __p = 0.5) : _M_p(__p) { - _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) -&& (_M_p < 1.0)); + _GLIBCXX_DEBUG_ASSERT((_M_p > 0.0) && (_M_p < 1.0)); _M_initialize(); } @@ -3782,7 +3781,9 @@ explicit param_type(_IntType __k = 1, double __p = 0.5) : _M_k(__k), _M_p(__p) - { } + { + _GLIBCXX_DEBUG_ASSERT((_M_k > 0) && (_M_p > 0.0) && (_M_p <= 1.0)); + } _IntType k() const @@ -3803,12 +3804,12 @@ explicit negative_binomial_distribution(_IntType __k = 1, double __p = 0.5) - : _M_param(__k, __p), _M_gd(__k, __p / (1.0 - __p)) + : _M_param(__k, __p), _M_gd(__k, 1.0) { } explicit negative_binomial_distribution(const param_type& __p) - : _M_param(__p), _M_gd(__p.k(), __p.p() / (1.0 - __p.p())) + : _M_param(__p), _M_gd(__p.k(), 1.0) { } /** Index: testsuite/26_numerics/random/uniform_int_distribution/operators/values.cc === --- testsuite/26_numerics/random/uniform_int_distribution/operators/values.cc (revision 0) +++ testsuite/26_numerics/random/uniform_int_distribution/operators/values.cc (revision 0) @@ -0,0 +1,50 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// +// Copyright (C) 2011 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 +//
[toplevel] remove tentative_cc
As Joseph pointed out in his mail, its time has come. Paolo 2011-03-24 Paolo Bonzini * configure.ac: Remove all mentions of tentative_cc. * configure: Regenerate. Index: configure.ac === --- configure.ac(revision 171414) +++ configure.ac(working copy) @@ -1034,7 +1034,6 @@ case "${noconfigdirs}" in esac # Work in distributions that contain no compiler tools, like Autoconf. -tentative_cc="" host_makefile_frag=/dev/null if test -d ${srcdir}/config ; then case "${host}" in @@ -1058,18 +1057,15 @@ case "${host}" in host_makefile_frag="config/mh-solaris" ;; hppa*-hp-hpux10*) -tentative_cc="cc -Wp,-H256000" host_makefile_frag="config/mh-pa-hpux10" ;; hppa*-hp-hpux*) -tentative_cc="cc -Wp,-H256000" host_makefile_frag="config/mh-pa" ;; hppa*-*) host_makefile_frag="config/mh-pa" ;; *-hp-hpux*) -tentative_cc="cc -Wp,-H256000" ;; *-*-darwin*) host_makefile_frag="config/mh-darwin" @@ -1081,8 +1077,6 @@ case "${host}" in host_makefile_frag="config/mh-ppc-aix" ;; *-*-lynxos*) -# /bin/cc is less than useful for our purposes. Always use GCC -tentative_cc="/bin/gcc" ;; # This is placed last to prevent interfering with the cases above. i[[3456789]]86-*-*) @@ -1092,25 +1086,6 @@ case "${host}" in esac fi -# If we aren't going to be using gcc, see if we can extract a definition -# of CC from the fragment. -# Actually, use the 'pre-extracted' version above. -if test -z "${CC}" && test "${build}" = "${host}" ; then - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:" - found= - for dir in $PATH; do -test -z "$dir" && dir=. -if test -f $dir/gcc; then - found=yes - break -fi - done - IFS="$save_ifs" - if test -z "${found}" && test -n "${tentative_cc}" ; then -CC=$tentative_cc - fi -fi - if test "${build}" != "${host}" ; then AR_FOR_BUILD=${AR_FOR_BUILD-ar} AS_FOR_BUILD=${AS_FOR_BUILD-as}
Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes
2011/3/24 Jason Merrill : > How about splitting this out into a separate function that can compare > either list or expression arguments? That would also be useful for > merge_attributes and attribute_list_contained. > > Jason > Ok, here is the patch ChangeLog gcc/ 2011-03-11 Kai Tietz * c-typeck.c (comptypes_internal): Replace target hook call of comp_type_attributes by version in tree.c file. * gimple.c (gimple_types_compatible_p_1): Likewise. * tree-ssa.c (useless_type_conversion_p): Likewise. * tree.c (build_type_attribute_qual_variant): Likewise. (attribute_equal): New static helper function. (comp_type_attributes): New function. (merge_attributes): Use attribute_equal for comparison. (attribute_list_contained): Likewise. * tree.h (comp_type_attributes): New prototype. ChangeLog cp/ 2011-03-11 Kai Tietz * decl.c (decls_match): Replace target hook call of comp_type_attributes by version in tree.c file. * search.c (check_final_overrider): Likewise. * typeck.c (structural_comptypes): Likewise. Regards, Kai Index: gcc/gcc/c-typeck.c === --- gcc.orig/gcc/c-typeck.c 2011-03-24 08:23:42.441173500 +0100 +++ gcc/gcc/c-typeck.c 2011-03-24 09:24:53.445892300 +0100 @@ -1079,7 +1079,7 @@ comptypes_internal (const_tree type1, co return 1; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - if (!(attrval = targetm.comp_type_attributes (t1, t2))) + if (!(attrval = comp_type_attributes (t1, t2))) return 0; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ Index: gcc/gcc/cp/decl.c === --- gcc.orig/gcc/cp/decl.c 2011-03-24 08:23:42.443173500 +0100 +++ gcc/gcc/cp/decl.c 2011-03-24 09:24:53.573408500 +0100 @@ -1012,8 +1012,8 @@ decls_match (tree newdecl, tree olddecl) types_match = compparms (p1, p2) && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE - || targetm.comp_type_attributes (TREE_TYPE (newdecl), - TREE_TYPE (olddecl)) != 0); + || comp_type_attributes (TREE_TYPE (newdecl), + TREE_TYPE (olddecl)) != 0); } else types_match = 0; Index: gcc/gcc/cp/search.c === --- gcc.orig/gcc/cp/search.c2011-03-24 08:23:42.444173500 +0100 +++ gcc/gcc/cp/search.c 2011-03-24 09:24:53.645417600 +0100 @@ -1897,7 +1897,7 @@ check_final_overrider (tree overrider, t } /* Check for conflicting type attributes. */ - if (!targetm.comp_type_attributes (over_type, base_type)) + if (!comp_type_attributes (over_type, base_type)) { error ("conflicting type attributes specified for %q+#D", overrider); error (" overriding %q+#D", basefn); Index: gcc/gcc/cp/typeck.c === --- gcc.orig/gcc/cp/typeck.c2011-03-24 08:23:42.495173500 +0100 +++ gcc/gcc/cp/typeck.c 2011-03-24 09:24:53.697424200 +0100 @@ -1338,7 +1338,7 @@ structural_comptypes (tree t1, tree t2, /* If we get here, we know that from a target independent POV the types are the same. Make sure the target attributes are also the same. */ - return targetm.comp_type_attributes (t1, t2); + return comp_type_attributes (t1, t2); } /* Return true if T1 and T2 are related as allowed by STRICT. STRICT Index: gcc/gcc/gimple.c === --- gcc.orig/gcc/gimple.c 2011-03-24 08:23:42.496173500 +0100 +++ gcc/gcc/gimple.c2011-03-24 09:24:53.793936500 +0100 @@ -3615,7 +3615,7 @@ gimple_types_compatible_p_1 (tree t1, tr state, sccstack, sccstate, sccstate_obstack)) goto different_types; - if (!targetm.comp_type_attributes (t1, t2)) + if (!comp_type_attributes (t1, t2)) goto different_types; if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2)) Index: gcc/gcc/tree-ssa.c === --- gcc.orig/gcc/tree-ssa.c 2011-03-24 08:23:42.498173500 +0100 +++ gcc/gcc/tree-ssa.c 2011-03-24 09:24:53.831441200 +0100 @@ -1438,7 +1438,7 @@ useless_type_conversion_p (tree outer_ty /* Defer to the target if necessary. */ if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type)) - return targetm.comp_type_attributes (outer_type, inner_type) != 0; + return comp_type_attributes (outer_type, inner_type) != 0; return true; } Index: gcc/gcc/tree.c === --- gcc.orig/gcc/tree.c 2011-03-24 08:23:42.499173500 +0100 +++ gcc/gcc/tree.c 2011-03-24 18:00:04.39808470
[toplevel] cleanup X11_FLAGS_TO_PASS
Yet another relic of cygnus configure. Eliminate. Committed to gcc and (shortly) to src. Paolo 2011-03-24 Paolo Bonzini * configure.ac: Remove all mentions of mh-sysv4 and mh-solaris. * configure: Regenerate. * Makefile.def: Remove all mentions of X11_FLAGS_TO_PASS. * Makefile.tpl: Likewise. * Makefile.in: Regenerate. config: 2011-03-24 Paolo Bonzini * mh-sysv4: Remove. * mh-solaris: Remove. Index: configure.ac === --- configure.ac(revision 171415) +++ configure.ac(working copy) @@ -1037,9 +1037,6 @@ esac host_makefile_frag=/dev/null if test -d ${srcdir}/config ; then case "${host}" in - i[[3456789]]86-*-solaris2*) -host_makefile_frag="config/mh-sysv4" -;; i[[3456789]]86-*-msdosdjgpp*) host_makefile_frag="config/mh-djgpp" ;; @@ -1054,7 +1051,6 @@ case "${host}" in host_makefile_frag="config/mh-interix" ;; *-*-solaris2*) -host_makefile_frag="config/mh-solaris" ;; hppa*-hp-hpux10*) host_makefile_frag="config/mh-pa-hpux10" Index: config/mh-solaris === --- config/mh-solaris (revision 171414) +++ config/mh-solaris (working copy) @@ -1,2 +0,0 @@ -# Makefile changes for Suns running Solaris 2 -X11_EXTRA_LIBS = -lnsl -lsocket 2011-03-24 Joseph Myers Index: config/mh-sysv4 === --- config/mh-sysv4 (revision 171414) +++ config/mh-sysv4 (working copy) @@ -1 +0,0 @@ -X11_EXTRA_LIBS = -lnsl Index: Makefile.def === --- Makefile.def(revision 171414) +++ Makefile.def(working copy) @@ -134,10 +134,10 @@ host_modules= { module= uudecode; }; host_modules= { module= wdiff; }; host_modules= { module= zip; no_check_cross=true; }; host_modules= { module= zlib; no_install=true; no_check=true; bootstrap=true; }; -host_modules= { module= gdb; extra_make_flags="$(X11_FLAGS_TO_PASS)"; }; -host_modules= { module= expect; extra_make_flags="$(X11_FLAGS_TO_PASS)"; }; -host_modules= { module= guile; extra_make_flags="$(X11_FLAGS_TO_PASS)"; }; -host_modules= { module= tk; extra_make_flags="$(X11_FLAGS_TO_PASS)"; }; +host_modules= { module= gdb; }; +host_modules= { module= expect; }; +host_modules= { module= guile; }; +host_modules= { module= tk; }; host_modules= { module= libtermcap; no_check=true; missing=mostlyclean; missing=clean; Index: Makefile.in === --- Makefile.in (revision 169877) +++ Makefile.in (working copy) @@ -796,18 +796,6 @@ EXTRA_HOST_FLAGS = \ FLAGS_TO_PASS = $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) -# Flags that are concerned with the location of the X11 include files -# and library files -# -# NOTE: until the top-level is getting the values via autoconf, it only -# causes problems to have this top-level Makefile overriding the autoconf-set -# values in child directories. Only variables that don't conflict with -# autoconf'ed ones should be passed by X11_FLAGS_TO_PASS for now. -# -X11_FLAGS_TO_PASS = \ - 'X11_EXTRA_CFLAGS=$(X11_EXTRA_CFLAGS)' \ - 'X11_EXTRA_LIBS=$(X11_EXTRA_LIBS)' - # Flags to pass to stage2 and later makes. POSTSTAGE1_FLAGS_TO_PASS = \ @@ -42263,7 +42251,7 @@ all-gdb: configure-gdb s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \ $(HOST_EXPORTS) \ (cd $(HOST_SUBDIR)/gdb && \ - $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) $(X11_FLAGS_TO_PASS) \ + $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) \ $(TARGET-gdb)) @endif gdb @@ -42281,7 +42269,7 @@ check-gdb: s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \ $(HOST_EXPORTS) \ (cd $(HOST_SUBDIR)/gdb && \ - $(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) check) + $(MAKE) $(FLAGS_TO_PASS) check) @endif gdb @@ -42296,7 +42284,7 @@ install-gdb: installdirs s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \ $(HOST_EXPORTS) \ (cd $(HOST_SUBDIR)/gdb && \ - $(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) install) + $(MAKE) $(FLAGS_TO_PASS) install) @endif gdb @@ -42311,7 +42299,7 @@ install-strip-gdb: installdirs s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \ $(HOST_EXPORTS) \ (cd $(HOST_SUBDIR)/gdb && \ - $(MAKE) $(FLAGS_TO_PASS) $(X11_FLAGS_TO_PASS) install-strip) + $(MAKE) $(FLAGS_TO_PASS) install-strip) @endif gdb @@ -42329,7 +42317,7 @@ info-gdb: \ r=`${PWD_COMMAND}`; export r; \ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \ $(HOST_EXPORTS) \ - for flag in $(EXTRA_HOST_FLAGS) $(X11_FLAGS_TO_PASS); do \ + for flag in $(EXTRA_HOST_FLAGS) ; do \ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\
Re: [PATCH] Better .debug_aranges fix (PR debug/48253)
On 03/23/2011 09:08 PM, Jakub Jelinek wrote: const char *dw_fde_begin; const char *dw_fde_end; const char *dw_fde_hot_section_label; const char *dw_fde_hot_section_end_label; const char *dw_fde_unlikely_section_label; const char *dw_fde_unlikely_section_end_label; dw_cfi_ref dw_fde_switch_cfi; /* Last CFI before switching sections. */ /* True iff dw_fde_begin label is in text_section or cold_text_section. */ unsigned in_std_section : 1; /* True iff dw_fde_unlikely_section_label is in text_section or cold_text_section. */ unsigned cold_in_std_section : 1; /* True iff switched sections. */ unsigned dw_fde_switched_sections : 1; /* True iff switching from cold to hot section. */ unsigned dw_fde_switched_cold_to_hot : 1; Looking at this patch, without having previously paid much attention to the hot/cold partitioning code, I find these flags very confusing; it took me a while to figure out what they really mean. It seems that we are sometimes splitting functions into hot and cold, and those partitions can either be in standard sections or function-specific ones. So it seems like the information we want is: Primary start/end label (dw_fde_begin/end) Primary in standard section (in_std_section or cold_in_std_section) Secondary section used (dw_fde_switched_sections) Secondary start/end label (dw_fde_{hot,unlikely}_section_{,end_}label) Secondary in standard section (in_std_section or cold_in_std_section) It seems to me that we don't need to have the labels for both hot and cold sections in addition to begin/end, and we could replace dw_fde_switched_sections with just checking whether the secondary labels are NULL. I think we could drop dw_fde_switched_cold_to_hot in favor of the primary/secondary model; for debugging purposes it doesn't matter whether the primary section is hot or cold. This ought to cut down on the number of cases we have to handle in all the different places in dwarf2out that deal with this stuff. Does that make sense to you? Jason
Re: Cleaning up expand optabs code
On 03/24/2011 05:13 AM, Richard Sandiford wrote: > gcc/ > PR rtl-optimization/48263 > * optabs.c (expand_binop_directly): Reinstate convert_modes code > and original commutative_p handling. Use maybe_gen_insn. Ok. r~
[toplevel] cleanup mh-cygwin
The cygwin host fragment is using obsolete variables and constructs, modernize it. Committed to gcc and (shortly) src. Paolo 2011-03-24 Paolo Bonzini * Makefile.def: Add dependency from termcap to gdb. * Makefile.in: Regenerate. config: 2011-03-24 Paolo Bonzini * mh-cygwin: Remove obsolete variables and dependencies. Index: Makefile.def === --- Makefile.def(revision 171416) +++ Makefile.def(working copy) @@ -387,6 +387,7 @@ dependencies = { module=all-gdb; on=all- dependencies = { module=all-gdb; on=all-build-byacc; }; dependencies = { module=all-gdb; on=all-sim; }; dependencies = { module=all-gdb; on=all-libdecnumber; }; +dependencies = { module=all-gdb; on=all-libtermcap; }; dependencies = { module=configure-libgui; on=configure-tcl; }; dependencies = { module=configure-libgui; on=configure-tk; }; Index: Makefile.in === --- Makefile.in (revision 171416) +++ Makefile.in (working copy) @@ -60576,6 +60576,7 @@ all-gdb: maybe-all-build-bison all-gdb: maybe-all-build-byacc all-gdb: maybe-all-sim all-gdb: maybe-all-libdecnumber +all-gdb: maybe-all-libtermcap configure-libgui: maybe-configure-tcl configure-libgui: maybe-configure-tk all-libgui: maybe-all-tcl Index: config/mh-cygwin === --- config/mh-cygwin(revision 171414) +++ config/mh-cygwin(working copy) @@ -1,11 +1,4 @@ -EXTRA_TARGET_HOST_ALL_MODULES=maybe-all-libtermcap -EXTRA_TARGET_HOST_INSTALL_MODULES=maybe-install-libtermcap - # Increase stack limit to a figure based on the Linux default, with 4MB added # as GCC turns out to need that much more to pass all the limits-* tests. LDFLAGS += -Wl,--stack,12582912 BOOT_LDFLAGS += -Wl,--stack,12582912 - -all-gdb: maybe-all-libtermcap - -install-gdb: maybe-all-libtermcap
Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes
On 03/24/2011 06:06 PM, Kai Tietz wrote: +/* Compare two attributes for identity. Return true if the attributes + are known to be equal; otherwise return false. */ + +static bool +attribute_equal (const_tree attr1, const_tree attr2) +{ + if (attr1 == attr2) +return true; + Shouldn't this compare the TREE_VALUEs? This function is also assuming that the TREE_PURPOSEs name the same attribute. I had figured that we would pull out the TREE_VALUE in the caller, but doing it in here is fine too as long as the function is documented as making that assumption. Jason
Re: [PATCH] Better .debug_aranges fix (PR debug/48253)
On Thu, Mar 24, 2011 at 06:08:01PM +0100, Jason Merrill wrote: > This ought to cut down on the number of cases we have to handle in > all the different places in dwarf2out that deal with this stuff. > > Does that make sense to you? I'll try to implement it tomorrow, currently don't see why your idea wouldn't work. I haven't actually been able to write a testcase that switches from cold to hot btw., not sure if that is because I just didn't try very hard or because gcc never emits it. -freorder-blocks-and-partition is certainly terribly undertested (though I wonder if anybody actually uses it, e.g. given that EH for it has been broken for years). Jakub
[toplevel] remove empty cases
This enables omit-frame-pointer for i386-solaris. I honestly haven't bootstrapped it, but I don't expect any problems (and if they appear, it's much better to fix them ;). Committed to gcc and (shortly) to src. Paolo 2011-03-24 Paolo Bonzini * configure.ac: Remove empty cases. * configure: Regenerate. Index: configure.ac === --- configure.ac(revision 171416) +++ configure.ac(working copy) @@ -1050,8 +1050,6 @@ case "${host}" in *-interix*) host_makefile_frag="config/mh-interix" ;; - *-*-solaris2*) -;; hppa*-hp-hpux10*) host_makefile_frag="config/mh-pa-hpux10" ;; @@ -1061,8 +1059,6 @@ case "${host}" in hppa*-*) host_makefile_frag="config/mh-pa" ;; - *-hp-hpux*) -;; *-*-darwin*) host_makefile_frag="config/mh-darwin" ;; @@ -1072,8 +1068,6 @@ case "${host}" in rs6000-*-aix*) host_makefile_frag="config/mh-ppc-aix" ;; - *-*-lynxos*) -;; # This is placed last to prevent interfering with the cases above. i[[3456789]]86-*-*) # Build the stage2 and stage3 compilers with -fomit-frame-pointer. Index: configure === --- configure (revision 171416) +++ configure (working copy) @@ -3623,8 +3623,6 @@ fi *-interix*) host_makefile_frag="config/mh-interix" ;; - *-*-solaris2*) -;; hppa*-hp-hpux10*) host_makefile_frag="config/mh-pa-hpux10" ;; @@ -3634,8 +3632,6 @@ fi hppa*-*) host_makefile_frag="config/mh-pa" ;; - *-hp-hpux*) -;; *-*-darwin*) host_makefile_frag="config/mh-darwin" ;; @@ -3645,8 +3641,6 @@ fi rs6000-*-aix*) host_makefile_frag="config/mh-ppc-aix" ;; - *-*-lynxos*) -;; # This is placed last to prevent interfering with the cases above. i[3456789]86-*-*) # Build the stage2 and stage3 compilers with -fomit-frame-pointer.
Re: [toplevel] remove empty cases
On Thu, 24 Mar 2011, Paolo Bonzini wrote: > This enables omit-frame-pointer for i386-solaris. I honestly haven't > bootstrapped it, but I don't expect any problems (and if they appear, it's > much better to fix them ;). How about killing mh-x86omitfp? The x86 compiler defaults to -fomit-frame-pointer on most platforms now anyway. -- Joseph S. Myers jos...@codesourcery.com
Re: [toplevel] remove empty cases
"Joseph S. Myers" writes: > On Thu, 24 Mar 2011, Paolo Bonzini wrote: > >> This enables omit-frame-pointer for i386-solaris. I honestly haven't >> bootstrapped it, but I don't expect any problems (and if they appear, it's >> much better to fix them ;). > > How about killing mh-x86omitfp? The x86 compiler defaults to > -fomit-frame-pointer on most platforms now anyway. I'd prefer that: Solaris 10+/x86 defaults to -fomit-frame-pointer for improved debuggability (cf. gcc/config/sol2-10.h: USE_IX86_FRAME_POINTER, USE_X86_64_FRAME_POINTER), so it would be better leave this to the individual platforms instead. Rainer -- - Rainer Orth, Center for Biotechnology, Bielefeld University
Commit: RX: Add alignment for jumps, loops and labels
Hi Guys, I am applying the patch below to add alignment control for jumps, loops and labels to the RX backend. Tested without regressions on an rx-elf target. Cheers Nick gcc/ChangeLog 2011-03-24 Nick Clifton * config/rx/rx.h (LABEL_ALIGN_FOR_BARRIER): Define. (ASM_OUTPUT_MAX_SKIP_ALIGN): Define. * config/rx/rx.c (rx_option_override): Set align_jumps, align_loops and align_labels if not set by the user. (rx_align_for_label): New function. (rx_max_skip_for_label): New function. (TARGET_ASM_JUMP_ALIGN_MAX_SKIP): Define. (TARGET_ASM_LOOP_ALIGN_MAX_SKIP): Define. (TARGET_ASM_LABEL_ALIGN_MAX_SKIP): Define. (TARGET_ASM_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP): Define. * config/rx/rx-protos.h (rx_align_for_label): Add prototype. Index: gcc/config/rx/rx.h === --- gcc/config/rx/rx.h (revision 171417) +++ gcc/config/rx/rx.h (working copy) @@ -413,6 +413,25 @@ #undef USER_LABEL_PREFIX #define USER_LABEL_PREFIX "_" +#define LABEL_ALIGN_AFTER_BARRIER(x) rx_align_for_label () + +#define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM, LOG, MAX_SKIP) \ + do \ +{ \ + if ((LOG) == 0 || (MAX_SKIP) == 0) \ +break; \ + if (TARGET_AS100_SYNTAX) \ + { \ + if ((LOG) >= 2) \ + fprintf (STREAM, "\t.ALIGN 4\t; %d alignment actually requested\n", 1 << (LOG)); \ + else \ + fprintf (STREAM, "\t.ALIGN 2\n"); \ + } \ + else \ + fprintf (STREAM, "\t.balign %d,3,%d\n", 1 << (LOG), (MAX_SKIP)); \ +} \ + while (0) + #define ASM_OUTPUT_ALIGN(STREAM, LOG) \ do \ { \ Index: gcc/config/rx/rx-protos.h === --- gcc/config/rx/rx-protos.h (revision 171417) +++ gcc/config/rx/rx-protos.h (working copy) @@ -26,6 +26,7 @@ #define Fargs CUMULATIVE_ARGS #define Rcode enum rtx_code +extern int rx_align_for_label (void); extern voidrx_expand_prologue (void); extern int rx_initial_elimination_offset (int, int); Index: gcc/config/rx/rx.c === --- gcc/config/rx/rx.c (revision 171417) +++ gcc/config/rx/rx.c (working copy) @@ -2350,6 +2350,13 @@ flag_strict_volatile_bitfields = 1; rx_override_options_after_change (); + + if (align_jumps == 0 && ! optimize_size) +align_jumps = 3; + if (align_loops == 0 && ! optimize_size) +align_loops = 3; + if (align_labels == 0 && ! optimize_size) +align_labels = 3; } /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ @@ -2740,8 +2747,47 @@ return true; } + +int +rx_align_for_label (void) +{ + return optimize_size ? 1 : 3; +} +static int +rx_max_skip_for_label (rtx lab) +{ + int opsize; + rtx op; + + if (lab == NULL_RTX) +return 0; + + op = lab; + do +{ + op = next_nonnote_nondebug_insn (op); +} + while (op && (LABEL_P (op) + || (INSN_P (op) && GET_CODE (PATTERN (op)) == USE))); + if (!op) +return 0; + + opsize = get_attr_length (op); + if (opsize >= 0 && opsize < 8) +return opsize - 1; + return 0; +} +#undef TARGET_ASM_JUMP_ALIGN_MAX_SKIP +#define TARGET_ASM_JUMP_ALIGN_MAX_SKIP rx_max_skip_for_label +#undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP +#define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rx_max_skip_for_label +#undef TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP +#define TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP rx_max_skip_for_label +#undef TARGET_ASM_LABEL_ALIGN_MAX_SKIP +#define TARGET_ASM_LABEL_ALIGN_MAX_SKIP rx_max_skip_for_label + #undef TARGET_FUNCTION_VALUE #define TARGET_FUNCTION_VALUE rx_function_value
Re: [toplevel] remove empty cases
On 03/24/2011 06:18 PM, Joseph S. Myers wrote: > On Thu, 24 Mar 2011, Paolo Bonzini wrote: > > This enables omit-frame-pointer for i386-solaris. I honestly haven't > > bootstrapped it, but I don't expect any problems (and if they appear, it's > > much better to fix them;). > > How about killing mh-x86omitfp? The x86 compiler defaults to > -fomit-frame-pointer on most platforms now anyway. Sounds good. Paolo 2011-03-24 Paolo Bonzini * configure.ac: Do not include mh-x86omitfp. * configure: Regenerate. config: 2011-03-24 Paolo Bonzini * mh-x86omitfp: Remove. Index: configure.ac === --- configure.ac(revision 171419) +++ configure.ac(working copy) @@ -1068,11 +1068,6 @@ case "${host}" in rs6000-*-aix*) host_makefile_frag="config/mh-ppc-aix" ;; - # This is placed last to prevent interfering with the cases above. - i[[3456789]]86-*-*) -# Build the stage2 and stage3 compilers with -fomit-frame-pointer. -host_makefile_frag="config/mh-x86omitfp" -;; esac fi Index: config/mh-x86omitfp === --- config/mh-x86omitfp (revision 171414) +++ config/mh-x86omitfp (working copy) @@ -1,2 +0,0 @@ -# Add -fomit-frame-pointer to the usual BOOT_CFLAGS to speed up the compiler. -BOOT_CFLAGS += -fomit-frame-pointer
Re: Can't use SImode as Pmode for x32
On 03/23/2011 08:40 PM, H.J. Lu wrote: > Are you suggesting that we should say that SP and BP are 32bits so > that x32 has 16 integer registers, 14 are 64 bites and 2 are 32 bits? No, merely that push/pop are valid with (reg:SI 7 sp). r~
Re: [PATCH 2/2] refactor emit_*_{after,before}{,_setloc} using common functions
On 03/23/2011 02:40 PM, Nathan Froyd wrote: > I can look into just how many places might need to be fixed up because > of this, but scattering a bunch of ifs all over the place seemed less > elegant than handling it all in the emit* functions. Yeah, maybe. On the other hand, the other complication that's going on there is attempting to provide a "sensible" return value in the case of emitting a NULL_RTX, and doing different things for insns vs non-insns. Merely removing the "different things" is surely an improvement. Getting rid of the "sensible" probably cleans things up more, but probably interferes more with reload. r~
[cxx-mem-model] disallow load data races (1 of some)
This is my first stab at disallowing load data races that happen when we cache the value of a global. I would appreciate input before committing, especially on the RTL bits, cause it's been quite a while since I typed d-e-b-u-g-_-r-t-x. :-) In the example below we usually hoist "global" into a register or temporary to avoid reading from it at each step. This would cause a race if another thread had modified "global" in between iterations. for (x=0; x< 5; x++) sum[x] = global; As expected, multiple passes can cause the same end result, so plugging the problem involves multiple places. First, loop invariant movement moves the invariant. Barring that, PRE moves the load, and even if we get past the SSA passes, rtl-CSE pulls the rug from under us. If that weren't enough, the post-reload pass performs CSE over the hard registers, and we end up eliminating subsequent loads of "global". I am sure there are many other places, but I'm starting with whatever it takes to fix gcc.dg/memmodel/global-hoist.c. The patch below fixes the test in question with "--param allow-load-data-races=0". What do y'all think? Thanks. * tree.h (DECL_THREAD_VISIBLE_P): New. * cselib.c (cselib_lookup_mem): Return 0 for globals for restrictive memory model. * cse.c (hash_rtx_cb): Same. * gimple.h (gimple_has_thread_visible_ops): Protoize. * gimple.c (gimple_has_thread_visible_ops): New. * tree-ssa-loop-im.c (movement_possibility): Disallow when avoiding load data races. * tree-ssa-pre.c (compute_avail): Same, for globals. Index: tree-ssa-loop-im.c === --- tree-ssa-loop-im.c (revision 170745) +++ tree-ssa-loop-im.c (working copy) @@ -377,6 +377,11 @@ movement_possibility (gimple stmt) || stmt_could_throw_p (stmt)) return MOVE_IMPOSSIBLE; + /* Do not move loads of globals if under a restrictive memory model. */ + if (PARAM_VALUE (PARAM_ALLOW_LOAD_DATA_RACES) == 0 + && gimple_has_thread_visible_ops (stmt)) +return MOVE_IMPOSSIBLE; + if (is_gimple_call (stmt)) { /* While pure or const call is guaranteed to have no side effects, we Index: tree.h === --- tree.h (revision 170745) +++ tree.h (working copy) @@ -3102,6 +3102,10 @@ struct GTY(()) tree_parm_decl { #define DECL_THREAD_LOCAL_P(NODE) \ (VAR_DECL_CHECK (NODE)->decl_with_vis.tls_model >= TLS_MODEL_REAL) +/* Return true if a VAR_DECL is visible from another thread. */ +#define DECL_THREAD_VISIBLE_P(NODE) \ + (TREE_STATIC (NODE) && !DECL_THREAD_LOCAL_P (NODE)) + /* In a non-local VAR_DECL with static storage duration, true if the variable has an initialization priority. If false, the variable will be initialized at the DEFAULT_INIT_PRIORITY. */ Index: cse.c === --- cse.c (revision 170745) +++ cse.c (working copy) @@ -2402,6 +2402,19 @@ hash_rtx_cb (const_rtx x, enum machine_m } case MEM: + /* Avoid hoisting loads of globals if under a restrictive memory +model. */ + if (PARAM_VALUE (PARAM_ALLOW_LOAD_DATA_RACES) == 0) + { + tree decl = MEM_EXPR (x); + if (do_not_record_p + && decl && TREE_CODE (decl) == VAR_DECL + && DECL_THREAD_VISIBLE_P (decl)) + { + *do_not_record_p = 1; + return 0; + } + } /* We don't record if marked volatile or if BLKmode since we don't know the size of the move. */ if (do_not_record_p && (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)) Index: cselib.c === --- cselib.c(revision 170745) +++ cselib.c(working copy) @@ -1190,6 +1190,16 @@ cselib_lookup_mem (rtx x, int create) cselib_val *mem_elt; struct elt_list *l; + /* Forget any reads from globals if under a restrictive memory + model. */ + if (PARAM_VALUE (PARAM_ALLOW_LOAD_DATA_RACES) == 0) +{ + tree decl = MEM_EXPR (x); + if (decl && TREE_CODE (decl) == VAR_DECL + && DECL_THREAD_VISIBLE_P (decl)) + return 0; +} + if (MEM_VOLATILE_P (x) || mode == BLKmode || !cselib_record_memory || (FLOAT_MODE_P (mode) && flag_float_store)) Index: tree-ssa-pre.c === --- tree-ssa-pre.c (revision 170745) +++ tree-ssa-pre.c (working copy) @@ -4000,6 +4000,12 @@ compute_avail (void) || stmt_could_throw_p (stmt)) continue; + /* Do not move loads of globals if under a restrictive +memory model. */ + if (PARAM_VALUE (PARAM_ALLOW_LOAD_DATA_RACES) == 0 + && gimple_has_thread_visible_ops (stmt)) + continue; +
mt-mep using EXTRA_TARGET_HOST_ALL_MODULES?
Is this actually desired? And what's all-utils? Can we just kill mt-mep? Thanks! :) Paolo
[patch i386 windows]: Introduce call-abi for 32-bit mingw and make callee_pop_aggregate_return attribute by default on for 32-bit mingw target
Hi, this patch introduces for windows 32-bit target also the call-abi specifiers (ms_abi/sys_v) and set its default for this target to "ms_abi". This patch set the default of the "callee_pop_aggregate_return" attribute to true for MS_ABI call-abi on 32-bit. Additionally it avoids the check of "callee_pop_aggregate_return" for any x86_64 target. I didn't changed here by intention the default settings of cygwin-target. But of course, if wished this change could be done as follow-up patch. ChangeLog gcc/ 2011-03-24 Kai Tietz * config/i386/cygming.h (DWARF_FRAME_REGISTERS): Adjust comment. (STACK_BOUNDARY): Check for bit-ness in case of MS_ABI. * config/i386/i386.c (ix86_conditional_register_usage): Adjust comment and use macro TARGET_64BIT_MS_ABI instead. (ix86_keep_aggregate_return_pointer): Optimize for 64-bit case and change default behavior for 32-bit MS_ABI. (ix86_reg_parm_stack_space): Check additionally for bit-ness. (ix86_function_type_abi): Allow check for ms_abi/sysv_abi for 32-bit, too. (ix86_cfun_abi): Likewise. (ix86_maybe_switch_abi): Adjust comment. (init_cumulative_args): Check for bit-ness in MS_ABI case. (ix86_gimplify_va_arg): Check just for not TARGET_64BIT_MS_ABI instead of checking for SYSV_ABI. (ix86_nsaved_sseregs): Likewise. (ix86_compute_frame_layout): Set only for 64-bit MS_ABI alignment to 16 bytes. (ix86_expand_call): Use TARGET_64BIT_MS_ABI macro. * config/i386.h (TARGET_32BIT_MS_ABI): New macro. (ACCUMULATE_OUTGOING_ARGS): Check explicit for 64-bit MS_ABI. (OUTGOING_REG_PARM_STACK_SPACE): Likewise. * config/mingw32.h (DEFAULT_ABI): Change default always to MS_ABI. Tested for x86_64-w64-mingw32, i686-pc-cygwin, and i686-w64-mingw32. Ok for apply? Regards, Kai
Re: mt-mep using EXTRA_TARGET_HOST_ALL_MODULES?
There's a top-level utils/ subdir in some trees. Yes, MeP has a tool there.
Re: [patch middle-end c c++]: Optimize cost of comp_type_attributes
2011/3/24 Jason Merrill : > On 03/24/2011 06:06 PM, Kai Tietz wrote: >> >> +/* Compare two attributes for identity. Return true if the attributes >> + are known to be equal; otherwise return false. */ >> + >> +static bool >> +attribute_equal (const_tree attr1, const_tree attr2) >> +{ >> + if (attr1 == attr2) >> + return true; >> + > > Shouldn't this compare the TREE_VALUEs? > > This function is also assuming that the TREE_PURPOSEs name the same > attribute. I had figured that we would pull out the TREE_VALUE in the > caller, but doing it in here is fine too as long as the function is > documented as making that assumption. > > Jason > I added an note to the documentation of the helper function. Ok by this? Kai Index: gcc/gcc/c-typeck.c === --- gcc.orig/gcc/c-typeck.c 2011-03-24 08:23:42.441173500 +0100 +++ gcc/gcc/c-typeck.c 2011-03-24 09:24:53.445892300 +0100 @@ -1079,7 +1079,7 @@ comptypes_internal (const_tree type1, co return 1; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - if (!(attrval = targetm.comp_type_attributes (t1, t2))) + if (!(attrval = comp_type_attributes (t1, t2))) return 0; /* 1 if no need for warning yet, 2 if warning cause has been seen. */ Index: gcc/gcc/cp/decl.c === --- gcc.orig/gcc/cp/decl.c 2011-03-24 08:23:42.443173500 +0100 +++ gcc/gcc/cp/decl.c 2011-03-24 09:24:53.573408500 +0100 @@ -1012,8 +1012,8 @@ decls_match (tree newdecl, tree olddecl) types_match = compparms (p1, p2) && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE - || targetm.comp_type_attributes (TREE_TYPE (newdecl), - TREE_TYPE (olddecl)) != 0); + || comp_type_attributes (TREE_TYPE (newdecl), + TREE_TYPE (olddecl)) != 0); } else types_match = 0; Index: gcc/gcc/cp/search.c === --- gcc.orig/gcc/cp/search.c2011-03-24 08:23:42.444173500 +0100 +++ gcc/gcc/cp/search.c 2011-03-24 09:24:53.645417600 +0100 @@ -1897,7 +1897,7 @@ check_final_overrider (tree overrider, t } /* Check for conflicting type attributes. */ - if (!targetm.comp_type_attributes (over_type, base_type)) + if (!comp_type_attributes (over_type, base_type)) { error ("conflicting type attributes specified for %q+#D", overrider); error (" overriding %q+#D", basefn); Index: gcc/gcc/cp/typeck.c === --- gcc.orig/gcc/cp/typeck.c2011-03-24 08:23:42.495173500 +0100 +++ gcc/gcc/cp/typeck.c 2011-03-24 09:24:53.697424200 +0100 @@ -1338,7 +1338,7 @@ structural_comptypes (tree t1, tree t2, /* If we get here, we know that from a target independent POV the types are the same. Make sure the target attributes are also the same. */ - return targetm.comp_type_attributes (t1, t2); + return comp_type_attributes (t1, t2); } /* Return true if T1 and T2 are related as allowed by STRICT. STRICT Index: gcc/gcc/gimple.c === --- gcc.orig/gcc/gimple.c 2011-03-24 08:23:42.496173500 +0100 +++ gcc/gcc/gimple.c2011-03-24 09:24:53.793936500 +0100 @@ -3615,7 +3615,7 @@ gimple_types_compatible_p_1 (tree t1, tr state, sccstack, sccstate, sccstate_obstack)) goto different_types; - if (!targetm.comp_type_attributes (t1, t2)) + if (!comp_type_attributes (t1, t2)) goto different_types; if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2)) Index: gcc/gcc/tree-ssa.c === --- gcc.orig/gcc/tree-ssa.c 2011-03-24 08:23:42.498173500 +0100 +++ gcc/gcc/tree-ssa.c 2011-03-24 09:24:53.831441200 +0100 @@ -1438,7 +1438,7 @@ useless_type_conversion_p (tree outer_ty /* Defer to the target if necessary. */ if (TYPE_ATTRIBUTES (inner_type) || TYPE_ATTRIBUTES (outer_type)) - return targetm.comp_type_attributes (outer_type, inner_type) != 0; + return comp_type_attributes (outer_type, inner_type) != 0; return true; } Index: gcc/gcc/tree.c === --- gcc.orig/gcc/tree.c 2011-03-24 08:23:42.499173500 +0100 +++ gcc/gcc/tree.c 2011-03-24 18:39:38.461052400 +0100 @@ -4283,7 +4283,7 @@ build_type_attribute_qual_variant (tree its canonical type, we will need to use structural equality checks for this type. */ if (TYPE_STRUCTURAL_EQUALITY_P (ttype) - || !targetm.comp_type_attributes (ntype, ttype)) + || !comp_type_attributes (ntype, ttype)) SET_TYPE_STRUCTURAL_EQUALITY (ntype); else if (TYPE_CANO