]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/gimple-expr.c
Update copyright years.
[thirdparty/gcc.git] / gcc / gimple-expr.c
index ed012ccfdc66cb89145ce3458b00a19fe9cc846d..8116993b8709acbb5b1a27810d3624a3cd581231 100644 (file)
@@ -1,6 +1,6 @@
 /* Gimple decl, type, and expression support functions.
 
-   Copyright (C) 2007-2016 Free Software Foundation, Inc.
+   Copyright (C) 2007-2020 Free Software Foundation, Inc.
    Contributed by Aldy Hernandez <aldyh@redhat.com>
 
 This file is part of GCC.
@@ -34,6 +34,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "demangle.h"
 #include "hash-set.h"
 #include "rtl.h"
+#include "tree-pass.h"
+#include "stringpool.h"
+#include "attribs.h"
 
 /* ----- Type related -----  */
 
@@ -123,7 +126,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
   /* Fixed point types with the same mode are compatible.  */
   else if (FIXED_POINT_TYPE_P (inner_type)
           && FIXED_POINT_TYPE_P (outer_type))
-    return true;
+    return TYPE_SATURATING (inner_type) == TYPE_SATURATING (outer_type);
 
   /* We need to take special care recursing to pointed-to types.  */
   else if (POINTER_TYPE_P (inner_type)
@@ -323,7 +326,7 @@ bool
 gimple_has_body_p (tree fndecl)
 {
   struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
-  return (gimple_body (fndecl) || (fn && fn->cfg));
+  return (gimple_body (fndecl) || (fn && fn->cfg && !(fn->curr_properties & PROP_rtl)));
 }
 
 /* Return a printable name for symbol DECL.  */
@@ -334,9 +337,8 @@ gimple_decl_printable_name (tree decl, int verbosity)
   if (!DECL_NAME (decl))
     return NULL;
 
-  if (DECL_ASSEMBLER_NAME_SET_P (decl))
+  if (HAS_DECL_ASSEMBLER_NAME_P (decl) && DECL_ASSEMBLER_NAME_SET_P (decl))
     {
-      const char *str, *mangled_str;
       int dmgl_opts = DMGL_NO_OPTS;
 
       if (verbosity >= 2)
@@ -349,9 +351,10 @@ gimple_decl_printable_name (tree decl, int verbosity)
            dmgl_opts |= DMGL_PARAMS;
        }
 
-      mangled_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-      str = cplus_demangle_v3 (mangled_str, dmgl_opts);
-      return (str) ? str : mangled_str;
+      const char *mangled_str
+       = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
+      const char *str = cplus_demangle_v3 (mangled_str, dmgl_opts);
+      return str ? str : mangled_str;
     }
 
   return IDENTIFIER_POINTER (DECL_NAME (decl));
