Add -march=interaptiv.
[platform/upstream/gcc.git] / gcc / tree-ssa-live.c
index eb36a90..5b00f58 100644 (file)
@@ -1,5 +1,5 @@
 /* Liveness for SSA trees.
-   Copyright (C) 2003-2013 Free Software Foundation, Inc.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
    Contributed by Andrew MacLeod <amacleod@redhat.com>
 
 This file is part of GCC.
@@ -21,19 +21,35 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "hash-table.h"
-#include "tm.h"
+#include "backend.h"
 #include "tree.h"
+#include "gimple.h"
+#include "rtl.h"
+#include "ssa.h"
+#include "alias.h"
+#include "fold-const.h"
 #include "gimple-pretty-print.h"
-#include "bitmap.h"
-#include "tree-ssa.h"
+#include "internal-fn.h"
+#include "gimple-iterator.h"
+#include "flags.h"
+#include "insn-config.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "varasm.h"
+#include "stmt.h"
+#include "expr.h"
+#include "tree-dfa.h"
 #include "timevar.h"
 #include "dumpfile.h"
 #include "tree-ssa-live.h"
 #include "diagnostic-core.h"
 #include "debug.h"
-#include "flags.h"
-#include "gimple.h"
+#include "tree-ssa.h"
+#include "cgraph.h"
+#include "ipa-utils.h"
 
 #ifdef ENABLE_CHECKING
 static void  verify_live_on_entry (tree_live_info_p);
@@ -56,22 +72,20 @@ static void  verify_live_on_entry (tree_live_info_p);
 
 /* Hashtable helpers.  */
 
-struct tree_int_map_hasher : typed_noop_remove <tree_int_map>
+struct tree_int_map_hasher : nofree_ptr_hash <tree_int_map>
 {
-  typedef tree_int_map value_type;
-  typedef tree_int_map compare_type;
-  static inline hashval_t hash (const value_type *);
-  static inline bool equal (const value_type *, const compare_type *);
+  static inline hashval_t hash (const tree_int_map *);
+  static inline bool equal (const tree_int_map *, const tree_int_map *);
 };
 
 inline hashval_t
-tree_int_map_hasher::hash (const value_type *v)
+tree_int_map_hasher::hash (const tree_int_map *v)
 {
   return tree_map_base_hash (v);
 }
 
 inline bool
-tree_int_map_hasher::equal (const value_type *v, const compare_type *c)
+tree_int_map_hasher::equal (const tree_int_map *v, const tree_int_map *c)
 {
   return tree_int_map_eq (v, c);
 }
@@ -84,11 +98,10 @@ var_map_base_init (var_map map)
 {
   int x, num_part;
   tree var;
-  hash_table <tree_int_map_hasher> tree_to_index;
   struct tree_int_map *m, *mapstorage;
 
   num_part = num_var_partitions (map);
-  tree_to_index.create (num_part);
+  hash_table<tree_int_map_hasher> tree_to_index (num_part);
   /* We can have at most num_part entries in the hash tables, so it's
      enough to allocate so many map elements once, saving some malloc
      calls.  */
@@ -136,7 +149,6 @@ var_map_base_init (var_map map)
   map->num_basevars = m - mapstorage;
 
   free (mapstorage);
-  tree_to_index. dispose ();
 }
 
 
@@ -422,7 +434,8 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
     {
       /* When a global var becomes used for the first time also walk its
          initializer (non global ones don't have any).  */
-      if (set_is_used (t) && is_global_var (t))
+      if (set_is_used (t) && is_global_var (t)
+         && DECL_CONTEXT (t) == current_function_decl)
        mark_all_vars_used (&DECL_INITIAL (t));
     }
   /* remove_unused_scope_block_p requires information about labels
@@ -468,12 +481,29 @@ mark_scope_block_unused (tree scope)
    done by the inliner.  */
 
 static bool
