]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree-into-ssa.c
Update copyright years.
[thirdparty/gcc.git] / gcc / tree-into-ssa.c
index eebb8047442cc2aea92c83b03ecff484b2ac3abd..ef99060403039082435c0a6fc6d8922e3b375237 100644 (file)
@@ -1,5 +1,5 @@
 /* Rewrite a program in Normal form into SSA.
-   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   Copyright (C) 2001-2021 Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -38,7 +38,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa.h"
 #include "domwalk.h"
 #include "statistics.h"
+#include "stringpool.h"
+#include "attribs.h"
 #include "asan.h"
+#include "attr-fnspec.h"
 
 #define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
 
@@ -321,7 +324,7 @@ get_ssa_name_ann (tree name)
 
   /* Re-allocate the vector at most once per update/into-SSA.  */
   if (ver >= len)
-    info_for_ssa_name.safe_grow_cleared (num_ssa_names);
+    info_for_ssa_name.safe_grow_cleared (num_ssa_names, true);
 
   /* But allocate infos lazily.  */
   info = info_for_ssa_name[ver];
@@ -938,14 +941,18 @@ mark_phi_for_rewrite (basic_block bb, gphi *phi)
   if (!blocks_with_phis_to_rewrite)
     return;
 
-  bitmap_set_bit (blocks_with_phis_to_rewrite, idx);
-
-  n = (unsigned) last_basic_block_for_fn (cfun) + 1;
-  if (phis_to_rewrite.length () < n)
-    phis_to_rewrite.safe_grow_cleared (n);
+  if (bitmap_set_bit (blocks_with_phis_to_rewrite, idx))
+    {
+      n = (unsigned) last_basic_block_for_fn (cfun) + 1;
+      if (phis_to_rewrite.length () < n)
+       phis_to_rewrite.safe_grow_cleared (n, true);
 
-  phis = phis_to_rewrite[idx];
-  phis.reserve (10);
+      phis = phis_to_rewrite[idx];
+      gcc_assert (!phis.exists ());
+      phis.create (10);
+    }
+  else
+    phis = phis_to_rewrite[idx];
 
   phis.safe_push (phi);
   phis_to_rewrite[idx] = phis;
@@ -1224,6 +1231,8 @@ get_reaching_def (tree var)
   if (currdef == NULL_TREE)
     {
       tree sym = DECL_P (var) ? var : SSA_NAME_VAR (var);
+      if (! sym)
+       sym = create_tmp_reg (TREE_TYPE (var));
       currdef = get_or_create_ssa_default_def (cfun, sym);
     }
 
@@ -1403,6 +1412,10 @@ rewrite_stmt (gimple_stmt_iterator *si)
        SET_DEF (def_p, name);
        register_new_def (DEF_FROM_PTR (def_p), var);
 
