Re: [PATCH, generic] Support printing of escaped curly braces and vertical bar in assembler output
Yep, sure. I missed that (*p != NULL) check. Thanks, Michael On 29 March 2013 05:15, Segher Boessenkool seg...@kernel.crashing.org wrote: I'd suggest rewriting this expression in some easier way: p += (*p == '%' *(p + 1)) ? 2 : 1; I'd prefer if (*p == '%') p++; p++; That's not the same thing though. Maksim's code is correct, although it could certainly be written more clearly. Maybe something like if (*p == '%') p++; if (*p) p++; Segher -- --- Best regards, Michael V. Zolotukhin, Software Engineer Intel Corporation.
Contents of PO file 'cpplib-4.8.0.vi.po'
cpplib-4.8.0.vi.po.gz Description: Binary data The Translation Project robot, in the name of your translation coordinator. coordina...@translationproject.org
New Vietnamese PO file for 'cpplib' (version 4.8.0)
Hello, gentle maintainer. This is a message from the Translation Project robot. A revised PO file for textual domain 'cpplib' has been submitted by the Vietnamese team of translators. The file is available at: http://translationproject.org/latest/cpplib/vi.po (This file, 'cpplib-4.8.0.vi.po', has just now been sent to you in a separate email.) All other PO files for your package are available in: http://translationproject.org/latest/cpplib/ Please consider including all of these in your next release, whether official or a pretest. Whenever you have a new distribution with a new version number ready, containing a newer POT file, please send the URL of that distribution tarball to the address below. The tarball may be just a pretest or a snapshot, it does not even have to compile. It is just used by the translators when they need some extra translation context. The following HTML page has been updated: http://translationproject.org/domain/cpplib.html If any question arises, please contact the translation coordinator. Thank you for all your work, The Translation Project robot, in the name of your translation coordinator. coordina...@translationproject.org
[patch] Remove unused symbols.
Remove various unused symbols. Tested on x86-64. Committed as obvious. Index: gcc/ChangeLog * graphds.h (struct graph.indicies): Remove unused. * graphite-poly.h (struct graph.original_pddrs): Remove unused. (SCOP_ORIGINAL_PDDRS): Remove unused. * sese.h (extern insert_loop_close_phis): Removed unused. (extern insert_guard_phis): Removed unused. (extern ivtype_map_elt_info): Removed unused. (new_ivtype_map_elt): Removed unused. * sese.c (ivtype_map_elt_info): Removed unused. 2013-03-28 Lawrence Crowl cr...@google.com Index: gcc/sese.c === --- gcc/sese.c (revision 197224) +++ gcc/sese.c (working copy) @@ -111,14 +111,6 @@ debug_ivtype_map (htab_t map) htab_traverse (map, debug_ivtype_map_1, NULL); } -/* Computes a hash function for database element ELT. */ - -hashval_t -ivtype_map_elt_info (const void *elt) -{ - return htab_hash_pointer (((const struct ivtype_map_elt_s *) elt)-cloog_iv); -} - /* Compares database elements E1 and E2. */ int Index: gcc/sese.h === --- gcc/sese.h (revision 197224) +++ gcc/sese.h (working copy) @@ -58,8 +58,6 @@ extern void build_sese_loop_nests (sese) extern edge copy_bb_and_scalar_dependences (basic_block, sese, edge, vectree , bool *); extern struct loop *outermost_loop_in_sese (sese, basic_block); -extern void insert_loop_close_phis (htab_t, loop_p); -extern void insert_guard_phis (basic_block, edge, edge, htab_t, htab_t); extern tree scalar_evolution_in_region (sese, loop_p, tree); /* Check that SESE contains LOOP. */ @@ -286,23 +284,8 @@ typedef struct ivtype_map_elt_s } *ivtype_map_elt; extern void debug_ivtype_map (htab_t); -extern hashval_t ivtype_map_elt_info (const void *); extern int eq_ivtype_map_elts (const void *, const void *); -/* Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW. */ - -static inline ivtype_map_elt -new_ivtype_map_elt (const char *cloog_iv, tree type) -{ - ivtype_map_elt res; - - res = XNEW (struct ivtype_map_elt_s); - res-cloog_iv = cloog_iv; - res-type = type; - - return res; -} - /* Free and compute again all the dominators information. */ static inline void Index: gcc/graphds.h === --- gcc/graphds.h (revision 197224) +++ gcc/graphds.h (working copy) @@ -46,7 +46,6 @@ struct graph int n_vertices; /* Number of vertices. */ struct vertex *vertices; /* The vertices. */ - htab_t indices; /* Fast lookup for indices. */ }; struct graph *new_graph (int); Index: gcc/graphite-poly.h === --- gcc/graphite-poly.h (revision 197224) +++ gcc/graphite-poly.h (working copy) @@ -1376,10 +1376,6 @@ struct scop *must_war, *may_war, *must_war_no_source, *may_war_no_source, *must_waw, *may_waw, *must_waw_no_source, *may_waw_no_source; - /* A hashtable of the data dependence relations for the original - scattering. */ - htab_t original_pddrs; - /* True when the scop has been converted to its polyhedral representation. */ bool poly_scop_p; @@ -1388,7 +1384,6 @@ struct scop #define SCOP_BBS(S) (S-bbs) #define SCOP_REGION(S) ((sese) S-region) #define SCOP_CONTEXT(S) (NULL) -#define SCOP_ORIGINAL_PDDRS(S) (S-original_pddrs) #define SCOP_ORIGINAL_SCHEDULE(S) (S-original_schedule) #define SCOP_TRANSFORMED_SCHEDULE(S) (S-transformed_schedule) #define SCOP_SAVED_SCHEDULE(S) (S-saved_schedule) -- Lawrence Crowl
[patch] Remove unused code from dse.c.
This patch has been in the hash-table branch for months. I thought it didn't quite meet the criteria for obvious, but it's close. In dse.c, remove alias hash tables that are never set. Remove conditions that are then never true. Remove functions that are then never called. Remove variables that are then never read. Tested on x86-64. Index: gcc/ChangeLog 2013-03-29 Lawrence Crowl cr...@google.com * dse.c (clear_alias_sets): Remove never set. (disqualified_clear_alias_sets): Remove never set. (clear_alias_mode_pool): Remove never set. (dse_step0): Remove condition that is never true. (canon_address): Remove condition that is never true. (dse_step7): Remove condition that is never true. (rest_of_handle_dse): Remove condition that is never true. (rest_of_handle_dse::did_global): Remove never read from above. (dse_step2_spill): Remove never called from above. (dse_step5_spill): Remove never called from above. Index: gcc/dse.c === --- gcc/dse.c (revision 197226) +++ gcc/dse.c (working copy) @@ -572,20 +572,6 @@ static alloc_pool deferred_change_pool; static deferred_change_t deferred_change_list = NULL; -/* This are used to hold the alias sets of spill variables. Since - these are never aliased and there may be a lot of them, it makes - sense to treat them specially. This bitvector is only allocated in - calls from dse_record_singleton_alias_set which currently is only - made during reload1. So when dse is called before reload this - mechanism does nothing. */ - -static bitmap clear_alias_sets = NULL; - -/* The set of clear_alias_sets that have been disqualified because - there are loads or stores using a different mode than the alias set - was registered with. */ -static bitmap disqualified_clear_alias_sets = NULL; - /* The group that holds all of the clear_alias_sets. */ static group_info_t clear_alias_group; @@ -599,8 +585,6 @@ struct clear_alias_mode_holder enum machine_mode mode; }; -static alloc_pool clear_alias_mode_pool; - /* This is true except if cfun-stdarg -- i.e. we cannot do this for vararg functions because they play games with the frame. */ static bool stores_off_frame_dead_at_return; @@ -788,10 +772,7 @@ dse_step0 (void) init_alias_analysis (); - if (clear_alias_sets) -clear_alias_group = get_group_info (NULL); - else -clear_alias_group = NULL; + clear_alias_group = NULL; } @@ -1189,39 +1170,6 @@ canon_address (rtx mem, rtx expanded_address, address; int expanded; - /* Make sure that cselib is has initialized all of the operands of - the address before asking it to do the subst. */ - - if (clear_alias_sets) -{ - /* If this is a spill, do not do any further processing. */ - alias_set_type alias_set = MEM_ALIAS_SET (mem); - if (dump_file (dump_flags TDF_DETAILS)) - fprintf (dump_file, found alias set %d\n, (int) alias_set); - if (bitmap_bit_p (clear_alias_sets, alias_set)) - { - struct clear_alias_mode_holder *entry - = clear_alias_set_lookup (alias_set); - - /* If the modes do not match, we cannot process this set. */ - if (entry-mode != GET_MODE (mem)) - { - if (dump_file (dump_flags TDF_DETAILS)) - fprintf (dump_file, -disqualifying alias set %d, (%s) != (%s)\n, -(int) alias_set, GET_MODE_NAME (entry-mode), -GET_MODE_NAME (GET_MODE (mem))); - - bitmap_set_bit (disqualified_clear_alias_sets, alias_set); - return false; - } - - *alias_set_out = alias_set; - *group_id = clear_alias_group-id; - return true; - } -} - *alias_set_out = 0; cselib_lookup (mem_address, address_mode, 1, GET_MODE (mem)); @@ -2993,47 +2941,6 @@ dse_step2_nospill (void) } -/* Init the offset tables for the spill case. */ - -static bool -dse_step2_spill (void) -{ - unsigned int j; - group_info_t group = clear_alias_group; - bitmap_iterator bi; - - /* Position 0 is unused because 0 is used in the maps to mean - unused. */ - current_position = 1; - - if (dump_file (dump_flags TDF_DETAILS)) -{ - bitmap_print (dump_file, clear_alias_sets, - clear alias sets , \n); - bitmap_print (dump_file, disqualified_clear_alias_sets, - disqualified clear alias sets , \n); -} - - memset (group-offset_map_n, 0, sizeof(int) * group-offset_map_size_n); - memset (group-offset_map_p, 0, sizeof(int) * group-offset_map_size_p); - bitmap_clear (group-group_kill); - - /* Remove the disqualified positions from the store2_p set. */ - bitmap_and_compl_into (group-store2_p, disqualified_clear_alias_sets); - - /* We do not need to process the store2_n set because - alias_sets are
[Patch/ARM] Cortex-M4 core pipeline patch to tune LDR/STR pairs
Hello, The attached pipeline patch intends to turn following code generation ldr r5, [r4, #12] adds r2, r2, #16 str r5, [r3, #8] to ldr r5, [r4, #12] str r5, [r3, #8] adds r2, r2, #16 The reason is that the STR can be started from the second cycle of its preceding LDR which takes 2 cycles, as long as the result of LDR isn't used as memory address of STR. Tested with various benchmarks on Cortex-M4 MPS. Except one regression caused by register allocation, the others either show performance improvement or no change. Is it OK to trunk? BR, Terry 2013-03-29 Terry Guo terry@arm.com * gcc/config/arm/cortex-m4.md: New bypass to tune LDR/STR pairs.From 19dd8bdc9a03f78690700ded911e0cee66328c01 Mon Sep 17 00:00:00 2001 From: Terry Guo terry@arm.com Date: Wed, 27 Mar 2013 17:23:09 +0800 Subject: [PATCH] improve m4 pipeline description --- gcc/config/arm/cortex-m4.md |4 1 file changed, 4 insertions(+) diff --git a/gcc/config/arm/cortex-m4.md b/gcc/config/arm/cortex-m4.md index 187867b..47b0364 100644 --- a/gcc/config/arm/cortex-m4.md +++ b/gcc/config/arm/cortex-m4.md @@ -84,6 +84,10 @@ (eq_attr type store4)) cortex_m4_ex*5) +(define_bypass 1 cortex_m4_load1 + cortex_m4_store1_1,cortex_m4_store1_2 + arm_no_early_store_addr_dep) + ;; If the address of load or store depends on the result of the preceding ;; instruction, the latency is increased by one. -- 1.7.9.5
Re: [PATCH, i386, AVX2] Fix intrinsic name for _mm256_broadcastsi128_si256
OK. Thanks, Checked into trunk: http://gcc.gnu.org/ml/gcc-cvs/2013-03/msg00860.html and 4.8: http://gcc.gnu.org/ml/gcc-cvs/2013-03/msg00861.html K
[patch] PR56729
Hello, It looks like there are places in the middle end that use remove_insn on insns that are not actually emitted. This breaks the assert I added in df_insn_delete. The patch disables the assert for now. The comment before the assert is now even messier than before but I think it's better to explain why the assert cannot work than to remove the comment and the assert altogether. Bootstrappedtested on powerpc64-unknown-linux-gnu (also tested 32bits ppc). OK for trunk? Ciao! Steven PR middle-end/56729 * df-scan.c (df_insn_delete): Disable failing assert. Index: df-scan.c === --- df-scan.c (revision 197180) +++ df-scan.c (working copy) @@ -1158,8 +1158,17 @@ df_insn_delete (rtx insn) In any case, we expect BB to be non-NULL at least up to register allocation, so disallow a non-NULL BB up to there. Not perfect but better than nothing... */ - + /* ??? bb can also be NULL if lower-subreg.c:resolve_simple_mov emits + an insn into a sequence and then does delete_insn on it. Not sure + if that makes sense, but for now it means this assert cannot work. + See PR56738. + Disable for now but revisit before the end of GCC 4.9 stage1. */ +#if 0 gcc_checking_assert (bb != NULL || reload_completed); +#else + if (bb == NULL) +return; +#endif df_grow_bb_info (df_scan); df_grow_reg_info ();
Re: [PATCH][IRA] Analysis of register usage of functions for usage by IRA.
On 14/03/13 16:11, Vladimir Makarov wrote: On 03/14/2013 05:34 AM, Tom de Vries wrote: On 13/02/13 23:35, Vladimir Makarov wrote: Actually, I am done with it. In general, it is ok. Although I have some minors comments: Vladimir, Thanks for the review. I split the patch up into 10 patches, to facilitate further review: ... 0001-Add-command-line-option.patch 0002-Add-new-reg-note-REG_CALL_DECL.patch 0003-Add-implicit-parameter-to-find_all_hard_reg_sets.patch 0004-Add-TARGET_FN_OTHER_HARD_REG_USAGE-hook.patch 0005-Implement-TARGET_FN_OTHER_HARD_REG_USAGE-hook-for-ARM.patch 0006-Collect-register-usage-information.patch 0007-Use-collected-register-usage-information.patch 0008-Enable-by-default-at-O2-and-higher.patch 0009-Add-documentation.patch 0010-Add-test-case.patch ... I'll post these in reply to this email. In Changelog, you missed '* before cgraph.h: * haifa-sched.c (recompute_todo_spec, check_clobbered_conditions): Add new argument to find_all_hard_reg_sets call. cgraph.h (struct cgraph_node): Add function_used_regs, function_used_regs_initialized and function_used_regs_valid fields. Fixed (in the log of 0006-Collect-register-usage-information.patch). @@ -3391,6 +3394,7 @@ df_get_call_refs (struct df_collection_r } } else if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i) I'd remove the test of regs_invalidated_by_call. +TEST_HARD_REG_BIT (fn_reg_set_usage, i) /* no clobbers for regs that are the result of the call */ !TEST_HARD_REG_BIT (defs_generated, i) Fixed (in 0007-Use-collected-register-usage-information.patch). +static void +collect_fn_hard_reg_usage (void) +{ + rtx insn; + int i; + struct cgraph_node *node; + struct hard_reg_set_container other_usage; + + if (!flag_use_caller_save) +return; + + node = cgraph_get_node (current_function_decl); + gcc_assert (node != NULL); + + gcc_assert (!node-function_used_regs_initialized); + node-function_used_regs_initialized = 1; + + for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn)) +{ + HARD_REG_SET insn_used_regs; + + if (!NONDEBUG_INSN_P (insn)) +continue; + + find_all_hard_reg_sets (insn, insn_used_regs, false); + + if (CALL_P (insn) + !get_call_reg_set_usage (insn, insn_used_regs, call_used_reg_set)) +{ + CLEAR_HARD_REG_SET (node-function_used_regs); + return; +} + I'd put it before find_all_hard_reg_sets + IOR_HARD_REG_SET (node-function_used_regs, insn_used_regs); +} + insn_used_regs is set by both find_all_hard_reg_sets, and by get_call_reg_set_usage. If we move the IOR to before find_all_hard_reg_sets, we're using an undefined value. But you can ignore my two last 2 comments. The patch is ok for me for trunk at stage1. But I think you need a formal approval for df-scan.c, arm.c, mips.c, GCC testsuite expect files (lib/target-supports.exp and gcc.target/mips/mips.exp) as I am not a maintainer of these parts although these changes look ok for me. I'm assuming you've ok'ed patch 1, 2, 3, 4, 6, 8, 9 and the non-df-scan part of 7. I'll ask other maintainers about the other parts (5, 10 and the df-scan part of 7). Thanks, - Tom
[PATCH][01/10] -fuse-caller-save - Add command line option
Vladimir, This patch adds the -fuse-caller-save command line option. Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * common.opt (fuse-caller-save): New option. diff --git a/gcc/common.opt b/gcc/common.opt index bdbd3b6..d29b0a0 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2549,4 +2549,8 @@ Create a position independent executable z Driver Joined Separate +fuse-caller-save +Common Report Var(flag_use_caller_save) Optimization +Use caller save register across calls if possible + ; This comment is to ensure we retain the blank line above.
[PATCH][02/10] -fuse-caller-save - Add new reg-note REG_CALL_DECL
Vladimir, This patch addes the REG_CALL_DECL reg-note. Using the reg-note we are able to easily link call_insns to their corresponding declaration, even after the calls may have been split into an insn (set register to function address) and a call_insn (call register), which can happen for f.i. sh, and mips with -mabi-calls. Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * reg-notes.def (REG_NOTE (CALL_DECL)): New reg-note REG_CALL_DECL. * calls.c (expand_call, emit_library_call_value_1): Add REG_CALL_DECL reg-note. * combine.c (distribute_notes): Handle REG_CALL_DECL reg-note. * emit-rtl.c (try_split): Same. diff --git a/gcc/calls.c b/gcc/calls.c index cdab8e0..39571da 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -3158,6 +3158,19 @@ expand_call (tree exp, rtx target, int ignore) next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, flags, args_so_far); + if (flag_use_caller_save) + { + rtx last, datum = NULL_RTX; + if (fndecl != NULL_TREE) + { + datum = XEXP (DECL_RTL (fndecl), 0); + gcc_assert (datum != NULL_RTX + GET_CODE (datum) == SYMBOL_REF); + } + last = last_call_insn (); + add_reg_note (last, REG_CALL_DECL, datum); + } + /* If the call setup or the call itself overlaps with anything of the argument setup we probably clobbered our call address. In that case we can't do sibcalls. */ @@ -4185,6 +4198,14 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value, valreg, old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far); + if (flag_use_caller_save) +{ + rtx last, datum = orgfun; + gcc_assert (GET_CODE (datum) == SYMBOL_REF); + last = last_call_insn (); + add_reg_note (last, REG_CALL_DECL, datum); +} + /* Right-shift returned value if necessary. */ if (!pcc_struct_value TYPE_MODE (tfom) != BLKmode diff --git a/gcc/combine.c b/gcc/combine.c index acb4cb4..191eb71 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -13187,6 +13187,7 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, case REG_NORETURN: case REG_SETJMP: case REG_TM: + case REG_CALL_DECL: /* These notes must remain with the call. It should not be possible for both I2 and I3 to be a call. */ if (CALL_P (i3)) diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index e412bef..e4843fe 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3473,6 +3473,7 @@ try_split (rtx pat, rtx trial, int last) int probability; rtx insn_last, insn; int njumps = 0; + rtx call_insn = NULL_RTX; /* We're not good at redistributing frame information. */ if (RTX_FRAME_RELATED_P (trial)) @@ -3545,6 +3546,9 @@ try_split (rtx pat, rtx trial, int last) { rtx next, *p; + gcc_assert (call_insn == NULL_RTX); + call_insn = insn; + /* Add the old CALL_INSN_FUNCTION_USAGE to whatever the target may have explicitly specified. */ p = CALL_INSN_FUNCTION_USAGE (insn); @@ -3616,6 +3620,11 @@ try_split (rtx pat, rtx trial, int last) fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0))); break; + case REG_CALL_DECL: + gcc_assert (call_insn != NULL_RTX); + add_reg_note (call_insn, REG_NOTE_KIND (note), XEXP (note, 0)); + break; + default: break; } diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def index db61c09..f0b6dad 100644 --- a/gcc/reg-notes.def +++ b/gcc/reg-notes.def @@ -216,3 +216,8 @@ REG_NOTE (ARGS_SIZE) that the return value of a call can be used to reinitialize a pseudo reg. */ REG_NOTE (RETURNED) + +/* Used to mark a call with the function decl called by the call. + The decl might not be available in the call due to splitting of the call + insn. This note is a SYMBOL_REF. */ +REG_NOTE (CALL_DECL)
[PATCH][05/10] -fuse-caller-save - Implement TARGET_FN_OTHER_HARD_REG_USAGE hook for ARM
Richard, This patch series adds analysis of register usage of functions for usage by IRA. The original post is here ( http://gcc.gnu.org/ml/gcc-patches/2013-01/msg01234.html ). This patch implements the target hook TARGET_FN_OTHER_HARD_REG_USAGE for ARM. The target hook TARGET_FN_OTHER_HARD_REG_USAGE was introduced in the previous patch in this patch series. Build and reg-tested on ARM. OK for trunk? Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * config/arm/arm.c (TARGET_FN_OTHER_HARD_REG_USAGE): Redefine as arm_fn_other_hard_reg_usage. (arm_fn_other_hard_reg_usage): New function. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5f63a2e..341fa86 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -280,6 +280,7 @@ static unsigned arm_add_stmt_cost (void *data, int count, static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, bool op0_preserve_value); +static void arm_fn_other_hard_reg_usage (struct hard_reg_set_container *); /* Table of machine attributes. */ static const struct attribute_spec arm_attribute_table[] = @@ -649,6 +650,10 @@ static const struct attribute_spec arm_attribute_table[] = #define TARGET_CANONICALIZE_COMPARISON \ arm_canonicalize_comparison +#undef TARGET_FN_OTHER_HARD_REG_USAGE +#define TARGET_FN_OTHER_HARD_REG_USAGE \ + arm_fn_other_hard_reg_usage + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -3762,6 +3767,19 @@ arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, } } +/* Implement TARGET_FN_OTHER_HARD_REG_USAGE. */ + +static void +arm_fn_other_hard_reg_usage (struct hard_reg_set_container *regs) +{ + if (TARGET_AAPCS_BASED) +{ + /* For AAPCS, IP and CC can be clobbered by veneers inserted by the + linker. */ + SET_HARD_REG_BIT (regs-set, IP_REGNUM); + SET_HARD_REG_BIT (regs-set, CC_REGNUM); +} +} /* Define how to find the value returned by a function. */
[PATCH][03/10] -fuse-caller-save - Add implicit parameter to find_all_hard_reg_sets
Vladimir, This patch adds an implicit parameter to find_all_hard_reg_sets. Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * rtlanal.c (find_all_hard_reg_sets): Add bool implicit parameter and handle. * rtl.h (find_all_hard_reg_sets): Add bool parameter. * haifa-sched.c (recompute_todo_spec, check_clobbered_conditions): Add new argument to find_all_hard_reg_sets call. diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index c4591bfe..fe24d43 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -1271,7 +1271,7 @@ recompute_todo_spec (rtx next, bool for_backtrack) { HARD_REG_SET t; - find_all_hard_reg_sets (prev, t); + find_all_hard_reg_sets (prev, t, true); if (TEST_HARD_REG_BIT (t, regno)) return HARD_DEP; if (prev == pro) @@ -3041,7 +3041,7 @@ check_clobbered_conditions (rtx insn) if ((current_sched_info-flags DO_PREDICATION) == 0) return; - find_all_hard_reg_sets (insn, t); + find_all_hard_reg_sets (insn, t, true); restart: for (i = 0; i ready.n_ready; i++) diff --git a/gcc/rtl.h b/gcc/rtl.h index b9defcc..6486f20 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2038,7 +2038,7 @@ extern const_rtx set_of (const_rtx, const_rtx); extern void record_hard_reg_sets (rtx, const_rtx, void *); extern void record_hard_reg_uses (rtx *, void *); #ifdef HARD_CONST -extern void find_all_hard_reg_sets (const_rtx, HARD_REG_SET *); +extern void find_all_hard_reg_sets (const_rtx, HARD_REG_SET *, bool); #endif extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *); extern void note_uses (rtx *, void (*) (rtx *, void *), void *); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index b198685..27c1974 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1028,13 +1028,13 @@ record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) /* Examine INSN, and compute the set of hard registers written by it. Store it in *PSET. Should only be called after reload. */ void -find_all_hard_reg_sets (const_rtx insn, HARD_REG_SET *pset) +find_all_hard_reg_sets (const_rtx insn, HARD_REG_SET *pset, bool implicit) { rtx link; CLEAR_HARD_REG_SET (*pset); note_stores (PATTERN (insn), record_hard_reg_sets, pset); - if (CALL_P (insn)) + if (implicit CALL_P (insn)) IOR_HARD_REG_SET (*pset, call_used_reg_set); for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) if (REG_NOTE_KIND (link) == REG_INC)
[PATCH][06/10] -fuse-caller-save - Collect register usage information
Vladimir, This patch adds analysis in pass_final to track which hard registers are set or clobbered by the function body, and stores that information in a struct cgraph_node. Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * cgraph.h (struct cgraph_node): Add function_used_regs, function_used_regs_initialized and function_used_regs_valid fields. * final.c: Move include of hard-reg-set.h to before rtl.h to declare find_all_hard_reg_sets. (collect_fn_hard_reg_usage, get_call_fndecl, get_call_cgraph_node) (get_call_reg_set_usage): New function. (rest_of_handle_final): Use collect_fn_hard_reg_usage. diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 8ab7ae1..2132d91 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -251,6 +251,15 @@ struct GTY(()) cgraph_node { /* Unique id of the node. */ int uid; + /* Call unsaved hard registers really used by the corresponding + function (including ones used by functions called by the + function). */ + HARD_REG_SET function_used_regs; + /* Set if function_used_regs is initialized. */ + unsigned function_used_regs_initialized: 1; + /* Set if function_used_regs is valid. */ + unsigned function_used_regs_valid: 1; + /* Set when decl is an abstract function pointed to by the ABSTRACT_DECL_ORIGIN of a reachable function. */ unsigned abstract_and_needed : 1; diff --git a/gcc/final.c b/gcc/final.c index d25b8e0..4e0fd01 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see #include tm.h #include tree.h +#include hard-reg-set.h #include rtl.h #include tm_p.h #include regs.h @@ -56,7 +57,6 @@ along with GCC; see the file COPYING3. If not see #include recog.h #include conditions.h #include flags.h -#include hard-reg-set.h #include output.h #include except.h #include function.h @@ -222,6 +222,7 @@ static int alter_cond (rtx); static int final_addr_vec_align (rtx); #endif static int align_fuzz (rtx, rtx, int, unsigned); +static void collect_fn_hard_reg_usage (void); /* Initialize data in final at the beginning of a compilation. */ @@ -4328,6 +4329,8 @@ rest_of_handle_final (void) rtx x; const char *fnname; + collect_fn_hard_reg_usage (); + /* Get the function's name, as described by its RTL. This may be different from the DECL_NAME name used in the source file. */ @@ -4584,3 +4587,121 @@ struct rtl_opt_pass pass_clean_state = 0 /* todo_flags_finish */ } }; + +/* Collect hard register usage for the current function. */ + +static void +collect_fn_hard_reg_usage (void) +{ + rtx insn; + int i; + struct cgraph_node *node; + struct hard_reg_set_container other_usage; + + if (!flag_use_caller_save) +return; + + node = cgraph_get_node (current_function_decl); + gcc_assert (node != NULL); + + gcc_assert (!node-function_used_regs_initialized); + node-function_used_regs_initialized = 1; + + for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn)) +{ + HARD_REG_SET insn_used_regs; + + if (!NONDEBUG_INSN_P (insn)) + continue; + + find_all_hard_reg_sets (insn, insn_used_regs, false); + + if (CALL_P (insn) + !get_call_reg_set_usage (insn, insn_used_regs, call_used_reg_set)) + { + CLEAR_HARD_REG_SET (node-function_used_regs); + return; + } + + IOR_HARD_REG_SET (node-function_used_regs, insn_used_regs); +} + + /* Be conservative - mark fixed and global registers as used. */ + IOR_HARD_REG_SET (node-function_used_regs, fixed_reg_set); + for (i = 0; i FIRST_PSEUDO_REGISTER; i++) +if (global_regs[i]) + SET_HARD_REG_BIT (node-function_used_regs, i); + +#ifdef STACK_REGS + /* Handle STACK_REGS conservatively, since the df-framework does not + provide accurate information for them. */ + + for (i = FIRST_STACK_REG; i = LAST_STACK_REG; i++) +SET_HARD_REG_BIT (node-function_used_regs, i); +#endif + + CLEAR_HARD_REG_SET (other_usage.set); + targetm.fn_other_hard_reg_usage (other_usage); + IOR_HARD_REG_SET (node-function_used_regs, other_usage.set); + + node-function_used_regs_valid = 1; +} + +/* Get the declaration of the function called by INSN. */ + +static tree +get_call_fndecl (rtx insn) +{ + rtx note, datum; + + if (!flag_use_caller_save) +return NULL_TREE; + + note = find_reg_note (insn, REG_CALL_DECL, NULL_RTX); + if (note == NULL_RTX) +return NULL_TREE; + + datum = XEXP (note, 0); + if (datum != NULL_RTX) +return SYMBOL_REF_DECL (datum); + + return NULL_TREE; +} + +static struct cgraph_node * +get_call_cgraph_node (rtx insn) +{ + tree fndecl; + + if (insn == NULL_RTX) +return NULL; + + fndecl = get_call_fndecl (insn);
[PATCH][04/10] -fuse-caller-save - Add TARGET_FN_OTHER_HARD_REG_USAGE hook
Vladimir, This patch adds a TARGET_FN_OTHER_HARD_REG_USAGE hook. The hook is used to list hard registers that are set or clobbered by a call to a function, but are not listed as such in the function body, such as f.i. registers clobbered by veneers inserted by the linker. Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * hooks.c (hook_void_hard_reg_set_containerp): New function. * hooks.h (hook_void_hard_reg_set_containerp): Declare. * target.def (fn_other_hard_reg_usage): New DEFHOOK. * doc/tm.texi.in (@node Stack and Calling): Add Miscellaneous Register Hooks to @menu. (@node Miscellaneous Register Hooks): New node. (@hook TARGET_FN_OTHER_HARD_REG_USAGE): New hook. * doc/tm.texi: Regenerate. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index cbbc82d..3bf7abe 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3074,6 +3074,7 @@ This describes the stack layout and calling conventions. * Profiling:: * Tail Calls:: * Stack Smashing Protection:: +* Miscellaneous Register Hooks:: @end menu @node Frame Layout @@ -4999,6 +5000,14 @@ normally defined in @file{libgcc2.c}. Whether this target supports splitting the stack when the options described in @var{opts} have been passed. This is called after options have been parsed, so the target may reject splitting the stack in some configurations. The default version of this hook returns false. If @var{report} is true, this function may issue a warning or error; if @var{report} is false, it must simply return a value @end deftypefn +@node Miscellaneous Register Hooks +@subsection Miscellaneous register hooks +@cindex miscellaneous register hooks + +@deftypefn {Target Hook} void TARGET_FN_OTHER_HARD_REG_USAGE (struct hard_reg_set_container *@var{regs}) +Add any hard registers to @var{regs} that are set or clobbered by a call to the function. This hook only needs to be defined to provide registers that cannot be found by examination of the final RTL representation of a function. +@end deftypefn + @node Varargs @section Implementing the Varargs Macros @cindex varargs implementation diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index dfba947..4dfd8aa 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3042,6 +3042,7 @@ This describes the stack layout and calling conventions. * Profiling:: * Tail Calls:: * Stack Smashing Protection:: +* Miscellaneous Register Hooks:: @end menu @node Frame Layout @@ -4922,6 +4923,12 @@ normally defined in @file{libgcc2.c}. @hook TARGET_SUPPORTS_SPLIT_STACK +@node Miscellaneous Register Hooks +@subsection Miscellaneous register hooks +@cindex miscellaneous register hooks + +@hook TARGET_FN_OTHER_HARD_REG_USAGE + @node Varargs @section Implementing the Varargs Macros @cindex varargs implementation diff --git a/gcc/hooks.c b/gcc/hooks.c index 3b54dfa..e038a95 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -446,3 +446,11 @@ void hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED) { } + +/* Generic hook that takes a struct hard_reg_set_container * and returns + void. */ + +void +hook_void_hard_reg_set_containerp (struct hard_reg_set_container *regs ATTRIBUTE_UNUSED) +{ +} diff --git a/gcc/hooks.h b/gcc/hooks.h index 50bcc6a..44decdf 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -69,6 +69,7 @@ extern void hook_void_tree (tree); extern void hook_void_tree_treeptr (tree, tree *); extern void hook_void_int_int (int, int); extern void hook_void_gcc_optionsp (struct gcc_options *); +extern void hook_void_hard_reg_set_containerp (struct hard_reg_set_container *); extern int hook_int_uint_mode_1 (unsigned int, enum machine_mode); extern int hook_int_const_tree_0 (const_tree); diff --git a/gcc/target.def b/gcc/target.def index 831cad8..e8f7c4a 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2850,6 +2850,17 @@ DEFHOOK void, (bitmap regs), hook_void_bitmap) +/* For targets that need to mark extra registers as clobbered on entry to + the function, they should define this target hook and set their + bits in the struct hard_reg_set_container passed in. */ +DEFHOOK +(fn_other_hard_reg_usage, + Add any hard registers to @var{regs} that are set or clobbered by a call to\ + the function. This hook only needs to be defined to provide registers that\ + cannot be found by examination of the final RTL representation of a function., + void, (struct hard_reg_set_container *regs), + hook_void_hard_reg_set_containerp) + /* Fill in additional registers set up by prologue into a regset. */ DEFHOOK (set_up_by_prologue,
[PATCH][07/10] -fuse-caller-save - Use collected register usage information
Paolo, This patch series adds analysis of register usage of functions for usage by IRA. The original post is here ( http://gcc.gnu.org/ml/gcc-patches/2013-01/msg01234.html ). This patch uses the information of which registers are clobbered by a call in IRA and df-scan. Bootstrapped and reg-tested on x86_64, Ada inclusive. Build and reg-tested on mips, arm, ppc and sh. Can you approve the df-scan part for trunk? Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * df-scan.c (df_get_call_refs): Use get_call_reg_set_usage. * caller-save.c (setup_save_areas, save_call_clobbered_regs): Use get_call_reg_set_usage. * resource.c (mark_set_resources, mark_target_live_regs): Use get_call_reg_set_usage. * ira-int.h (struct ira_allocno): Add crossed_calls_clobbered_regs field. (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS): Define. * ira-lives.c (process_bb_node_lives): Use get_call_reg_set_usage. Calculate ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS. * ira-build.c (ira_create_allocno): Init ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS. (create_cap_allocno, propagate_allocno_info) (propagate_some_info_from_allocno) (copy_info_to_removed_store_destinations): Handle ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS. * ira-costs.c (ira_tune_allocno_costs): Use ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS to adjust costs. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 5e65294..39d75ad 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -441,7 +441,7 @@ setup_save_areas (void) freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (insn)); REG_SET_TO_HARD_REG_SET (hard_regs_to_save, chain-live_throughout); - COPY_HARD_REG_SET (used_regs, call_used_reg_set); + get_call_reg_set_usage (insn, used_regs, call_used_reg_set); /* Record all registers set in this call insn. These don't need to be saved. N.B. the call insn might set a subreg @@ -525,7 +525,7 @@ setup_save_areas (void) REG_SET_TO_HARD_REG_SET (hard_regs_to_save, chain-live_throughout); - COPY_HARD_REG_SET (used_regs, call_used_reg_set); + get_call_reg_set_usage (insn, used_regs, call_used_reg_set); /* Record all registers set in this call insn. These don't need to be saved. N.B. the call insn might set a subreg @@ -804,6 +804,7 @@ save_call_clobbered_regs (void) { unsigned regno; HARD_REG_SET hard_regs_to_save; + HARD_REG_SET call_def_reg_set; reg_set_iterator rsi; rtx cheap; @@ -854,7 +855,9 @@ save_call_clobbered_regs (void) AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); - AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set); + get_call_reg_set_usage (insn, call_def_reg_set, + call_used_reg_set); + AND_HARD_REG_SET (hard_regs_to_save, call_def_reg_set); for (regno = 0; regno FIRST_PSEUDO_REGISTER; regno++) if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) diff --git a/gcc/df-scan.c b/gcc/df-scan.c index fdfa931..898454c 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -3398,10 +3398,13 @@ df_get_call_refs (struct df_collection_rec *collection_rec, bool is_sibling_call; unsigned int i; HARD_REG_SET defs_generated; + HARD_REG_SET fn_reg_set_usage; CLEAR_HARD_REG_SET (defs_generated); df_find_hard_reg_defs (PATTERN (insn_info-insn), defs_generated); is_sibling_call = SIBLING_CALL_P (insn_info-insn); + get_call_reg_set_usage (insn_info-insn, fn_reg_set_usage, + regs_invalidated_by_call); for (i = 0; i FIRST_PSEUDO_REGISTER; i++) { @@ -3425,7 +3428,7 @@ df_get_call_refs (struct df_collection_rec *collection_rec, NULL, bb, insn_info, DF_REF_REG_DEF, flags); } } - else if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i) + else if (TEST_HARD_REG_BIT (fn_reg_set_usage, i) /* no clobbers for regs that are the result of the call */ !TEST_HARD_REG_BIT (defs_generated, i) (!is_sibling_call diff --git a/gcc/ira-build.c b/gcc/ira-build.c index b1e481b..054139a 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -507,6 +507,7 @@ ira_create_allocno (int regno, bool cap_p, ALLOCNO_CALL_FREQ (a) = 0; ALLOCNO_CALLS_CROSSED_NUM (a) = 0; ALLOCNO_CHEAP_CALLS_CROSSED_NUM (a) = 0; + CLEAR_HARD_REG_SET (ALLOCNO_CROSSED_CALLS_CLOBBERED_REGS (a)); #ifdef STACK_REGS ALLOCNO_NO_STACK_REG_P (a) = false; ALLOCNO_TOTAL_NO_STACK_REG_P (a) = false; @@ -904,6 +905,8 @@ create_cap_allocno (ira_allocno_t a) ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a);
[PATCH][08/10] -fuse-caller-save - Enable by default at O2 and higher
Vladimir, This patch enables the -fuse-caller-save optimization by default. Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * opts.c (default_options_table): Add OPT_LEVELS_2_PLUS entry with OPT_fuse_caller_save. diff --git a/gcc/opts.c b/gcc/opts.c index 45b12fe..52a42b9 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -486,6 +486,7 @@ static const struct default_options default_options_table[] = { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 }, { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 }, { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 }, +{ OPT_LEVELS_2_PLUS, OPT_fuse_caller_save, NULL, 1 }, /* -O3 optimizations. */ { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
[PATCH][09/10] -fuse-caller-save - Add documentation
Vladimir, This patch adds the documentation of -fuse-caller-save. Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * doc/invoke.texi (@item Optimization Options): Add -fuse-caller-save to gccoptlist. (@item -fuse-caller-save): New item. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 475dcf0..efb8a1a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -421,8 +421,8 @@ Objective-C and Objective-C++ Dialects}. -ftree-ter -ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol -funit-at-a-time -funroll-all-loops -funroll-loops @gol -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol --fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol --fwhole-program -fwpa -fuse-ld=@var{linker} -fuse-linker-plugin @gol +-fuse-caller-save -fvariable-expansion-in-unroller -fvect-cost-model -fvpt @gol +-fweb -fwhole-program -fwpa -fuse-ld=@var{linker} -fuse-linker-plugin @gol --param @var{name}=@var{value} -O -O0 -O1 -O2 -O3 -Os -Ofast -Og} @@ -7382,6 +7382,14 @@ and then tries to find ways to combine them. Enabled by default at @option{-O1} and higher. +@item -fuse-caller-save +Use caller save registers for allocation if those registers are not used by +any called function. In that case it is not necessary to save and restore +them around calls. This is only possible if called functions are part of +same compilation unit as current function and they are compiled before it. + +Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}. + @item -fconserve-stack @opindex fconserve-stack Attempt to minimize stack usage. The compiler attempts to use less
[PATCH][10/10] -fuse-caller-save - Add test-case
Richard, This patch series adds analysis of register usage of functions for usage by IRA. The original post is here ( http://gcc.gnu.org/ml/gcc-patches/2013-01/msg01234.html ). This patch adds a test-case for -fuse-caller-save. Since the test-case has different output for mips16 and micromips, new effective targets are introduced. Build and reg-tested on mips. OK for trunk? Thanks, -Tom 2013-03-29 Radovan Obradovic robrado...@mips.com Tom de Vries t...@codesourcery.com * lib/target-supports.exp (check_effective_target_mips16) (check_effective_target_micromips): New proc. * gcc.target/mips/mips.exp: Add use-caller-save to -ffoo/-fno-foo options. Add -save-temps to mips_option_groups. * gcc.target/mips/aru-1.c: New test. diff --git a/gcc/testsuite/gcc.target/mips/aru-1.c b/gcc/testsuite/gcc.target/mips/aru-1.c new file mode 100644 index 000..71515a9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/aru-1.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options -fuse-caller-save -save-temps } */ +/* { dg-skip-if { *-*-* } { * } { -Os } } */ +/* Testing -fuse-caller-save optimization option. */ + +static int __attribute__((noinline)) +bar (int x) +{ + return x + 3; +} + +int __attribute__((noinline)) +foo (int y) +{ + return y + bar (y); +} + +int +main (void) +{ + return !(foo (5) == 13); +} + +/* Check that there are only 2 stack-saves: r31 in main and foo. */ + +/* Variant not mips16. Check that there only 2 sw/sd. */ +/* { dg-final { scan-assembler-times (?n)s\[wd\]\t\\\$.*,.*\\(\\\$sp\\) 2 { target { ! mips16 } } } } */ + +/* Variant not mips16, Subvariant micromips. Additionally check there's no + swm. */ +/* { dg-final { scan-assembler-times (?n)swm\t\\\$.*,.*\\(\\\$sp\\) 0 {target micromips } } } */ + +/* Variant mips16. The save can save 1 or more registers, check that only 1 is + saved, twice in total. */ +/* { dg-final { scan-assembler-times (?n)save\t\[0-9\]*,\\\$\[^,\]*\$ 2 { target mips16 } } } */ + +/* Check that the first caller-save register is unused. */ +/* { dg-final { scan-assembler-not (\\\$16) } } */ diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index 15b1386..63570bd 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -246,6 +246,7 @@ set mips_option_groups { small-data -G[0-9]+ warnings -w dump -fdump-.* +save_temps -save-temps } # Add -mfoo/-mno-foo options to mips_option_groups. @@ -302,6 +303,7 @@ foreach option { tree-vectorize unroll-all-loops unroll-loops +use-caller-save } { lappend mips_option_groups $option -f(no-|)$option } diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index a146f17..dbd0037 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -918,6 +918,26 @@ proc check_effective_target_mips16_attribute { } { } [add_options_for_mips16_attribute ]] } +# Return 1 if the target generates mips16 code by default. + +proc check_effective_target_mips16 { } { +return [check_no_compiler_messages mips16 assembly { + #if !(defined __mips16) + #error FOO + #endif +} ] +} + +# Return 1 if the target generates micromips code by default. + +proc check_effective_target_micromips { } { +return [check_no_compiler_messages micromips assembly { + #if !(defined __mips_micromips) + #error FOO + #endif +} ] +} + # Return 1 if the target supports long double larger than double when # using the new ABI, 0 otherwise.
Re: [patch, fortran, 4.9] Improve efficiency of array constructor operators
I wrote: PS: Regarding the string comparison patch: As Janne, think it should be fine with also supporting kind=4 (don't forget to multiply the length by the kind, e.g. ts.kind or more properly (but equivalently) gfc_character_kinds[index].bit_size/BITS_PER_BYTE). I'll do that. Oops, it turns out we can't do this, at least not on little-endian systems. Consider: #include stdio.h int main() { unsigned int i,j; i = 0x102; j = 0x201; printf(%d %d\n, ij, memcmp(i, j, sizeof(i))); return 0; } On a little-endian system, the output is 0 1 because i = 02 01 00 00 and j = 01 02 00 00 (in hex). So, is the original patch OK for trunk? Thomas
[lto patch, committed as obvious] PR 56777
Hi, committed mainline and 4_8-branch. Paolo. / 2013-03-29 Paolo Carlini paolo.carl...@oracle.com PR lto/56777 * doc/invoke.texi ([-fwhole-program]): Fix typo. Index: doc/invoke.texi === --- doc/invoke.texi (revision 197230) +++ doc/invoke.texi (working copy) @@ -8179,7 +8179,7 @@ and those merged by attribute @code{externally_visible} become static functions and in effect are optimized more aggressively by interprocedural optimizers. -In combination with @code{-flto} using this option should not be used. +This option should not be used in combination with @code{-flto}. Instead relying on a linker plugin should provide safer and more precise information.
Re: [patch] Remove unused code from dse.c.
On 03/29/2013 02:24 AM, Lawrence Crowl wrote: This patch has been in the hash-table branch for months. I thought it didn't quite meet the criteria for obvious, but it's close. In dse.c, remove alias hash tables that are never set. Remove conditions that are then never true. Remove functions that are then never called. Remove variables that are then never read. Tested on x86-64. Index: gcc/ChangeLog 2013-03-29 Lawrence Crowl cr...@google.com * dse.c (clear_alias_sets): Remove never set. (disqualified_clear_alias_sets): Remove never set. (clear_alias_mode_pool): Remove never set. (dse_step0): Remove condition that is never true. (canon_address): Remove condition that is never true. (dse_step7): Remove condition that is never true. (rest_of_handle_dse): Remove condition that is never true. (rest_of_handle_dse::did_global): Remove never read from above. (dse_step2_spill): Remove never called from above. (dse_step5_spill): Remove never called from above. At what point did we stop setting clear_alias_sets? Was that intentional or not? If that was an intentional change, then this patchset is OK as-is. If losing the setting of clear_alias_sets was accidental, then I think we'll need to dig a bit further. The whole point of that code is to prevent wild reads from killing the spill slot stores being tracked. Of course with IRA/LRA all this may not be as important as it once was. Jeff
Re: [patch, fortran, 4.9] Improve efficiency of array constructor operators
Am 29.03.2013 14:42, schrieb Thomas Koenig: I wrote: PS: Regarding the string comparison patch: As Janne, think it should be fine with also supporting kind=4 (don't forget to multiply the length by the kind, e.g. ts.kind or more properly (but equivalently) gfc_character_kinds[index].bit_size/BITS_PER_BYTE). I'll do that. Oops, it turns out we can't do this, at least not on little-endian systems. I somehow completely missed that is permitted for characters.* Thanks for the reminder. Actually, we still can do use memcpy for == and /= - but admittedly not for , =, = and =. Thus, how about using memcmp for kind=4 for == and /= only - and for kind=1 also for , etc.? Side note: The elemental intrinsic functions lge, lgt, lle and llt work likewise. Thus, they could also profit from the same optimization. However, I do not know whether anyone one uses these. The difference between and llt() seems to be that llt takes a default-kind (or F2008: also ASCII kind) and uses the ASCII collating sequence while etc use the collating sequence. As our default-kind character is the ASCII character, the distinction does not matter. Tobias * For , = etc., see Fortran 2003, 7.2.3 Relational intrinsic operations, 7th paragraph; Fortran 2008, 9th paragraph of 7.1.5.5.1 Interpretation of relational intrinsic operations
Ping on PowerPC PR55033
Hi Would it be possible for a PowerPC maintainer to look into committing the fix to this PR to the impacted branches which are open? http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55033 http://gcc.gnu.org/ml/gcc-patches/2013-03/msg00970.html Thanks. -- Joel Sherrill, Ph.D. Director of Research Development joel.sherr...@oarcorp.comOn-Line Applications Research Ask me about RTEMS: a free RTOS Huntsville AL 35805 Support Available(256) 722-9985
C++ PATCH: Use VAR_P instead of direct TREE_CODE (t) == VAR_DECL
This patch introduces the predicate VAR_P and use it in place of direct TREE_CODE (t) == VAR_DECL It improves readability and makes predicates easier to follow. Tested on an x86_64-suse-linux. Applying to trunk. -- Gaby 2013-03-29 Gabriel Dos Reis g...@integrable-solutions.net * tree.h (VAR_P): New. cp/ChangeLog 2013-03-29 Gabriel Dos Reis g...@integrable-solutions.net * call.c (build_java_interface_fn_ref): Likewise. (make_temporary_var_for_ref_to_temp): Likewise. * class.c (check_field_decls): Likewise. (layout_class_type): Likewise. (finish_struct_1): Likewise. (fixed_type_or_null): Likewise. (get_vtbl_decl_for_binfo): Likewise. * cp-gimplify.c (omp_var_to_track): Likewise. (cp_genericize_r): Likewise. * cp-objcp-common.c (cxx_warn_unused_global_decl): Likewise. * cp-tree.h (LANG_DECL_HAS_MIN): Likewise. (DECL_DISCRIMINATOR_P): Likewise. * decl.c (poplevel): Likewise. (decls_match): Likewise. (duplicate_decls): Likewise. (decl_jump_unsafe): Likewise. (start_decl): Likewise. (check_for_uninitialized_const_var): Likewise. (make_rtl_for_nonlocal_decl): Likewise. (cp_finish_decl): Likewise. (expand_static_init): Likewise. (local_variable_p): Likewise. (maybe_register_incomplete_var): Likewise. * decl2.c (grokfield): Likewise. (comdat_linkage): Likewise. (determine_visibility): Likewise. (import_export_decl): Likewise. (prune_vars_needing_no_initialization): Likewise. (decl_maybe_constant_var_p): Likewise. * error.c (dump_simple_decl): Likewise. (dump_template_decl): Likewise. (cp_printer): Likewise. * except.c (build_throw): Likewise. * init.c (build_vtbl_address): Likewise. (member_init_ok_or_else): Likewise. (build_aggr_init): Likewise. (expand_aggr_init_1): Likewise. (build_offset_ref): Likewise. (constant_value_1): Likewise. * mangle.c (write_mangled_name): Likewise. (write_prefix): Likewise. * name-lookup.c (supplement_binding_1): Likewise. (add_decl_to_level): Likewise. (pushdecl_maybe_friend_1): Likewise. (check_for_out_of_scope_variable): Likewise. (validate_nonmember_using_decl): Likewise. (lookup_name_innermost_nonclass_level_1): Likewise. (lookup_arg_dependent_1): Likewise. * parser.c (cp_parser_lambda_introducer): Likewise. (cp_parser_template_argument): Likewise. (cp_parser_single_declaration): Likewise. * pt.c (convert_nontype_argument): Likewise. (instantiate_class_template_1): Likewise. (tsubst_decl): Likewise. (tsubst_expr): Likewise. (do_decl_instantiation): Likewise. (do_type_instantiation): Likewise. (regenerate_decl_from_template): Likewise. (always_instantiate_p): Likewise. (instantiate_decl): Likewise. (type_dependent_expression_p): Likewise. (build_non_dependent_expr): Likewise. * repo.c (repo_emit_p): Likewise. * rtti.c (build_dynamic_cast_1): Likewise. * search.c (shared_member_p): Likewise. * semantics.c (outer_var_p): Likewise. (finish_id_expression): Likewise. (finish_omp_clauses): Likewise. (finish_decltype_type): Likewise. (ensure_literal_type_for_constexpr_object): Likewise. * tree.c (lvalue_kind): Likewise. (bot_replace): Likewise. (cp_tree_equal): Likewise. (handle_init_priority_attribute): Likewise. (decl_storage_duration): Likewise. * typeck.c (cxx_sizeof_expr): Likewise. (cxx_alignof_expr): Likewise. (decay_conversion): Likewise. (build_class_member_access_expr): Likewise. (cp_build_array_ref): Likewise. (cxx_mark_addressable): Likewise. (maybe_warn_about_returning_address_of_local): Likewise. (check_return_expr): Likewise. * typeck2.c (cxx_readonly_error): Likewise. (abstract_virtuals_error_sfinae): Likewise. (cxx_incomplete_type_diagnostic): Likewise. Index: gcc/cp/call.c === --- gcc/cp/call.c (revision 197239) +++ gcc/cp/call.c (working copy) @@ -7162,7 +7162,7 @@ /* Get the java.lang.Class pointer for the interface being called. */ iface = DECL_CONTEXT (fn); iface_ref = lookup_field (iface, get_identifier (class$), 0, false); - if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL + if (!iface_ref || !VAR_P (iface_ref) || DECL_CONTEXT (iface_ref) != iface) { error (could not find class$ field in java interface type %qT, @@ -9009,7 +9009,7 @@ var = create_temporary_var (type); /* Register the variable. */ - if (TREE_CODE (decl) == VAR_DECL + if (VAR_P
[c++-concepts] Default to C++1y
Andrew, As we discussed a couple of days ago, this patch defaults us to C++1y. Applied to branch. -- Gaby 2013-03-29 Gabriel Dos Reis g...@integrable-solutions.net * c-common.c (cxx_dialect): Default to C++1y. Index: gcc/c-family/c-common.c === --- gcc/c-family/c-common.c (revision 197241) +++ gcc/c-family/c-common.c (working copy) @@ -240,7 +240,7 @@ /* The C++ dialect being used. C++11 is the default. */ -enum cxx_dialect cxx_dialect = cxx11; +enum cxx_dialect cxx_dialect = cxx1y; /* Maximum template instantiation depth. This limit exists to limit the time it takes to notice excessively recursive template instantiations.
Re: [c++concepts] Reducing requirements
Andrew Sutton andrew.n.sut...@gmail.com writes: | Implements reduction of requirements into the constraints language: | logical formulas comprised of atomic propositions. Calls to constraint | predicates are recursively inlined in the resulting expression. All | other calls are treated as atoms. | | 2013-03-01 Andrew Sutton andrew.n.sut...@gmail.com | | * gcc/cp/Makefile.lang.in: Add constraints.o target. Wrong filename. It should be gcc/cp/Make-lang.in. [...] Index: constraint.cc === --- constraint.cc (revision 0) +++ constraint.cc (revision 0) @@ -0,0 +1,450 @@ +/* Process declarations and variables for C++ compiler. + Copyright (C) 1988-2013 Free Software Foundation, Inc. + Contributed by Michael Tiemann (tiem...@cygnus.com) This file is newly introduced, so the copyright date should be 2013. It is being contributed by Andrew Sutton if I am not mistaken :-) Patch OK to commit with these issues fixed. -- Gaby
Re: [c++concepts] Reducing requirements
Andrew Sutton andrew.n.sut...@gmail.com writes: | Implements reduction of requirements into the constraints language: | logical formulas comprised of atomic propositions. Calls to constraint | predicates are recursively inlined in the resulting expression. All | other calls are treated as atoms. | | 2013-03-01 Andrew Sutton andrew.n.sut...@gmail.com Forgot to add: the ChangeLog goes into ChangeLog.concepts. -- Gaby
Re: C++ PATCH: Use VAR_P instead of direct TREE_CODE (t) == VAR_DECL
Hi, On 03/29/2013 04:59 PM, Gabriel Dos Reis wrote: This patch introduces the predicate VAR_P and use it in place of direct TREE_CODE (t) == VAR_DECL It improves readability and makes predicates easier to follow. Tested on an x86_64-suse-linux. Applying to trunk. Thanks. Do you think it would also make sense to consistently use in C++ front-end TYPE_PTR_P instead of TREE_CODE (t) == POINTER_TYPE? It's something I noticed a while ago when I cleaned-up predicated related to pointers and occurred to me again now that you are doing some of this kind of work. If you like I can do this bit. Thanks, Paolo.
Re: C++ PATCH: Use VAR_P instead of direct TREE_CODE (t) == VAR_DECL
Paolo Carlini paolo.carl...@oracle.com writes: | Hi, | | On 03/29/2013 04:59 PM, Gabriel Dos Reis wrote: | This patch introduces the predicate VAR_P and use it in place of direct | | TREE_CODE (t) == VAR_DECL | | It improves readability and makes predicates easier to follow. | Tested on an x86_64-suse-linux. Applying to trunk. | Thanks. | | Do you think it would also make sense to consistently use in C++ | front-end TYPE_PTR_P instead of TREE_CODE (t) == POINTER_TYPE? It's | something I noticed a while ago when I cleaned-up predicated related | to pointers and occurred to me again now that you are doing some of | this kind of work. If you like I can do this bit. | | Thanks, | Paolo. Yes, you are absolutely right. Thanks for volunteering. -- Gaby
DOC PATCH: document var-template branch
as the $(Subject) says. -- Gaby Index: svn.html === RCS file: /cvs/gcc/wwwdocs/htdocs/svn.html,v retrieving revision 1.179 diff -r1.179 svn.html 515a516,520 dtvar-template/dt ddThis branch is for implementation work on emvariable template for C++/em. It is maintained by a href=mailto:g...@gcc.gnu.org;Gabriel Dos Reis/a./dd
Re: [patch] Remove unused code from dse.c.
On 3/29/13, Jeff Law l...@redhat.com wrote: On 03/29/2013 02:24 AM, Lawrence Crowl wrote: This patch has been in the hash-table branch for months. I thought it didn't quite meet the criteria for obvious, but it's close. In dse.c, remove alias hash tables that are never set. Remove conditions that are then never true. Remove functions that are then never called. Remove variables that are then never read. Tested on x86-64. Index: gcc/ChangeLog 2013-03-29 Lawrence Crowl cr...@google.com * dse.c (clear_alias_sets): Remove never set. (disqualified_clear_alias_sets): Remove never set. (clear_alias_mode_pool): Remove never set. (dse_step0): Remove condition that is never true. (canon_address): Remove condition that is never true. (dse_step7): Remove condition that is never true. (rest_of_handle_dse): Remove condition that is never true. (rest_of_handle_dse::did_global): Remove never read from above. (dse_step2_spill): Remove never called from above. (dse_step5_spill): Remove never called from above. At what point did we stop setting clear_alias_sets? Was that intentional or not? I do not know the answer to either question. If that was an intentional change, then this patchset is OK as-is. If losing the setting of clear_alias_sets was accidental, then I think we'll need to dig a bit further. The whole point of that code is to prevent wild reads from killing the spill slot stores being tracked. Of course with IRA/LRA all this may not be as important as it once was. My view is that we have already lost the feature. The code that populates the set is gone. The remaining code has probably suffered bitrot because it is not being tested. Trying to recreate the population will probably result in inconsistencies anyway, necessitating a rewrite of the remaining code. So, the remaining code has little value, and might have negative value. -- Lawrence Crowl
Re: [patch] Remove unused code from dse.c.
On 03/29/2013 11:24 AM, Lawrence Crowl wrote: At what point did we stop setting clear_alias_sets? Was that intentional or not? I do not know the answer to either question. That's what needs to be determined before I'll approve. It means digging a bit. My view is that we have already lost the feature. The code that populates the set is gone. The remaining code has probably suffered bitrot because it is not being tested. Trying to recreate the population will probably result in inconsistencies anyway, necessitating a rewrite of the remaining code. So, the remaining code has little value, and might have negative value. But that doesn't mean dropping the code is the right thing to do. The right thing to do is see if the feature was dropped on purpose. If so, then we remove this dead code. If not, then we fix the real problem, namely the code was accidentally disabled (and add suitable tests to the suite to catch this kind of problem in the future). jeff
Re: [patch] Remove unused code from dse.c.
On Fri, Mar 29, 2013 at 6:29 PM, Jeff Law l...@redhat.com wrote: On 03/29/2013 11:24 AM, Lawrence Crowl wrote: At what point did we stop setting clear_alias_sets? Was that intentional or not? I do not know the answer to either question. That's what needs to be determined before I'll approve. It means digging a bit. My view is that we have already lost the feature. The code that populates the set is gone. The remaining code has probably suffered bitrot because it is not being tested. Trying to recreate the population will probably result in inconsistencies anyway, necessitating a rewrite of the remaining code. So, the remaining code has little value, and might have negative value. But that doesn't mean dropping the code is the right thing to do. The right thing to do is see if the feature was dropped on purpose. If so, then we remove this dead code. If not, then we fix the real problem, namely the code was accidentally disabled (and add suitable tests to the suite to catch this kind of problem in the future). It's left over cleanups from code removed last year: http://gcc.gnu.org/ml/gcc-patches/2012-03/msg01862.html I like the patch. Ciao! Steven
Compute precise counter histogram at LTO
Hi, currently we use Theresa's code to determine hot/cold decisions based on counter. Histogram of gcov counters is computed and then threshold is identified so 99.9% of counter increments gets done in hot region. There are some problems with this method, most importantly the non-precise way the counters are merged across train runs. This patch implements histogram construction at LTO time, where we can do it wihhout help from libgcov and thus we get more precise results. Per-compilation unit histograms are computed at compilation stage and then streamed into profile section. At WPA time we combine all histograms (this time precisely) and determine the cutoff. I added dumping facility comparing libgcov based decisions with the new implementation and tested it only on cc1 binary and tramp3d. For tramp3d the results seems to agree (more or less) after fixing the overflow problem I submitted yesterday. With cc1 there is noticeabl difference: GCOV min count: 262829 Time:98.97% Size:11.54% Determined min count: 22990 Time:99.90% Size:20.43% i.e. the gcov min count seems 10 times higher than intended and accounts about half of the code that should be hot based on current 99.9% threshold. I guess we need to collect data over more applications to see if there is anohter implementation bug in the gcov code or if we want to get different threshold on LTO and during libgcov driven decisions. Profiledbootstraped/regtested x86_64-linux, committed. * lto-cgraph.c (output_profile_summary, input_profile_summary): Use gcov streaming; stream hot bb threshold to ltrans. * predict.c (get_hot_bb_threshold): Break out from (maybe_hot_count_p): ... here. (set_hot_bb_threshold): New function. * lto-section-in.c (lto_section_name): Add profile. * profile.h (get_hot_bb_threshold, set_hot_bb_threshold): Declare. * ipa.c: Include hash-table.h, tree-inline.h, profile.h, lto-streamer.h and data-streamer.h (histogram_entry): New structure. (histogram, histogram_pool): New global vars. (histogram_hash): New structure. (histogram_hash::hash): New method. (histogram_hash::equal): Likewise. (account_time_size): New function. (cmp_counts): New function. (dump_histogram): New function. (ipa_profile_generate_summary): New function. (ipa_profile_write_summary): New function. (ipa_profile_read_summary): New function. (ipa_profile): Decide on threshold. (pass_ipa_profile): Add ipa_profile_write_summary and ipa_profile_read_summary. * Makefile.in (ipa.o): Update dependencies. * lto-streamer.h (LTO_section_ipa_profile): New section. Index: lto-cgraph.c === *** lto-cgraph.c(revision 197218) --- lto-cgraph.c(working copy) *** output_profile_summary (struct lto_simpl *** 604,614 units. */ gcc_assert (profile_info-runs); streamer_write_uhwi_stream (ob-main_stream, profile_info-runs); ! streamer_write_uhwi_stream (ob-main_stream, profile_info-sum_max); /* sum_all is needed for computing the working set with the histogram. */ ! streamer_write_uhwi_stream (ob-main_stream, profile_info-sum_all); /* Create and output a bitpack of non-zero histogram entries indices. */ bp = bitpack_create (ob-main_stream); --- 604,614 units. */ gcc_assert (profile_info-runs); streamer_write_uhwi_stream (ob-main_stream, profile_info-runs); ! streamer_write_gcov_count_stream (ob-main_stream, profile_info-sum_max); /* sum_all is needed for computing the working set with the histogram. */ ! streamer_write_gcov_count_stream (ob-main_stream, profile_info-sum_all); /* Create and output a bitpack of non-zero histogram entries indices. */ bp = bitpack_create (ob-main_stream); *** output_profile_summary (struct lto_simpl *** 620,632 { if (!profile_info-histogram[h_ix].num_counters) continue; ! streamer_write_uhwi_stream (ob-main_stream, profile_info-histogram[h_ix].num_counters); ! streamer_write_uhwi_stream (ob-main_stream, profile_info-histogram[h_ix].min_value); ! streamer_write_uhwi_stream (ob-main_stream, profile_info-histogram[h_ix].cum_value); ! } } else streamer_write_uhwi_stream (ob-main_stream, 0); --- 620,637 { if (!profile_info-histogram[h_ix].num_counters) continue; ! streamer_write_gcov_count_stream (ob-main_stream, profile_info-histogram[h_ix].num_counters); !
[Fortran, RFC patch] Document naming and argument passing convention
Dear all, the attached patch attempts to document gfortran's naming and argument passing convention when Bind(C) is not used. While Bind(C) is the recommended way for interoperation with other Fortran compilers and other languages, there are situations where this is not possible; for instance, legacy code. Or in case of the MPI standard, the MPI implementation might need this information and MPI performance tool developers (PMPI) have to know how the different Fortran compilers pass the arguments. The attached patch does not (yet) state how array descriptors are handled internally. (I was thinking of deferring this until the new array descriptor becomes available.) I also believe there are other omissions as well and the wording could be improved. Suggestions are welcome. The patch was motivated by Walter's comment** to my VALUE+OPTIONAL patch.* It takes his comments into account and, that part, only reflects gfortran's implementation after the VALUE+OPTIONAL patch has been committed with his suggested change. What do you think? Tobias * http://gcc.gnu.org/ml/fortran/2013-03/msg00102.html ** http://gcc.gnu.org/ml/fortran/2013-03/msg00173.html 2013-01-30 Tobias Burnus bur...@net-b.de PR fortran/54339 * gfortran.texi (Standards): Mention TS29113. (Varying Length Character): Mention deferred-length strings. (Fortran 2003 Status): Add unlimited polymorphic. (TS 29113 Status): Add TYPE(*) and DIMENSION(..). (C Interop): Update the section about TS29113. diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index eff12d7..c80855c 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -522,12 +522,13 @@ ISO/IEC 1539:1997 (Fortran 95). As such, it can also compile essentially all standard-compliant Fortran 90 and Fortran 77 programs. It also supports the ISO/IEC TR-15581 enhancements to allocatable arrays. -In the future, the GNU Fortran compiler will also support ISO/IEC -1539-1:2004 (Fortran 2003), ISO/IEC 1539-1:2010 (Fortran 2008) and -future Fortran standards. Partial support of the Fortran 2003 and -Fortran 2008 standard is already provided; the current status of the -support is reported in the @ref{Fortran 2003 status} and -@ref{Fortran 2008 status} sections of the documentation. +GNU Fortran also have a partial support for ISO/IEC 1539-1:2004 (Fortran +2003), ISO/IEC 1539-1:2010 (Fortran 2008), the Technical Specification +@code{Further Interoperability of Fortran with C} (ISO/IEC TS 29113:2012). +Full support of those standards and future Fortran standards is planned. +The current status of the support is can be found in the +@ref{Fortran 2003 status}, @ref{Fortran 2008 status} and +@ref{TS 29113 status} sections of the documentation. Additionally, the GNU Fortran compilers supports the OpenMP specification (version 3.1, @url{http://openmp.org/@/wp/@/openmp-specifications/}). @@ -545,6 +546,10 @@ for them, which work with GNU Fortran. They can be found at @uref{http://www.fortran.com/@/iso_varying_string.f95} and at @uref{ftp://ftp.nag.co.uk/@/sc22wg5/@/ISO_VARYING_STRING/}. +Deferred-length character strings of Fortran 2003 support part of +the features of @code{ISO_VARYING_STRING} and should be considered as +replacement. (Namely, allocatable or pointers of the type +@code{character(len=:)}.) @c = @@ -807,8 +812,8 @@ operators bound to a type. override type-bound procedures or to have deferred binding. @item Polymorphic entities (``@code{CLASS}'') for derived types -- including -@code{SAME_TYPE_AS}, @code{EXTENDS_TYPE_OF} and @code{SELECT TYPE}. -Note that unlimited polymorphism is currently not supported. +@code{SAME_TYPE_AS}, @code{EXTENDS_TYPE_OF} and @code{SELECT TYPE} for +scalars and arrays, including unlimited polymorphism. @item Generic interface names, which have the same name as derived types, are now supported. This allows one to write constructor functions. Note @@ -1079,16 +1084,23 @@ The @uref{http://gcc.gnu.org/wiki/TS29113Status, wiki} has some information about the current TS 29113 implementation status. In particular, the following is implemented. +See also @ref{Further Interoperability of Fortran with C}. + @itemize @item The @option{-std=f2008ts} option. @item The @code{OPTIONAL} attribute is allowed for dummy arguments of @code{BIND(C) procedures.} -@item The RANK intrinsic is supported. +@item The @code{RANK} intrinsic is supported. @item GNU Fortran's implementation for variables with @code{ASYNCHRONOUS} attribute is compatible with TS 29113. + +@item Assumed types (@code{TYPE(*)}. + +@item Assumed-rank (@code{DIMENSION(..)}). However, the array descriptor +of the TS is not yet supported. @end itemize @@ -2264,7 +2276,7 @@ Derived types with the C binding attribute shall not have the @code{sequence} attribute, type parameters, the @code{extends} attribute, nor type-bound procedures.
Re: [Fortran, RFC patch] Document naming and argument passing convention
Ups - I attached the wrong patch (same file name, wrong directory). Hopefully, this one is the correct one. Tobias Am 29.03.2013 19:40, schrieb Tobias Burnus: Dear all, the attached patch attempts to document gfortran's naming and argument passing convention when Bind(C) is not used. While Bind(C) is the recommended way for interoperation with other Fortran compilers and other languages, there are situations where this is not possible; for instance, legacy code. Or in case of the MPI standard, the MPI implementation might need this information and MPI performance tool developers (PMPI) have to know how the different Fortran compilers pass the arguments. The attached patch does not (yet) state how array descriptors are handled internally. (I was thinking of deferring this until the new array descriptor becomes available.) I also believe there are other omissions as well and the wording could be improved. Suggestions are welcome. The patch was motivated by Walter's comment** to my VALUE+OPTIONAL patch.* It takes his comments into account and, that part, only reflects gfortran's implementation after the VALUE+OPTIONAL patch has been committed with his suggested change. What do you think? Tobias * http://gcc.gnu.org/ml/fortran/2013-03/msg00102.html ** http://gcc.gnu.org/ml/fortran/2013-03/msg00173.html diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 4f9008d..b998c8d 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -2204,6 +2204,7 @@ common, but not the former. * Interoperability with C:: * GNU Fortran Compiler Directives:: * Non-Fortran Main Program:: +* Naming and argument-passing conventions:: @end menu This chapter is about mixed-language interoperability, but also applies @@ -2250,6 +2251,21 @@ in C and Fortran, the named constants shall be used which are defined in the for kind parameters and character named constants for the escape sequences in C. For a list of the constants, see @ref{ISO_C_BINDING}. +For logical types, please note that the Fortran standard only guarantees +interoperability between C99's @code{_Bool} and Fortran's @code{C_Bool}-kind +logicals and C99 defines that @code{true} has the value 1 and @code{false} +the value 0. In GCC, Boolean variables (Fortran @code{logicals} with and +without C binding [and for all @code{kind} values], C99's @code{_Bool}, +C++'s @code{bool}, Ada's @code{Boolean}, etc.) all expect that only the +value 0 and 1 are used; using other values might lead to wrong results. +Therefore, using @code{logical(kind=c_int)} to interoperate with C99's +@code{int} is discouraged and should be replaced either by +@code{integer(kind=c_int)} on the Fortran side (which can then be +converted to @code{logical}) -- or to use @code{_Bool} and +@code{logical(kind=c_bool)}. Note that some other (Fortran) compilers +use a different value for @code{.true.} (e.g. @math{-1}), even with C binding. + + @node Derived Types and struct @subsection Derived Types and struct @@ -2975,6 +2991,115 @@ int main (int argc, char *argv[]) @end table +@node Naming and argument-passing conventions +@section Naming and argument-passing conventions + +This section gives an overview about the naming convention of procedures +and global variables and about the argument passing conventions used by +GNU Fortran if no C binding has been specified. If possible, mixed-language +and mixed-compiled projects should use the better C binding for +interoperability. See @pxref{Interoperability with C}. + +@menu +* Naming conventions:: +* Argument passing conventions:: +@end menu + + +@node Naming conventions +@subsection Naming conventions + +According the Fortran standard, valid Fortran names consist of a letter +between @code{A} to @code{Z}, @code{a} to @code{z}, digits @code{0}, +@code{1} to @code{9} and underscores (@code{_}) with the restriction +that names may only start with a letter. As vendor extension, the +dollar sign (@code{$}) is additionally permitted with the option +@option{-fdollar-ok}, but not as first character and only if the +target system supports it. + +By default, the procedure name is the lower-cased Fortran name with an +appended underscore (@code{_}); using @option{-fno-underscoring} no +underscore is appended while @code{-fsecond-underscore} appends two +underscores. Depending on the target system and the calling convention, +the procedure might be additionally dressed; for instance, on 32bit +Windows with @code{stdcall}, a at-sign @code{@@} followed by an integer +number is appended. For the changing the calling convention, see +@pxref{GNU Fortran Compiler Directives}. + +For common blocks, the same convention is used, i.e. by default an +underscore is appended to the lower-cased Fortran name. Blank commons +have the name @code{__BLNK__}. + +For procedures and variables declared in the specification space of a +module, the name is formed by @code{__}, followed by the lower-cased
C++ PATCH for c++/56774 (jumbled variadic template args)
In my patch for 35722/N2555, I forgot to adjust the index into the argument pack based on how many non-packed arguments there are. Tested x86_64-pc-linux-gnu, applying to trunk, 4.8, 4.7. commit 4b4cf682c8f7d15d3cf3097a2f4cf4f7f4f6acb5 Author: Jason Merrill ja...@redhat.com Date: Fri Mar 29 14:25:12 2013 -0400 PR c++/56774 PR c++/35722 * pt.c (unify_pack_expansion): Fix indexing. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 27e3ff8..f6101b6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -16213,10 +16213,10 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, arg = NULL_TREE; if (TREE_VALUE (pack) (pargs = ARGUMENT_PACK_EXPLICIT_ARGS (TREE_VALUE (pack))) - (i TREE_VEC_LENGTH (pargs))) + (i - start TREE_VEC_LENGTH (pargs))) { any_explicit = true; - arg = TREE_VEC_ELT (pargs, i); + arg = TREE_VEC_ELT (pargs, i - start); } TMPL_ARG (targs, level, idx) = arg; } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-explicit2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-explicit2.C new file mode 100644 index 000..4a80745 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-explicit2.C @@ -0,0 +1,14 @@ +// PR c++/56774 +// { dg-require-effective-target c++11 } + +template class ... Args +struct mytype {}; + +template class T, class ... Args +void something( mytypeT, Args... ) +{ } + +int main() +{ + somethingint, char, bool( mytypeint, char, bool() ); +}
[C++ Patch] Use TYPE_PTR_P and VOID_TYPE_P more often
Hi, thus, as mentioned in the exchange with Gaby, I took care of this clean-up. Two relatively interesting bits: - In cp_build_function_call_vec I simplified a tad the code with TYPE_PTRFN_P. - In convert_force we had a curious duplicate: TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE Booted and tested x86_64-linux. Ok? Thanks, Paolo. /// 2013-03-29 * call.c (add_builtin_candidate): Use TYPE_PTR_P and VOID_TYPE_P. (build_op_call_1): Likewise. (build_over_call): Likewise. (compare_ics): Likewise. * class.c (build_base_path): Likewise. (resolve_address_of_overloaded_function): Likewise. * cp-tree.h: Likewise. * cvt.c (cp_convert_to_pointer): Likewise. (convert_to_reference): Likewise. (ocp_convert): Likewise. (convert_force): Likewise, tidy. * cxx-pretty-print.c (pp_cxx_postfix_expression): Likewise. (pp_cxx_ptr_operator): Likewise. * decl.c (duplicate_decls): Likewise. (start_decl): Likewise. (grok_op_properties): Likewise. (start_preparsed_function): Likewise. (store_parm_decls): Likewise. (finish_function): Likewise. * decl2.c (delete_sanity): Likewise. (acceptable_java_type): Likewise. (grokbitfield): Likewise. (cp_reconstruct_complex_type): Likewise. * error.c (dump_type_prefix): Likewise. (dump_expr): Likewise. * except.c (push_eh_cleanup): Likewise. (complete_ptr_ref_or_void_ptr_p): Likewise. (can_convert_eh): Likewise. * init.c (build_new_1): Likewise. (build_delete): Likewise. (build_vec_delete): Likewise. * mangle.c (write_type): Likewise. * parser.c (lookup_literal_operator): Likewise. * pt.c (convert_nontype_argument_function): Likewise. (convert_nontype_argument): Likewise. (tsubst): Likewise. (unify): Likewise. (dependent_type_p_r): Likewise. * rtti.c (build_headof): Likewise. (build_typeid): Likewise. (build_dynamic_cast_1): Likewise. (target_incomplete_p): Likewise. (typeinfo_in_lib_p): Likewise. * semantics.c (finish_omp_for): Likewise. (cxx_eval_call_expression): Likewise. (maybe_resolve_dummy): Likewise. * tree.c (build_target_expr): Likewise. (cp_build_qualified_type_real): Likewise. * typeck.c (composite_pointer_type_r): Likewise. (composite_pointer_type): Likewise. (comp_except_types): Likewise. (cxx_sizeof_nowarn): Likewise. (string_conv_p): Likewise. (cp_build_array_ref): Likewise. (cp_build_function_call_vec): Likewise, also use TYPE_PTRFN_P. (pointer_diff): Likewise. (cp_build_addr_expr_1): Likewise. (cp_build_unary_op): Likewise. (build_static_cast_1): Likewise. (cp_build_c_cast): Likewise. (comp_ptr_ttypes_real): Likewise. (ptr_reasonably_similar): Likewise. (comp_ptr_ttypes_const): Likewise. (casts_away_constness): Likewise. (check_literal_operator_args): Likewise. * typeck2.c (build_x_arrow): Likewise. (add_exception_specifier): Likewise. Index: call.c === --- call.c (revision 197242) +++ call.c (working copy) @@ -2285,7 +2285,7 @@ add_builtin_candidate (struct z_candidate **candid T operator*(T*); */ case INDIRECT_REF: - if (TREE_CODE (type1) == POINTER_TYPE + if (TYPE_PTR_P (type1) !uses_template_parms (TREE_TYPE (type1)) (TYPE_PTROB_P (type1) || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)) @@ -2301,7 +2301,7 @@ add_builtin_candidate (struct z_candidate **candid T operator-(T); */ case UNARY_PLUS_EXPR: /* unary + */ - if (TREE_CODE (type1) == POINTER_TYPE) + if (TYPE_PTR_P (type1)) break; case NEGATE_EXPR: if (ARITHMETIC_TYPE_P (type1)) @@ -2325,8 +2325,7 @@ add_builtin_candidate (struct z_candidate **candid where CV12 is the union of CV1 and CV2. */ case MEMBER_REF: - if (TREE_CODE (type1) == POINTER_TYPE - TYPE_PTRMEM_P (type2)) + if (TYPE_PTR_P (type1) TYPE_PTRMEM_P (type2)) { tree c1 = TREE_TYPE (type1); tree c2 = TYPE_PTRMEM_CLASS_TYPE (type2); @@ -2546,7 +2545,7 @@ add_builtin_candidate (struct z_candidate **candid || (TYPE_PTR_P (type1) TYPE_PTR_P (type2)) || (TYPE_PTRDATAMEM_P (type1) TYPE_PTRDATAMEM_P (type2)) || ((TYPE_PTRMEMFUNC_P (type1) - || TREE_CODE (type1) == POINTER_TYPE) + || TYPE_PTR_P (type1)) null_ptr_cst_p (args[1]))) { type2 = type1; @@ -4083,12 +4082,12 @@ build_op_call_1 (tree obj, vectree, va_gc **args tree
Re: [patch] Remove unused code from dse.c.
On 03/29/2013 12:12 PM, Steven Bosscher wrote: On Fri, Mar 29, 2013 at 6:29 PM, Jeff Law l...@redhat.com wrote: On 03/29/2013 11:24 AM, Lawrence Crowl wrote: At what point did we stop setting clear_alias_sets? Was that intentional or not? I do not know the answer to either question. That's what needs to be determined before I'll approve. It means digging a bit. My view is that we have already lost the feature. The code that populates the set is gone. The remaining code has probably suffered bitrot because it is not being tested. Trying to recreate the population will probably result in inconsistencies anyway, necessitating a rewrite of the remaining code. So, the remaining code has little value, and might have negative value. But that doesn't mean dropping the code is the right thing to do. The right thing to do is see if the feature was dropped on purpose. If so, then we remove this dead code. If not, then we fix the real problem, namely the code was accidentally disabled (and add suitable tests to the suite to catch this kind of problem in the future). It's left over cleanups from code removed last year: http://gcc.gnu.org/ml/gcc-patches/2012-03/msg01862.html More correctly, it's been dead since an Oct 2008 patch from Richard Henderson which introduced set_mem_attrs_for_spill which effectively provides the alias analysis code with the information it needs to disambiguate stack slots from everything else without the callback. Lawrence, that's the critical bit of information you failed to provide. Patch approved, please install. Thanks, Jeff
C++ PATCH to implement N3582 changes to proposed C++14 return type deduction
I've updated my proposal for return type deduction for normal functions in C++14 for the upcoming Bristol meeting: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3582.html and this patch implements the changes in the new proposal relative to the previous revision. I started trying to change the parsing of initializers and return expressions in order to implement decltype(auto), but that got rather hairy, particularly for initializers, so I ended up going a different way: determining whether an expression is an identifier or member reference based on the trees rather than directly in the parser. To make that work, I needed to make sure that a parenthesized expression, or a folded ?: expression, could be distinguished from a simpler expression; to that end, I've adopted PAREN_EXPR from the middle end. Tested x86_64-pc-linux-gnu, applying to trunk. commit 81070bed26366c95a3115b902c333bd32a1c9df8 Author: Jason Merrill ja...@redhat.com Date: Fri Mar 22 21:31:38 2013 -0400 N3582 * cp-tree.h (AUTO_IS_DECLTYPE): New. * parser.c (cp_parser_decltype): Handle decltype(auto). (cp_parser_type_id_1): Allow auto without a late-specified return in C++1y. (cp_parser_primary_expression): Use the return value of finish_parenthesized_expr. (cp_parser_transaction_expression): Likewise. * semantics.c (force_paren_expr): New. (finish_parenthesized_expr): Use it. * call.c (build_conditional_expr_1): Likewise. * pt.c (do_auto_deduction): Handle decltype(auto). (tsubst_copy): Handle PAREN_EXPR. (tsubst_copy_and_build): Likewise. * error.c (dump_expr): Handle PAREN_EXPR. * cxx-pretty-print.c (pp_cxx_expression): Likewise. * mangle.c (write_expression): Ignore PAREN_EXPR. * parser.c (cp_parser_decltype_expr): Split out... (cp_parser_decltype): ...from here. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d1777a0..62d6e15 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4845,6 +4845,8 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3, lvalue, we must add a NON_LVALUE_EXPR. */ result = rvalue (result); } + else +result = force_paren_expr (result); return result; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index edf46d4..521da00 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -121,6 +121,7 @@ c-common.h, not after. 4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR 5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE) ENUM_FIXED_UNDERLYING_TYPE_P (in ENUMERAL_TYPE) + AUTO_IS_DECLTYPE (in TEMPLATE_TYPE_PARM) 6: TYPE_DEPENDENT_P_VALID Usage of DECL_LANG_FLAG_?: @@ -4604,6 +4605,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; #define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \ (TEMPLATE_PARM_PARAMETER_PACK (TEMPLATE_TYPE_PARM_INDEX (NODE))) +/* True iff this TEMPLATE_TYPE_PARM represents decltype(auto). */ +#define AUTO_IS_DECLTYPE(NODE) \ + (TYPE_LANG_FLAG_5 (TEMPLATE_TYPE_PARM_CHECK (NODE))) + /* These constants can used as bit flags in the process of tree formatting. TFF_PLAIN_IDENTIFIER: unqualified part of a name. @@ -5659,6 +5664,7 @@ extern tree finish_asm_stmt (int, tree, tree, tree, tree, extern tree finish_label_stmt (tree); extern void finish_label_decl (tree); extern tree finish_parenthesized_expr (tree); +extern tree force_paren_expr (tree); extern tree finish_non_static_data_member (tree, tree, tree); extern tree begin_stmt_expr (void); extern tree finish_stmt_expr_expr (tree, tree); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 45ad20c..4275b45 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -1167,6 +1167,12 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t) pp_cxx_ws_string (pp, lambda); break; +case PAREN_EXPR: + pp_cxx_left_paren (pp); + pp_cxx_expression (pp, TREE_OPERAND (t, 0)); + pp_cxx_right_paren (pp); + break; + default: pp_c_expression (pp_c_base (pp), t); break; diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 2af900d..dd27e6c 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2506,6 +2506,12 @@ dump_expr (tree t, int flags) pp_string (cxx_pp, M_(lambda)); break; +case PAREN_EXPR: + pp_cxx_left_paren (cxx_pp); + dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS); + pp_cxx_right_paren (cxx_pp); + break; + /* This list is incomplete, but should suffice for now. It is very important that `sorry' does not call `report_error_function'. That could cause an infinite loop. */ diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 08bfa22..e303ea2 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2555,6 +2555,8 @@ write_expression (tree expr) is converted (via qualification conversions) to another type. */ while (TREE_CODE (expr) == NOP_EXPR + /* Parentheses aren't
Re: Fill more delay slots in conditional returns
On 03/25/2013 05:25 AM, Eric Botcazou wrote: Hi, for a private port with conditional returns and delay slots, only the simple algorithm (fill_simple_delay_slots) is able to fill the slots. It's because get_branch_condition just punts on conditional returns. Fixed thusly. While I investigated this, I realized that the block of code in fill_simple_delay_slots between line 2097 and line 2274 is dead for JUMP insns (and has been so for a long time, which is consistent with various comments in the code, for example the head comment of fill_eager_delay_slots) so the patch also cleans it up (modulo the formatting to make the patch readable). Jeff, any objections? Tested on SPARC/Solaris, no difference in the generated code at -O2 for the gcc.c-torture/compile testsuite. 2013-03-25 Eric Botcazouebotca...@adacore.com * reorg.c (get_branch_condition): Deal with conditional returns. (fill_simple_delay_slots): Remove dead code dealing with jumps. -- Eric Botcazou p.diff Index: reorg.c === --- reorg.c (revision 196816) +++ reorg.c (working copy) @@ -921,8 +921,8 @@ get_branch_condition (rtx insn, rtx targ if (condjump_in_parallel_p (insn)) pat = XVECEXP (pat, 0, 0); - if (ANY_RETURN_P (pat)) -return pat == target ? const_true_rtx : 0; + if (ANY_RETURN_P (pat) pat == target) +return const_true_rtx; I'm not sure what this is supposed to do. How is pat == target ever going to be true when ANY_RETURN_P (pat) is true? Isn't target supposed to be a CODE_LABEL or NULL? What am I missing? What does the RTL for your conditional return look like (if_then_else (cond) (pc) (return)) Where the (pc) and (return) can be reversed as well? That's what the later hunks in get_branch_condition seem to imply. Maybe if I saw the RTL that first hunk would make sense. It feels like I'm missing something. The cleanup stuff is OK, check that in whenver you'd like. jeff
Re: [C++ Patch] Use TYPE_PTR_P and VOID_TYPE_P more often
OK. Jason
Re: Compute precise counter histogram at LTO
On Fri, Mar 29, 2013 at 11:16 AM, Jan Hubicka hubi...@ucw.cz wrote: Hi, currently we use Theresa's code to determine hot/cold decisions based on counter. Histogram of gcov counters is computed and then threshold is identified so 99.9% of counter increments gets done in hot region. There are some problems with this method, most importantly the non-precise way the counters are merged across train runs. This patch implements histogram construction at LTO time, where we can do it wihhout help from libgcov and thus we get more precise results. Per-compilation unit histograms are computed at compilation stage and then streamed into profile section. At WPA time we combine all histograms (this time precisely) and determine the cutoff. I added dumping facility comparing libgcov based decisions with the new implementation and tested it only on cc1 binary and tramp3d. For tramp3d the results seems to agree (more or less) after fixing the overflow problem I submitted yesterday. With cc1 there is noticeabl difference: GCOV min count: 262829 Time:98.97% Size:11.54% Determined min count: 22990 Time:99.90% Size:20.43% i.e. the gcov min count seems 10 times higher than intended and accounts about half of the code that should be hot based on current 99.9% threshold. That's a larger error than I had expected from the merging, although as you note it is an approximation so there is going to be some amount of error. If the error is that large then maybe there is a better merging algorithm, since in the non-LTO case we won't be able to recompute it exactly. For cc1, what was your test case - profiledbootstrap or something simpler? I can try to reproduce this and see if it is another bug or just due to the approximation. I guess we need to collect data over more applications to see if there is anohter implementation bug in the gcov code or if we want to get different threshold on LTO and during libgcov driven decisions. I'll try some test cases. It would probably also be straightforward to read in all the gcda files with an offline tool and recompute the histogram exactly and do the comparison. That way we wouldn't need to use LTO to find the error. Rong Xu from my team is developing an offline profile merging tool that may already have the functionality to do this. Thanks, Teresa Profiledbootstraped/regtested x86_64-linux, committed. * lto-cgraph.c (output_profile_summary, input_profile_summary): Use gcov streaming; stream hot bb threshold to ltrans. * predict.c (get_hot_bb_threshold): Break out from (maybe_hot_count_p): ... here. (set_hot_bb_threshold): New function. * lto-section-in.c (lto_section_name): Add profile. * profile.h (get_hot_bb_threshold, set_hot_bb_threshold): Declare. * ipa.c: Include hash-table.h, tree-inline.h, profile.h, lto-streamer.h and data-streamer.h (histogram_entry): New structure. (histogram, histogram_pool): New global vars. (histogram_hash): New structure. (histogram_hash::hash): New method. (histogram_hash::equal): Likewise. (account_time_size): New function. (cmp_counts): New function. (dump_histogram): New function. (ipa_profile_generate_summary): New function. (ipa_profile_write_summary): New function. (ipa_profile_read_summary): New function. (ipa_profile): Decide on threshold. (pass_ipa_profile): Add ipa_profile_write_summary and ipa_profile_read_summary. * Makefile.in (ipa.o): Update dependencies. * lto-streamer.h (LTO_section_ipa_profile): New section. Index: lto-cgraph.c === *** lto-cgraph.c(revision 197218) --- lto-cgraph.c(working copy) *** output_profile_summary (struct lto_simpl *** 604,614 units. */ gcc_assert (profile_info-runs); streamer_write_uhwi_stream (ob-main_stream, profile_info-runs); ! streamer_write_uhwi_stream (ob-main_stream, profile_info-sum_max); /* sum_all is needed for computing the working set with the histogram. */ ! streamer_write_uhwi_stream (ob-main_stream, profile_info-sum_all); /* Create and output a bitpack of non-zero histogram entries indices. */ bp = bitpack_create (ob-main_stream); --- 604,614 units. */ gcc_assert (profile_info-runs); streamer_write_uhwi_stream (ob-main_stream, profile_info-runs); ! streamer_write_gcov_count_stream (ob-main_stream, profile_info-sum_max); /* sum_all is needed for computing the working set with the histogram. */ ! streamer_write_gcov_count_stream (ob-main_stream, profile_info-sum_all); /* Create and output a bitpack of non-zero histogram entries indices. */ bp =
[Patch, fortran] Use memcmp for string comparisons a bit more
Am 29.03.2013 15:56, schrieb Tobias Burnus: Thus, how about using memcmp for kind=4 for == and /= only - and for kind=1 also for , etc.? OK, there is the updated patch. 2013-03-25 Thomas Koenig tkoe...@gcc.gnu.org * trans-expr.c (build_memcmp_call): New function. (gfc_build_compare_string): If the strings compared have constant and equal lengths and the strings are kind=1, or (for kind=4) strings, the test is for (in)equality, use memcmp(). 2013-03-25 Thomas Koenig tkoe...@gcc.gnu.org * gfortran.dg/character_comparison_3.f90: Adjust for use of memcmp for constant and equal string lengths. * gfortran.dg/character_comparison_5.f90: Likewise. * gfortran.dg/character_comparison_9.f90: New test. Regerssion-tested. OK for trunk? Thomas Index: fortran/trans-expr.c === --- fortran/trans-expr.c (Revision 197233) +++ fortran/trans-expr.c (Arbeitskopie) @@ -2665,6 +2665,32 @@ return -1; } +/* Helper to build a call to memcmp. */ + +static tree +build_memcmp_call (tree s1, tree s2, tree n) +{ + tree tmp; + + if (!POINTER_TYPE_P (TREE_TYPE (s1))) +s1 = gfc_build_addr_expr (pvoid_type_node, s1); + else +s1 = fold_convert (pvoid_type_node, s1); + + if (!POINTER_TYPE_P (TREE_TYPE (s2))) +s2 = gfc_build_addr_expr (pvoid_type_node, s2); + else +s2 = fold_convert (pvoid_type_node, s2); + + n = fold_convert (size_type_node, n); + + tmp = build_call_expr_loc (input_location, + builtin_decl_explicit (BUILT_IN_MEMCMP), + 3, s1, s2, n); + + return fold_convert (integer_type_node, tmp); +} + /* Compare two strings. If they are all single characters, the result is the subtraction of them. Otherwise, we build a library call. */ @@ -2706,6 +2732,26 @@ return integer_one_node; } + /* We can compare via memcpy if the strings are known to be equal + in length and they are + - kind=1 + - kind=4 and the comparision is for (in)equality. */ + + if (INTEGER_CST_P (len1) INTEGER_CST_P (len2) + tree_int_cst_equal (len1, len2) + (kind == 1 || code == EQ_EXPR || code == NE_EXPR)) +{ + tree tmp; + tree chartype; + + chartype = gfc_get_char_type (kind); + tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE(len1), + fold_convert (TREE_TYPE(len1), + TYPE_SIZE_UNIT(chartype)), + len1); + return build_memcmp_call (str1, str2, tmp); +} + /* Build a call for the comparison. */ if (kind == 1) fndecl = gfor_fndecl_compare_string; Index: testsuite/gfortran.dg/character_comparison_3.f90 === --- testsuite/gfortran.dg/character_comparison_3.f90 (Revision 197233) +++ testsuite/gfortran.dg/character_comparison_3.f90 (Arbeitskopie) @@ -25,6 +25,7 @@ if (c(:k3) == c(:k44)) call abort end program main -! { dg-final { scan-tree-dump-times gfortran_compare_string 8 original } } +! { dg-final { scan-tree-dump-times gfortran_compare_string 6 original } } +! { dg-final { scan-tree-dump-times __builtin_memcmp 2 original } } ! { dg-final { cleanup-tree-dump original } } Index: testsuite/gfortran.dg/character_comparison_5.f90 === --- testsuite/gfortran.dg/character_comparison_5.f90 (Revision 197233) +++ testsuite/gfortran.dg/character_comparison_5.f90 (Arbeitskopie) @@ -16,6 +16,6 @@ end program main ! { dg-final { scan-tree-dump-times gfortran_concat_string 0 original } } -! { dg-final { scan-tree-dump-times gfortran_compare_string 2 original } } +! { dg-final { scan-tree-dump-times __builtin_memcmp 2 original } } ! { dg-final { cleanup-tree-dump original } } ! { dg-do run } ! { dg-options -fdump-tree-original } program main character (len=2) :: a, b character (kind=4,len=4) :: c,d a = 'ab' b = 'aa' if (a b) call abort c = 4_ d = 4_aaab if (c == d) call abort if (c d) call abort end program main ! { dg-final { scan-tree-dump-times _gfortran_compare_string_char4 1 original } } ! { dg-final { scan-tree-dump-times __builtin_memcmp 2 original } } ! { dg-final { cleanup-tree-dump original } }
Re: [Patch, fortran] Use memcmp for string comparisons a bit more
Am 29.03.2013 21:53, schrieb Thomas Koenig: Am 29.03.2013 15:56, schrieb Tobias Burnus: Thus, how about using memcmp for kind=4 for == and /= only - and for kind=1 also for , etc.? OK, there is the updated patch. OK thanks for the patch! 2013-03-25 Thomas Koenig tkoe...@gcc.gnu.org * trans-expr.c (build_memcmp_call): New function. (gfc_build_compare_string): If the strings compared have constant and equal lengths and the strings are kind=1, or (for kind=4) strings, the test is for (in)equality, use memcmp(). Somehow the commas and parentheses look odd. Shouldn't that be, e.g., or (for kind=4 strings) the ...? Tobias
RE: [patch] cilkplus: Array notation for C patch
Hello Joseph, Aldy et al., I reworded couple comments (e.g changed builtin with built-in, etc) and added a header comment to the c-array-notation.c that explains the overall process. I am attaching a fixed patch. Thanks, Balaji V. Iyer. Here are the Changelog entries again: gcc/ChangeLog +2013-03-28 Balaji V. Iyer balaji.v.i...@intel.com + + * doc/extend.texi (C Extensions): Added documentation about Cilk Plus + array notation built-in reduction functions. + * doc/passes.texi (Passes): Added documentation about changes done + for Cilk Plus. + * doc/invoke.texi (C Dialect Options): Added documentation about + the -fcilkplus flag. + * doc/generic.texi (Storage References): Added documentation for + ARRAY_NOTATION_REF storage. + * Makefile.in (C_COMMON_OBJS): Added c-family/array-notation-common.o. + * tree-pretty-print.c (dump_generic_node): Add case for + ARRAY_NOTATION_REF. + (BUILTINS_DEF): Depend on cilkplus.def. + * builtins.def: Include cilkplus.def. + Define DEF_CILKPLUS_BUILTIN. + * builtin-types.def: Define BT_FN_INT_PTR_PTR_PTR. + * cilkplus.def: New file. gcc/c-family/ChangeLog +2013-03-28 Balaji V. Iyer balaji.v.i...@intel.com + + * c-common.c (c_define_builtins): When cilkplus is enabled, the + function array_notation_init_builtins is called. + (c_common_init_ts): Added ARRAY_NOTATION_REF as typed. + * c-common.def (ARRAY_NOTATION_REF): New tree. + * c-common.h (build_array_notation_expr): New function declaration. + (build_array_notation_ref): Likewise. + (extract_sec_implicit_index_arg): New extern declaration. + (is_sec_implicit_index_fn): Likewise. + (ARRAY_NOTATION_CHECK): New define. + (ARRAY_NOTATION_ARRAY): Likewise. + (ARRAY_NOTATION_START): Likewise. + (ARRAY_NOTATION_LENGTH): Likewise. + (ARRAY_NOTATION_STRIDE): Likewise. + (ARRAY_NOTATION_TYPE): Likewise. + * c-pretty-print.c (pp_c_postifix_expression): Added a new case for + ARRAY_NOTATION_REF. + (pp_c_expression): Likewise. + * c.opt (flag_enable_cilkplus): New flag. + * array-notation-common.c: New file. gcc/c/ChangeLog +2013-03-28 Balaji V. Iyer balaji.v.i...@intel.com + + * c-typeck.c (build_array_ref): Added a check to see if array's + index is greater than one. If true, then emit an error. + (build_function_call_vec): Exclude error reporting and checking + for builtin array-notation functions. + (convert_arguments): Likewise. + (c_finish_return): Added a check for array notations as a return + expression. If true, then emit an error. + (c_finish_loop): Added a check for array notations in a loop + condition. If true then emit an error. + (lvalue_p): Added a ARRAY_NOTATION_REF case. + (build_binary_op): Added a check for array notation expr inside + op1 and op0. If present, we call another function to find correct + type. + * Make-lang.in (C_AND_OBJC_OBJS): Added c-array-notation.o. + * c-parser.c (c_parser_compound_statement): Check if array + notation code is used in tree, if so, then transform them into + appropriate C code. + (c_parser_expr_no_commas): Check if array notation is used in LHS + or RHS, if so, then build array notation expression instead of + regular modify. + (c_parser_postfix_expression_after_primary): Added a check for + colon(s) after square braces, if so then handle it like an array + notation. Also, break up array notations in unary op if found. + (c_parser_direct_declarator_inner): Added a check for array + notation. + (c_parser_compound_statement): Added a check for array notation in + a stmt. If one is present, then expand array notation expr. + (c_parser_if_statement): Likewise. + (c_parser_switch_statement): Added a check for array notations in + a switch statement's condition. If true, then output an error. + (c_parser_while_statement): Similarly, but for a while. + (c_parser_do_statement): Similarly, but for a do-while. + (c_parser_for_statement): Similarly, but for a for-loop. + (c_parser_unary_expression): Check if array notation is used in a + pre-increment or pre-decrement expression. If true, then expand + them. + (c_parser_array_notation): New function. + * c-array-notation.c: New file. + * c-tree.h (is_cilkplus_reduce_builtin): Protoize. -Original Message- From: Iyer, Balaji V Sent: Thursday, March 28, 2013 1:07 PM To: Joseph Myers; Aldy Hernandez Cc: gcc-patches Subject: [patch] cilkplus: Array notation for C patch Hello Joseph, Aldy et al., Attached, please find a fixed patch (bzipped) that implements array notation for C. To my best knowledge, I have fixed all the changes Joseph and Aldy have
[var-template] Accept variable template declaration
This patch lets us accept declarations of constexpr variable templates. Actual semantics processing of specialization is subject of follow up patches. The patch represents a variable template as a variable temploid whose scope is a namespace, or member template that generates a static data member. Applied to var-template branch. -- Gaby 2013-03-29 Gabriel Dos Reis g...@integrable-solutions.net * cp-tree.h (variable_template_p): New. * pt.c (check_template_variable): Accept variable temploids at non-class scope. (push_template_decl_real): The current instantiation of a template can be a VAR_DECL. Index: gcc/cp/cp-tree.h === --- gcc/cp/cp-tree.h(revision 197248) +++ gcc/cp/cp-tree.h(working copy) @@ -4926,6 +4926,18 @@ return TREE_TYPE (type_of_this_parm (fntype)); } +/* True if T designates a variable template declaration. */ +inline bool +variable_template_p (tree t) +{ + if (TREE_CODE (t) != TEMPLATE_DECL + || !(DECL_NAMESPACE_SCOPE_P (t) || DECL_MEMBER_TEMPLATE_P (t))) +return false; + if (tree r = DECL_TEMPLATE_RESULT (t)) +return VAR_P (r); + return false; +} + /* A parameter list indicating for a function with no parameters, e.g int f(void). */ extern cp_parameter_declarator *no_parameters; Index: gcc/cp/pt.c === --- gcc/cp/pt.c (revision 197248) +++ gcc/cp/pt.c (working copy) @@ -2270,9 +2270,11 @@ { tree ctx = CP_DECL_CONTEXT (decl); int wanted = num_template_headers_for_class (ctx); - if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) -permerror (DECL_SOURCE_LOCATION (decl), - %qD is not a static data member of a class template, decl); + if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) { +if (cxx_dialect cxx1y) + permerror (DECL_SOURCE_LOCATION (decl), + %qD is not a static data member of a class template, decl); + } else if (template_header_count wanted) { pedwarn (DECL_SOURCE_LOCATION (decl), 0, @@ -4616,6 +4618,10 @@ TYPE_DECL_ALIAS_P (decl)) /* alias-declaration */ gcc_assert (!DECL_ARTIFICIAL (decl)); + else if (VAR_P (decl)) { +if (!DECL_DECLARED_CONSTEXPR_P (decl)) + error (template declaration of non-constexpr variable %qD, decl); + } else { error (template declaration of %q#D, decl);
Re: [C++ Patch] Use TYPE_PTR_P and VOID_TYPE_P more often
On 03/29/2013 09:03 PM, Jason Merrill wrote: OK. Thanks. Earlier today I missed 2 more TYPE_PTRFN_P and a TYPE_REFFN_P: I'm applying as obvious the below, which just passed testing. Thanks again, Paolo. /// 2013-03-29 Paolo Carlini paolo.carl...@oracle.com * call.c (build_op_call_1): Use TYPE_PTRFN_P and TYPE_REFFN_P. Index: call.c === --- call.c (revision 197249) +++ call.c (working copy) @@ -4082,13 +4082,10 @@ build_op_call_1 (tree obj, vectree, va_gc **args tree fns = TREE_VALUE (convs); tree totype = TREE_TYPE (convs); - if ((TYPE_PTR_P (totype) - TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE) + if (TYPE_PTRFN_P (totype) + || TYPE_REFFN_P (totype) || (TREE_CODE (totype) == REFERENCE_TYPE - TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE) - || (TREE_CODE (totype) == REFERENCE_TYPE - TYPE_PTR_P (TREE_TYPE (totype)) - TREE_CODE (TREE_TYPE (TREE_TYPE (totype))) == FUNCTION_TYPE)) + TYPE_PTRFN_P (TREE_TYPE (totype for (; fns; fns = OVL_NEXT (fns)) { tree fn = OVL_CURRENT (fns);
[patch] Stop using JUMP_INSN for jump table data
Hello, GCC uses fake JUMP_INSNs as placeholders for jump table data. These JUMP_INSNs have an ADDR_VEC or ADDR_DIFF_VEC as PATTERN, but they are not real instructions and they are not inside basic blocks. This results in special-casing JUMP_P insns in various places throughout the compiler. The attached patch adds a new object, JUMP_TABLE_DATA, to hold jump table data. All remaining JUMP_P insns will be real insns, which helps simplify things a bit -- or at least make things more intuitive. A number of back ends, and probably some code in the middle end (not sure), uses the *active_insn* family of functions while traversing the insn chain (instead of the CFG) and expect jump table data to be considered an active insn. Therefore, JUMP_TABLE_DATA is an RTX_INSN for the moment, but I intend to make it an RTX_EXTRA before stage1 ends. Bootstrapped and tested on powerpc64-unknown-linux-gnu and on x86_64-unknown-linux-gnu. OK for trunk? Ciao! Steven * postreload-gcse.c (bb_has_well_behaved_predecessors): Correct test for table jump at the end of a basic block using tablejump_p. * targhooks.c (default_invalid_within_doloop): Likewise. * config/rs6000/rs6000.c (TARGET_INVALID_WITHIN_DOLOOP): Remove target hook implementation that is identical to the default hook. (rs6000_invalid_within_doloop): Remove. * bb-reorder.c (fix_crossing_unconditional_branches): Remove set but unused variable from tablejump_p call. * rtl.def (JUMP_TABLE_DATA): New RTX_INSN object. * rtl.h (RTX_PREV, RTX_NEXT): Adjust for new JUMP_TABLE_DATA. (INSN_DELETED_P): Likewise. (emit_jump_table_data): New prototype. * gengtype.c (adjust_field_rtx_def): Handle JUMP_TABLE_DATA fields after 4th as unused. * print-rtl.c (print_rtl): Handle JUMP_TABLE_DATA. * sched-vis.c (print_insn): Likewise. * emit-rtl.c (active_insn_p): Consider JUMP_TABLE_DATA an active insn for compatibility with back ends that use next_active_insn to identify jump table data. (set_insn_deleted): Remove no longer useful JUMP_TABLE_DATA_P check. (remove_insn): Likewise. (emit_insn): Do not accept JUMP_TABLE_DATA objects in insn chains to be emitted. (emit_debug_insn, emit_jump_insn, emit_call_insn, emit_label): Idem. (emit_jump_table_data): New function. * cfgbuild.c (inside_basic_block_p): A JUMP_INSN is always inside a basic block, a JUMP_TABLE_DATA never is. (control_flow_insn_p): JUMP_TABLE_DATA is not a control flow insn. * cfgrtl.c (duplicate_insn_chain): Split handling of JUMP_TABLE_DATA off from code handling real insns. * final.c (get_attr_length_1): Simplify for JUMP_INSNs. * function.c (instantiate_virtual_regs): Remove JUMP_TABLE_DATA_P test, now redundant because JUMP_TABLE_DATA is not an INSN_P insn. * gcse.c (insert_insn_end_basic_block): Likewise, JUMP_TABLE_DATA_P is not a NONDEBUG_INSN_P. * ira-costs.c (scan_one_insn): Likewise. * jump.c (mark_all_labels): Likewise. (mark_jump_label_1): Likewise. * lra-eliminations.c (eliminate_regs_in_insn): Likewise. * lra.c (get_insn_freq): Expect all insns reaching here to be in a basic block. (check_rtl): Remove JUMP_TABLE_DATA_P test, not a NONDEBUG_INSN_P insn. * predict.c (expensive_function_p): Use FOR_BB_INSNS. * reload1.c (calculate_needs_all_insns): Call set_label_offsets for JUMP_TABLE_DATA_P insns. (calculate_elim_costs_all_insns): Likewise. (set_label_offsets): Recurse on the PATTERN of JUMP_TABLE_DATA insns. (elimination_costs_in_insn): Remove redundant JUMP_TABLE_DATA_P test. (delete_output_reload): Code style fixups. * reorg.c (dbr_schedule): Move JUMP_TABLE_DATA_P up to avoid setting insn flags on this non-insn. * sched-rgn.c (add_branch_dependences): Treat JUMP_TABLE_DATA insns as scheduling barriers, for pre-change compatibility. * stmt.c (emit_case_dispatch_table): Emit jump table data not as JUMP_INSN objects but instead as JUMP_TABLE_DATA objects. * config/alpha/alpha.c (alpha_does_function_need_gp): Remove redundant JUMP_TABLE_DATA_P test. * config/arm/arm.c (thumb_far_jump_used_p): Likewise. * config/frv/frv.c (frv_function_contains_far_jump): Likewise. (frv_for_each_packet): Likewise. * config/i386/i386.c (min_insn_size): Likewise. (ix86_avoid_jump_mispredicts): Likewise. * config/m32r/m32r.c (m32r_is_insn): Likewise. * config/mep/mep.c (mep_reorg_erepeat): Likewise. * config/mips/mips.c (USEFUL_INSN_P): Likewise. (mips16_insn_length): Robustify. (mips_has_long_branch_p): Remove redundant JUMP_TABLE_DATA_P test. (mips16_split_long_branches): Likewise.
Re: [var-template] Accept variable template declaration
On 03/29/2013 06:29 PM, Gabriel Dos Reis wrote: + if (TREE_CODE (t) != TEMPLATE_DECL + || !(DECL_NAMESPACE_SCOPE_P (t) || DECL_MEMBER_TEMPLATE_P (t))) Why check the scope? - if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) -permerror (DECL_SOURCE_LOCATION (decl), - %qD is not a static data member of a class template, decl); + if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) { +if (cxx_dialect cxx1y) + permerror (DECL_SOURCE_LOCATION (decl), + %qD is not a static data member of a class template, decl); + } else if (template_header_count wanted) I think we still want to check for excess template headers. + else if (VAR_P (decl)) { +if (!DECL_DECLARED_CONSTEXPR_P (decl)) + error (template declaration of non-constexpr variable %qD, decl); + } Open brace should be on a line by itself. Jason
C++ PATCH: Fix typo in documentation
There is no TMPL_ARG_DEPTH; should be TMPL_ARGS_DEPTH. Committed as obvious. -- Gaby 2013-03-29 Gabriel Dos Reis g...@integrable-solutions.net * pt.c (template_parms_to_args): Fix typo in comment. Index: pt.c === --- pt.c(revision 197258) +++ pt.c(working copy) @@ -3874,10 +3874,10 @@ Consider the level of the parms of TT; T and U both have level 2; TT has no template parm of level 1. So in this case the first element of full_template_args is NULL_TREE. If we -leave it like this TMPL_ARG_DEPTH on args returns 1 instead +leave it like this TMPL_ARGS_DEPTH on args returns 1 instead of 2. This will make tsubst wrongly consider that T and U have level 1. Instead, let's create a dummy vector as the -first element of full_template_args so that TMPL_ARG_DEPTH +first element of full_template_args so that TMPL_ARGS_DEPTH returns the correct depth for args. */ TREE_VEC_ELT (args, 0) = make_tree_vec (1); return args;
Re: [var-template] Accept variable template declaration
Jason Merrill ja...@redhat.com writes: | On 03/29/2013 06:29 PM, Gabriel Dos Reis wrote: | + if (TREE_CODE (t) != TEMPLATE_DECL | + || !(DECL_NAMESPACE_SCOPE_P (t) || DECL_MEMBER_TEMPLATE_P (t))) | | Why check the scope? ah right, if it is a template the scope was already checked. | - if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) | -permerror (DECL_SOURCE_LOCATION (decl), | - %qD is not a static data member of a class template, decl); | + if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx)) { | +if (cxx_dialect cxx1y) | + permerror (DECL_SOURCE_LOCATION (decl), | + %qD is not a static data member of a class template, decl); | + } | else if (template_header_count wanted) | | I think we still want to check for excess template headers. right your are. | + else if (VAR_P (decl)) { | +if (!DECL_DECLARED_CONSTEXPR_P (decl)) | + error (template declaration of non-constexpr variable %qD, decl); | + } | | Open brace should be on a line by itself. oops, fixed. Too many coding standards... -- Gaby 2013-03-29 Gabriel Dos Reis g...@integrable-solutions.net * cp-tree.h (variable_template_p): Do not check scope. * pt.c (check_template_variable): Fix thinko from previous change. (push_template_decl_real): Fix formatting. Index: gcc/cp/cp-tree.h === --- gcc/cp/cp-tree.h(revision 197259) +++ gcc/cp/cp-tree.h(working copy) @@ -4930,8 +4930,7 @@ inline bool variable_template_p (tree t) { - if (TREE_CODE (t) != TEMPLATE_DECL - || !(DECL_NAMESPACE_SCOPE_P (t) || DECL_MEMBER_TEMPLATE_P (t))) + if (TREE_CODE (t) != TEMPLATE_DECL) return false; if (tree r = DECL_TEMPLATE_RESULT (t)) return VAR_P (r); Index: gcc/cp/pt.c === --- gcc/cp/pt.c (revision 197259) +++ gcc/cp/pt.c (working copy) @@ -2275,7 +2275,7 @@ permerror (DECL_SOURCE_LOCATION (decl), %qD is not a static data member of a class template, decl); } - else if (template_header_count wanted) + if (template_header_count wanted) { pedwarn (DECL_SOURCE_LOCATION (decl), 0, too many template headers for %D (should be %d), @@ -4618,10 +4618,11 @@ TYPE_DECL_ALIAS_P (decl)) /* alias-declaration */ gcc_assert (!DECL_ARTIFICIAL (decl)); - else if (VAR_P (decl)) { -if (!DECL_DECLARED_CONSTEXPR_P (decl)) - error (template declaration of non-constexpr variable %qD, decl); - } + else if (VAR_P (decl)) +{ + if (!DECL_DECLARED_CONSTEXPR_P (decl)) +error (template declaration of non-constexpr variable %qD, decl); +} else { error (template declaration of %q#D, decl);