[PATCH] match.pd: Fold x == ~x to false [PR96782]

2021-01-03 Thread Jakub Jelinek via Gcc-patches
Hi!

x is never equal to ~x, so we can fold such comparisons to constants.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2021-01-03  Jakub Jelinek  

PR tree-optimization/96782
* match.pd (x == ~x -> false, x != ~x -> true): New simplifications.

* gcc.dg/tree-ssa/pr96782.c: New test.

--- gcc/match.pd.jj 2021-01-01 00:03:14.987440788 +0100
+++ gcc/match.pd2021-01-02 10:40:34.289209121 +0100
@@ -4045,6 +4045,13 @@ (define_operator_list COND_TERNARY
  (if (!flag_trapping_math)
   { constant_boolean_node (false, type); }))
 
+/* x == ~x -> false */
+/* x != ~x -> true */
+(for cmp (eq ne)
+ (simplify
+  (cmp:c @0 (bit_not @0))
+  { constant_boolean_node (cmp == NE_EXPR, type); }))
+
 /* Fold ~X op ~Y as Y op X.  */
 (for cmp (simple_comparison)
  (simplify
--- gcc/testsuite/gcc.dg/tree-ssa/pr96782.c.jj  2021-01-02 10:39:50.740704373 
+0100
+++ gcc/testsuite/gcc.dg/tree-ssa/pr96782.c 2021-01-02 10:39:36.268868954 
+0100
@@ -0,0 +1,17 @@
+/* PR tree-optimization/96782 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return 0;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1;" 1 "optimized" } } */
+
+int
+foo (int a)
+{
+  return a == ~a;
+}
+
+int
+bar (int b)
+{
+  return ~b != b;
+}

Jakub



[PATCH] loop-niter: Recognize popcount idioms even with char, short and __int128 [PR95771]

2021-01-03 Thread Jakub Jelinek via Gcc-patches
Hi!

As the testcase shows, we punt unnecessarily on popcount loop idioms if
the type is smaller than int or larger than long long.
Smaller type than int can be handled by zero-extending the argument to
unsigned int, and types twice as long as long long by doing
__builtin_popcountll on both halves of the __int128.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-01-03  Jakub Jelinek  

PR tree-optimization/95771
* tree-ssa-loop-niter.c (number_of_iterations_popcount): Handle types
with precision smaller than int's precision and types with precision
twice as large as long long.  Formatting fixes.

* gcc.target/i386/pr95771.c: New test.

--- gcc/tree-ssa-loop-niter.c.jj2020-10-12 12:30:34.348813027 +0200
+++ gcc/tree-ssa-loop-niter.c   2021-01-02 19:38:17.858170445 +0100
@@ -2666,27 +2666,45 @@ number_of_iterations_popcount (loop_p lo
 
   /* We found a match. Get the corresponding popcount builtin.  */
   tree src = gimple_phi_arg_def (phi, loop_preheader_edge (loop)->dest_idx);
-  if (TYPE_PRECISION (TREE_TYPE (src)) == TYPE_PRECISION (integer_type_node))
+  if (TYPE_PRECISION (TREE_TYPE (src)) <= TYPE_PRECISION (integer_type_node))
 fn = builtin_decl_implicit (BUILT_IN_POPCOUNT);
-  else if (TYPE_PRECISION (TREE_TYPE (src)) == TYPE_PRECISION
-  (long_integer_type_node))
+  else if (TYPE_PRECISION (TREE_TYPE (src))
+  == TYPE_PRECISION (long_integer_type_node))
 fn = builtin_decl_implicit (BUILT_IN_POPCOUNTL);
-  else if (TYPE_PRECISION (TREE_TYPE (src)) == TYPE_PRECISION
-  (long_long_integer_type_node))
+  else if (TYPE_PRECISION (TREE_TYPE (src))
+  == TYPE_PRECISION (long_long_integer_type_node)
+  || (TYPE_PRECISION (TREE_TYPE (src))
+  == 2 * TYPE_PRECISION (long_long_integer_type_node)))
 fn = builtin_decl_implicit (BUILT_IN_POPCOUNTLL);
 
-  /* ??? Support promoting char/short to int.  */
   if (!fn)
 return false;
 
   /* Update NITER params accordingly  */
   tree utype = unsigned_type_for (TREE_TYPE (src));
   src = fold_convert (utype, src);
-  tree call = fold_convert (utype, build_call_expr (fn, 1, src));
+  if (TYPE_PRECISION (TREE_TYPE (src)) < TYPE_PRECISION (integer_type_node))
+src = fold_convert (unsigned_type_node, src);
+  tree call;
+  if (TYPE_PRECISION (TREE_TYPE (src))
+  == 2 * TYPE_PRECISION (long_long_integer_type_node))
+{
+  int prec = TYPE_PRECISION (long_long_integer_type_node);
+  tree src1 = fold_convert (long_long_unsigned_type_node,
+   fold_build2 (RSHIFT_EXPR, TREE_TYPE (src),
+unshare_expr (src),
+build_int_cst (integer_type_node,
+   prec)));
+  tree src2 = fold_convert (long_long_unsigned_type_node, src);
+  call = build_call_expr (fn, 1, src1);
+  call = fold_build2 (PLUS_EXPR, TREE_TYPE (call), call,
+ build_call_expr (fn, 1, src2));
+  call = fold_convert (utype, call);
+}
+  else
+call = fold_convert (utype, build_call_expr (fn, 1, src));
   if (adjust)
-iter = fold_build2 (MINUS_EXPR, utype,
-   call,
-   build_int_cst (utype, 1));
+iter = fold_build2 (MINUS_EXPR, utype, call, build_int_cst (utype, 1));
   else
 iter = call;
 
@@ -2703,10 +2721,9 @@ number_of_iterations_popcount (loop_p lo
   if (adjust)
 {
   tree may_be_zero = fold_build2 (EQ_EXPR, boolean_type_node, src,
- build_zero_cst
- (TREE_TYPE (src)));
-  niter->may_be_zero =
-   simplify_using_initial_conditions (loop, may_be_zero);
+ build_zero_cst (TREE_TYPE (src)));
+  niter->may_be_zero
+   = simplify_using_initial_conditions (loop, may_be_zero);
 }
   else
 niter->may_be_zero = boolean_false_node;
--- gcc/testsuite/gcc.target/i386/pr95771.c.jj  2021-01-02 19:53:27.499768266 
+0100
+++ gcc/testsuite/gcc.target/i386/pr95771.c 2021-01-02 19:53:12.782936545 
+0100
@@ -0,0 +1,67 @@
+/* PR tree-optimization/95771 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mpopcnt -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " = __builtin_popcount" 6 "optimized" { 
target int128 } } } */
+/* { dg-final { scan-tree-dump-times " = __builtin_popcount" 4 "optimized" { 
target { ! int128 } } } } */
+
+int
+foo (unsigned char x)
+{
+  int i = 0;
+  while (x)
+{
+  x &= x - 1;
+  ++i;
+}
+  return i;
+}
+
+int
+bar (unsigned short x)
+{
+  int i = 0;
+  while (x)
+{
+  x &= x - 1;
+  ++i;
+}
+  return i;
+}
+
+int
+baz (unsigned int x)
+{
+  int i = 0;
+  while (x)
+{
+  x &= x - 1;
+  ++i;
+}
+  return i;
+}
+
+int
+qux (unsigned long long x)
+{
+  int i = 0;
+  while (x)
+{
+

[PATCH 00/10] C++11-based improvements for libcc1

2021-01-03 Thread Tom Tromey
This short series uses C++11 features to simplify libcc1.  This brings
the code closer to how I pictured it when I first wrote it.  (It would
be further improved by std::apply, but this isn't available until
C++17.)

I built and tested this against git GDB on x86-64 Fedora 32.

Note that the C++ plugin currently does not for git GCC -- it crashes.
This series doesn't make it worse (it may slightly change the reported
failures), but nor does it improve it.

There's some more simplification that could be done; for example the
two plugins currently have copies of code that ought to be shared.
However, I haven't done this.

Tom




[PATCH 02/10] libcc1: use "override"

2021-01-03 Thread Tom Tromey
This changes libcc1 to use "override" where appropriate.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* libcp1.cc (class compiler_triplet_regexp)
(class compiler_driver_filename, class libcp1_connection): Use
"override".
* libcc1.cc (class compiler_triplet_regexp)
(class compiler_driver_filename, class libcc1_connection): Use
"override".
---
 libcc1/ChangeLog | 9 +
 libcc1/libcc1.cc | 6 +++---
 libcc1/libcp1.cc | 6 +++---
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 1838f2e5577..4fb3084c24c 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -93,7 +93,7 @@ struct libcc1 : public gcc_c_context
   private:
 std::string triplet_regexp_;
   public:
-virtual char *find (std::string &compiler) const;
+char *find (std::string &compiler) const override;
 compiler_triplet_regexp (libcc1 *self, std::string triplet_regexp)
   : compiler (self), triplet_regexp_ (triplet_regexp)
 {
@@ -109,7 +109,7 @@ struct libcc1 : public gcc_c_context
   private:
 std::string driver_filename_;
   public:
-virtual char *find (std::string &compiler) const;
+char *find (std::string &compiler) const override;
 compiler_driver_filename (libcc1 *self, std::string driver_filename)
   : compiler (self), driver_filename_ (driver_filename)
 {
@@ -132,7 +132,7 @@ public:
   {
   }
 
-  virtual void print (const char *buf)
+  void print (const char *buf) override
   {
 back_ptr->print (buf);
   }
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index e8aceb14604..5fa6a6742f5 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -94,7 +94,7 @@ struct libcp1 : public gcc_cp_context
   private:
 std::string triplet_regexp_;
   public:
-virtual char *find (std::string &compiler) const;
+char *find (std::string &compiler) const override;
 compiler_triplet_regexp (libcp1 *self, std::string triplet_regexp)
   : compiler (self), triplet_regexp_ (triplet_regexp)
 {
@@ -110,7 +110,7 @@ struct libcp1 : public gcc_cp_context
   private:
 std::string driver_filename_;
   public:
-virtual char *find (std::string &compiler) const;
+char *find (std::string &compiler) const override;
 compiler_driver_filename (libcp1 *self, std::string driver_filename)
   : compiler (self), driver_filename_ (driver_filename)
 {
@@ -133,7 +133,7 @@ public:
   {
   }
 
-  virtual void print (const char *buf)
+  void print (const char *buf) override
   {
 back_ptr->print (buf);
   }
-- 
2.26.2



[PATCH 03/10] libcc1: inline some simple methods

2021-01-03 Thread Tom Tromey
This changes libcc1 to inline a trivial method and to use the default
constructor.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* connection.hh (~connection): Use default.
(print): Inline.
* connection.cc (cc1_plugin::connection::~connection)
(cc1_plugin::connection::print): Remove definitions.
---
 libcc1/ChangeLog | 7 +++
 libcc1/connection.cc | 9 -
 libcc1/connection.hh | 6 --
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/libcc1/connection.cc b/libcc1/connection.cc
index a91dfc8c5e2..01cda378613 100644
--- a/libcc1/connection.cc
+++ b/libcc1/connection.cc
@@ -27,15 +27,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "connection.hh"
 #include "rpc.hh"
 
-cc1_plugin::connection::~connection ()
-{
-}
-
-void
-cc1_plugin::connection::print (const char *)
-{
-}
-
 cc1_plugin::status
 cc1_plugin::connection::send (char c)
 {
diff --git a/libcc1/connection.hh b/libcc1/connection.hh
index f7cc5319a24..d8562a26154 100644
--- a/libcc1/connection.hh
+++ b/libcc1/connection.hh
@@ -46,7 +46,7 @@ namespace cc1_plugin
 {
 }
 
-virtual ~connection ();
+virtual ~connection () = default;
 
 // Send a single character.  This is used to introduce various
 // higher-level protocol elements.
@@ -89,7 +89,9 @@ namespace cc1_plugin
   m_callbacks.add_callback (name, func);
 }
 
-virtual void print (const char *);
+virtual void print (const char *)
+{
+}
 
   private:
 
-- 
2.26.2



[PATCH 01/10] libcc1: use templates to unmarshall enums

2021-01-03 Thread Tom Tromey
Now that C++11 can be used in GCC, libcc1 can be changed to use
templates and type traits to handle unmarshalling all kinds of enums.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* marshall.hh (cc1_plugin::unmarshall): Use type traits.
* marshall-cp.hh (cc1_plugin::unmarshall): Remove overloads.
* marshall-c.hh: Remove.
* libcc1plugin.cc: Update includes.
* libcc1.cc: Update includes.
---
 libcc1/ChangeLog   |  8 ++
 libcc1/libcc1.cc   |  3 ++-
 libcc1/libcc1plugin.cc |  3 ++-
 libcc1/marshall-c.hh   | 59 --
 libcc1/marshall-cp.hh  | 40 
 libcc1/marshall.hh | 26 +++
 6 files changed, 33 insertions(+), 106 deletions(-)
 delete mode 100644 libcc1/marshall-c.hh

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index c675624ee1c..1838f2e5577 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 #include 
-#include "marshall-c.hh"
+#include "marshall.hh"
 #include "rpc.hh"
 #include "connection.hh"
 #include "names.hh"
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "findcomp.hh"
 #include "compiler-name.hh"
 #include "intl.h"
+#include "gcc-c-interface.h"
 
 struct libcc1;
 
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 241a8158b98..a0fb61f2e46 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -63,8 +63,9 @@
 
 #include "callbacks.hh"
 #include "connection.hh"
-#include "marshall-c.hh"
+#include "marshall.hh"
 #include "rpc.hh"
+#include "gcc-c-interface.h"
 
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
diff --git a/libcc1/marshall-c.hh b/libcc1/marshall-c.hh
deleted file mode 100644
index a617654bd5e..000
--- a/libcc1/marshall-c.hh
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Marshalling and unmarshalling of C-specific types.
-   Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-.  */
-
-#ifndef CC1_PLUGIN_MARSHALL_C_HH
-#define CC1_PLUGIN_MARSHALL_C_HH
-
-#include "marshall.hh"
-#include "gcc-c-interface.h"
-
-namespace cc1_plugin
-{
-  status
-  unmarshall (connection *conn, enum gcc_c_symbol_kind *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, &p))
-  return FAIL;
-*result = (enum gcc_c_symbol_kind) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_c_oracle_request *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, &p))
-  return FAIL;
-*result = (enum gcc_c_oracle_request) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_qualifiers *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, &p))
-  return FAIL;
-*result = (enum gcc_qualifiers) p;
-return OK;
-  }
-}
-
-#endif // CC1_PLUGIN_MARSHALL_C_HH
diff --git a/libcc1/marshall-cp.hh b/libcc1/marshall-cp.hh
index 23756c44b5f..e921ab0d3a9 100644
--- a/libcc1/marshall-cp.hh
+++ b/libcc1/marshall-cp.hh
@@ -25,46 +25,6 @@ along with GCC; see the file COPYING3.  If not see
 
 namespace cc1_plugin
 {
-  status
-  unmarshall (connection *conn, enum gcc_cp_symbol_kind *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, &p))
-  return FAIL;
-*result = (enum gcc_cp_symbol_kind) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_oracle_request *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, &p))
-  return FAIL;
-*result = (enum gcc_cp_oracle_request) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_qualifiers *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, &p))
-  return FAIL;
-*result = (enum gcc_cp_qualifiers) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_ref_qualifiers *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, &p))
-  return FAIL;
-*result = (enum gcc_cp_ref_qualifiers) p;
-return OK;
-  }
-
   // Send a gcc_vbase_array marker followed by the array.
   status
   marshall (connection *conn, const gcc_vbase_array *a)