-remove_unused_scope_block_p (tree scope)
+remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block)
 {
   tree *t, *next;
   bool unused = !TREE_USED (scope);
   int nsubblocks = 0;
 
+  /* For ipa-polymorphic-call.c purposes, preserve blocks:
+     1) with BLOCK_ABSTRACT_ORIGIN of a ctor/dtor or their clones  */
+  if (inlined_polymorphic_ctor_dtor_block_p (scope, true))
+    {
+      in_ctor_dtor_block = true;
+      unused = false;
+    }
+  /* 2) inside such blocks, the outermost block with BLOCK_ABSTRACT_ORIGIN
+     being a FUNCTION_DECL.  */
+  else if (in_ctor_dtor_block
+          && BLOCK_ABSTRACT_ORIGIN (scope)
+          && TREE_CODE (BLOCK_ABSTRACT_ORIGIN (scope)) == FUNCTION_DECL)
+    {
+      in_ctor_dtor_block = false;
+      unused = false;
+    }
+
   for (t = &BLOCK_VARS (scope); *t; t = next)
     {
       next = &DECL_CHAIN (*t);
@@ -553,7 +583,7 @@ remove_unused_scope_block_p (tree scope)
     }
 
   for (t = &BLOCK_SUBBLOCKS (scope); *t ;)
-    if (remove_unused_scope_block_p (*t))
+    if (remove_unused_scope_block_p (*t, in_ctor_dtor_block))
       {
        if (BLOCK_SUBBLOCKS (*t))
          {
@@ -591,11 +621,11 @@ remove_unused_scope_block_p (tree scope)
       eliminated.  */
    else if (!nsubblocks)
      ;
-   /* For terse debug info we can eliminate info on unused variables.  */
-   else if (debug_info_level == DINFO_LEVEL_NONE
-           || debug_info_level == DINFO_LEVEL_TERSE)
+   /* When not generating debug info we can eliminate info on unused
+      variables.  */
+   else if (!flag_auto_profile && debug_info_level == DINFO_LEVEL_NONE)
      {
-       /* Even for -g0/-g1 don't prune outer scopes from artificial
+       /* Even for -g0 don't prune outer scopes from artificial
          functions, otherwise diagnostics using tree_nonartificial_location
          will not be emitted properly.  */
        if (inlined_function_outer_scope_p (scope))
@@ -660,7 +690,7 @@ clear_unused_block_pointer (void)
   basic_block bb;
   gimple_stmt_iterator gsi;
 
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
       {
        unsigned i;
@@ -778,7 +808,7 @@ remove_unused_locals (void)
   usedvars = BITMAP_ALLOC (NULL);
 
   /* Walk the CFG marking all referenced symbols.  */
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     {
       gimple_stmt_iterator gsi;
       size_t i;
@@ -807,12 +837,14 @@ remove_unused_locals (void)
            mark_all_vars_used (gimple_op_ptr (gsi_stmt (gsi), i));
        }
 
-      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gphi_iterator gpi = gsi_start_phis (bb);
+          !gsi_end_p (gpi);
+          gsi_next (&gpi))
         {
           use_operand_p arg_p;
           ssa_op_iter i;
          tree def;
-         gimple phi = gsi_stmt (gsi);
+         gphi *phi = gpi.phi ();
 
          if (virtual_operand_p (gimple_phi_result (phi)))
            continue;
@@ -843,7 +875,7 @@ remove_unused_locals (void)
      ignores them, and the second pass (if there were any) tries to remove
      them.  */
   if (have_local_clobbers)
-    FOR_EACH_BB (bb)
+    FOR_EACH_BB_FN (bb, cfun)
       {
        gimple_stmt_iterator gsi;
 
@@ -916,7 +948,7 @@ remove_unused_locals (void)
       cfun->local_decls->truncate (dstidx);
     }
 
-  remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
+  remove_unused_scope_block_p (DECL_INITIAL (current_function_decl), false);
   clear_unused_block_pointer ();
 
   BITMAP_FREE (usedvars);
@@ -930,13 +962,6 @@ remove_unused_locals (void)
   timevar_pop (TV_REMOVE_UNUSED);
 }
 
-/* Obstack for globale liveness info bitmaps.  We don't want to put these
-   on the default obstack because these bitmaps can grow quite large and
-   we'll hold on to all that memory until the end of the compiler run.
-   As a bonus, delete_tree_live_info can destroy all the bitmaps by just
-   releasing the whole obstack.  */
-static bitmap_obstack liveness_bitmap_obstack;
-
 /* Allocate and return a new live range information object base on MAP.  */
 
 static tree_live_info_p
@@ -947,20 +972,22 @@ new_tree_live_info (var_map map)
 
   live = XNEW (struct tree_live_info_d);
   live->map = map;
-  live->num_blocks = last_basic_block;
+  live->num_blocks = last_basic_block_for_fn (cfun);
 
-  live->livein = XNEWVEC (bitmap_head, last_basic_block);
-  FOR_EACH_BB (bb)
-    bitmap_initialize (&live->livein[bb->index], &liveness_bitmap_obstack);
+  bitmap_obstack_initialize (&live->livein_obstack);
+  bitmap_obstack_initialize (&live->liveout_obstack);
+  live->livein = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
+  FOR_EACH_BB_FN (bb, cfun)
+    bitmap_initialize (&live->livein[bb->index], &live->livein_obstack);
 
-  live->liveout = XNEWVEC (bitmap_head, last_basic_block);
-  FOR_EACH_BB (bb)
-    bitmap_initialize (&live->liveout[bb->index], &liveness_bitmap_obstack);
+  live->liveout = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
+  FOR_EACH_BB_FN (bb, cfun)
+    bitmap_initialize (&live->liveout[bb->index], &live->liveout_obstack);
 
-  live->work_stack = XNEWVEC (int, last_basic_block);
+  live->work_stack = XNEWVEC (int, last_basic_block_for_fn (cfun));
   live->stack_top = live->work_stack;
 
-  live->global = BITMAP_ALLOC (&liveness_bitmap_obstack);
+  live->global = BITMAP_ALLOC (NULL);
   return live;
 }
 
@@ -970,10 +997,18 @@ new_tree_live_info (var_map map)
 void
 delete_tree_live_info (tree_live_info_p live)
 {
-  bitmap_obstack_release (&liveness_bitmap_obstack);
+  if (live->livein)
+    {
+      bitmap_obstack_release (&live->livein_obstack);
+      free (live->livein);
+    }
+  if (live->liveout)
+    {
+      bitmap_obstack_release (&live->liveout_obstack);
+      free (live->liveout);
+    }
+  BITMAP_FREE (live->global);
   free (live->work_stack);
-  free (live->liveout);
-  free (live->livein);
   free (live);
 }
 
@@ -984,8 +1019,7 @@ delete_tree_live_info (tree_live_info_p live)
    it each time.  */
 
 static void
-loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited,
-                bitmap tmp)
+loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited)
 {
   edge e;
   bool change;
@@ -1001,19 +1035,19 @@ loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited,
   FOR_EACH_EDGE (e, ei, bb->preds)
     {
       pred_bb = e->src;
-      if (pred_bb == ENTRY_BLOCK_PTR)
+      if (pred_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
        continue;
-      /* TMP is variables live-on-entry from BB that aren't defined in the
+      /* Variables live-on-entry from BB that aren't defined in the
         predecessor block.  This should be the live on entry vars to pred.
         Note that liveout is the DEFs in a block while live on entry is
-        being calculated.  */
-      bitmap_and_compl (tmp, loe, &live->liveout[pred_bb->index]);
-
-      /* Add these bits to live-on-entry for the pred. if there are any
+        being calculated.
+        Add these bits to live-on-entry for the pred. if there are any
         changes, and pred_bb has been visited already, add it to the
         revisit stack.  */
-      change = bitmap_ior_into (live_on_entry (live, pred_bb), tmp);
-      if (bitmap_bit_p (visited, pred_bb->index) && change)
+      change = bitmap_ior_and_compl_into (live_on_entry (live, pred_bb),
+                                         loe, &live->liveout[pred_bb->index]);
+      if (change
+         && bitmap_bit_p (visited, pred_bb->index))
        {
          bitmap_clear_bit (visited, pred_bb->index);
          *(live->stack_top)++ = pred_bb->index;
@@ -1030,24 +1064,22 @@ live_worklist (tree_live_info_p live)
 {
   unsigned b;
   basic_block bb;
-  sbitmap visited = sbitmap_alloc (last_basic_block + 1);
-  bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack);
+  sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun) + 1);
 
   bitmap_clear (visited);
 
   /* Visit all the blocks in reverse order and propagate live on entry values
      into the predecessors blocks.  */
-  FOR_EACH_BB_REVERSE (bb)
-    loe_visit_block (live, bb, visited, tmp);
+  FOR_EACH_BB_REVERSE_FN (bb, cfun)
+    loe_visit_block (live, bb, visited);
 
   /* Process any blocks which require further iteration.  */
   while (live->stack_top != live->work_stack)
     {
       b = *--(live->stack_top);
-      loe_visit_block (live, BASIC_BLOCK (b), visited, tmp);
+      loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited);
     }
 
-  BITMAP_FREE (tmp);
   sbitmap_free (visited);
 }
 
@@ -1079,7 +1111,11 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
        bitmap_set_bit (&live->liveout[def_bb->index], p);
     }
   else
