d: Move d_gimplify_expr and dependencies to d-gimplify.cc
authorIain Buclaw <ibuclaw@gdcproject.org>
Fri, 21 Aug 2020 09:58:51 +0000 (11:58 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Wed, 26 Aug 2020 08:03:54 +0000 (10:03 +0200)
gcc/d/ChangeLog:

* Make-lang.in (D_OBJS): Add d-gimplify.o.
* d-lang.cc (empty_modify_p): Move to d-gimplify.cc.
(d_gimplify_expr): Likewise.
* d-tree.h (d_gimplify_expr): Declare.
* d-gimplify.cc: New file.

gcc/d/Make-lang.in
gcc/d/d-gimplify.cc [new file with mode: 0644]
gcc/d/d-lang.cc
gcc/d/d-tree.h

index 6c8c611a0f7f78abbf673ad7f7954ebf1669fc43..18d99abab354db7a14bc7d45173b97bee3389239 100644 (file)
@@ -141,6 +141,7 @@ D_OBJS = \
        d/d-ctfloat.o \
        d/d-diagnostic.o \
        d/d-frontend.o \
+       d/d-gimplify.o \
        d/d-incpath.o \
        d/d-lang.o \
        d/d-longdouble.o \
diff --git a/gcc/d/d-gimplify.cc b/gcc/d/d-gimplify.cc
new file mode 100644 (file)
index 0000000..ed49e5f
--- /dev/null
@@ -0,0 +1,187 @@
+/* D-specific tree lowering bits; see also gimple.c.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+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
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "dmd/globals.h"
+
+#include "tree.h"
+#include "gimple-expr.h"
+#include "gimplify.h"
+
+#include "d-tree.h"
+
+
+/* Return TRUE if an operand OP of a given TYPE being copied has no data.
+   The middle-end does a similar check with zero sized types.  */
+
+static bool
+empty_modify_p (tree type, tree op)
+{
+  tree_code code = TREE_CODE (op);
+  switch (code)
+    {
+    case COMPOUND_EXPR:
+      return empty_modify_p (type, TREE_OPERAND (op, 1));
+
+    case CONSTRUCTOR:
+      /* Non-empty construcors are valid.  */
+      if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op))
+       return false;
+      break;
+
+    case CALL_EXPR:
+      /* Leave nrvo alone because it isn't a copy.  */
+      if (CALL_EXPR_RETURN_SLOT_OPT (op))
+       return false;
+      break;
+
+    default:
+      /* If the operand doesn't have a simple form.  */
+      if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op))
+       return false;
+      break;
+    }
+
+  return empty_aggregate_p (type);
+}
+
+/* Implements the lang_hooks.gimplify_expr routine for language D.
+   Do gimplification of D specific expression trees in EXPR_P.  */
+
+int
+d_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
+                gimple_seq *post_p ATTRIBUTE_UNUSED)
+{
+  tree_code code = TREE_CODE (*expr_p);
+  enum gimplify_status ret = GS_UNHANDLED;
+  tree op0, op1;
+  tree type;
+
+  switch (code)
+    {
+    case INIT_EXPR:
+    case MODIFY_EXPR:
+      op0 = TREE_OPERAND (*expr_p, 0);
+      op1 = TREE_OPERAND (*expr_p, 1);
+
+      if (!error_operand_p (op0) && !error_operand_p (op1)
+         && (AGGREGATE_TYPE_P (TREE_TYPE (op0))
+             || AGGREGATE_TYPE_P (TREE_TYPE (op1)))
+         && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
+       {
+         /* If the back end isn't clever enough to know that the lhs and rhs
+            types are the same, add an explicit conversion.  */
+         TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
+                                             TREE_TYPE (op0), op1);
+         ret = GS_OK;
+       }
+      else if (empty_modify_p (TREE_TYPE (op0), op1))
+       {
+         /* Remove any copies of empty aggregates.  */
+         gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+                        is_gimple_lvalue, fb_lvalue);
+
+         if (TREE_SIDE_EFFECTS (op1))
+           gimplify_and_add (op1, pre_p);
+
+         *expr_p = TREE_OPERAND (*expr_p, 0);
+         ret = GS_OK;
+       }
+      break;
+
+    case ADDR_EXPR:
+      op0 = TREE_OPERAND (*expr_p, 0);
+      /* Constructors are not lvalues, so make them one.  */
+      if (TREE_CODE (op0) == CONSTRUCTOR)
+       {
+         TREE_OPERAND (*expr_p, 0) = force_target_expr (op0);
+         ret = GS_OK;
+       }
+      break;
+
+    case CALL_EXPR:
+      if (CALL_EXPR_ARGS_ORDERED (*expr_p))
+       {
+         /* Strictly evaluate all arguments from left to right.  */
+         int nargs = call_expr_nargs (*expr_p);
+         location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
+
+         /* No need to enforce evaluation order if only one argument.  */
+         if (nargs < 2)
+           break;
+
+         /* Or if all arguments are already free of side-effects.  */
+         bool has_side_effects = false;
+         for (int i = 0; i < nargs; i++)
+           {
+             if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
+               {
+                 has_side_effects = true;
+                 break;
+               }
+           }
+
+         if (!has_side_effects)
+           break;
+
+         /* Leave the last argument for gimplify_call_expr.  */
+         for (int i = 0; i < nargs - 1; i++)
+           {
+             tree new_arg = CALL_EXPR_ARG (*expr_p, i);
+
+             /* If argument has a side-effect, gimplify_arg will handle it.  */
+             if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR)
+               ret = GS_ERROR;
+
+             /* Even if an argument itself doesn't have any side-effects, it
+                might be altered by another argument in the list.  */
+             if (new_arg == CALL_EXPR_ARG (*expr_p, i)
+                 && !really_constant_p (new_arg))
+               new_arg = get_formal_tmp_var (new_arg, pre_p);
+
+             CALL_EXPR_ARG (*expr_p, i) = new_arg;
+           }
+
+         if (ret != GS_ERROR)
+           ret = GS_OK;
+       }
+      break;
+
+    case UNSIGNED_RSHIFT_EXPR:
+      /* Convert op0 to an unsigned type.  */
+      op0 = TREE_OPERAND (*expr_p, 0);
+      op1 = TREE_OPERAND (*expr_p, 1);
+
+      type = d_unsigned_type (TREE_TYPE (op0));
+
+      *expr_p = convert (TREE_TYPE (*expr_p),
+                        build2 (RSHIFT_EXPR, type, convert (type, op0), op1));
+      ret = GS_OK;
+      break;
+
+    case FLOAT_MOD_EXPR:
+      gcc_unreachable ();
+
+    default:
+      break;
+    }
+
+  return ret;
+}
index 6412c1c204c44fddaa9c31120792b96b3c80a2cd..6183389007ad0f20d69b96e39c899783564f69bd 100644 (file)
@@ -48,8 +48,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "varasm.h"
 #include "output.h"
 #include "print-tree.h"