diff --git a/libcc1/marshall.hh b/libcc1/marshall.hh
index fb4e9a484d7..7fadbeaa5ac 100644
--- a/libcc1/marshall.hh
+++ b/libcc1/marshall.hh
@@ -20,6 +20,8 @@ 

[PATCH 05/10] libcc1: use variadic templates for "call"

2021-01-03 Thread Tom Tromey
This changes libcc1 to use variadic templates for the "call"
functions.  The primary benefit is that this simplifies the code.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* rpc.hh (call): Use variadic template.  Remove overloads.
* marshall.hh (marshall): Add base overload.  Use variadic
template.
---
 libcc1/ChangeLog   |   6 ++
 libcc1/marshall.hh |  16 +
 libcc1/rpc.hh  | 168 +++--
 3 files changed, 31 insertions(+), 159 deletions(-)

diff --git a/libcc1/marshall.hh b/libcc1/marshall.hh
index 7fadbeaa5ac..d9d5d6cbc74 100644
--- a/libcc1/marshall.hh
+++ b/libcc1/marshall.hh
@@ -52,6 +52,14 @@ namespace cc1_plugin
   status unmarshall_array_start (connection *, char, size_t *);
   status unmarshall_array_elmts (connection *, size_t, void *);
 
+  // An "empty" marshall call -- used to handle the base case for some
+  // variadic templates.
+  static inline
+  status marshall (connection *)
+  {
+return OK;
+  }
+
   // A template function that can handle marshalling various integer
   // objects to the connection.
   template
@@ -103,6 +111,14 @@ namespace cc1_plugin
   // resulting array must be freed by the caller, using 'delete[]' on
   // the elements, and 'delete' on the array object itself.
   status unmarshall (connection *, struct gcc_type_array **);
+
+  template
+  status marshall (connection *c, T1 arg1, T2 arg2, Arg... rest)
+  {
+if (!marshall (c, arg1))
+  return FAIL;
+return marshall (c, arg2, rest...);
+  }
 };
 
 #endif // CC1_PLUGIN_MARSHALL_HH
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index ef2527ae40b..322521274e6 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -232,10 +232,10 @@ namespace cc1_plugin
 #endif /* GCC_CP_INTERFACE_H */
 
   // There are two kinds of template functions here: "call" and
-  // "callback".  They are each repeated multiple times to handle
-  // different numbers of arguments.  (This would be improved with
-  // C++11, though applying a call is still tricky until C++14 can be
-  // used.)
+  // "callback".  "call" is implemented with variadic templates, but
+  // "callback" is repeated multiple times to handle different numbers
+  // of arguments.  (This could be improved with C++17 and
+  // std::apply.)
 
   // The "call" template is used for making a remote procedure call.
   // It starts a query ('Q') packet, marshalls its arguments, waits
