]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree-object-size.c
Merge from trunk.
[thirdparty/gcc.git] / gcc / tree-object-size.c
index 98d44bda3f5835647561997ddf965558f9efa4d2..ced1f60f1e4f9fe4a5bf975340aff13ad7f6a44d 100644 (file)
@@ -23,15 +23,19 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "tree-object-size.h"
 #include "diagnostic-core.h"
 #include "gimple-pretty-print.h"
 #include "bitmap.h"
 #include "gimple.h"
 #include "gimple-iterator.h"
 #include "gimple-ssa.h"
+#include "stringpool.h"
 #include "tree-ssanames.h"
 #include "tree-pass.h"
 #include "tree-ssa-propagate.h"
+#include "tree-phinodes.h"
+#include "ssa-iterators.h"
 
 struct object_size_info
 {
@@ -82,7 +86,7 @@ static void
 init_offset_limit (void)
 {
   if (tree_fits_uhwi_p (TYPE_MAX_VALUE (sizetype)))
-    offset_limit = tree_low_cst (TYPE_MAX_VALUE (sizetype), 1);
+    offset_limit = tree_to_uhwi (TYPE_MAX_VALUE (sizetype));
   else
     offset_limit = -1;
   offset_limit /= 2;
@@ -110,7 +114,7 @@ compute_object_offset (const_tree expr, const_tree var)
 
       t = TREE_OPERAND (expr, 1);
       off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
-                       size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t), 1)
+                       size_int (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (t))
                                  / BITS_PER_UNIT));
       break;
 
@@ -145,7 +149,7 @@ compute_object_offset (const_tree expr, const_tree var)
 
     case MEM_REF:
       gcc_assert (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR);
-      return double_int_to_tree (sizetype, mem_ref_offset (expr));
+      return wide_int_to_tree (sizetype, mem_ref_offset (expr));
 
     default:
       return error_mark_node;
@@ -195,10 +199,10 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
        }
       if (sz != unknown[object_size_type])
        {
-         double_int dsz = double_int::from_uhwi (sz) - mem_ref_offset (pt_var);
-         if (dsz.is_negative ())
+         offset_int dsz = wi::sub (sz, mem_ref_offset (pt_var));
+         if (wi::neg_p (dsz))
            sz = 0;
-         else if (dsz.fits_uhwi ())
+         else if (wi::fits_uhwi_p (dsz))
            sz = dsz.to_uhwi ();
          else
            sz = unknown[object_size_type];
@@ -210,15 +214,13 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
   else if (pt_var
           && DECL_P (pt_var)
           && tree_fits_uhwi_p (DECL_SIZE_UNIT (pt_var))
-          && (unsigned HOST_WIDE_INT)
-               tree_low_cst (DECL_SIZE_UNIT (pt_var), 1) < offset_limit)
+          && tree_to_uhwi (DECL_SIZE_UNIT (pt_var)) < offset_limit)
     pt_var_size = DECL_SIZE_UNIT (pt_var);
   else if (pt_var
           && TREE_CODE (pt_var) == STRING_CST
           && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
           && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)))
-          && (unsigned HOST_WIDE_INT)
-             tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
+          && tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)))
              < offset_limit)
     pt_var_size = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
   else
@@ -372,7 +374,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
     bytes = pt_var_size;
 
   if (tree_fits_uhwi_p (bytes))
-    return tree_low_cst (bytes, 1);
+    return tree_to_uhwi (bytes);
 
   return unknown[object_size_type];
 }
@@ -436,7 +438,7 @@ alloc_object_size (const_gimple call, int object_size_type)
     bytes = fold_convert (sizetype, gimple_call_arg (call, arg1));
 
   if (bytes && tree_fits_uhwi_p (bytes))
-    return tree_low_cst (bytes, 1);
+    return tree_to_uhwi (bytes);
 
   return unknown[object_size_type];
 }
@@ -799,10 +801,10 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
       if (! tree_fits_uhwi_p (op1))
        bytes = unknown[object_size_type];
       else if (TREE_CODE (op0) == SSA_NAME)
-       return merge_object_sizes (osi, var, op0, tree_low_cst (op1, 1));
+       return merge_object_sizes (osi, var, op0, tree_to_uhwi (op1));
       else
        {
-         unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
+         unsigned HOST_WIDE_INT off = tree_to_uhwi (op1);
 
           /* op0 will be ADDR_EXPR here.  */
          bytes = addr_object_size (osi, op0, object_size_type);
@@ -1207,16 +1209,9 @@ compute_object_sizes (void)
       gimple_stmt_iterator i;
       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
        {
-         tree callee, result;
+         tree result;
          gimple call = gsi_stmt (i);
-
-          if (gimple_code (call) != GIMPLE_CALL)
-           continue;
-
-         callee = gimple_call_fndecl (call);
-         if (!callee
-             || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
-             || DECL_FUNCTION_CODE (callee) != BUILT_IN_OBJECT_SIZE)
+         if (!gimple_call_builtin_p (call, BUILT_IN_OBJECT_SIZE))
            continue;
 
          init_object_sizes ();
@@ -1231,7 +1226,7 @@ compute_object_sizes (void)
                  if (tree_fits_uhwi_p (ost))
                    {
                      unsigned HOST_WIDE_INT object_size_type
-                       = tree_low_cst (ost, 1);
+                       = tree_to_uhwi (ost);
 
                      if (object_size_type < 2)
                        result = fold_convert (size_type_node,
@@ -1245,20 +1240,32 @@ compute_object_sizes (void)
                continue;
            }
 
+         gcc_assert (TREE_CODE (result) == INTEGER_CST);
+
          if (dump_file && (dump_flags & TDF_DETAILS))
            {
              fprintf (dump_file, "Simplified\n  ");
              print_gimple_stmt (dump_file, call, 0, dump_flags);
+             fprintf (dump_file, " to ");
+             print_generic_expr (dump_file, result, 0);
+             fprintf (dump_file, "\n");
            }
 
-         if (!update_call_from_tree (&i, result))
-           gcc_unreachable ();
+         tree lhs = gimple_call_lhs (call);
+         if (!lhs)
+           continue;
 
-         if (dump_file && (dump_flags & TDF_DETAILS))
+         /* Propagate into all uses and fold those stmts.  */
+         gimple use_stmt;
+         imm_use_iterator iter;
+         FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
            {
-             fprintf (dump_file, "to\n  ");
-             print_gimple_stmt (dump_file, gsi_stmt (i), 0, dump_flags);
-             fprintf (dump_file, "\n");
+             use_operand_p use_p;
+             FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+               SET_USE (use_p, result);
+             gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
+             fold_stmt (&gsi);
+             update_stmt (gsi_stmt (gsi));
            }
        }
     }