+       /* Do not insert debug stmts if the stmt ends the BB.  */
+       if (stmt_ends_bb_p (stmt))
+         continue;
+       
        tracked_var = target_for_debug_bind (var);
        if (tracked_var)
          {
@@ -1432,20 +1445,12 @@ rewrite_add_phi_arguments (basic_block bb)
       for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);
           gsi_next (&gsi))
        {
-         tree currdef, res, argvar;
+         tree currdef, res;
          location_t loc;
 
          phi = gsi.phi ();
          res = gimple_phi_result (phi);
-         /* If we have pre-existing PHI (via the GIMPLE FE) its args may
-            be different vars than existing vars and they may be constants
-            as well.  Note the following supports partial SSA for PHI args.  */
-         argvar = gimple_phi_arg_def (phi, e->dest_idx);
-         if (argvar && ! DECL_P (argvar))
-           continue;
-         if (!argvar)
-           argvar = SSA_NAME_VAR (res);
-         currdef = get_reaching_def (argvar);
+         currdef = get_reaching_def (SSA_NAME_VAR (res));
          /* Virtual operand PHI args do not need a location.  */
          if (virtual_operand_p (res))
            loc = UNKNOWN_LOCATION;
@@ -1459,7 +1464,8 @@ rewrite_add_phi_arguments (basic_block bb)
 class rewrite_dom_walker : public dom_walker
 {
 public:
-  rewrite_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+  rewrite_dom_walker (cdi_direction direction)
+    : dom_walker (direction, ALL_BLOCKS, NULL) {}
 
   virtual edge before_dom_children (basic_block);
   virtual void after_dom_children (basic_block);
@@ -1608,10 +1614,10 @@ dump_defs_stack (FILE *file, int n)
        }
 
       fprintf (file, "    Previous CURRDEF (");
-      print_generic_expr (file, var, 0);
+      print_generic_expr (file, var);
       fprintf (file, ") = ");
       if (name)
-       print_generic_expr (file, name, 0);
+       print_generic_expr (file, name);
       else
        fprintf (file, "<NIL>");
       fprintf (file, "\n");
@@ -1647,10 +1653,10 @@ dump_currdefs (FILE *file)
     {
       common_info *info = get_common_info (var);
       fprintf (file, "CURRDEF (");
-      print_generic_expr (file, var, 0);
+      print_generic_expr (file, var);
       fprintf (file, ") = ");
       if (info->current_def)
-       print_generic_expr (file, info->current_def, 0);
+       print_generic_expr (file, info->current_def);
       else
        fprintf (file, "<NIL>");
       fprintf (file, "\n");
@@ -2114,7 +2120,7 @@ rewrite_update_phi_arguments (basic_block bb)
           /* Update the argument if there is a reaching def.  */
          if (reaching_def)
            {
-             source_location locus;
+             location_t locus;
              int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p);
 
              SET_USE (arg_p, reaching_def);
@@ -2149,7 +2155,8 @@ rewrite_update_phi_arguments (basic_block bb)
 class rewrite_update_dom_walker : public dom_walker
 {
 public:
-  rewrite_update_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+  rewrite_update_dom_walker (cdi_direction direction)
+    : dom_walker (direction, ALL_BLOCKS, NULL) {}
 
   virtual edge before_dom_children (basic_block);
   virtual void after_dom_children (basic_block);
@@ -2318,7 +2325,7 @@ private:
 };
 
 mark_def_dom_walker::mark_def_dom_walker (cdi_direction direction)
-  : dom_walker (direction), m_kills (BITMAP_ALLOC (NULL))
+  : dom_walker (direction, ALL_BLOCKS, NULL), m_kills (BITMAP_ALLOC (NULL))
 {
 }
 
@@ -2427,6 +2434,11 @@ pass_build_ssa::execute (function *fun)
   bitmap_head *dfs;
   basic_block bb;
 
+  /* Increase the set of variables we can rewrite into SSA form
+     by clearing TREE_ADDRESSABLE and transform the IL to support this.  */
+  if (optimize)
+    execute_update_addresses_taken ();
+
   /* Initialize operand data structures.  */
   init_ssa_operands (fun);
 
@@ -2484,6 +2496,28 @@ pass_build_ssa::execute (function *fun)
        SET_SSA_NAME_VAR_OR_IDENTIFIER (name, DECL_NAME (decl));
     }
 
+  /* Initialize SSA_NAME_POINTS_TO_READONLY_MEMORY.  */
+  tree fnspec_tree
+        = lookup_attribute ("fn spec",
+                            TYPE_ATTRIBUTES (TREE_TYPE (fun->decl)));
+  if (fnspec_tree)
+    {
+      attr_fnspec fnspec (TREE_VALUE (TREE_VALUE (fnspec_tree)));
+      unsigned i = 0;
+      for (tree arg = DECL_ARGUMENTS (cfun->decl);
+          arg; arg = DECL_CHAIN (arg), ++i)
+       {
+         if (!fnspec.arg_specified_p (i))
+          break;
+         if (fnspec.arg_readonly_p (i))
+           {
+             tree name = ssa_default_def (fun, arg);
+             if (name)
+               SSA_NAME_POINTS_TO_READONLY_MEMORY (name) = 1;
+           }
+       }
+    }
+
   return 0;
 }
 
@@ -2563,11 +2597,9 @@ mark_use_interesting (tree var, gimple *stmt, basic_block bb,
     }
 }
 
-
-/* Do a dominator walk starting at BB processing statements that
-   reference symbols in SSA operands.  This is very similar to
-   mark_def_sites, but the scan handles statements whose operands may
-   already be SSA names.
+/* Processing statements in BB that reference symbols in SSA operands.
+   This is very similar to mark_def_sites, but the scan handles
+   statements whose operands may already be SSA names.
 
    If INSERT_PHI_P is true, mark those uses as live in the
    corresponding block.  This is later used by the PHI placement
@@ -2580,9 +2612,8 @@ mark_use_interesting (tree var, gimple *stmt, basic_block bb,
           that.  */
 
 static void