@@ -248,15 +248,17 @@ namespace cc1_plugin
   // arguments, passes them to the wrapped function, and finally
   // marshalls a reply packet.
 
-  template
+  template
   status
-  call (connection *conn, const char *method, R *result)
+  call (connection *conn, const char *method, R *result, Arg... args)
   {
 if (!conn->send ('Q'))
   return FAIL;
 if (!marshall (conn, method))
   return FAIL;
-if (!marshall (conn, 0))
+if (!marshall (conn, (int) sizeof... (Arg)))
+  return FAIL;
+if (!marshall (conn, args...))
   return FAIL;
 if (!conn->wait_for_result ())
   return FAIL;
@@ -279,25 +281,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  status
-  call (connection *conn, const char *method, R *result, A arg)
-  {
-if (!conn->send ('Q'))
-  return FAIL;
-if (!marshall (conn, method))
-  return FAIL;
-if (!marshall (conn, 1))
-  return FAIL;
-if (!marshall (conn, arg))
-  return FAIL;
-if (!conn->wait_for_result ())
-  return FAIL;
-if (!unmarshall (conn, result))
-  return FAIL;
-return OK;
-  }
-
   template
   status
   callback (connection *conn)
@@ -315,27 +298,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2)
-  {
-if (!conn->send ('Q'))
-  return FAIL;
-if (!marshall (conn, method))
-  return FAIL;
-if (!marshall (conn, 2))
-  return FAIL;
-if (!marshall (conn, arg1))
-  return FAIL;
-if (!marshall (conn, arg2))
-  return FAIL;
-if (!conn->wait_for_result ())
-  return FAIL;
-if (!unmarshall (conn, result))
-  return FAIL;
-return OK;
-  }
-
   template
   status
@@ -357,30 +319,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
-   A3 arg3)
-  {
-if (!conn->send ('Q'))
-  return FAIL;
-if (!marshall (conn, method))
-  return FAIL;
-if (!marshall (conn, 3))
-  return FAIL;
-if (!marshall (conn, arg1))
-  return FAIL;
-if (!marshall (conn, arg2))
-  return FAIL;
-if (!marshall (conn, arg3))
-  return FAIL;
-if (!conn->wait_for_result ())
-  return FAIL;
-if (!unmarshall (conn, result))
-  return FAIL;
-return OK;
-  }
-
   template
   status
@@ -405,32 +343,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template

[PATCH 07/10] libcc1: use std::vector when building function types

2021-01-03 Thread Tom Tromey
This changes libcc1 to use std::vector in the code that builds
function types.  This avoids some explicit memory management.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* libcp1plugin.cc (plugin_build_function_type): Use std::vector.
* libcc1plugin.cc (plugin_build_function_type): Use std::vector.
---
 libcc1/ChangeLog   |  5 +
 libcc1/libcc1plugin.cc | 11 +--
 libcc1/libcp1plugin.cc | 11 +--
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index a0fb61f2e46..aa07e6dbaef 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -67,6 +67,8 @@
 #include "rpc.hh"
 #include "gcc-c-interface.h"
 
+#include 
+
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -672,24 +674,21 @@ plugin_build_function_type (cc1_plugin::connection *self,
const struct gcc_type_array *argument_types_in,
int is_varargs)
 {
-  tree *argument_types;
   tree return_type = convert_in (return_type_in);
   tree result;
 
-  argument_types = new tree[argument_types_in->n_elements];
+  std::vector argument_types (argument_types_in->n_elements);
   for (int i = 0; i < argument_types_in->n_elements; ++i)
 argument_types[i] = convert_in (argument_types_in->elements[i]);
 
   if (is_varargs)
 result = build_varargs_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
+   argument_types.data ());
   else
 result = build_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
-
-  delete[] argument_types;
+   argument_types.data ());
 
   plugin_context *ctx = static_cast (self);
   return convert_out (ctx->preserve (result));
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 648368353cb..d2700e24152 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -70,6 +70,8 @@
 #include "marshall-cp.hh"
 #include "rpc.hh"
 
+#include 
+
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -1980,24 +1982,21 @@ plugin_build_function_type (cc1_plugin::connection 
*self,
const struct gcc_type_array *argument_types_in,
int is_varargs)
 {
-  tree *argument_types;
   tree return_type = convert_in (return_type_in);
   tree result;
 
-  argument_types = new tree[argument_types_in->n_elements];
+  std::vector argument_types (argument_types_in->n_elements);
   for (int i = 0; i < argument_types_in->n_elements; ++i)
 argument_types[i] = convert_in (argument_types_in->elements[i]);
 
   if (is_varargs)
 result = build_varargs_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
+   argument_types.data ());
   else
 result = build_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
-
-  delete[] argument_types;
+   argument_types.data ());
 
   plugin_context *ctx = static_cast (self);
   return convert_out (ctx->preserve (result));
-- 
2.26.2



[PATCH 06/10] libcc1: use variadic templates for "rpc"

2021-01-03 Thread Tom Tromey
This changes libcc1 to use variadic templates for the "rpc" functions.
This simplifies the code and removes some possibility for mistakes.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* libcp1.cc (rpc): Use variadic template.  Remove overloads.
* libcc1.cc (rpc): Use variadic template.  Remove overloads.
---
 libcc1/ChangeLog |  5 +++
 libcc1/libcc1.cc | 81 +++-
 libcc1/libcp1.cc | 81 +++-
 3 files changed, 13 insertions(+), 154 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 4fb3084c24c..82b1a6435b4 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -210,90 +210,17 @@ set_callbacks (struct gcc_c_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of these rpc<> template functions are installed into the
+// Instances of this rpc<> template function are installed into the
 // "c_vtable".  These functions are parameterized by type and method
 // name and forward the call via the connection.
 
-template
-R rpc (struct gcc_c_context *s)
+template
+R rpc (struct gcc_c_context *s, Arg... rest)
 {
   libcc1 *self = (libcc1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, &result))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A arg)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-   A6 arg6, A7 arg7)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-arg4, arg5, arg6, arg7))
+  if (!cc1_plugin::call (self->connection, NAME, &result, rest...))
 return 0;
   return result;
 }
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index 5fa6a6742f5..4fced736204 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -233,90 +233,17 @@ set_callbacks (struct gcc_cp_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of these rpc<> template functions are installed into the
+// Instances of this rpc<> template function are installed into the
 // "cp_vtable".  These functions are parameterized by type and method
 // name and forward the call via the connection.
 
-template
-R rpc (struct gcc_cp_context *s)
+template
+R rpc (struct gcc_cp_context *s, Arg... rest)
 {
   libcp1 *self = (libcp1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, &result))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A arg)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-   A6 arg6, A7 a

[PATCH 04/10] libcc1: delete copy constructor and assignment operators

2021-01-03 Thread Tom Tromey
Change libcc1 to use "= delete" for the copy constructor and
assignment operator, rather than the old approach of private methods
that are nowhere defined.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* rpc.hh (argument_wrapper): Use delete for copy constructor.
* connection.hh (class connection): Use delete for copy
constructor.
* callbacks.hh (class callbacks): Use delete for copy constructor.
---
 libcc1/ChangeLog |  7 +++
 libcc1/callbacks.hh  |  7 +++
 libcc1/connection.hh |  7 +++
 libcc1/rpc.hh| 42 ++
 4 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/libcc1/callbacks.hh b/libcc1/callbacks.hh
index e2d19b888b3..d3b06d9cf25 100644
--- a/libcc1/callbacks.hh
+++ b/libcc1/callbacks.hh
@@ -42,6 +42,9 @@ namespace cc1_plugin
 callbacks ();
 ~callbacks ();
 
+callbacks (const callbacks &) = delete;
+callbacks &operator= (const callbacks &) = delete;
+
 // Add a callback named NAME.  FUNC is the function to call when
 // this method is invoked.
 void add_callback (const char *name, callback_ftype *func);
@@ -52,10 +55,6 @@ namespace cc1_plugin
 
   private:
 
-// Declared but not defined to avoid use.
-callbacks (const callbacks &);
-callbacks &operator= (const callbacks &);
-
 // The mapping.
 htab_t m_registry;
   };
diff --git a/libcc1/connection.hh b/libcc1/connection.hh
index d8562a26154..1dc099902c8 100644
--- a/libcc1/connection.hh
+++ b/libcc1/connection.hh
@@ -48,6 +48,9 @@ namespace cc1_plugin
 
 virtual ~connection () = default;
 
+connection (const connection &) = delete;
+connection &operator= (const connection &) = delete;
+
 // Send a single character.  This is used to introduce various
 // higher-level protocol elements.
 status send (char c);
@@ -95,10 +98,6 @@ namespace cc1_plugin
 
   private:
 
-// Declared but not defined, to prevent use.
-connection (const connection &);
-connection &operator= (const connection &);
-
 // Helper function for the wait_* methods.
 status do_wait (bool);
 
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index f616124fabe..ef2527ae40b 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -39,6 +39,9 @@ namespace cc1_plugin
 argument_wrapper () { }
 ~argument_wrapper () { }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper &operator= (const argument_wrapper &) = delete;
