Re: [PATCH] Teach VRP to register assertions along default switch labels (PR 18046)

2016-07-24 Thread Patrick Palka
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

2016-07-24 Thread Alan Modra
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

2016-07-24 Thread Prathamesh Kulkarni
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)

2016-07-24 Thread Jason Merrill
Here we got into infinite recursion trying to determine if A is
the same as A because 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.

2016-07-24 Thread Ville Voutilainen
On 19 July 2016 at 21:34, Ville Voutilainen  wrote:
> 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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

Hi,

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

2016-07-24 Thread Gleb Natapov
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 Natapov  wrote:
> > _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

2016-07-24 Thread Andrew Pinski
On Sun, Jul 24, 2016 at 8:01 AM, Gleb Natapov  wrote:
> _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)

2016-07-24 Thread Andrew Pinski
On Sun, Jul 24, 2016 at 9:49 AM, Patrick Palka  wrote:
> 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)

2016-07-24 Thread Patrick Palka
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?

>
> Thanks,
> Kugan


Re: [PATCH 1/6] add auto_sbitmap class

2016-07-24 Thread Richard Biener
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

2016-07-24 Thread Richard Biener
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

2016-07-24 Thread Gleb Natapov
_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

2016-07-24 Thread Janne Blomqvist
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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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

2016-07-24 Thread tbsaunde+gcc
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.
---
 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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

Hi,

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

2016-07-24 Thread tbsaunde+gcc
From: Trevor Saunders 

gcc/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