Re: [PATCH] Teach VRP to register assertions along default switch labels (PR 18046)
On Fri, 22 Jul 2016, Patrick Palka wrote: > On Fri, 22 Jul 2016, Patrick Palka wrote: > > > On Fri, 22 Jul 2016, Patrick Palka wrote: > > > > > This patch teaches VRP to register along a default switch label > > > assertions that corresponds to the anti range of each case label. > > > > > > Does this look OK to commit after bootstrap + regtest on > > > x86_64-pc-linux-gnu? > > > > Forgot the changelog: > > > > gcc/ChangeLog: > > > > PR tree-optimization/18046 > > * tree-vrp.c (find_switch_asserts): Register edge assertions > > for the default label which correspond to the anti-ranges > > of each non-case label. > > > > gcc/testsuite/ChangeLog: > > > > PR tree-optimization/18046 > > * gcc.dg/tree-ssa/ssa-dom-thread-6.c: Bump FSM count to 5. > > * gcc.dg/tree-ssa/vrp103.c: New test. > > * gcc.dg/tree-ssa/vrp104.c: New test. > > > > The patch failed to bootstrap due to a number -Warray-bounds warnings > getting emitted for the autogenerated header file insn-modes.h: > > In file included from /home/patrick/code/gcc/gcc/machmode.h:24:0, > from /home/patrick/code/gcc/gcc/coretypes.h:391, > from /home/patrick/code/gcc/gcc/lto-streamer-out.c:25: > ./insn-modes.h: In function ‘void produce_asm_for_decls()’: > ./insn-modes.h:638:36: warning: array subscript is outside array bounds > [-Warray-bounds] > default: return mode_inner[mode]; > ~~~^ > > These new warnings seem legitimate. From what I can tell, this array > access along the default switch label will always be out of bounds. The > code it's warning about basically looks like this: > > enum A { a, b, c }; > int foo (A i) > { > int array[3]; > switch (i) > { > case a: return x; > case b: return y; > case c: return z; > default: return array[i]; > } > } > > and while the switch does exhaust every possible enumeration value of A, > there's nothing stopping the user from passing an arbitrary int to > foo() thus triggering the default case. So this patch suppresses these > warnings by making genemit emit an assertion that verifies that mode is > within the bounds of the array. This assertion won't affect performance > because the mode_*_inline functions are always called with constant > arguments. > > This version of the patch has the following changes: > > 1. Fixes the bootstrap failure as mentioned above. > 2. Checks if the switch operand is live along the default edge before > registering assertions. > 3. Combines contiguous case ranges to reduce the number of assert > expressions to insert. > > Bootstrap + regtesting in progress on x86_64-pc-linux-gnu. > > gcc/ChangeLog: > > PR tree-optimization/18046 > * genmodes.c (emit_mode_size_inline): Emit an assert that > verifies that mode is a valid array index. > (emit_mode_nuinits_inline): Likewise. > (emit_mode_inner_inline): Likewise. > (emit_mode_unit_size_inline): Likewise. > (emit_mode_unit_precision_inline): Likewise. > * tree-vrp.c (compare_case_label_values): New qsort callback. > (find_switch_asserts): Register edge assertions for > the default label, which correspond to the anti-range of each > non-case label. > > gcc/testsuite/ChangeLog: > > PR tree-optimization/18046 > * gcc.dg/tree-ssa/ssa-dom-thread-6.c: Bump FSM count to 5. > * gcc.dg/tree-ssa/vrp103.c: New test. > * gcc.dg/tree-ssa/vrp104.c: New test. Here's another version of the patch, which has the following changes: 1. Use wide-int arithmetic directly instead of tree arithmetic. 2. Don't bother re-sorting and re-using the ci vector. Instead just inspect gimple_switch_label() directly since cases are already sorted there by CASE_LOW. 3. Add an insertion limit of 10 and a tunable param. Bootstrapped + regtested on x86_64-pc-linux-gnu. gcc/ChangeLog: PR tree-optimization/18046 * genmodes.c (emit_mode_size_inline): Emit an assert that verifies that mode is a valid array index. (emit_mode_nuinits_inline): Likewise. (emit_mode_inner_inline): Likewise. (emit_mode_unit_size_inline): Likewise. (emit_mode_unit_precision_inline): Likewise. * tree-vrp.c: Include params.h. (find_switch_asserts): Register edge assertions for the default label which correspond to the anti-ranges of each non-case label. * params.def (PARAM_MAX_VRP_SWITCH_ASSERTIONS): New. * doc/invoke.texi: Document it. gcc/testsuite/ChangeLog: PR tree-optimization/18046 * gcc.dg/tree-ssa/ssa-dom-thread-6.c: Bump FSM count to 5. * gcc.dg/tree-ssa/vrp103.c: New test. * gcc.dg/tree-ssa/vrp104.c: New test. --- gcc/doc/invoke.texi | 4 ++ gcc/genmodes.c | 5 ++ gcc/params.def | 6 +++
Revert 2015-11-09 sanitizer/obstack configury
The 2015-11-23 sanitizer merge from upstream lost the changes from f6528435 to sanitizer_common/sanitizer_common_interceptors.inc, which made use of _OBSTACK_SIZE_T. So the configury changes to define _OBSTACK_SIZE_T don't do anything. This wasn't such a bad thing anyway.. The configure test wrongly adds -I${srcdir}/../include, effectively resulting in a test of libiberty/obstack rather than libc obstack support, and it's the latter that asan and tsan need to work with. So, remove the useless configure test. Upstream santizer project has been made aware of the problem if glibc obstack support is ever updated. Bootsrapped etc. x86_64-linux and committed as obvious. Revert 2015-11-09 Alan Modra* configure.ac: Don't substitute OBSTACK_DEFS. * asan/Makefile.am: Remove OBSTACK_DEFS from DEFS. * tsan/Makefile.am: Likewise. * configure: Regenerate. * Makefile.in: Regenerate. * asan/Makefile.in: Regenerate. * interception/Makefile.in: Regenerate. * libbacktrace/Makefile.in: Regenerate. * lsan/Makefile.in: Regenerate. * sanitizer_common/Makefile.in: Regenerate. * tsan/Makefile.in: Regenerate. * ubsan/Makefile.in: Regenerate. diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac index 063b1d6..93192e1 100644 --- a/libsanitizer/configure.ac +++ b/libsanitizer/configure.ac @@ -339,30 +339,6 @@ fi AC_SUBST([RPC_DEFS], [$rpc_defs]) -dnl If this file is processed by autoconf-2.67 or later then the CPPFLAGS -dnl "-o conftest.iii" can disappear, conftest.iii be replaced with -dnl conftest.i in the sed command line, and the rm deleted. -dnl Not all cpp's accept -o, and gcc -E does not accept a second file -dnl argument as the output file. -AC_CACHE_CHECK([obstack params], -[libsanitizer_cv_sys_obstack], -[save_cppflags=$CPPFLAGS -CPPFLAGS="-I${srcdir}/../include -o conftest.iii $CPPFLAGS" -AC_PREPROC_IFELSE([AC_LANG_SOURCE([ -#include "obstack.h" -#ifdef _OBSTACK_SIZE_T -_OBSTACK_SIZE_T -#else -int -#endif -])], -[libsanitizer_cv_sys_obstack=`sed -e '/^#/d;/^[ ]*$/d' conftest.iii | sed -e '$!d;s/size_t/SIZE_T/'`], -[libsanitizer_cv_sys_obstack=int]) -CPPFLAGS=$save_cppflags -rm -f conftest.iii -]) -AC_SUBST([OBSTACK_DEFS], [-D_OBSTACK_SIZE_T=\"$libsanitizer_cv_sys_obstack\"]) - AM_CONDITIONAL(LIBBACKTRACE_SUPPORTED, [test "x${BACKTRACE_SUPPORTED}x${BACKTRACE_USES_MALLOC}" = "x1x0"]) diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am index 4500e21..bd3cd73 100644 --- a/libsanitizer/asan/Makefile.am +++ b/libsanitizer/asan/Makefile.am @@ -3,7 +3,7 @@ AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir) # May be used by toolexeclibdir. gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) -DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DASAN_HAS_EXCEPTIONS=1 -DASAN_NEEDS_SEGV=1 -DCAN_SANITIZE_UB=0 @OBSTACK_DEFS@ +DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DASAN_HAS_EXCEPTIONS=1 -DASAN_NEEDS_SEGV=1 -DCAN_SANITIZE_UB=0 if USING_MAC_INTERPOSE DEFS += -DMAC_INTERPOSE_FUNCTIONS -DMISSING_BLOCKS_SUPPORT endif diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am index 6776923..9833de2 100644 --- a/libsanitizer/tsan/Makefile.am +++ b/libsanitizer/tsan/Makefile.am @@ -3,7 +3,7 @@ AM_CPPFLAGS = -I $(top_srcdir) -I $(top_srcdir)/include # May be used by toolexeclibdir. gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) -DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DCAN_SANITIZE_UB=0 @OBSTACK_DEFS@ +DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DCAN_SANITIZE_UB=0 AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fno-rtti -fomit-frame-pointer -funwind-tables -fvisibility=hidden -Wno-variadic-macros AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS) AM_CXXFLAGS += -std=gnu++11 -- Alan Modra Australia Development Lab, IBM
[PR70920] transform (intptr_t) x eq/ne CST to x eq/ne (typeof x) cst
Hi Richard, The attached patch tries to fix PR70920. It adds your pattern from comment 1 in the PR (with additional gating on INTEGRAL_TYPE_P to avoid regressing finalize_18.f90) and second pattern, which is reverse of the first transform. I needed to update ssa-dom-branch-1.c because with patch applied, jump threading removed the second if (i != 0B) block. The dumps with and without patch for ssa-dom-branch-1.c start to differ with forwprop1: before: : _1 = temp_16(D)->code; _2 = _1 == 42; _3 = (int) _2; _4 = (long int) _3; temp_17 = (struct rtx_def *) _4; if (temp_17 != 0B) goto ; else goto ; after: : _1 = temp_16(D)->code; _2 = _1 == 42; _3 = (int) _2; _4 = (long int) _2; temp_17 = (struct rtx_def *) _4; if (_1 == 42) goto ; else goto ; I suppose the transform is correct for above test-case ? Then vrp dump shows: Threaded jump 5 --> 9 to 13 Threaded jump 8 --> 9 to 13 Threaded jump 3 --> 9 to 13 Threaded jump 12 --> 9 to 14 Removing basic block 9 basic block 9, loop depth 0 pred: if (i1_10(D) != 0B) goto ; else goto ; succ: 10 11 So there remained two instances of if (i1_10 (D) != 0B) in dom2 dump file, and hence needed to update the test-case. Bootstrapped and tested on x86_64-unknown-linux-gnu. OK to commit ? PS: Writing changelog entries for match.pd is a bit tedious. Should we add optional names for pattern so we can refer to them by names in the ChangeLog for the more complicated ones ? Or maybe just use comments: (simplify /* name */ ... ) -;) Thanks, Prathamesh diff --git a/gcc/match.pd b/gcc/match.pd index 21bf617..7c736be 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3408,3 +3408,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { CONSTRUCTOR_ELT (ctor, idx / k)->value; }) (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / k)->value; } @1 { bitsize_int ((idx % k) * width); }) + +/* PR70920: Transform (intptr_t)x eq/ne CST to x eq/ne (typeof x) CST. */ + +(for cmp (ne eq) + (simplify + (cmp (convert@2 @0) INTEGER_CST@1) + (if (POINTER_TYPE_P (TREE_TYPE (@0)) + && INTEGRAL_TYPE_P (TREE_TYPE (@2))) + (cmp @0 (convert @1) + +/* Reverse of the above case: + x has integral_type, CST is a pointer constant. + Transform (typeof CST)x eq/ne CST to x eq/ne (typeof x) CST. */ + +(for cmp (ne eq) + (simplify + (cmp (convert @0) @1) + (if (POINTER_TYPE_P (TREE_TYPE (@1)) + && INTEGRAL_TYPE_P (TREE_TYPE (@0))) +(cmp @0 (convert @1) diff --git a/gcc/testsuite/gcc.dg/pr70920-1.c b/gcc/testsuite/gcc.dg/pr70920-1.c new file mode 100644 index 000..9b7e2d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr70920-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-gimple" } */ + +#include + +void f1(); +void f2(); + +void +foo (int *a) +{ + if ((intptr_t) a == 0) +{ + f1 (); + if (a) + f2 (); +} +} + +/* { dg-final { scan-tree-dump "if \\(a == 0B\\)" "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/pr70920-2.c b/gcc/testsuite/gcc.dg/pr70920-2.c new file mode 100644 index 000..2db9897 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr70920-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop-details" } */ + +#include + +void f1(); +void f2(); + +void +foo (int *a) +{ + int cst = 0; + if ((intptr_t) a == cst) +{ + f1 (); + if (a) + f2 (); +} +} + +/* { dg-final { scan-tree-dump "gimple_simplified to if \\(a_\[0-9\]*\\(D\\) == 0B\\)" "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/pr70920-3.c b/gcc/testsuite/gcc.dg/pr70920-3.c new file mode 100644 index 000..71e0d8d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr70920-3.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-Wno-int-to-pointer-cast -fdump-tree-gimple" } */ + +#include + +void f1(); +void f2(); + +void +foo (int a) +{ + if ((int *) a == 0) +{ + f1 (); + if (a) + f2 (); +} +} + +/* { dg-final { scan-tree-dump "if \\(a == 0\\)" "gimple" } } */ diff --git a/gcc/testsuite/gcc.dg/pr70920-4.c b/gcc/testsuite/gcc.dg/pr70920-4.c new file mode 100644 index 000..f92c5a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr70920-4.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop-details -Wno-int-to-pointer-cast" } */ + +#include + +void f1(); +void f2(); + +void +foo (int a) +{ + void *cst = 0; + if ((int *) a == cst) +{ + f1 (); + if (a) + f2 (); +} +} + +/* { dg-final { scan-tree-dump "gimple_simplified to if \\(a_\[0-9\]*\\(D\\) == 0\\)" "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c index 18f9041..d38e3a8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c @@ -21,7 +21,7 @@ try_combine (rtx i1, rtx newpat) /* There should be three tests
C++ PATCH for c++/71515 (typename in partial specialization)
Here we got into infinite recursion trying to determine if A is the same as Abecause we would keep trying to resolve the typename, which would want to compare the types again to see if A is a currently open class, and so on. This patch avoids this recursion by checking whether the typename scope has TYPE_FIELDS set before we bother to see if it's a currently open class; if TYPE_FIELDS isn't set then this particular dependent template-id has not been defined as a partial specialization anywhere, so there's no point in checking to see if it matches one of the currently open classes. Tested x86_64-pc-linux-gnu, applying to trunk. commit 56912a98d98144373a621a87455dcb5721f346a8 Author: Jason Merrill Date: Fri Jul 22 14:42:53 2016 -0400 PR c++/71515 - typename in partial specialization * pt.c (resolve_typename_type): Try to avoid calling currently_open_class. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 65fa982..a61f1c8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23678,29 +23678,26 @@ resolve_typename_type (tree type, bool only_current_p) } /* If we don't know what SCOPE refers to, then we cannot resolve the TYPENAME_TYPE. */ - if (TREE_CODE (scope) == TYPENAME_TYPE) -return type; - /* If the SCOPE is a template type parameter, we have no way of - resolving the name. */ - if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM) -return type; - /* If the SCOPE is not the current instantiation, there's no reason - to look inside it. */ - if (only_current_p && !currently_open_class (scope)) + if (!CLASS_TYPE_P (scope)) return type; /* If this is a typedef, we don't want to look inside (c++/11987). */ if (typedef_variant_p (type)) return type; /* If SCOPE isn't the template itself, it will not have a valid TYPE_FIELDS list. */ - if (CLASS_TYPE_P (scope) - && same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope))) + if (same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope))) /* scope is either the template itself or a compatible instantiation like X, so look up the name in the original template. */ scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope); - else -/* scope is a partial instantiation, so we can't do the lookup or we - will lose the template arguments. */ + /* We shouldn't have built a TYPENAME_TYPE with a non-dependent scope. */ + gcc_checking_assert (uses_template_parms (scope)); + /* If scope has no fields, it can't be a current instantiation. Check this + before currently_open_class to avoid infinite recursion (71515). */ + if (!TYPE_FIELDS (scope)) +return type; + /* If the SCOPE is not the current instantiation, there's no reason + to look inside it. */ + if (only_current_p && !currently_open_class (scope)) return type; /* Enter the SCOPE so that name lookup will be resolved as if we were in the class definition. In particular, SCOPE will no diff --git a/gcc/testsuite/g++.dg/template/typename22.C b/gcc/testsuite/g++.dg/template/typename22.C new file mode 100644 index 000..b5dc1b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename22.C @@ -0,0 +1,8 @@ +// PR c++/71515 + +template < typename, typename = int > struct A; + +template < typename T > struct A < T, typename A < T >::type > +{ + A < int > *a; +};
Re: [v3 PATCH] Implement std::string_view and P0254r2, Integrating std::string_view and std::string.
On 19 July 2016 at 21:34, Ville Voutilainenwrote: > Tested on Linux-x64. > > I'm quite sure there are cosmetic issues left in this patch, like in the > section > references of the tests. I will send it out for review now anyway. I fixed the section references for the tests that add new tests for basic_string, they are now correct and mnemonic rather than incorrect and numeric. I also tweaked the compare implementation a bit based on my discussions with Marshall. Changelog as it was before, tested on Linux-x64. I haven't fixed all section references of string tests, and I haven't added section references to string_view tests, because they didn't have any. I also haven't added tests that test the various exception-throwing cases for the various operations. Doing those changes is a) going to change many many files b) probably not urgent so here's a modest suggestion: let's put this patch in, and tweak the section references in the other tests later with separate patches, as well as add more comprehensive exception-tests. Ok for trunk? std_string_view_2.diff.gz Description: GNU Zip compressed data
[PATCH 3/3] merge adjust_cost and adjust_cost_2 target hooks
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * config/alpha/alpha.c (alpha_adjust_cost): Adjust. * config/arm/arm-protos.h (struct tune_params): Likewise. * config/arm/arm.c (xscale_sched_adjust_cost): Likewise. (cortex_a9_sched_adjust_cost): Likewise. (fa726te_sched_adjust_cost): Likewise. (arm_adjust_cost): Likewise. * config/bfin/bfin.c (bfin_adjust_cost): Likewise. * config/c6x/c6x.c (c6x_adjust_cost): Likewise. * config/epiphany/epiphany.c (epiphany_adjust_cost): Likewise. * config/i386/i386.c (ix86_adjust_cost): Likewise. * config/ia64/ia64.c: Likewise. * config/m68k/m68k.c: Likewise. * config/mep/mep.c (mep_adjust_cost): Likewise. * config/microblaze/microblaze.c (microblaze_adjust_cost): * Likewise. * config/mips/mips.c (mips_adjust_cost): Likewise. * config/mn10300/mn10300.c (mn10300_adjust_sched_cost): * Likewise. * config/pa/pa.c (pa_adjust_cost): Likewise. * config/rs6000/rs6000.c (rs6000_adjust_cost): Likewise. (rs6000_debug_adjust_cost): Likewise. * config/sh/sh.c (sh_adjust_cost): Likewise. * config/sparc/sparc.c (supersparc_adjust_cost): Likewise. (hypersparc_adjust_cost): Likewise. (sparc_adjust_cost): Likewise. * config/spu/spu.c (spu_sched_adjust_cost): Likewise. * config/tilegx/tilegx.c (tilegx_sched_adjust_cost): Likewise. * config/tilepro/tilepro.c (tilepro_sched_adjust_cost): * Likewise. * config/visium/visium.c (visium_adjust_cost): Likewise. * doc/tm.texi: Regenerate. * haifa-sched.c (dep_cost_1): Adjust. * target.def: Merge adjust_cost and adjust_cost_2. --- gcc/config/alpha/alpha.c | 5 +++-- gcc/config/arm/arm-protos.h| 2 +- gcc/config/arm/arm.c | 40 +- gcc/config/bfin/bfin.c | 5 +++-- gcc/config/c6x/c6x.c | 5 +++-- gcc/config/epiphany/epiphany.c | 5 +++-- gcc/config/i386/i386.c | 5 +++-- gcc/config/ia64/ia64.c | 10 +- gcc/config/m68k/m68k.c | 7 --- gcc/config/microblaze/microblaze.c | 10 -- gcc/config/mips/mips.c | 8 ++-- gcc/config/mn10300/mn10300.c | 5 +++-- gcc/config/pa/pa.c | 9 + gcc/config/rs6000/rs6000.c | 16 --- gcc/config/sh/sh.c | 10 +- gcc/config/sparc/sparc.c | 23 -- gcc/config/spu/spu.c | 5 +++-- gcc/config/tilegx/tilegx.c | 6 +++--- gcc/config/tilepro/tilepro.c | 6 +++--- gcc/config/visium/visium.c | 11 ++- gcc/doc/tm.texi| 14 ++--- gcc/haifa-sched.c | 25 +++- gcc/target.def | 25 +--- 23 files changed, 122 insertions(+), 135 deletions(-) diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 94fed102..702cd27 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -4758,14 +4758,15 @@ alpha_split_atomic_exchange_12 (rtx operands[]) a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ static int -alpha_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost) +alpha_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, + unsigned int) { enum attr_type dep_insn_type; /* If the dependence is an anti-dependence, there is no cost. For an output dependence, there is sometimes a cost, but it doesn't seem worth handling those few cases. */ - if (REG_NOTE_KIND (link) != 0) + if (dep_type != 0) return cost; /* If we can't recognize the insns, we can't really do anything. */ diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 49c3a92..3975612 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -260,7 +260,7 @@ struct tune_params { bool (*rtx_costs) (rtx, RTX_CODE, RTX_CODE, int *, bool); const struct cpu_cost_table *insn_extra_cost; - bool (*sched_adjust_cost) (rtx_insn *, rtx, rtx_insn *, int *); + bool (*sched_adjust_cost) (rtx_insn *, int, rtx_insn *, int *); int (*branch_cost) (bool, bool); /* Vectorizer costs. */ const struct cpu_vec_costs* vec_costs; diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 195de48..a6afdcc 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -138,7 +138,7 @@ static void arm_output_function_epilogue (FILE *, HOST_WIDE_INT); static void arm_output_function_prologue (FILE *, HOST_WIDE_INT); static int arm_comp_type_attributes (const_tree, const_tree); static void arm_set_default_type_attributes (tree); -static int
[PATCH 2/3] haifa-sched.c: make twins a auto_vec
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * haifa-sched.c (add_to_speculative_block): Make twins a vector. --- gcc/haifa-sched.c | 25 - 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 9503576..93b7089 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -7991,7 +7991,7 @@ add_to_speculative_block (rtx_insn *insn) ds_t ts; sd_iterator_def sd_it; dep_t dep; - rtx_insn_list *twins = NULL; + auto_vec twins; ts = TODO_SPEC (insn); gcc_assert (!(ts & ~BE_IN_SPEC)); @@ -8060,7 +8060,7 @@ add_to_speculative_block (rtx_insn *insn) fprintf (spec_info->dump, ";;\t\tGenerated twin insn : %d/rec%d\n", INSN_UID (twin), rec->index); - twins = alloc_INSN_LIST (twin, twins); + twins.safe_push (twin); /* Add dependences between TWIN and all appropriate instructions from REC. */ @@ -8099,23 +8099,14 @@ add_to_speculative_block (rtx_insn *insn) /* We couldn't have added the dependencies between INSN and TWINS earlier because that would make TWINS appear in the INSN_BACK_DEPS (INSN). */ - while (twins) + unsigned int i; + rtx_insn *twin; + FOR_EACH_VEC_ELT_REVERSE (twins, i, twin) { - rtx_insn *twin; - rtx_insn_list *next_node; - - twin = twins->insn (); - - { - dep_def _new_dep, *new_dep = &_new_dep; + dep_def _new_dep, *new_dep = &_new_dep; - init_dep (new_dep, insn, twin, REG_DEP_OUTPUT); - sd_add_dep (new_dep, false); - } - - next_node = twins->next (); - free_INSN_LIST_node (twins); - twins = next_node; + init_dep (new_dep, insn, twin, REG_DEP_OUTPUT); + sd_add_dep (new_dep, false); } calc_priorities (priorities_roots); -- 2.9.0
[PATCH 1/3] make pattern_regs a vec
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * store-motion.c (struct st_expr): Make pattern_regs a vector. (extract_mentioned_regs): Append to a vector instead of returning a rtx_expr_list. (st_expr_entry): Adjust. (store_ops_ok): Likewise. (store_killed_in_insn): Likewise. (find_moveable_store): Likewise. --- gcc/store-motion.c | 51 +-- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/gcc/store-motion.c b/gcc/store-motion.c index 6d7d37f..0293d96 100644 --- a/gcc/store-motion.c +++ b/gcc/store-motion.c @@ -63,7 +63,7 @@ struct st_expr /* Pattern of this mem. */ rtx pattern; /* List of registers mentioned by the mem. */ - rtx pattern_regs; + vec pattern_regs; /* INSN list of stores that are locally anticipatable. */ vec antic_stores; /* INSN list of stores that are locally available. */ @@ -146,7 +146,7 @@ st_expr_entry (rtx x) ptr->next = store_motion_mems; ptr->pattern = x; - ptr->pattern_regs = NULL_RTX; + ptr->pattern_regs.create (0); ptr->antic_stores.create (0); ptr->avail_stores.create (0); ptr->reaching_reg = NULL_RTX; @@ -248,16 +248,13 @@ print_store_motion_mems (FILE * file) due to set of registers in bitmap REGS_SET. */ static bool -store_ops_ok (const_rtx x, int *regs_set) +store_ops_ok (const vec , int *regs_set) { - const_rtx reg; - - for (; x; x = XEXP (x, 1)) -{ - reg = XEXP (x, 0); - if (regs_set[REGNO (reg)]) - return false; -} + unsigned int i; + rtx temp; + FOR_EACH_VEC_ELT (x, i, temp) +if (regs_set[REGNO (temp)]) + return false; return true; } @@ -265,18 +262,16 @@ store_ops_ok (const_rtx x, int *regs_set) /* Returns a list of registers mentioned in X. FIXME: A regset would be prettier and less expensive. */ -static rtx_expr_list * -extract_mentioned_regs (rtx x) +static void +extract_mentioned_regs (rtx x, vec *mentioned_regs) { - rtx_expr_list *mentioned_regs = NULL; subrtx_var_iterator::array_type array; FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST) { rtx x = *iter; if (REG_P (x)) - mentioned_regs = alloc_EXPR_LIST (0, x, mentioned_regs); + mentioned_regs->safe_push (x); } - return mentioned_regs; } /* Check to see if the load X is aliased with STORE_PATTERN. @@ -373,9 +368,10 @@ store_killed_in_pat (const_rtx x, const_rtx pat, int after) after the insn. Return true if it does. */ static bool -store_killed_in_insn (const_rtx x, const_rtx x_regs, const rtx_insn *insn, int after) +store_killed_in_insn (const_rtx x, const vec _regs, + const rtx_insn *insn, int after) { - const_rtx reg, note, pat; + const_rtx note, pat; if (! NONDEBUG_INSN_P (insn)) return false; @@ -389,8 +385,10 @@ store_killed_in_insn (const_rtx x, const_rtx x_regs, const rtx_insn *insn, int a /* But even a const call reads its parameters. Check whether the base of some of registers used in mem is stack pointer. */ - for (reg = x_regs; reg; reg = XEXP (reg, 1)) - if (may_be_sp_based_p (XEXP (reg, 0))) + rtx temp; + unsigned int i; + FOR_EACH_VEC_ELT (x_regs, i, temp) + if (may_be_sp_based_p (temp)) return true; return false; @@ -435,8 +433,8 @@ store_killed_in_insn (const_rtx x, const_rtx x_regs, const rtx_insn *insn, int a is killed, return the last insn in that it occurs in FAIL_INSN. */ static bool -store_killed_after (const_rtx x, const_rtx x_regs, const rtx_insn *insn, - const_basic_block bb, +store_killed_after (const_rtx x, const vec _regs, + const rtx_insn *insn, const_basic_block bb, int *regs_set_after, rtx *fail_insn) { rtx_insn *last = BB_END (bb), *act; @@ -465,8 +463,9 @@ store_killed_after (const_rtx x, const_rtx x_regs, const rtx_insn *insn, within basic block BB. X_REGS is list of registers mentioned in X. REGS_SET_BEFORE is bitmap of registers set before or in this insn. */ static bool -store_killed_before (const_rtx x, const_rtx x_regs, const rtx_insn *insn, -const_basic_block bb, int *regs_set_before) +store_killed_before (const_rtx x, const vec _regs, +const rtx_insn *insn, const_basic_block bb, +int *regs_set_before) { rtx_insn *first = BB_HEAD (bb); @@ -555,8 +554,8 @@ find_moveable_store (rtx_insn *insn, int *regs_set_before, int *regs_set_after) return; ptr = st_expr_entry (dest); - if (!ptr->pattern_regs) -ptr->pattern_regs = extract_mentioned_regs (dest); + if (ptr->pattern_regs.is_empty ()) +extract_mentioned_regs (dest, >pattern_regs); /* Do not check for anticipatability if we either found one anticipatable store already, or tested for
[PATCH 0/3] more removal of rtl lists
From: Trevor SaundersHi, Here's a few more patches getting rid of usage of rtl lists. In patches 1 and 2 a list is created and then iterated over, which would generally seem to be a better fit for a vector than a linked list. The code involved in patch 3 doesn't really use a list at all, it just simplifies an API that used a list node. patches bootstrapped on x86_64-linux-gnu, and I checked one target per effected config/ directory still builds, ok? Trev Trevor Saunders (3): make pattern_regs a vec haifa-sched.c: make twins a auto_vec merge adjust_cost and adjust_cost_2 target hooks gcc/config/alpha/alpha.c | 5 ++-- gcc/config/arm/arm-protos.h| 2 +- gcc/config/arm/arm.c | 40 -- gcc/config/bfin/bfin.c | 5 ++-- gcc/config/c6x/c6x.c | 5 ++-- gcc/config/epiphany/epiphany.c | 5 ++-- gcc/config/i386/i386.c | 5 ++-- gcc/config/ia64/ia64.c | 10 gcc/config/m68k/m68k.c | 7 +++--- gcc/config/microblaze/microblaze.c | 10 +++- gcc/config/mips/mips.c | 8 ++ gcc/config/mn10300/mn10300.c | 5 ++-- gcc/config/pa/pa.c | 9 --- gcc/config/rs6000/rs6000.c | 16 ++-- gcc/config/sh/sh.c | 10 gcc/config/sparc/sparc.c | 23 + gcc/config/spu/spu.c | 5 ++-- gcc/config/tilegx/tilegx.c | 6 ++--- gcc/config/tilepro/tilepro.c | 6 ++--- gcc/config/visium/visium.c | 11 gcc/doc/tm.texi| 14 +-- gcc/haifa-sched.c | 50 - gcc/store-motion.c | 51 +++--- gcc/target.def | 25 +++ 24 files changed, 155 insertions(+), 178 deletions(-) -- 2.9.0
Re: [PATCH RFC] do not take mutex in _Unwind_Find_registered_FDE if there is no registered objects
Thank you for prompt review. On Sun, Jul 24, 2016 at 11:00:53AM -0700, Andrew Pinski wrote: > On Sun, Jul 24, 2016 at 8:01 AM, Gleb Natapovwrote: > > _Unwind_Find_FDE calls _Unwind_Find_registered_FDE and it takes lock even > > when there is no registered objects. As far as I see only statically > > linked applications call __register_frame_info* functions, so for > > dynamically linked executables taking the lock to check unseen_objects > > and seen_objects is a pessimization. Since the function is called on > > each thrown exception this is a lot of unneeded locking. This patch > > checks unseen_objects and seen_objects outside of the lock and returns > > earlier if both are NULL. > > There are problems with this patch. > First the stores to unseen_objects and seen_objects are not atomic stores. They are not atomic yes, but they are in locked section so there is a release after the store which should order writes to both of them. I can use __atomic_store_n for storing but I do not see (yet) why it is needed. > The second issue is not all targets support atomics because some are > single threaded. __atomic builtins should compile to regular stores/loads on those, no? If __atomic builtins cannot be used on those platforms can this be detected with preprocessor macros somehow? > Another issue is CONSUME memory model should almost never be used; it > just decays into acquire anyways. > > Hmm, yes, not sure why I used CONSUME here instead of ACQUIRE. > > > > diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c > > index 5b16a1f..9af558d 100644 > > --- a/libgcc/unwind-dw2-fde.c > > +++ b/libgcc/unwind-dw2-fde.c > > @@ -1001,6 +1001,10 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases > > *bases) > >struct object *ob; > >const fde *f = NULL; > > > > + if (!__atomic_load_n(_objects, __ATOMIC_CONSUME) && > > !__atomic_load_n(_objects, __ATOMIC_CONSUME)) { > > + return NULL; > > + } > > There is formatting issues too. > if (!__atomic_load_n(_objects, __ATOMIC_CONSUME) > && !__atomic_load_n(_objects, __ATOMIC_CONSUME)) > { > return NULL; > } > > is the correct formating. > OK. > > + > >init_object_mutex_once (); > >__gthread_mutex_lock (_mutex); > > > > @@ -1020,8 +1024,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases > > *bases) > >while ((ob = unseen_objects)) > > { > >struct object **p; > > + struct object *next = ob->next; > > > > - unseen_objects = ob->next; > >f = search_object (ob, pc); > > > >/* Insert the object into the classified list. */ > > @@ -1031,6 +1035,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases > > *bases) > >ob->next = *p; > >*p = ob; > > > > + unseen_objects = next; > > This store should be an atomic store to be paired with the loads. > This store is inside mutex, so unlock will have RELEASE. > Thanks, > Andrew > > > + > >if (f) > > goto fini; > > } > > -- > > Gleb. -- Gleb.
Re: [PATCH RFC] do not take mutex in _Unwind_Find_registered_FDE if there is no registered objects
On Sun, Jul 24, 2016 at 8:01 AM, Gleb Natapovwrote: > _Unwind_Find_FDE calls _Unwind_Find_registered_FDE and it takes lock even > when there is no registered objects. As far as I see only statically > linked applications call __register_frame_info* functions, so for > dynamically linked executables taking the lock to check unseen_objects > and seen_objects is a pessimization. Since the function is called on > each thrown exception this is a lot of unneeded locking. This patch > checks unseen_objects and seen_objects outside of the lock and returns > earlier if both are NULL. There are problems with this patch. First the stores to unseen_objects and seen_objects are not atomic stores. The second issue is not all targets support atomics because some are single threaded. Another issue is CONSUME memory model should almost never be used; it just decays into acquire anyways. > > diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c > index 5b16a1f..9af558d 100644 > --- a/libgcc/unwind-dw2-fde.c > +++ b/libgcc/unwind-dw2-fde.c > @@ -1001,6 +1001,10 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases > *bases) >struct object *ob; >const fde *f = NULL; > > + if (!__atomic_load_n(_objects, __ATOMIC_CONSUME) && > !__atomic_load_n(_objects, __ATOMIC_CONSUME)) { > + return NULL; > + } There is formatting issues too. if (!__atomic_load_n(_objects, __ATOMIC_CONSUME) && !__atomic_load_n(_objects, __ATOMIC_CONSUME)) { return NULL; } is the correct formating. > + >init_object_mutex_once (); >__gthread_mutex_lock (_mutex); > > @@ -1020,8 +1024,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases > *bases) >while ((ob = unseen_objects)) > { >struct object **p; > + struct object *next = ob->next; > > - unseen_objects = ob->next; >f = search_object (ob, pc); > >/* Insert the object into the classified list. */ > @@ -1031,6 +1035,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases > *bases) >ob->next = *p; >*p = ob; > > + unseen_objects = next; This store should be an atomic store to be paired with the loads. Thanks, Andrew > + >if (f) > goto fini; > } > -- > Gleb.
Re: [PATCH] Teach VRP to register assertions along default switch labels (PR 18046)
On Sun, Jul 24, 2016 at 9:49 AM, Patrick Palkawrote: > On Sat, Jul 23, 2016 at 9:13 PM, kugan > wrote: >> >> >> On 23/07/16 05:26, Patrick Palka wrote: >>> >>> This patch teaches VRP to register along a default switch label >>> assertions that corresponds to the anti range of each case label. >> >> >> Hi Patrick, >> >> In case of a larger switch statement with case values that cannot be >> combined, you could end up with very large number of ASSERT_EXPRs in the >> default basic block. I am not sure if this would have any impact on compile >> time/memory usage? If that is the case you might want to punt at some >> length? > > Hi Kugan, > > That sounds like a good idea to me. So I gathered some info about the > number of assert_exprs inserted in the default bb during GCC bootstrap > with this patch: > > Max # of asserts inserted in a default BB: 59 > Median #: 2 > Average #: 3.33817 > Std. dev: 4.76926 > 95% percentile: 10 > > Based on the last point I guess 10 would be a good limit? > Make sure this is a parameter so someone can increase it if they want. But 10 seems like a good default. Thanks, Andrew Pinski >> >> Thanks, >> Kugan
Re: [PATCH] Teach VRP to register assertions along default switch labels (PR 18046)
On Sat, Jul 23, 2016 at 9:13 PM, kuganwrote: > > > On 23/07/16 05:26, Patrick Palka wrote: >> >> This patch teaches VRP to register along a default switch label >> assertions that corresponds to the anti range of each case label. > > > Hi Patrick, > > In case of a larger switch statement with case values that cannot be > combined, you could end up with very large number of ASSERT_EXPRs in the > default basic block. I am not sure if this would have any impact on compile > time/memory usage? If that is the case you might want to punt at some > length? Hi Kugan, That sounds like a good idea to me. So I gathered some info about the number of assert_exprs inserted in the default bb during GCC bootstrap with this patch: Max # of asserts inserted in a default BB: 59 Median #: 2 Average #: 3.33817 Std. dev: 4.76926 95% percentile: 10 Based on the last point I guess 10 would be a good limit? > > Thanks, > Kugan
Re: [PATCH 1/6] add auto_sbitmap class
On July 24, 2016 1:44:44 PM GMT+02:00, tbsaunde+...@tbsaunde.org wrote: >From: Trevor Saunders> >gcc/ChangeLog: > >2016-07-24 Trevor Saunders > > * sbitmap.h (auto_sbitmap): New class. OK. Richard. > gcc/sbitmap.h | 21 + > 1 file changed, 21 insertions(+) > >diff --git a/gcc/sbitmap.h b/gcc/sbitmap.h >index c208171..d4a2918 100644 >--- a/gcc/sbitmap.h >+++ b/gcc/sbitmap.h >@@ -256,4 +256,25 @@ extern int bitmap_last_set_bit (const_sbitmap); > > extern void debug_bitmap (const_sbitmap); > extern sbitmap sbitmap_realloc (sbitmap, unsigned int); >+ >+/* a class that ties the lifetime of a sbitmap to its scope. */ >+class auto_sbitmap >+{ >+public: >+ explicit auto_sbitmap (unsigned int size) : >+m_bitmap (sbitmap_alloc (size)) {} >+ ~auto_sbitmap () { sbitmap_free (m_bitmap); } >+ >+ /* Allow calling sbitmap functions on our bitmap. */ >+ operator sbitmap () { return m_bitmap; } >+ >+private: >+ /* Prevent making a copy that refers to our sbitmap. */ >+ auto_sbitmap (const auto_sbitmap &); >+ auto_sbitmap = (const auto_sbitmap &); >+ >+ /* The bitmap we are managing. */ >+ sbitmap m_bitmap; >+}; >+ > #endif /* ! GCC_SBITMAP_H */
Re: [PATCH 6/6] add [cd]tors to scc_info
On July 24, 2016 1:44:49 PM GMT+02:00, tbsaunde+...@tbsaunde.org wrote: >From: Trevor Saunders> >gcc/ChangeLog: > >2016-07-24 Trevor Saunders > > * tree-ssa-structalias.c (struct scc_info): Change types of > members to auto_sbitmap and auto_vec. > (scc_info::scc_info): New constructor. > (scc_info::~scc_info): New destructor. > (init_scc_info): Remove. > (free_scc_info): Remove. > (find_indirect_cycles): Adjust. > (perform_var_substitution): Likewise. > (free_var_substitution_info): Likewise. >--- OK. Richard. >gcc/tree-ssa-structalias.c | 57 >++ > 1 file changed, 22 insertions(+), 35 deletions(-) > >diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c >index 94d81ed1..a669065 100644 >--- a/gcc/tree-ssa-structalias.c >+++ b/gcc/tree-ssa-structalias.c >@@ -1379,12 +1379,15 @@ static bitmap changed; > > struct scc_info > { >- sbitmap visited; >- sbitmap deleted; >+ scc_info (size_t size); >+ ~scc_info (); >+ >+ auto_sbitmap visited; >+ auto_sbitmap deleted; > unsigned int *dfs; > unsigned int *node_mapping; > int current_index; >- vec scc_stack; >+ auto_vec scc_stack; > }; > > >@@ -1809,38 +1812,24 @@ do_complex_constraint (constraint_graph_t >graph, constraint_t c, bitmap delta, > > /* Initialize and return a new SCC info structure. */ > >-static struct scc_info * >-init_scc_info (size_t size) >+scc_info::scc_info (size_t size) : >+ visited (size), deleted (size), current_index (0), scc_stack (1) > { >- struct scc_info *si = XNEW (struct scc_info); >- size_t i; >- >- si->current_index = 0; >- si->visited = sbitmap_alloc (size); >- bitmap_clear (si->visited); >- si->deleted = sbitmap_alloc (size); >- bitmap_clear (si->deleted); >- si->node_mapping = XNEWVEC (unsigned int, size); >- si->dfs = XCNEWVEC (unsigned int, size); >- >- for (i = 0; i < size; i++) >-si->node_mapping[i] = i; >+ bitmap_clear (visited); >+ bitmap_clear (deleted); >+ node_mapping = XNEWVEC (unsigned int, size); >+ dfs = XCNEWVEC (unsigned int, size); > >- si->scc_stack.create (1); >- return si; >+ for (size_t i = 0; i < size; i++) >+node_mapping[i] = i; > } > > /* Free an SCC info structure pointed to by SI */ > >-static void >-free_scc_info (struct scc_info *si) >+scc_info::~scc_info () > { >- sbitmap_free (si->visited); >- sbitmap_free (si->deleted); >- free (si->node_mapping); >- free (si->dfs); >- si->scc_stack.release (); >- free (si); >+ free (node_mapping); >+ free (dfs); > } > > >@@ -1856,13 +1845,11 @@ find_indirect_cycles (constraint_graph_t graph) > { > unsigned int i; > unsigned int size = graph->size; >- struct scc_info *si = init_scc_info (size); >+ scc_info si (size); > > for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ ) >-if (!bitmap_bit_p (si->visited, i) && find (i) == i) >- scc_visit (graph, si, i); >- >- free_scc_info (si); >+if (!bitmap_bit_p (si.visited, i) && find (i) == i) >+ scc_visit (graph, , i); > } > >/* Compute a topological ordering for GRAPH, and store the result in >the >@@ -2276,7 +2263,7 @@ perform_var_substitution (constraint_graph_t >graph) > { > unsigned int i; > unsigned int size = graph->size; >- struct scc_info *si = init_scc_info (size); >+ scc_info *si = new scc_info (size); > > bitmap_obstack_initialize (_obstack); > pointer_equiv_class_table = new hash_table (511); >@@ -2407,7 +2394,7 @@ perform_var_substitution (constraint_graph_t >graph) > static void > free_var_substitution_info (struct scc_info *si) > { >- free_scc_info (si); >+ delete si; > free (graph->pointer_label); > free (graph->loc_label); > free (graph->pointed_by);
[PATCH RFC] do not take mutex in _Unwind_Find_registered_FDE if there is no registered objects
_Unwind_Find_FDE calls _Unwind_Find_registered_FDE and it takes lock even when there is no registered objects. As far as I see only statically linked applications call __register_frame_info* functions, so for dynamically linked executables taking the lock to check unseen_objects and seen_objects is a pessimization. Since the function is called on each thrown exception this is a lot of unneeded locking. This patch checks unseen_objects and seen_objects outside of the lock and returns earlier if both are NULL. diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c index 5b16a1f..9af558d 100644 --- a/libgcc/unwind-dw2-fde.c +++ b/libgcc/unwind-dw2-fde.c @@ -1001,6 +1001,10 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) struct object *ob; const fde *f = NULL; + if (!__atomic_load_n(_objects, __ATOMIC_CONSUME) && !__atomic_load_n(_objects, __ATOMIC_CONSUME)) { + return NULL; + } + init_object_mutex_once (); __gthread_mutex_lock (_mutex); @@ -1020,8 +1024,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) while ((ob = unseen_objects)) { struct object **p; + struct object *next = ob->next; - unseen_objects = ob->next; f = search_object (ob, pc); /* Insert the object into the classified list. */ @@ -1031,6 +1035,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) ob->next = *p; *p = ob; + unseen_objects = next; + if (f) goto fini; } -- Gleb.
[Patch, libfortran] Multi-threaded random_number
Hi, the attached patch replaces the current random_number / random_seed implementations with an implementation that better supports threads. It's an improved version of the RFC patch I posted earlier at https://gcc.gnu.org/ml/gcc-patches/2015-12/msg02110.html . Please see that earlier message for a longer-winded explanation of what's wrong with the current implementation and how the patch addresses this. In short, with the patch the random number generator state is now per-thread and stored in a per-thread (TLS) variable, enabling a lockless fast-path. This provides up to 2 orders of magnitude better performance on a synthetic benchmark using 4 threads, and provides a more deterministic result as the order that threads are scheduled does not affect the random number streams for each thread. Compared to the RFC patch, a number of minor and not-so-minor bugs have been fixed, so the patch now passes the testsuite (with a few modifications to the suite, part of the patch). Also, for REAL kinds 4, 8, 10 the generated streams are identical (except precision, of course) (like the current implementation), enabling precision comparisons, as requested by Steve Kargl. However, this does not extend to REAL(16) as that would have necessitated doubling the size of the state, along with potential issues of slower escape from a low-entropy state, for a feature that I believe is not used by particularly many users in the end. So if one wants to do precision comparisons with REAL(16) one must employ a wrapper routine. Regtested on x86_64-pc-linux-gnu, Ok for trunk? frontend ChangeLog: 2016-07-27 Janne Blomqvist* check.c (gfc_check_random_seed): Use new seed size in check. * intrinsic.texi (RANDOM_NUMBER): Updated documentation. (RANDOM_SEED): Likewise. testsuite: 2016-07-27 Janne Blomqvist * gfortran.dg/random_7.f90: Take into account that the last seed value is the special p value. * gfortran.dg/random_seed_1.f90: Seed size is now constant. libgfortran: 2016-07-27 Janne Blomqvist * intrinsics/random.c: Replace KISS with xorshift1024* with per-thread (TLS) state. * runtime/main.c (init): Don't call random_seed_i4. -- Janne Blomqvist random_threads.diff.gz Description: GNU Zip compressed data
[PATCH 3/6] add ctor to topo_info
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * tree-ssa-structalias.c (struct topo_info): Add constructor, and change types of members to auto_vec and auto_sbitmap. (init_topo_info): Remove. (topo_info::topo_info): New constructor. (solve_graph): Adjust. --- gcc/tree-ssa-structalias.c | 31 --- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 5e3c7d0..94d81ed1 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -1536,36 +1536,21 @@ unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from, struct topo_info { + topo_info (); + /* sbitmap of visited nodes. */ - sbitmap visited; + auto_sbitmap visited; /* Array that stores the topological order of the graph, *in reverse*. */ - vec topo_order; + auto_vec topo_order; }; /* Initialize and return a topological info structure. */ -static struct topo_info * -init_topo_info (void) -{ - size_t size = graph->size; - struct topo_info *ti = XNEW (struct topo_info); - ti->visited = sbitmap_alloc (size); - bitmap_clear (ti->visited); - ti->topo_order.create (1); - return ti; -} - - -/* Free the topological sort info pointed to by TI. */ - -static void -free_topo_info (struct topo_info *ti) +topo_info::topo_info () : visited (graph->size), topo_order (1) { - sbitmap_free (ti->visited); - ti->topo_order.release (); - free (ti); + bitmap_clear (visited); } /* Visit the graph in topological order, and store the order in the @@ -2679,7 +2664,7 @@ solve_graph (constraint_graph_t graph) while (!bitmap_empty_p (changed)) { unsigned int i; - struct topo_info *ti = init_topo_info (); + topo_info *ti = new topo_info (); stats.iterations++; bitmap_obstack_initialize (_obstack); @@ -2797,7 +2782,7 @@ solve_graph (constraint_graph_t graph) } } } - free_topo_info (ti); + delete ti; bitmap_obstack_release (_obstack); } -- 2.9.0
[PATCH 2/6] use auto_sbitmap in various places
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * bt-load.c (compute_out): Use auto_sbitmap class. (link_btr_uses): Likewise. * cfganal.c (mark_dfs_back_edges): Likewise. (post_order_compute): Likewise. (inverted_post_order_compute): Likewise. (pre_and_rev_post_order_compute_fn): Likewise. (single_pred_before_succ_order): Likewise. * cfgexpand.c (pass_expand::execute): Likewise. * cfgloop.c (verify_loop_structure): Likewise. * cfgloopmanip.c (fix_bb_placements): Likewise. (remove_path): Likewise. (update_dominators_in_loop): Likewise. * cfgrtl.c (break_superblocks): Likewise. * ddg.c (check_sccs): Likewise. (create_ddg_all_sccs): Likewise. * df-core.c (df_worklist_dataflow): Likewise. * dse.c (dse_step3): Likewise. * except.c (eh_region_outermost): Likewise. * function.c (thread_prologue_and_epilogue_insns): Likewise. * gcse.c (prune_expressions): Likewise. (prune_insertions_deletions): Likewise. * gimple-ssa-backprop.c (backprop::~backprop): Likewise. * graph.c (draw_cfg_nodes_no_loops): Likewise. * ira-lives.c (remove_some_program_points_and_update_live_ranges): Likewise. * lcm.c (compute_earliest): Likewise. (compute_farthest): Likewise. * loop-unroll.c (unroll_loop_constant_iterations): Likewise. (unroll_loop_runtime_iterations): Likewise. (unroll_loop_stupid): Likewise. * lower-subreg.c (decompose_multiword_subregs): Likewise. * lra-lives.c: Likewise. * lra.c (lra): Likewise. * modulo-sched.c (schedule_reg_moves): Likewise. (optimize_sc): Likewise. (get_sched_window): Likewise. (sms_schedule_by_order): Likewise. (check_nodes_order): Likewise. (order_nodes_of_sccs): Likewise. (order_nodes_in_scc): Likewise. * recog.c (split_all_insns): Likewise. * regcprop.c (pass_cprop_hardreg::execute): Likewise. * reload1.c (reload): Likewise. * sched-rgn.c (haifa_find_rgns): Likewise. (split_edges): Likewise. (compute_trg_info): Likewise. * sel-sched.c (init_seqno): Likewise. * store-motion.c (remove_reachable_equiv_notes): Likewise. * tree-into-ssa.c (update_ssa): Likewise. * tree-ssa-live.c (live_worklist): Likewise. * tree-ssa-loop-im.c (fill_always_executed_in): Likewise. * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): * Likewise. (try_peel_loop): Likewise. * tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): * Likewise. * tree-ssa-pre.c (compute_antic): Likewise. * tree-ssa-reassoc.c (undistribute_ops_list): Likewise. * tree-stdarg.c (reachable_at_most_once): Likewise. * tree-vect-slp.c (vect_attempt_slp_rearrange_stmts): Likewise. * var-tracking.c (vt_find_locations): Likewise. --- gcc/bt-load.c | 9 ++ gcc/cfganal.c | 19 +++ gcc/cfgexpand.c | 4 +-- gcc/cfgloop.c | 8 ++--- gcc/cfgloopmanip.c | 13 ++-- gcc/cfgrtl.c| 5 +-- gcc/ddg.c | 12 +++ gcc/df-core.c | 3 +- gcc/dse.c | 3 +- gcc/except.c| 5 +-- gcc/function.c | 3 +- gcc/gcse.c | 9 ++ gcc/gimple-ssa-backprop.c | 5 ++- gcc/graph.c | 5 +-- gcc/ira-lives.c | 11 +++ gcc/lcm.c | 16 ++ gcc/loop-unroll.c | 16 ++ gcc/lower-subreg.c | 5 +-- gcc/lra-lives.c | 10 ++ gcc/lra.c | 4 +-- gcc/modulo-sched.c | 78 ++--- gcc/recog.c | 5 +-- gcc/regcprop.c | 4 +-- gcc/reload1.c | 4 +-- gcc/sched-rgn.c | 36 ++--- gcc/sel-sched.c | 4 +-- gcc/store-motion.c | 3 +- gcc/tree-into-ssa.c | 3 +- gcc/tree-ssa-live.c | 4 +-- gcc/tree-ssa-loop-im.c | 4 +-- gcc/tree-ssa-loop-ivcanon.c | 10 ++ gcc/tree-ssa-loop-manip.c | 4 +-- gcc/tree-ssa-pre.c | 3 +- gcc/tree-ssa-reassoc.c | 12 ++- gcc/tree-stdarg.c | 4 +-- gcc/tree-vect-slp.c | 20 +++- gcc/var-tracking.c | 5 ++- 37 files changed, 99 insertions(+), 269 deletions(-) diff --git a/gcc/bt-load.c b/gcc/bt-load.c index aa02f64..5b1bcec 100644 --- a/gcc/bt-load.c +++ b/gcc/bt-load.c @@ -626,7 +626,7 @@ compute_out (sbitmap *bb_out, sbitmap *bb_gen, sbitmap *bb_kill, int max_uid) Iterate until the bb_out sets stop growing. */ int i; int changed; - sbitmap bb_in = sbitmap_alloc
[PATCH 4/6] remove elim_graph typedef
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * tree-outof-ssa.c (struct elim_graph): Remove typedef. (new_elim_graph): Adjust. (clear_elim_graph): Likewise. (delete_elim_graph): Likewise. (elim_graph_size): Likewise. (elim_graph_add_node): Likewise. (elim_graph_add_edge): Likewise. (elim_graph_remove_succ_edge): Likewise. (eliminate_name): Likewise. (eliminate_build): Likewise. (elim_forward): Likewise. (elim_unvisited_predecessor): Likewise. (elim_backward): Likewise. (elim_create): Likewise. (eliminate_phi): Likewise. (expand_phi_nodes): Likewise. --- gcc/tree-outof-ssa.c | 37 +++-- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 4125529..5047788 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -126,7 +126,8 @@ ssa_is_replaceable_p (gimple *stmt) rarely more than 6, and in the bootstrap of gcc, the maximum number of nodes encountered was 12. */ -typedef struct _elim_graph { +struct elim_graph +{ /* Size of the elimination vectors. */ int size; @@ -157,7 +158,7 @@ typedef struct _elim_graph { /* Source locations for any constant copies. */ vec copy_locus; -} *elim_graph; +}; /* For an edge E find out a good source location to associate with @@ -394,10 +395,10 @@ insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus) /* Create an elimination graph with SIZE nodes and associated data structures. */ -static elim_graph +static elim_graph * new_elim_graph (int size) { - elim_graph g = (elim_graph) xmalloc (sizeof (struct _elim_graph)); + elim_graph *g = (elim_graph *) xmalloc (sizeof (struct elim_graph)); g->nodes.create (30); g->const_dests.create (20); @@ -416,7 +417,7 @@ new_elim_graph (int size) /* Empty elimination graph G. */ static inline void -clear_elim_graph (elim_graph g) +clear_elim_graph (elim_graph *g) { g->nodes.truncate (0); g->edge_list.truncate (0); @@ -427,7 +428,7 @@ clear_elim_graph (elim_graph g) /* Delete elimination graph G. */ static inline void -delete_elim_graph (elim_graph g) +delete_elim_graph (elim_graph *g) { sbitmap_free (g->visited); g->stack.release (); @@ -445,7 +446,7 @@ delete_elim_graph (elim_graph g) /* Return the number of nodes in graph G. */ static inline int -elim_graph_size (elim_graph g) +elim_graph_size (elim_graph *g) { return g->nodes.length (); } @@ -454,7 +455,7 @@ elim_graph_size (elim_graph g) /* Add NODE to graph G, if it doesn't exist already. */ static inline void -elim_graph_add_node (elim_graph g, int node) +elim_graph_add_node (elim_graph *g, int node) { int x; int t; @@ -469,7 +470,7 @@ elim_graph_add_node (elim_graph g, int node) /* Add the edge PRED->SUCC to graph G. */ static inline void -elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus) +elim_graph_add_edge (elim_graph *g, int pred, int succ, source_location locus) { g->edge_list.safe_push (pred); g->edge_list.safe_push (succ); @@ -481,7 +482,7 @@ elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus) return the successor node. -1 is returned if there is no such edge. */ static inline int -elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus) +elim_graph_remove_succ_edge (elim_graph *g, int node, source_location *locus) { int y; unsigned x; @@ -543,7 +544,7 @@ do { \ /* Add T to elimination graph G. */ static inline void -eliminate_name (elim_graph g, int T) +eliminate_name (elim_graph *g, int T) { elim_graph_add_node (g, T); } @@ -570,7 +571,7 @@ queue_phi_copy_p (var_map map, tree t) G->e. */ static void -eliminate_build (elim_graph g) +eliminate_build (elim_graph *g) { tree Ti; int p0, pi; @@ -619,7 +620,7 @@ eliminate_build (elim_graph g) /* Push successors of T onto the elimination stack for G. */ static void -elim_forward (elim_graph g, int T) +elim_forward (elim_graph *g, int T) { int S; source_location locus; @@ -637,7 +638,7 @@ elim_forward (elim_graph g, int T) /* Return 1 if there unvisited predecessors of T in graph G. */ static int -elim_unvisited_predecessor (elim_graph g, int T) +elim_unvisited_predecessor (elim_graph *g, int T) { int P; source_location locus; @@ -653,7 +654,7 @@ elim_unvisited_predecessor (elim_graph g, int T) /* Process predecessors first, and insert a copy. */ static void -elim_backward (elim_graph g, int T) +elim_backward (elim_graph *g, int T) { int P; source_location locus; @@ -688,7 +689,7 @@ get_temp_reg (tree name) region, and create a temporary to break the cycle if one is found.
[PATCH 6/6] add [cd]tors to scc_info
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * tree-ssa-structalias.c (struct scc_info): Change types of members to auto_sbitmap and auto_vec. (scc_info::scc_info): New constructor. (scc_info::~scc_info): New destructor. (init_scc_info): Remove. (free_scc_info): Remove. (find_indirect_cycles): Adjust. (perform_var_substitution): Likewise. (free_var_substitution_info): Likewise. --- gcc/tree-ssa-structalias.c | 57 ++ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 94d81ed1..a669065 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -1379,12 +1379,15 @@ static bitmap changed; struct scc_info { - sbitmap visited; - sbitmap deleted; + scc_info (size_t size); + ~scc_info (); + + auto_sbitmap visited; + auto_sbitmap deleted; unsigned int *dfs; unsigned int *node_mapping; int current_index; - vec scc_stack; + auto_vec scc_stack; }; @@ -1809,38 +1812,24 @@ do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta, /* Initialize and return a new SCC info structure. */ -static struct scc_info * -init_scc_info (size_t size) +scc_info::scc_info (size_t size) : + visited (size), deleted (size), current_index (0), scc_stack (1) { - struct scc_info *si = XNEW (struct scc_info); - size_t i; - - si->current_index = 0; - si->visited = sbitmap_alloc (size); - bitmap_clear (si->visited); - si->deleted = sbitmap_alloc (size); - bitmap_clear (si->deleted); - si->node_mapping = XNEWVEC (unsigned int, size); - si->dfs = XCNEWVEC (unsigned int, size); - - for (i = 0; i < size; i++) -si->node_mapping[i] = i; + bitmap_clear (visited); + bitmap_clear (deleted); + node_mapping = XNEWVEC (unsigned int, size); + dfs = XCNEWVEC (unsigned int, size); - si->scc_stack.create (1); - return si; + for (size_t i = 0; i < size; i++) +node_mapping[i] = i; } /* Free an SCC info structure pointed to by SI */ -static void -free_scc_info (struct scc_info *si) +scc_info::~scc_info () { - sbitmap_free (si->visited); - sbitmap_free (si->deleted); - free (si->node_mapping); - free (si->dfs); - si->scc_stack.release (); - free (si); + free (node_mapping); + free (dfs); } @@ -1856,13 +1845,11 @@ find_indirect_cycles (constraint_graph_t graph) { unsigned int i; unsigned int size = graph->size; - struct scc_info *si = init_scc_info (size); + scc_info si (size); for (i = 0; i < MIN (LAST_REF_NODE, size); i ++ ) -if (!bitmap_bit_p (si->visited, i) && find (i) == i) - scc_visit (graph, si, i); - - free_scc_info (si); +if (!bitmap_bit_p (si.visited, i) && find (i) == i) + scc_visit (graph, , i); } /* Compute a topological ordering for GRAPH, and store the result in the @@ -2276,7 +2263,7 @@ perform_var_substitution (constraint_graph_t graph) { unsigned int i; unsigned int size = graph->size; - struct scc_info *si = init_scc_info (size); + scc_info *si = new scc_info (size); bitmap_obstack_initialize (_obstack); pointer_equiv_class_table = new hash_table (511); @@ -2407,7 +2394,7 @@ perform_var_substitution (constraint_graph_t graph) static void free_var_substitution_info (struct scc_info *si) { - free_scc_info (si); + delete si; free (graph->pointer_label); free (graph->loc_label); free (graph->pointed_by); -- 2.9.0
[PATCH 5/6] add a constructor to elim_graph
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * tree-outof-ssa.c (struct elim_graph): Change type of members to auto_vec and auto_sbitmap. (elim_graph::elim_graph): New constructor. (delete_elim_graph): Remove. (expand_phi_nodes): Adjust. --- gcc/tree-outof-ssa.c | 64 +--- 1 file changed, 16 insertions(+), 48 deletions(-) diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 5047788..be57ce4 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -128,23 +128,25 @@ ssa_is_replaceable_p (gimple *stmt) struct elim_graph { + elim_graph (var_map map); + /* Size of the elimination vectors. */ int size; /* List of nodes in the elimination graph. */ - vec nodes; + auto_vec nodes; /* The predecessor and successor edge list. */ - vec edge_list; + auto_vec edge_list; /* Source locus on each edge */ - vec edge_locus; + auto_vec edge_locus; /* Visited vector. */ - sbitmap visited; + auto_sbitmap visited; /* Stack for visited nodes. */ - vec stack; + auto_vec stack; /* The variable partition map. */ var_map map; @@ -153,11 +155,11 @@ struct elim_graph edge e; /* List of constant copies to emit. These are pushed on in pairs. */ - vec const_dests; - vec const_copies; + auto_vec const_dests; + auto_vec const_copies; /* Source locations for any constant copies. */ - vec copy_locus; + auto_vec copy_locus; }; @@ -392,25 +394,12 @@ insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus) } -/* Create an elimination graph with SIZE nodes and associated data - structures. */ +/* Create an elimination graph for map. */ -static elim_graph * -new_elim_graph (int size) +elim_graph::elim_graph (var_map map) : + nodes (30), edge_list (20), edge_locus (10), visited (map->num_partitions), + stack (30), map (map), const_dests (20), const_copies (20), copy_locus (10) { - elim_graph *g = (elim_graph *) xmalloc (sizeof (struct elim_graph)); - - g->nodes.create (30); - g->const_dests.create (20); - g->const_copies.create (20); - g->copy_locus.create (10); - g->edge_list.create (20); - g->edge_locus.create (10); - g->stack.create (30); - - g->visited = sbitmap_alloc (size); - - return g; } @@ -425,24 +414,6 @@ clear_elim_graph (elim_graph *g) } -/* Delete elimination graph G. */ - -static inline void -delete_elim_graph (elim_graph *g) -{ - sbitmap_free (g->visited); - g->stack.release (); - g->edge_list.release (); - g->const_copies.release (); - g->const_dests.release (); - g->nodes.release (); - g->copy_locus.release (); - g->edge_locus.release (); - - free (g); -} - - /* Return the number of nodes in graph G. */ static inline int @@ -925,8 +896,7 @@ void expand_phi_nodes (struct ssaexpand *sa) { basic_block bb; - elim_graph *g = new_elim_graph (sa->map->num_partitions); - g->map = sa->map; + elim_graph g (sa->map); FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) @@ -935,7 +905,7 @@ expand_phi_nodes (struct ssaexpand *sa) edge e; edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->preds) - eliminate_phi (e, g); + eliminate_phi (e, ); set_phi_nodes (bb, NULL); /* We can't redirect EH edges in RTL land, so we need to do this here. Redirection happens only when splitting is necessary, @@ -961,8 +931,6 @@ expand_phi_nodes (struct ssaexpand *sa) ei_next (); } } - - delete_elim_graph (g); } -- 2.9.0
[PATCH 0/6] add and use an auto_sbitmap class
From: Trevor SaundersHi, This series adds a auto_sbitmap class that manages the lifetime of a sbitmap. Then it replaces most manual management with uses of auto_sbitmap. patches individually bootstrapped + regtested on x86_linux-gnu, ok? Trev Trevor Saunders (6): add auto_sbitmap class use auto_sbitmap in various places add ctor to topo_info remove elim_graph typedef add a constructor to elim_graph add [cd]tors to scc_info gcc/bt-load.c | 9 ++--- gcc/cfganal.c | 19 +++-- gcc/cfgexpand.c | 4 +- gcc/cfgloop.c | 8 +--- gcc/cfgloopmanip.c | 13 ++- gcc/cfgrtl.c| 5 +-- gcc/ddg.c | 12 ++ gcc/df-core.c | 3 +- gcc/dse.c | 3 +- gcc/except.c| 5 +-- gcc/function.c | 3 +- gcc/gcse.c | 9 + gcc/gimple-ssa-backprop.c | 5 +-- gcc/graph.c | 5 +-- gcc/ira-lives.c | 11 ++ gcc/lcm.c | 16 +--- gcc/loop-unroll.c | 16 ++-- gcc/lower-subreg.c | 5 +-- gcc/lra-lives.c | 10 ++--- gcc/lra.c | 4 +- gcc/modulo-sched.c | 78 - gcc/recog.c | 5 +-- gcc/regcprop.c | 4 +- gcc/reload1.c | 4 +- gcc/sbitmap.h | 21 ++ gcc/sched-rgn.c | 36 +- gcc/sel-sched.c | 4 +- gcc/store-motion.c | 3 +- gcc/tree-into-ssa.c | 3 +- gcc/tree-outof-ssa.c| 93 +++-- gcc/tree-ssa-live.c | 4 +- gcc/tree-ssa-loop-im.c | 4 +- gcc/tree-ssa-loop-ivcanon.c | 10 + gcc/tree-ssa-loop-manip.c | 4 +- gcc/tree-ssa-pre.c | 3 +- gcc/tree-ssa-reassoc.c | 12 ++ gcc/tree-ssa-structalias.c | 88 +++--- gcc/tree-stdarg.c | 4 +- gcc/tree-vect-slp.c | 20 +++--- gcc/var-tracking.c | 5 +-- 40 files changed, 181 insertions(+), 389 deletions(-) -- 2.9.0
[PATCH 1/6] add auto_sbitmap class
From: Trevor Saundersgcc/ChangeLog: 2016-07-24 Trevor Saunders * sbitmap.h (auto_sbitmap): New class. --- gcc/sbitmap.h | 21 + 1 file changed, 21 insertions(+) diff --git a/gcc/sbitmap.h b/gcc/sbitmap.h index c208171..d4a2918 100644 --- a/gcc/sbitmap.h +++ b/gcc/sbitmap.h @@ -256,4 +256,25 @@ extern int bitmap_last_set_bit (const_sbitmap); extern void debug_bitmap (const_sbitmap); extern sbitmap sbitmap_realloc (sbitmap, unsigned int); + +/* a class that ties the lifetime of a sbitmap to its scope. */ +class auto_sbitmap +{ +public: + explicit auto_sbitmap (unsigned int size) : +m_bitmap (sbitmap_alloc (size)) {} + ~auto_sbitmap () { sbitmap_free (m_bitmap); } + + /* Allow calling sbitmap functions on our bitmap. */ + operator sbitmap () { return m_bitmap; } + +private: + /* Prevent making a copy that refers to our sbitmap. */ + auto_sbitmap (const auto_sbitmap &); + auto_sbitmap = (const auto_sbitmap &); + + /* The bitmap we are managing. */ + sbitmap m_bitmap; +}; + #endif /* ! GCC_SBITMAP_H */ -- 2.9.0