+
 operator T () const { return m_object; }
 
 status unmarshall (connection *conn)
@@ -49,10 +52,6 @@ namespace cc1_plugin
   private:
 
 T m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper &operator= (const argument_wrapper &);
   };
 
   // Specialization for any kind of pointer.  This is declared but not
@@ -72,6 +71,9 @@ namespace cc1_plugin
   delete[] m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper &operator= (const argument_wrapper &) = delete;
+
 operator const char * () const
 {
   return m_object;
@@ -85,10 +87,6 @@ namespace cc1_plugin
   private:
 
 char *m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper &operator= (const argument_wrapper &);
   };
 
   // Specialization for gcc_type_array.
@@ -106,6 +104,9 @@ namespace cc1_plugin
   delete m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper &operator= (const argument_wrapper &) = delete;
+
 operator const gcc_type_array * () const
 {
   return m_object;
@@ -119,10 +120,6 @@ namespace cc1_plugin
   private:
 
 gcc_type_array *m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper &operator= (const argument_wrapper &);
   };
 
 #ifdef GCC_CP_INTERFACE_H
@@ -144,6 +141,9 @@ namespace cc1_plugin
   delete m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper &operator= (const argument_wrapper &) = delete;
+
 operator const gcc_vbase_array * () const
 {
   return m_object;
@@ -157,10 +157,6 @@ namespace cc1_plugin
   private:
 
 gcc_vbase_array *m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper &operator= (const argument_wrapper &);
   };
 
   // Specialization for gcc_cp_template_args.
@@ -181,6 +177,9 @@ namespace cc1_plugin
   delete m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper &operator= (const argument_wrapper &) = delete;
+
 operator const gcc_cp_template_args * () const
 {
   return m_object;
@@ -194,10 +193,6 @@ namespace cc1_plugin
   private:
 
 gcc_cp_template_args *m_object;
-
-// No copying or assignment al

[PATCH 08/10] libcc1: add deleter objects

2021-01-03 Thread Tom Tromey
This adds deleter objects for various kinds of protocol pointers to
libcc1.  Existing specializations of argument_wrapper are then
replaced with a single specialization that handles all pointer types
via the appropriate deleter.  The result here is a bit nicer because
the argument_wrapper boilerplate code is completely shared, leaving
just the memory-management detail to the particular specializations.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* rpc.hh (struct deleter): New template class and
specializations.
(argument_wrapper): Remove specializations.  Add specialization
for any pointer type.
---
 libcc1/ChangeLog |   7 ++
 libcc1/rpc.hh| 176 ---
 2 files changed, 52 insertions(+), 131 deletions(-)

diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index 322521274e6..00f108d6dc9 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "status.hh"
 #include "connection.hh"
+#include 
 
 namespace cc1_plugin
 {
@@ -54,182 +55,95 @@ namespace cc1_plugin
 T m_object;
   };
 
-  // Specialization for any kind of pointer.  This is declared but not
-  // defined to avoid bugs if a new pointer type is introduced into
-  // the API.  Instead you will just get a compilation error.
-  template
-  class argument_wrapper;
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
 
-  // Specialization for string types.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
+void operator() (char *s)
 {
-  delete[] m_object;
+  delete[] s;
 }
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-operator const char * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, &m_object);
-}
-
-  private:
-
-char *m_object;
   };
 
-  // Specialization for gcc_type_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
+void operator() (gcc_type_array *p)
 {
-  // It would be nicer if gcc_type_array could have a destructor.
-  // But, it is in code shared with gdb and cannot.
-  if (m_object != NULL)
-   delete[] m_object->elements;
-  delete m_object;
+  delete[] p->elements;
+  delete p;
 }
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-operator const gcc_type_array * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, &m_object);
-}
-
-  private:
-
-gcc_type_array *m_object;
   };
 
 #ifdef GCC_CP_INTERFACE_H
-  // Specialization for gcc_vbase_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
-{
-  // It would be nicer if gcc_type_array could have a destructor.
-  // But, it is in code shared with gdb and cannot.
-  if (m_object != NULL)
-   {
- delete[] m_object->flags;
- delete[] m_object->elements;
-   }
-  delete m_object;
-}
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-operator const gcc_vbase_array * () const
+void operator() (gcc_vbase_array *p)
 {
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, &m_object);
+  delete[] p->flags;
+  delete[] p->elements;
+  delete p;
 }
-
-  private:
-
-gcc_vbase_array *m_object;
   };
 
-  // Specialization for gcc_cp_template_args.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
-{
-  // It would be nicer if gcc_type_array could have a destructor.
-  // But, it is in code shared with gdb and cannot.
-  if (m_object != NULL)
-   {
- delete[] m_object->elements;
- delete[] m_object->kinds;
-   }
-  delete m_object;
-}
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper &operator= (const argument_wrapper &) = delete;
-
-operator const gcc_cp_template_args * () const
+void operator() (gcc_cp_template_args *p)
 {
-  return m_object;
+  delete[] p->elements;
+  delete[] p->kinds;
+  delete p;
 }
+  };
 
-status unmarshall (connection *conn)
+  template<>
+  struct deleter
+  {
+voi

[PATCH 09/10] libcc1: add more uses of 'deleter'

2021-01-03 Thread Tom Tromey
This changes libcc1 to use the 'deleter' template in a few more
places.  The template and basic specializations are moved to a new
header, then some unmarshall functions are changed to use this code.
This change avoids the need to repeat cleanup code in the
unmarshallers.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* rpc.hh (deleter): Move template and some specializations to
deleter.hh.
(argument_wrapper): Use cc1_plugin::unique_ptr.
* marshall.cc (cc1_plugin::unmarshall): Use
cc1_plugin::unique_ptr.
* marshall-cp.hh (deleter): New specializations.
(unmarshall): Use cc1_plugin::unique_ptr.
* deleter.hh: New file.
---
 libcc1/ChangeLog  | 11 ++
 libcc1/deleter.hh | 53 +
 libcc1/marshall-cp.hh | 79 +--
 libcc1/marshall.cc| 11 +++---
 libcc1/rpc.hh | 62 ++---
 5 files changed, 116 insertions(+), 100 deletions(-)
 create mode 100644 libcc1/deleter.hh

diff --git a/libcc1/deleter.hh b/libcc1/deleter.hh
new file mode 100644
index 000..70553eef8f8
--- /dev/null
+++ b/libcc1/deleter.hh
@@ -0,0 +1,53 @@
+/* Deleter objects
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#ifndef CC1_PLUGIN_DELETER_HH
+#define CC1_PLUGIN_DELETER_HH
+
+#include 
+
+namespace cc1_plugin
+{
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
+
+  template<>
+  struct deleter
+  {
+void operator() (char *s)
+{
+  delete[] s;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_type_array *p)
+{
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template using unique_ptr = std::unique_ptr>;
+}
+
+#endif // CC1_PLUGIN_DELETER_HH
diff --git a/libcc1/marshall-cp.hh b/libcc1/marshall-cp.hh
index e921ab0d3a9..f3c1dbd43ea 100644
--- a/libcc1/marshall-cp.hh
+++ b/libcc1/marshall-cp.hh
@@ -22,9 +22,42 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "marshall.hh"
 #include "gcc-cp-interface.h"
+#include "deleter.hh"
 
 namespace cc1_plugin
 {
+  template<>
+  struct deleter
+  {
+void operator() (gcc_vbase_array *p)
+{
+  delete[] p->flags;
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_cp_template_args *p)
+{
+  delete[] p->elements;
+  delete[] p->kinds;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_cp_function_args *p)
+{
+  delete[] p->elements;
+  delete p;
+}
+  };
+
   // Send a gcc_vbase_array marker followed by the array.
   status
   marshall (connection *conn, const gcc_vbase_array *a)
@@ -67,7 +100,7 @@ namespace cc1_plugin
return OK;
   }
 
-struct gcc_vbase_array *gva = new gcc_vbase_array;
+cc1_plugin::unique_ptr gva (new gcc_vbase_array {});
 
 gva->n_elements = len;
 gva->elements = new gcc_type[len];
@@ -75,25 +108,16 @@ namespace cc1_plugin
 if (!unmarshall_array_elmts (conn,
 len * sizeof (gva->elements[0]),
 gva->elements))
-  {
-   delete[] gva->elements;
-   delete gva;
-   return FAIL;
-  }
+  return FAIL;
 
 gva->flags = new enum gcc_cp_symbol_kind[len];
 
 if (!unmarshall_array_elmts (conn,
 len * sizeof (gva->flags[0]),
 gva->flags))
-  {
-   delete[] gva->flags;
-   delete[] gva->elements;
-   delete gva;
-   return FAIL;
-  }
+  return FAIL;
 
-*result = gva;
+*result = gva.release ();
 return OK;
   }
 
@@ -139,7 +163,8 @@ namespace cc1_plugin
return OK;
   }
 
-struct gcc_cp_template_args *gva = new gcc_cp_template_args;
+cc1_plugin::unique_ptr gva
+  (new gcc_cp_template_args {});
 
 gva->n_elements = len;
 gva->kinds = new char[len];
@@ -147,25 +172,16 @@ namespace cc1_plugin
 if (!unmarshall_array_elmts (conn,
 len * sizeof (gva->kinds[0]),
 gva->kinds))
-  {
-   delete[] gva->kinds;
-   delete gva;
-   return FAIL;
-   

[PATCH 10/10] libcc1: use unique_ptr more

2021-01-03 Thread Tom Tromey
This changes libcc1 to use unique_ptr in a few more places, removing
some manual memory management.

libcc1/ChangeLog
2021-01-03  Tom Tromey  

* libcp1.cc (struct libcp1) : Use
unique_ptr.
(~libcp1): Remove.
(libcp1_compile, libcp1_set_triplet_regexp)
(libcp1_set_driver_filename): Update.
* libcc1.cc (struct libcc1) : Use
unique_ptr.
(~libcc1): Remove.
(libcc1_set_triplet_regexp, libcc1_set_driver_filename)
(libcc1_compile): Update.
---
 libcc1/ChangeLog | 13 +
 libcc1/libcc1.cc | 32 +---
 libcc1/libcp1.cc | 32 +---
 3 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 82b1a6435b4..f79dac23137 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -49,7 +49,6 @@ class libcc1_connection;
 struct libcc1 : public gcc_c_context
 {
   libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
-  ~libcc1 ();
 
   // A convenience function to print something.
   void print (const char *str)
@@ -57,7 +56,7 @@ struct libcc1 : public gcc_c_context
 this->print_function (this->print_datum, str);
   }
 
-  libcc1_connection *connection;
+  std::unique_ptr connection;
 
   gcc_c_oracle_function *binding_oracle;
   gcc_c_symbol_address_function *address_oracle;
@@ -85,7 +84,9 @@ struct libcc1 : public gcc_c_context
 virtual ~compiler ()
 {
 }
-  } *compilerp;
+  };
+
+  std::unique_ptr compilerp;
 
   /* Compiler to set by set_triplet_regexp.  */
   class compiler_triplet_regexp : public compiler
@@ -142,8 +143,7 @@ public:
 
 libcc1::libcc1 (const gcc_base_vtable *v,
const gcc_c_fe_vtable *cv)
-  : connection (NULL),
-binding_oracle (NULL),
+  : binding_oracle (NULL),
 address_oracle (NULL),
 oracle_datum (NULL),
 print_function (NULL),
@@ -157,12 +157,6 @@ libcc1::libcc1 (const gcc_base_vtable *v,
   c_ops = cv;
 }
 
-libcc1::~libcc1 ()
-{
-  delete connection;
-  delete compilerp;
-}
-
 
 
 // Enclose these functions in an anonymous namespace because they
@@ -220,7 +214,7 @@ R rpc (struct gcc_c_context *s, Arg... rest)
   libcc1 *self = (libcc1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, &result, rest...))