-    def_bb = ENTRY_BLOCK_PTR;
+    def_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
+
+  /* An undefined local variable does not need to be very alive.  */
+  if (ssa_undefined_value_p (ssa_name, false))
+    return;
 
   /* Visit each use of SSA_NAME and if it isn't in the same block as the def,
      add it to the list of live on entry blocks.  */
@@ -1094,8 +1130,8 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
             as this is where a copy would be inserted.  Check to see if it is
             defined in that block, or whether its live on entry.  */
          int index = PHI_ARG_INDEX_FROM_USE (use);
-         edge e = gimple_phi_arg_edge (use_stmt, index);
-         if (e->src != ENTRY_BLOCK_PTR)
+         edge e = gimple_phi_arg_edge (as_a <gphi *> (use_stmt), index);
+         if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
            {
              if (e->src != def_bb)
                add_block = e->src;
@@ -1128,7 +1164,7 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
 
 /* Calculate the live on exit vectors based on the entry info in LIVEINFO.  */
 
-void
+static void
 calculate_live_on_exit (tree_live_info_p liveinfo)
 {
   basic_block bb;
@@ -1136,19 +1172,19 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
   edge_iterator ei;
 
   /* live on entry calculations used liveout vectors for defs, clear them.  */
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     bitmap_clear (&liveinfo->liveout[bb->index]);
 
   /* Set all the live-on-exit bits for uses in PHIs.  */
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     {
-      gimple_stmt_iterator gsi;
+      gphi_iterator gsi;
       size_t i;
 
       /* Mark the PHI arguments which are live on exit to the pred block.  */
       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         gimple phi = gsi_stmt (gsi);
+         gphi *phi = gsi.phi ();
          for (i = 0; i < gimple_phi_num_args (phi); i++)
            {
              tree t = PHI_ARG_DEF (phi, i);
@@ -1161,14 +1197,14 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
              if (p == NO_PARTITION)
                continue;
              e = gimple_phi_arg_edge (phi, i);
-             if (e->src != ENTRY_BLOCK_PTR)
+             if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
                bitmap_set_bit (&liveinfo->liveout[e->src->index], p);
            }
        }
 
       /* Add each successors live on entry to this bock live on exit.  */
       FOR_EACH_EDGE (e, ei, bb->succs)
-        if (e->dest != EXIT_BLOCK_PTR)
+       if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
          bitmap_ior_into (&liveinfo->liveout[bb->index],
                           live_on_entry (liveinfo, e->dest));
     }
@@ -1179,13 +1215,12 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
    each partition.  Return a new live info object.  */
 
 tree_live_info_p
-calculate_live_ranges (var_map map)
+calculate_live_ranges (var_map map, bool want_livein)
 {
   tree var;
   unsigned i;
   tree_live_info_p live;
 
-  bitmap_obstack_initialize (&liveness_bitmap_obstack);
   live = new_tree_live_info (map);
   for (i = 0; i < num_var_partitions (map); i++)
     {
@@ -1201,6 +1236,14 @@ calculate_live_ranges (var_map map)
 #endif
 
   calculate_live_on_exit (live);
+
+  if (!want_livein)
+    {
+      bitmap_obstack_release (&live->livein_obstack);
+      free (live->livein);
+      live->livein = NULL;
+    }
+
   return live;
 }
 
@@ -1237,7 +1280,7 @@ dump_var_map (FILE *f, var_map map)
            {
              if (t++ == 0)
                {
-                 fprintf(f, "Partition %d (", x);
+                 fprintf (f, "Partition %d (", x);
                  print_generic_expr (f, partition_to_var (map, p), TDF_SLIM);
                  fprintf (f, " - ");
                }
@@ -1281,7 +1324,7 @@ dump_live_info (FILE *f, tree_live_info_p live, int flag)
 
   if ((flag & LIVEDUMP_ENTRY) && live->livein)
     {
-      FOR_EACH_BB (bb)
+      FOR_EACH_BB_FN (bb, cfun)
        {
          fprintf (f, "\nLive on entry to BB%d : ", bb->index);
          EXECUTE_IF_SET_IN_BITMAP (&live->livein[bb->index], 0, i, bi)
@@ -1295,7 +1338,7 @@ dump_live_info (FILE *f, tree_live_info_p live, int flag)
 
   if ((flag & LIVEDUMP_EXIT) && live->liveout)
     {
-      FOR_EACH_BB (bb)
+      FOR_EACH_BB_FN (bb, cfun)
        {
          fprintf (f, "\nLive on exit from BB%d : ", bb->index);
          EXECUTE_IF_SET_IN_BITMAP (&live->liveout[bb->index], 0, i, bi)
@@ -1361,12 +1404,12 @@ verify_live_on_entry (tree_live_info_p live)
    /* Check for live on entry partitions and report those with a DEF in
       the program. This will typically mean an optimization has done
       something wrong.  */
-  bb = ENTRY_BLOCK_PTR;
+  bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
   num = 0;
   FOR_EACH_EDGE (e, ei, bb->succs)
     {
       int entry_block = e->dest->index;
-      if (e->dest == EXIT_BLOCK_PTR)
+      if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
         continue;
       for (i = 0; i < (unsigned)num_var_partitions (map); i++)
        {
@@ -1417,16 +1460,21 @@ verify_live_on_entry (tree_live_info_p live)
          else
            if (d == var)
              {
+               /* An undefined local variable does not need to be very
+                  alive.  */
+               if (ssa_undefined_value_p (var, false))
+                 continue;
+
                /* The only way this var shouldn't be marked live on entry is
                   if it occurs in a PHI argument of the block.  */
                size_t z;
                bool ok = false;
-               gimple_stmt_iterator gsi;
+               gphi_iterator gsi;
                for (gsi = gsi_start_phis (e->dest);
                     !gsi_end_p (gsi) && !ok;
                     gsi_next (&gsi))
                  {
-                   gimple phi = gsi_stmt (gsi);
+                   gphi *phi = gsi.phi ();
                    for (z = 0; z < gimple_phi_num_args (phi); z++)
                      if (var == gimple_phi_arg_def (phi, z))
                        {