-prepare_block_for_update (basic_block bb, bool insert_phi_p)
+prepare_block_for_update_1 (basic_block bb, bool insert_phi_p)
 {
-  basic_block son;
   edge e;
   edge_iterator ei;
 
@@ -2664,13 +2695,51 @@ prepare_block_for_update (basic_block bb, bool insert_phi_p)
        }
     }
 
-  /* Now visit all the blocks dominated by BB.  */
-  for (son = first_dom_son (CDI_DOMINATORS, bb);
-       son;
-       son = next_dom_son (CDI_DOMINATORS, son))
-    prepare_block_for_update (son, insert_phi_p);
 }
 
+/* Do a dominator walk starting at BB processing statements that
+   reference symbols in SSA operands.  This is very similar to
+   mark_def_sites, but the scan handles statements whose operands may
+   already be SSA names.
+
+   If INSERT_PHI_P is true, mark those uses as live in the
+   corresponding block.  This is later used by the PHI placement
+   algorithm to make PHI pruning decisions.
+
+   FIXME.  Most of this would be unnecessary if we could associate a
+          symbol to all the SSA names that reference it.  But that
+          sounds like it would be expensive to maintain.  Still, it
+          would be interesting to see if it makes better sense to do
+          that.  */
+static void
+prepare_block_for_update (basic_block bb, bool insert_phi_p)
+{
+  size_t sp = 0;
+  basic_block *worklist;
+
+  /* Allocate the worklist.  */
+  worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
+  /* Add the BB to the worklist.  */
+  worklist[sp++] = bb;
+
+  while (sp)
+    {
+      basic_block bb;
+      basic_block son;
+
+      /* Pick a block from the worklist.  */
+      bb = worklist[--sp];
+
+      prepare_block_for_update_1 (bb, insert_phi_p);
+
+      /* Now add all the blocks dominated by BB to the worklist.  */
+      for (son = first_dom_son (CDI_DOMINATORS, bb);
+          son;
+          son = next_dom_son (CDI_DOMINATORS, son))
+       worklist[sp++] = son;
+    }
+  free (worklist);
+}
 
 /* Helper for prepare_names_to_update.  Mark all the use sites for
    NAME as interesting.  BLOCKS and INSERT_PHI_P are as in
@@ -2784,13 +2853,13 @@ dump_names_replaced_by (FILE *file, tree name)
   bitmap old_set;
   bitmap_iterator bi;
 
-  print_generic_expr (file, name, 0);
+  print_generic_expr (file, name);
   fprintf (file, " -> { ");
 
   old_set = names_replaced_by (name);
   EXECUTE_IF_SET_IN_BITMAP (old_set, 0, i, bi)
     {
-      print_generic_expr (file, ssa_name (i), 0);
+      print_generic_expr (file, ssa_name (i));
       fprintf (file, " ");
     }
 
@@ -2842,7 +2911,7 @@ dump_update_ssa (FILE *file)
       fprintf (file, "\nSSA names to release after updating the SSA web\n\n");
       EXECUTE_IF_SET_IN_BITMAP (names_to_release, 0, i, bi)
        {
-         print_generic_expr (file, ssa_name (i), 0);
+         print_generic_expr (file, ssa_name (i));
          fprintf (file, " ");
        }
       fprintf (file, "\n");
@@ -2911,11 +2980,7 @@ delete_update_ssa (void)
 
   if (blocks_with_phis_to_rewrite)
     EXECUTE_IF_SET_IN_BITMAP (blocks_with_phis_to_rewrite, 0, i, bi)
-      {
-       vec<gphi *> phis = phis_to_rewrite[i];
-       phis.release ();
-       phis_to_rewrite[i].create (0);
-      }
+      phis_to_rewrite[i].release ();
 
   BITMAP_FREE (blocks_with_phis_to_rewrite);
   BITMAP_FREE (blocks_to_update);
@@ -3284,10 +3349,10 @@ update_ssa (unsigned update_flags)
 
                  if (SSA_NAME_IN_FREE_LIST (use))
                    {
-                     error ("statement uses released SSA name:");
+                     error ("statement uses released SSA name");
                      debug_gimple_stmt (stmt);
                      fprintf (stderr, "The use of ");
-                     print_generic_expr (stderr, use, 0);
+                     print_generic_expr (stderr, use);
                      fprintf (stderr," should have been replaced\n");
                      err = true;
                    }