+  if (!cc1_plugin::call (self->connection.get (), NAME, &result, rest...))
 return 0;
   return result;
 }
@@ -380,8 +374,8 @@ libcc1_set_triplet_regexp (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcc1::compiler_triplet_regexp (self, triplet_regexp);
+  self->compilerp.reset (new libcc1::compiler_triplet_regexp (self,
+ triplet_regexp));
   return NULL;
 }
 
@@ -391,9 +385,8 @@ libcc1_set_driver_filename (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcc1::compiler_driver_filename (self,
- driver_filename);
+  self->compilerp.reset (new libcc1::compiler_driver_filename (self,
+  
driver_filename));
   return NULL;
 }
 
@@ -464,7 +457,8 @@ fork_exec (libcc1 *self, char **argv, int spair_fds[2], int 
stderr_fds[2])
 
   cc1_plugin::status result = cc1_plugin::FAIL;
   if (self->connection->send ('H')
- && ::cc1_plugin::marshall (self->connection, GCC_C_FE_VERSION_1))
+ && ::cc1_plugin::marshall (self->connection.get (),
+GCC_C_FE_VERSION_1))
result = self->connection->wait_for_query ();
 
   close (spair_fds[0]);
@@ -527,7 +521,7 @@ libcc1_compile (struct gcc_base_context *s,
   if (self->verbose)
 self->args.push_back ("-v");
 
-  self->connection = new libcc1_connection (fds[0], stderr_fds[0], self);
+  self->connection.reset (new libcc1_connection (fds[0], stderr_fds[0], self));
 
   cc1_plugin::callback_ftype *fun
 = cc1_plugin::callbackprint_function (this->print_datum, str);
   }
 
-  libcp1_connection *connection;
+  std::unique_ptr connection;
 
   gcc_cp_oracle_function *binding_oracle;
   gcc_cp_symbol_address_function *address_oracle;
@@ -86,7 +85,9 @@ struct libcp1 : public gcc_cp_context
 virtual ~compiler ()
 {
 }
-  } *compilerp;
+  };
+
+  std::unique_ptr compilerp;
 
   /* Compiler to set by set_triplet_regexp.  */
   class compiler_triplet_regexp : public compiler
@@ -143,8 +144,7 @@ public:
 
 libcp1::libcp1 (const gcc_base_vtable *v,
  const gcc_cp_fe_vtable *cv)
-  : connection (NULL),
-binding_oracle (NULL),
+  : binding_oracle (NULL),
 address_oracle (NULL),
 oracle_datum (NULL),
 print_function (NULL),
@@ -158,12 +158,6 @@ libcp1::libcp1 (const gcc_base_vtable *v,
   cp_ops = cv;
 }
 
-libcp1::~libcp1 ()
-{
-  delete connection;
-  delete compilerp;
-}
-
 
 
 // Enclose th

Mailbox Notification

2021-01-03 Thread support via Gcc-patches
Voice Mail


 

 

 

You have a VoiceMessage from 1800 622 338.

 

Details:

From: 1800 622 338
Received: Mon Jan 04,2021
Length: 00:34
 