-#include "gimple-expr.h"
-#include "gimplify.h"
 #include "debug.h"
 
 #include "d-tree.h"
@@ -843,164 +841,6 @@ d_post_options (const char ** fn)
   return false;
 }
 
-/* Return TRUE if an operand OP of a given TYPE being copied has no data.
-   The middle-end does a similar check with zero sized types.  */
-
-static bool
-empty_modify_p (tree type, tree op)
-{
-  tree_code code = TREE_CODE (op);
-  switch (code)
-    {
-    case COMPOUND_EXPR:
-      return empty_modify_p (type, TREE_OPERAND (op, 1));
-
-    case CONSTRUCTOR:
-      /* Non-empty construcors are valid.  */
-      if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op))
-       return false;
-      break;
-
-    case CALL_EXPR:
-      /* Leave nrvo alone because it isn't a copy.  */
-      if (CALL_EXPR_RETURN_SLOT_OPT (op))
-       return false;
-      break;
-
-    default:
-      /* If the operand doesn't have a simple form.  */
-      if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op))
-       return false;
-      break;
-    }
-
-  return empty_aggregate_p (type);
-}
-
-/* Implements the lang_hooks.gimplify_expr routine for language D.
-   Do gimplification of D specific expression trees in EXPR_P.  */
-
-static int
-d_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
-                gimple_seq *post_p ATTRIBUTE_UNUSED)
-{
-  tree_code code = TREE_CODE (*expr_p);
-  enum gimplify_status ret = GS_UNHANDLED;
-  tree op0, op1;
-  tree type;
-
-  switch (code)
-    {
-    case INIT_EXPR:
-    case MODIFY_EXPR:
-      op0 = TREE_OPERAND (*expr_p, 0);
-      op1 = TREE_OPERAND (*expr_p, 1);
-
-      if (!error_operand_p (op0) && !error_operand_p (op1)
-         && (AGGREGATE_TYPE_P (TREE_TYPE (op0))
-             || AGGREGATE_TYPE_P (TREE_TYPE (op1)))
-         && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
-       {
-         /* If the back end isn't clever enough to know that the lhs and rhs
-            types are the same, add an explicit conversion.  */
-         TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
-                                             TREE_TYPE (op0), op1);
-         ret = GS_OK;
-       }
-      else if (empty_modify_p (TREE_TYPE (op0), op1))
-       {
-         /* Remove any copies of empty aggregates.  */
-         gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
-                        is_gimple_lvalue, fb_lvalue);
-
-         if (TREE_SIDE_EFFECTS (op1))
-           gimplify_and_add (op1, pre_p);
-
-         *expr_p = TREE_OPERAND (*expr_p, 0);
-         ret = GS_OK;
-       }
-      break;
-
-    case ADDR_EXPR:
-      op0 = TREE_OPERAND (*expr_p, 0);
-      /* Constructors are not lvalues, so make them one.  */
-      if (TREE_CODE (op0) == CONSTRUCTOR)
-       {
-         TREE_OPERAND (*expr_p, 0) = force_target_expr (op0);
-         ret = GS_OK;
-       }
-      break;
-
-    case CALL_EXPR:
-      if (CALL_EXPR_ARGS_ORDERED (*expr_p))
-       {
-         /* Strictly evaluate all arguments from left to right.  */
-         int nargs = call_expr_nargs (*expr_p);
-         location_t loc = EXPR_LOC_OR_LOC (*expr_p, input_location);
-
-         /* No need to enforce evaluation order if only one argument.  */
-         if (nargs < 2)
-           break;
-
-         /* Or if all arguments are already free of side-effects.  */
-         bool has_side_effects = false;
-         for (int i = 0; i < nargs; i++)
-           {
-             if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
-               {
-                 has_side_effects = true;
-                 break;
-               }
-           }
-
-         if (!has_side_effects)
-           break;
-
-         /* Leave the last argument for gimplify_call_expr.  */
-         for (int i = 0; i < nargs - 1; i++)
-           {
-             tree new_arg = CALL_EXPR_ARG (*expr_p, i);
-
-             /* If argument has a side-effect, gimplify_arg will handle it.  */
-             if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR)
-               ret = GS_ERROR;
-
-             /* Even if an argument itself doesn't have any side-effects, it
-                might be altered by another argument in the list.  */
-             if (new_arg == CALL_EXPR_ARG (*expr_p, i)
-                 && !really_constant_p (new_arg))
-               new_arg = get_formal_tmp_var (new_arg, pre_p);
-
-             CALL_EXPR_ARG (*expr_p, i) = new_arg;
-           }
-
-         if (ret != GS_ERROR)
-           ret = GS_OK;
-       }
-      break;
-
-    case UNSIGNED_RSHIFT_EXPR:
-      /* Convert op0 to an unsigned type.  */
-      op0 = TREE_OPERAND (*expr_p, 0);
-      op1 = TREE_OPERAND (*expr_p, 1);
-
-      type = d_unsigned_type (TREE_TYPE (op0));
-
-      *expr_p = convert (TREE_TYPE (*expr_p),
-                        build2 (RSHIFT_EXPR, type, convert (type, op0), op1));
-      ret = GS_OK;
-      break;
-
-    case FLOAT_MOD_EXPR:
-      gcc_unreachable ();
-
-    default:
-      break;
-    }
-
-  return ret;
-}
-
 /* Add the module M to the list of modules that may declare GCC builtins.
    These are scanned after first semantic and before codegen passes.
    See d_maybe_set_builtin() for the implementation.  */
index 072de7e65439c20458eccc40071c4528998300a1..b01a133fe62f18b79106ff8e082c078f578ddea2 100644 (file)
@@ -593,6 +593,9 @@ extern tree convert_for_condition (tree, Type *);
 extern tree d_array_convert (Expression *);
 extern tree d_array_convert (Type *, Expression *);
 
+/* In d-gimplify.cc.  */
+extern int d_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
+
 /* In d-incpath.cc.  */
 extern void add_import_paths (const char *, const char *, bool);