@@ -387,14 +390,14 @@ copy_var_decl (tree var, tree name, tree type)
 /* Strip off a legitimate source ending from the input string NAME of
    length LEN.  Rather than having to know the names used by all of
    our front ends, we strip off an ending of a period followed by
-   up to five characters.  (Java uses ".class".)  */
+   up to four characters.  (like ".cpp".)  */
 
 static inline void
 remove_suffix (char *name, int len)
 {
   int i;
 
-  for (i = 2;  i < 8 && len > i;  i++)
+  for (i = 2;  i < 7 && len > i;  i++)
     {
       if (name[len - i] == '.')
        {
@@ -443,6 +446,9 @@ create_tmp_var_raw (tree type, const char *prefix)
   DECL_ARTIFICIAL (tmp_var) = 1;
   /* And we don't want debug info for it.  */
   DECL_IGNORED_P (tmp_var) = 1;
+  /* And we don't want even the fancy names of those printed in
+     -fdump-final-insns= dumps.  */
+  DECL_NAMELESS (tmp_var) = 1;
 
   /* Make the variable writable.  */
   TREE_READONLY (tmp_var) = 0;
@@ -522,37 +528,40 @@ void
 extract_ops_from_tree (tree expr, enum tree_code *subcode_p, tree *op1_p,
                       tree *op2_p, tree *op3_p)
 {
-  enum gimple_rhs_class grhs_class;
-
   *subcode_p = TREE_CODE (expr);
-  grhs_class = get_gimple_rhs_class (*subcode_p);
-
-  if (grhs_class == GIMPLE_TERNARY_RHS)
+  switch (get_gimple_rhs_class (*subcode_p))
     {
-      *op1_p = TREE_OPERAND (expr, 0);
-      *op2_p = TREE_OPERAND (expr, 1);
-      *op3_p = TREE_OPERAND (expr, 2);
-    }
-  else if (grhs_class == GIMPLE_BINARY_RHS)
-    {
-      *op1_p = TREE_OPERAND (expr, 0);
-      *op2_p = TREE_OPERAND (expr, 1);
-      *op3_p = NULL_TREE;
-    }
-  else if (grhs_class == GIMPLE_UNARY_RHS)
-    {
-      *op1_p = TREE_OPERAND (expr, 0);
-      *op2_p = NULL_TREE;
-      *op3_p = NULL_TREE;
-    }
-  else if (grhs_class == GIMPLE_SINGLE_RHS)
-    {
-      *op1_p = expr;
-      *op2_p = NULL_TREE;
-      *op3_p = NULL_TREE;
+    case GIMPLE_TERNARY_RHS:
+      {
+       *op1_p = TREE_OPERAND (expr, 0);
+       *op2_p = TREE_OPERAND (expr, 1);
+       *op3_p = TREE_OPERAND (expr, 2);
+       break;
+      }
+    case GIMPLE_BINARY_RHS:
+      {
+       *op1_p = TREE_OPERAND (expr, 0);
+       *op2_p = TREE_OPERAND (expr, 1);
+       *op3_p = NULL_TREE;
+       break;
+      }
+    case GIMPLE_UNARY_RHS:
+      {
+       *op1_p = TREE_OPERAND (expr, 0);
+       *op2_p = NULL_TREE;
+       *op3_p = NULL_TREE;
+       break;
+      }
+    case GIMPLE_SINGLE_RHS:
+      {
+       *op1_p = expr;
+       *op2_p = NULL_TREE;
+       *op3_p = NULL_TREE;
+       break;
+      }
+    default:
+      gcc_unreachable ();
     }
-  else
-    gcc_unreachable ();
 }
 
 /* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND.  */
@@ -565,6 +574,7 @@ gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p,
              || TREE_CODE (cond) == TRUTH_NOT_EXPR
              || is_gimple_min_invariant (cond)
              || SSA_VAR_P (cond));
+  gcc_checking_assert (!tree_could_throw_p (cond));
 
   extract_ops_from_tree (cond, code_p, lhs_p, rhs_p);
 
@@ -596,17 +606,33 @@ is_gimple_lvalue (tree t)
          || TREE_CODE (t) == BIT_FIELD_REF);
 }
 
-/*  Return true if T is a GIMPLE condition.  */
+/* Helper for is_gimple_condexpr and is_gimple_condexpr_for_cond.  */
 
-bool
-is_gimple_condexpr (tree t)
+static bool
+is_gimple_condexpr_1 (tree t, bool allow_traps)
 {
   return (is_gimple_val (t) || (COMPARISON_CLASS_P (t)
-                               && !tree_could_throw_p (t)
+                               && (allow_traps || !tree_could_throw_p (t))
                                && is_gimple_val (TREE_OPERAND (t, 0))
                                && is_gimple_val (TREE_OPERAND (t, 1))));
 }
 
+/* Return true if T is a GIMPLE condition.  */
+
+bool
+is_gimple_condexpr (tree t)
+{
+  return is_gimple_condexpr_1 (t, true);
+}
+
+/* Like is_gimple_condexpr, but does not allow T to trap.  */
+
+bool
+is_gimple_condexpr_for_cond (tree t)
+{
+  return is_gimple_condexpr_1 (t, false);
+}
+
 /* Return true if T is a gimple address.  */
 
 bool
@@ -628,7 +654,9 @@ is_gimple_address (const_tree t)
       op = TREE_OPERAND (op, 0);
     }
 
-  if (CONSTANT_CLASS_P (op) || TREE_CODE (op) == MEM_REF)
+  if (CONSTANT_CLASS_P (op)
+      || TREE_CODE (op) == TARGET_MEM_REF
+      || TREE_CODE (op) == MEM_REF)
     return true;
 
   switch (TREE_CODE (op))
@@ -888,7 +916,7 @@ mark_addressable (tree x)
   if (TREE_CODE (x) == MEM_REF
       && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
     x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
-  if (TREE_CODE (x) != VAR_DECL
+  if (!VAR_P (x)
       && TREE_CODE (x) != PARM_DECL
       && TREE_CODE (x) != RESULT_DECL)
     return;