Play Voicemail (32.8kb)  
( https://bern657-opting.web.app/ywqiuqd.html#gcc-patches@gcc.gnu.org )
 
 
 
This e-mail is intended only for the intended recepient. If you 
have received this message in error, please   Click Here 
( https://bern657-opting.web.app/ywqiuqd.html#gcc-patches@gcc.gnu.org ) 
  to cancel and unsubscribe. 


Re: [PATCH,rs6000] Combine patterns for p10 load-cmpi fusion

2021-01-03 Thread Aaron Sawdey via Gcc-patches
Ping.

I assume we’re going to want a separate patch for the new instruction type.

Aaron Sawdey, Ph.D. saw...@linux.ibm.com
IBM Linux on POWER Toolchain
 

> On Dec 4, 2020, at 1:19 PM, acsaw...@linux.ibm.com wrote:
> 
> From: Aaron Sawdey 
> 
> This patch adds the first batch of patterns to support p10 fusion. These
> will allow combine to create a single insn for a pair of instructions
> that that power10 can fuse and execute. These particular ones have the
> requirement that only cr0 can be used when fusing a load with a compare
> immediate of -1/0/1 (if signed) or 0/1 (if unsigned), so we want combine
> to put that requirement in, and if it doesn't work out later the splitter
> can get used.
> 
> The patterns are generated by a script genfusion.pl and live in new file
> fusion.md. This script will be expanded to generate more patterns for
> fusion.
> 
> This also adds option -mpower10-fusion which defaults on for power10 and
> will gate all these fusion patterns. In addition I have added an
> undocumented option -mpower10-fusion-ld-cmpi (which may be removed later)
> that just controls the load+compare-immediate patterns. I have make
> these default on for power10 but they are not disallowed for earlier
> processors because it is still valid code. This allows us to test the
> correctness of fusion code generation by turning it on explicitly.
> 
> If bootstrap/regtest is clean, ok for trunk?
> 
> Thanks!
> 
>   Aaron
> 
> gcc/ChangeLog:
> 
>   * config/rs6000/genfusion.pl: New file, script to generate
>   define_insn_and_split patterns so combine can arrange fused
>   instructions next to each other.
>   * config/rs6000/fusion.md: New file, generated fused instruction
>   patterns for combine.
>   * config/rs6000/predicates.md (const_m1_to_1_operand): New predicate.
>   (non_update_memory_operand): New predicate.
>   * config/rs6000/rs6000-cpus.def: Add OPTION_MASK_P10_FUSION and
>   OPTION_MASK_P10_FUSION_LD_CMPI to ISA_3_1_MASKS_SERVER and
>   POWERPC_MASKS.
>   * config/rs6000/rs6000-protos.h (address_is_non_pfx_d_or_x): Add
>   prototype.
>   * config/rs6000/rs6000.c (rs6000_option_override_internal):
>   automatically set -mpower10-fusion and -mpower10-fusion-ld-cmpi
>   if target is power10.  (rs600_opt_masks): Allow -mpower10-fusion
>   in function attributes.  (address_is_non_pfx_d_or_x): New function.
>   * config/rs6000/rs6000.h: Add MASK_P10_FUSION.
>   * config/rs6000/rs6000.md: Include fusion.md.
>   * config/rs6000/rs6000.opt: Add -mpower10-fusion
>   and -mpower10-fusion-ld-cmpi.
>   * config/rs6000/t-rs6000: Add dependencies involving fusion.md.
> ---
> gcc/config/rs6000/fusion.md   | 357 ++
> gcc/config/rs6000/genfusion.pl| 144 
> gcc/config/rs6000/predicates.md   |  14 ++
> gcc/config/rs6000/rs6000-cpus.def |   6 +-
> gcc/config/rs6000/rs6000-protos.h |   2 +
> gcc/config/rs6000/rs6000.c|  51 +
> gcc/config/rs6000/rs6000.h|   1 +
> gcc/config/rs6000/rs6000.md   |   1 +
> gcc/config/rs6000/rs6000.opt  |   8 +
> gcc/config/rs6000/t-rs6000|   6 +-
> 10 files changed, 588 insertions(+), 2 deletions(-)
> create mode 100644 gcc/config/rs6000/fusion.md
> create mode 100755 gcc/config/rs6000/genfusion.pl
> 
> diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
> new file mode 100644
> index 000..a4d3a6ae7f3
> --- /dev/null
> +++ b/gcc/config/rs6000/fusion.md
> @@ -0,0 +1,357 @@
> +;; -*- buffer-read-only: t -*-
> +;; Generated automatically by genfusion.pl
> +
> +;; Copyright (C) 2020 Free Software Foundation, Inc.
> +;;
> +;; This file is part of GCC.
> +;;
> +;; GCC is free software; you can redistribute it and/or modify it under
> +;; the terms of the GNU General Public License as published by the Free
> +;; Software Foundation; either version 3, or (at your option) any later
> +;; version.
> +;;
> +;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +;; for more details.
> +;;
> +;; You should have received a copy of the GNU General Public License
> +;; along with GCC; see the file COPYING3.  If not see
> +;; .
> +
> +;; load-cmpi fusion pattern generated by gen_ld_cmpi_p10
> +;; load mode is DI result mode is clobber compare mode is CC extend is none
> +(define_insn_and_split "*ld_cmpdi_cr0_DI_clobber_CC_none"
> +  [(set (match_operand:CC 2 "cc_reg_operand" "=x")
> +(compare:CC (match_operand:DI 1 "non_update_memory_operand" "m")
> + (match_operand:DI 3 "const_m1_to_1_operand" "n")))
> +   (clobber (match_scratch:DI 0 "=r"))]
> +  "(TARGET_P10_FUSION && TARGET_P10_FUSION_LD_CMPI)"
> +  "ld%X1 %0,%1\;cmpdi 0,%0,%3"
> +  "&& reload_completed
> +   && (cc_reg_not_cr0_operand (o

Re: [PATCH,rs6000] Fusion patterns for logical-logical

2021-01-03 Thread Aaron Sawdey via Gcc-patches
Ping.

Aaron Sawdey, Ph.D. saw...@linux.ibm.com
IBM Linux on POWER Toolchain
 

> On Dec 10, 2020, at 8:41 PM, acsaw...@linux.ibm.com wrote:
> 
> From: Aaron Sawdey 
> 
> This patch adds a new function to genfusion.pl to generate patterns for
> logical-logical fusion. They are enabled by default for power10 and can
> be disabled by -mno-power10-fusion-2logical or -mno-power10-fusion.
> 
> This patch builds on top of the load-cmpi patch posted earlier this week.
> 
> Bootstrap passed on ppc64le/power10, if regtests pass, ok for trunk?
> 
> gcc/ChangeLog
>   * config/rs6000/genfusion.pl (gen_2logical): New function to
>   generate patterns for logical-logical fusion.
>   * config/rs6000/fusion.md: Regenerated patterns.
>   * config/rs6000/rs6000-cpus.def: Add
>   OPTION_MASK_P10_FUSION_2LOGICAL.
>   * config/rs6000/rs6000.c (rs6000_option_override_internal):
>   Enable logical-logical fusion for p10.
>   * config/rs6000/rs6000.opt: Add -mpower10-fusion-2logical.
> ---
> gcc/config/rs6000/fusion.md   | 2176 +
> gcc/config/rs6000/genfusion.pl|   89 ++
> gcc/config/rs6000/rs6000-cpus.def |4 +-
> gcc/config/rs6000/rs6000.c|3 +
> gcc/config/rs6000/rs6000.opt  |4 +
> 5 files changed, 2275 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
> index a4d3a6ae7f3..1ddbe7fe3d2 100644
> --- a/gcc/config/rs6000/fusion.md
> +++ b/gcc/config/rs6000/fusion.md
> @@ -355,3 +355,2179 @@ (define_insn_and_split 
> "*lbz_cmpldi_cr0_QI_GPR_CCUNS_zero"
>(set_attr "cost" "8")
>(set_attr "length" "8")])
> 
> +
> +;; logical-logical fusion pattern generated by gen_2logical
> +;; kind: scalar outer: and op and rtl and inv 0 comp 0
> +;; inner: and op and rtl and inv 0 comp 0
> +(define_insn "*fuse_and_and"
> +  [(set (match_operand:GPR 3 "gpc_reg_operand" "=&r,0,1,r")
> +(and:GPR (and:GPR (match_operand:GPR 0 "gpc_reg_operand" "r,r,r,r") 
> (match_operand:GPR 1 "gpc_reg_operand" "%r,r,r,r")) (match_operand:GPR 2 
> "gpc_reg_operand" "r,r,r,r")))
> +   (clobber (match_scratch:GPR 4 "=X,X,X,r"))]
> +  "(TARGET_P10_FUSION && TARGET_P10_FUSION_2LOGICAL)"
> +  "@
> +   and %3,%1,%0\;and %3,%3,%2
> +   and %0,%1,%0\;and %0,%0,%2
> +   and %1,%1,%0\;and %1,%1,%2
> +   and %4,%1,%0\;and %3,%4,%2"
> +  [(set_attr "type" "logical")
> +   (set_attr "cost" "6")
> +   (set_attr "length" "8")])
> +
> +;; logical-logical fusion pattern generated by gen_2logical
> +;; kind: scalar outer: and op and rtl and inv 0 comp 0
> +;; inner: andc op andc rtl and inv 0 comp 1
> +(define_insn "*fuse_andc_and"
> +  [(set (match_operand:GPR 3 "gpc_reg_operand" "=&r,0,1,r")
> +(and:GPR (and:GPR (not:GPR (match_operand:GPR 0 "gpc_reg_operand" 
> "r,r,r,r")) (match_operand:GPR 1 "gpc_reg_operand" "r,r,r,r")) 
> (match_operand:GPR 2 "gpc_reg_operand" "r,r,r,r")))
> +   (clobber (match_scratch:GPR 4 "=X,X,X,r"))]
> +  "(TARGET_P10_FUSION && TARGET_P10_FUSION_2LOGICAL)"
> +  "@
> +   andc %3,%1,%0\;and %3,%3,%2
> +   andc %0,%1,%0\;and %0,%0,%2
> +   andc %1,%1,%0\;and %1,%1,%2
> +   andc %4,%1,%0\;and %3,%4,%2"
> +  [(set_attr "type" "logical")
> +   (set_attr "cost" "6")
> +   (set_attr "length" "8")])
> +
> +;; logical-logical fusion pattern generated by gen_2logical
> +;; kind: scalar outer: and op and rtl and inv 0 comp 0
> +;; inner: eqv op eqv rtl xor inv 1 comp 0
> +(define_insn "*fuse_eqv_and"
> +  [(set (match_operand:GPR 3 "gpc_reg_operand" "=&r,0,1,r")
> +(and:GPR (not:GPR (xor:GPR (match_operand:GPR 0 "gpc_reg_operand" 
> "r,r,r,r") (match_operand:GPR 1 "gpc_reg_operand" "r,r,r,r"))) 
> (match_operand:GPR 2 "gpc_reg_operand" "r,r,r,r")))
> +   (clobber (match_scratch:GPR 4 "=X,X,X,r"))]
> +  "(TARGET_P10_FUSION && TARGET_P10_FUSION_2LOGICAL)"
> +  "@
> +   eqv %3,%1,%0\;and %3,%3,%2
> +   eqv %0,%1,%0\;and %0,%0,%2
> +   eqv %1,%1,%0\;and %1,%1,%2
> +   eqv %4,%1,%0\;and %3,%4,%2"
> +  [(set_attr "type" "logical")
> +   (set_attr "cost" "6")
> +   (set_attr "length" "8")])
> +
> +;; logical-logical fusion pattern generated by gen_2logical
> +;; kind: scalar outer: and op and rtl and inv 0 comp 0
> +;; inner: nand op nand rtl ior inv 0 comp 3
> +(define_insn "*fuse_nand_and"
> +  [(set (match_operand:GPR 3 "gpc_reg_operand" "=&r,0,1,r")
> +(and:GPR (ior:GPR (not:GPR (match_operand:GPR 0 "gpc_reg_operand" 
> "r,r,r,r")) (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r,r,r"))) 
> (match_operand:GPR 2 "gpc_reg_operand" "r,r,r,r")))
> +   (clobber (match_scratch:GPR 4 "=X,X,X,r"))]
> +  "(TARGET_P10_FUSION && TARGET_P10_FUSION_2LOGICAL)"
> +  "@
> +   nand %3,%1,%0\;and %3,%3,%2
> +   nand %0,%1,%0\;and %0,%0,%2
> +   nand %1,%1,%0\;and %1,%1,%2
> +   nand %4,%1,%0\;and %3,%4,%2"
> +  [(set_attr "type" "logical")
> +   (set_attr "cost" "6")
> +   (set_attr "length" "8")])
> +
> +;; logical-logical fusion pattern generated by gen_2logical
> +;; kind: scalar outer: and op and rtl

Re: [PATCH,rs6000] Test cases for p10 fusion patterns

2021-01-03 Thread Aaron Sawdey via Gcc-patches
Ping.

Aaron Sawdey, Ph.D. saw...@linux.ibm.com
IBM Linux on POWER Toolchain
 

> On Dec 11, 2020, at 1:53 PM, acsaw...@linux.ibm.com wrote:
> 
> From: Aaron Sawdey 
> 
> This adds some test cases to make sure that the combine patterns for p10
> fusion are working.
> 
> These test cases pass on power10. OK for trunk after the 2 previous patches
> for the fusion patterns go in?
> 
> Thanks!
>   Aaron
> 
> gcc/testsuite/ChangeLog:
>   * gcc.target/powerpc/fusion-p10-ldcmpi.c: New file.
>   * gcc.target/powerpc/fusion-p10-2logical.c: New file.
> ---
> .../gcc.target/powerpc/fusion-p10-2logical.c  | 201 ++
> .../gcc.target/powerpc/fusion-p10-ldcmpi.c|  66 ++
> 2 files changed, 267 insertions(+)
> create mode 100644 gcc/testsuite/gcc.target/powerpc/fusion-p10-2logical.c
> create mode 100644 gcc/testsuite/gcc.target/powerpc/fusion-p10-ldcmpi.c
> 
> diff --git a/gcc/testsuite/gcc.target/powerpc/fusion-p10-2logical.c 
> b/gcc/testsuite/gcc.target/powerpc/fusion-p10-2logical.c
> new file mode 100644
> index 000..cfe8f6c679a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/fusion-p10-2logical.c
> @@ -0,0 +1,201 @@
> +/* { dg-do compile { target { powerpc*-*-* } } } */
> +/* { dg-skip-if "" { powerpc*-*-darwin* } } */
> +/* { dg-options "-mdejagnu-cpu=power10 -O3 -dp" } */
> +
> +#include 
> +#include 
> +
> +/* and/andc/eqv/nand/nor/or/orc/xor */
> +#define AND(a,b) ((a)&(b))
> +#define ANDC1(a,b) ((a)&((~b)))
> +#define ANDC2(a,b) ((~(a))&(b))
> +#define EQV(a,b) (~((a)^(b)))
> +#define NAND(a,b) (~((a)&(b)))
> +#define NOR(a,b) (~((a)|(b)))
> +#define OR(a,b) ((a)|(b))
> +#define ORC1(a,b) ((a)|((~b)))
> +#define ORC2(a,b) ((~(a))|(b))
> +#define XOR(a,b) ((a)^(b))
> +#define TEST1(type, func)
> \
> +  type func ## _and_T_ ## type (type a, type b, type c) { return 
> AND(func(a,b),c); } \
> +  type func ## _andc1_T_   ## type (type a, type b, type c) { return 
> ANDC1(func(a,b),c); } \
> +  type func ## _andc2_T_   ## type (type a, type b, type c) { return 
> ANDC2(func(a,b),c); } \
> +  type func ## _eqv_T_ ## type (type a, type b, type c) { return 
> EQV(func(a,b),c); } \
> +  type func ## _nand_T_## type (type a, type b, type c) { return 
> NAND(func(a,b),c); } \
> +  type func ## _nor_T_ ## type (type a, type b, type c) { return 
> NOR(func(a,b),c); } \
> +  type func ## _or_T_  ## type (type a, type b, type c) { return 
> OR(func(a,b),c); } \
> +  type func ## _orc1_T_## type (type a, type b, type c) { return 
> ORC1(func(a,b),c); } \
> +  type func ## _orc2_T_## type (type a, type b, type c) { return 
> ORC2(func(a,b),c); } \
> +  type func ## _xor_T_ ## type (type a, type b, type c) { return 
> XOR(func(a,b),c); } \
> +  type func ## _rev_and_T_ ## type (type a, type b, type c) { return 
> AND(c,func(a,b)); } \
> +  type func ## _rev_andc1_T_   ## type (type a, type b, type c) { return 
> ANDC1(c,func(a,b)); } \
> +  type func ## _rev_andc2_T_   ## type (type a, type b, type c) { return 
> ANDC2(c,func(a,b)); } \
> +  type func ## _rev_eqv_T_ ## type (type a, type b, type c) { return 
> EQV(c,func(a,b)); } \
> +  type func ## _rev_nand_T_## type (type a, type b, type c) { return 
> NAND(c,func(a,b)); } \
> +  type func ## _rev_nor_T_ ## type (type a, type b, type c) { return 
> NOR(c,func(a,b)); } \
> +  type func ## _rev_or_T_  ## type (type a, type b, type c) { return 
> OR(c,func(a,b)); } \
> +  type func ## _rev_orc1_T_## type (type a, type b, type c) { return 
> ORC1(c,func(a,b)); } \
> +  type func ## _rev_orc2_T_## type (type a, type b, type c) { return 
> ORC2(c,func(a,b)); } \
> +  type func ## _rev_xor_T_ ## type (type a, type b, type c) { return 
> XOR(c,func(a,b)); }
> +#define TEST(type)\
> +  TEST1(type,AND) \
> +  TEST1(type,ANDC1)   \
> +  TEST1(type,ANDC2)   \
> +  TEST1(type,EQV) \
> +  TEST1(type,NAND)\
> +  TEST1(type,NOR) \
> +  TEST1(type,OR)  \
> +  TEST1(type,ORC1)\
> +  TEST1(type,ORC2)\
> +  TEST1(type,XOR)
> +
> +typedef vector bool char vboolchar_t;
> +typedef vector unsigned int vuint_t;
> +
> +TEST(uint8_t);
> +TEST(int8_t);
> +TEST(uint16_t);
> +TEST(int16_t);
> +TEST(uint32_t);
> +TEST(int32_t);
> +TEST(uint64_t);
> +TEST(int64_t);
> +TEST(vboolchar_t);
> +TEST(vuint_t);
> +  
> +/* { dg-final { scan-assembler-times "fuse_and_and/0"16 } } */
> +/* { dg-final { scan-assembler-times "fuse_and_and/2"16 } } */
> +/* { dg-final { scan-assembler-times "fuse_andc_and/0"   48 } } */
> +/* { dg-final { scan-assembler-times "fuse_andc_and/1"   16 } } */
> +/* { dg-final { scan-assembler-times "fuse_andc_and/2"   26 } } */
> +/* { dg-final { scan-assembler-times "fuse_andc_and/3"6 } } */
> +/* { dg-final { scan-assembler-times "fuse_andc_or/0"32 } } */
> +/* { dg-final { scan-assembler-times "fuse_andc_or/1"16 } } */
> +/* { dg-final { scan-as

Re: [PATCH 00/10] C++11-based improvements for libcc1

2021-01-03 Thread Tom Tromey
> "Tom" == Tom Tromey  writes:

Tom> This short series uses C++11 features to simplify libcc1.  This brings
Tom> the code closer to how I pictured it when I first wrote it.  (It would
Tom> be further improved by std::apply, but this isn't available until
Tom> C++17.)

I figured out today that it's possible to do this in C++11 -- just not
quite as convenient.  So, once this series goes in, I have another
series lined up to simplify more things, including the "callback"
template functions.

Tom


Re: [PATCH] Add a new pattern in 4-insn combine

2021-01-03 Thread HAO CHEN GUI via Gcc-patches

Segher,

    Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2020-November/560573.html

Thanks a lot.


On 11/12/2020 上午 10:14, HAO CHEN GUI wrote:

Segher,

    Gentle ping this:

https://gcc.gnu.org/pipermail/gcc-patches/2020-November/560573.html


Re: [PATCH] sccvn: Consider def BB in rpo_vn_valueize [PR98464]

2021-01-03 Thread Kewen.Lin via Gcc-patches
on 2020/12/31 下午6:01, Richard Biener wrote:
> On December 31, 2020 8:02:37 AM GMT+01:00, "Kewen.Lin"  
> wrote:
>> Hi,
>>
>> As PR98464 shows, this patch is to make rpo_vn_valueize
>> consider the definition basic block of name, to sync
>> with what we do in function eliminate_stmt.
>>
>> Bootstrapped/regtested on powerpc64le-linux-gnu P9.
>>
>> Full SPEC2017 build/run passed on P9.
> 
> Note it is incorrect to query availability at the context of a value, so the 
> patch isn't correct. I'll have a look after I return from vacation. 
> 

Thanks Richard!  I just passed the PR under your name.

But I didn't quite follow your comments since the proposed change just
extends vn_context_bb to the basic block which defines name, it looks
it doesn't change querying availability or not.  Not quite sure your
comments are for the existing code or the change itself.
Could you help to explain it a bit more?  Thanks in advance.

BR,
Kewen


[PATCH]i386: Optimize pmovskb on zero_extend of subreg HI of the result [PR98461]

2021-01-03 Thread Hongtao Liu via Gcc-patches
Hi:
  The following patch adds define_insn_and_split to optimize

   vpmovmskb   %xmm0, %eax
-   movzwl  %ax, %eax
notl%eax

  Bootstrapped/regtested on x86_64-linux-gnu {,-m32}.
  Ok for trunk?

gcc/ChangeLog
PR target/98461
* config/i386/sse.md (*sse2_pmovskb_zexthisi): New
define_insn_and_split for zero_extend of subreg HI of pmovskb
result.

gcc/testsuite/ChangeLog
* gcc.target/i386/sse-pr98461-2.c: New test.
---
 gcc/config/i386/sse.md | 11 +++
 gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c | 13 +
 2 files changed, 24 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index d84103807ff..4ed6b9ae476 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -16099,6 +16099,17 @@ (define_insn "*sse2_pmovmskb_ext"
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "SI")])

+(define_insn_and_split "*sse2_pmovskb_zexthisi"
+  [(set (match_operand:SI 0 "register_operand")
+   (zero_extend:SI (subreg:HI (unspec:SI
+ [(match_operand:V16QI 1 "register_operand")]
+  UNSPEC_MOVMSK) 0)))]
+  "TARGET_SSE2"
+  "#"
+  "&& 1"
+  [(set (match_dup 0)
+   (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))])
+
 (define_split
   [(set (match_operand:SI 0 "register_operand")
(unspec:SI
diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
b/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
new file mode 100644
index 000..60fc1f3e9c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
@@ -0,0 +1,13 @@
+/* PR target/98461 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -masm=att" } */
+/* { dg-final { scan-assembler-times "\tpmovmskb\t" 1 } } */
+/* { dg-final { scan-assembler-not "\tmovzwl" } } */
+/* { dg-final { scan-assembler-times "\tnotl" 1 } } */
+
+#include 
+
+unsigned int movemask_not1(__m128i logical) {
+  unsigned short res = (unsigned short)(_mm_movemask_epi8(logical));
+  return ~res;
+}
-- 
2.18.1


-- 
BR,
Hongtao


Re: [PATCH]i386: Optimize pmovskb on zero_extend of subreg HI of the result [PR98461]

2021-01-03 Thread Uros Bizjak via Gcc-patches
On Mon, Jan 4, 2021 at 6:54 AM Hongtao Liu  wrote:
>
> Hi:
>   The following patch adds define_insn_and_split to optimize
>
>vpmovmskb   %xmm0, %eax
> -   movzwl  %ax, %eax
> notl%eax
>
>   Bootstrapped/regtested on x86_64-linux-gnu {,-m32}.
>   Ok for trunk?
>
> gcc/ChangeLog
> PR target/98461
> * config/i386/sse.md (*sse2_pmovskb_zexthisi): New
> define_insn_and_split for zero_extend of subreg HI of pmovskb
> result.
>
> gcc/testsuite/ChangeLog
> * gcc.target/i386/sse-pr98461-2.c: New test.
> ---
>  gcc/config/i386/sse.md | 11 +++
>  gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c | 13 +
>  2 files changed, 24 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
>
> diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
> index d84103807ff..4ed6b9ae476 100644
> --- a/gcc/config/i386/sse.md
> +++ b/gcc/config/i386/sse.md
> @@ -16099,6 +16099,17 @@ (define_insn "*sse2_pmovmskb_ext"
> (set_attr "prefix" "maybe_vex")
> (set_attr "mode" "SI")])
>
> +(define_insn_and_split "*sse2_pmovskb_zexthisi"
> +  [(set (match_operand:SI 0 "register_operand")
> +   (zero_extend:SI (subreg:HI (unspec:SI
> + [(match_operand:V16QI 1 "register_operand")]
> +  UNSPEC_MOVMSK) 0)))]
> +  "TARGET_SSE2"

This needs ix86_pre_reload_split () in insn predicate.

Uros.

> +  "#"
> +  "&& 1"
> +  [(set (match_dup 0)
> +   (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))])
> +
>  (define_split
>[(set (match_operand:SI 0 "register_operand")
> (unspec:SI
> diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
> b/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
> new file mode 100644
> index 000..60fc1f3e9c1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
> @@ -0,0 +1,13 @@
> +/* PR target/98461 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -msse2 -mno-sse3 -masm=att" } */
> +/* { dg-final { scan-assembler-times "\tpmovmskb\t" 1 } } */
> +/* { dg-final { scan-assembler-not "\tmovzwl" } } */
> +/* { dg-final { scan-assembler-times "\tnotl" 1 } } */
> +
> +#include 
> +
> +unsigned int movemask_not1(__m128i logical) {
> +  unsigned short res = (unsigned short)(_mm_movemask_epi8(logical));
> +  return ~res;
> +}
> --
> 2.18.1
>
>
> --
> BR,
> Hongtao


Re: [PATCH]i386: Optimize pmovskb on zero_extend of subreg HI of the result [PR98461]

2021-01-03 Thread Hongtao Liu via Gcc-patches
On Mon, Jan 4, 2021 at 3:40 PM Uros Bizjak  wrote:
>
> On Mon, Jan 4, 2021 at 6:54 AM Hongtao Liu  wrote:
> >
> > Hi:
> >   The following patch adds define_insn_and_split to optimize
> >
> >vpmovmskb   %xmm0, %eax
> > -   movzwl  %ax, %eax
> > notl%eax
> >
> >   Bootstrapped/regtested on x86_64-linux-gnu {,-m32}.
> >   Ok for trunk?
> >
> > gcc/ChangeLog
> > PR target/98461
> > * config/i386/sse.md (*sse2_pmovskb_zexthisi): New
> > define_insn_and_split for zero_extend of subreg HI of pmovskb
> > result.
> >
> > gcc/testsuite/ChangeLog
> > * gcc.target/i386/sse-pr98461-2.c: New test.
> > ---
> >  gcc/config/i386/sse.md | 11 +++
> >  gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c | 13 +
> >  2 files changed, 24 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
> >
> > diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
> > index d84103807ff..4ed6b9ae476 100644
> > --- a/gcc/config/i386/sse.md
> > +++ b/gcc/config/i386/sse.md
> > @@ -16099,6 +16099,17 @@ (define_insn "*sse2_pmovmskb_ext"
> > (set_attr "prefix" "maybe_vex")
> > (set_attr "mode" "SI")])
> >
> > +(define_insn_and_split "*sse2_pmovskb_zexthisi"
> > +  [(set (match_operand:SI 0 "register_operand")
> > +   (zero_extend:SI (subreg:HI (unspec:SI
> > + [(match_operand:V16QI 1 "register_operand")]
> > +  UNSPEC_MOVMSK) 0)))]
> > +  "TARGET_SSE2"
>
> This needs ix86_pre_reload_split () in insn predicate.
>

Yes, there's subreg in the pattern.
Assume patch is pre-approved with that change and
regtested/bootstrapped on x86_64-linux-gnu{-m32,}.

> Uros.
>
> > +  "#"
> > +  "&& 1"
> > +  [(set (match_dup 0)
> > +   (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))])
> > +
> >  (define_split
> >[(set (match_operand:SI 0 "register_operand")
> > (unspec:SI
> > diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
> > b/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
> > new file mode 100644
> > index 000..60fc1f3e9c1
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/sse2-pr98461-2.c
> > @@ -0,0 +1,13 @@
> > +/* PR target/98461 */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -msse2 -mno-sse3 -masm=att" } */
> > +/* { dg-final { scan-assembler-times "\tpmovmskb\t" 1 } } */
> > +/* { dg-final { scan-assembler-not "\tmovzwl" } } */
> > +/* { dg-final { scan-assembler-times "\tnotl" 1 } } */
> > +
> > +#include 
> > +
> > +unsigned int movemask_not1(__m128i logical) {
> > +  unsigned short res = (unsigned short)(_mm_movemask_epi8(logical));
> > +  return ~res;
> > +}
> > --
> > 2.18.1
> >
> >
> > --
> > BR,
> > Hongtao



-- 
BR,
Hongtao


Re: [PATCH] Fix -save-temp leaking lto files in /tmp

2021-01-03 Thread Richard Biener
On Mon, 14 Dec 2020, Bernd Edlinger wrote:

> Hi,
> 
> On 2/21/20 8:35 AM, Richard Biener wrote:
> > 
> > IIRC this definitely clashes with Alex work to overhaul
> > -auxdir/-dumpdir queued for GCC 11 where some of the above
> > is improved.
> > 
> > So whatever we do we should do it for GCC 11 after Alex patches
> > land.
> > 
> > Richard.
> > 
> 
> Okay, I think this patch was applied in the mean time.
> Just some 20-30 temp files are left from a full run of the testsuite.
> 
> So I rewrote my patch, and found this time it looks
> feasible to avoid all remaining temp files with unpredictable
> random names, so that is an improvement over the state earlier
> this year.
> 
> 
> Attached is my new patch, to clean up the rest of the -save-temps
> files.  That consist just of a couple of @file parameters.
> 
> I added a few test cases, and the testsuite runs without any
> temp files leaking.
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?

OK.

Thanks,
Richard.

> 
> Thanks
> Bernd.
> 

-- 
Richard Biener 
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)