IA MCU psABI support: changes to libraries
[gcc.git] / gcc / tree-ssa-live.c
index 1effb43bd380259faa8350a99939675edff618c3..450cf90d2efb598e273f889eb042f2aa933de577 100644 (file)
@@ -1,5 +1,5 @@
 /* Liveness for SSA trees.
-   Copyright (C) 2003-2014 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,16 @@ 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 "alias.h"
+#include "symtab.h"
 #include "tree.h"
+#include "fold-const.h"
 #include "gimple-pretty-print.h"
 #include "bitmap.h"
 #include "sbitmap.h"
 #include "predict.h"
-#include "vec.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "machmode.h"
 #include "hard-reg-set.h"
-#include "input.h"
 #include "function.h"
 #include "dominance.h"
 #include "cfg.h"
@@ -41,7 +38,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
 #include "gimple-expr.h"
-#include "is-a.h"
 #include "gimple.h"
 #include "gimple-iterator.h"
 #include "gimple-ssa.h"
@@ -49,6 +45,16 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssa-iterators.h"
 #include "stringpool.h"
 #include "tree-ssanames.h"
+#include "rtl.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"
@@ -56,7 +62,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-live.h"
 #include "diagnostic-core.h"
 #include "debug.h"
-#include "flags.h"
+#include "tree-ssa.h"
+#include "lto-streamer.h"
+#include "cgraph.h"
+#include "ipa-utils.h"
 
 #ifdef ENABLE_CHECKING
 static void  verify_live_on_entry (tree_live_info_p);
@@ -79,22 +88,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);
 }
@@ -490,12 +497,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);
@@ -575,7 +599,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))
          {
@@ -829,12 +853,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;
@@ -938,7 +964,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);
@@ -952,13 +978,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
@@ -971,18 +990,20 @@ new_tree_live_info (var_map map)
   live->map = map;
   live->num_blocks = last_basic_block_for_fn (cfun);
 
+  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], &liveness_bitmap_obstack);
+    bitmap_initialize (&live->livein[bb->index], &live->livein_obstack);
 
   live->liveout = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
   FOR_EACH_BB_FN (bb, cfun)
-    bitmap_initialize (&live->liveout[bb->index], &liveness_bitmap_obstack);
+    bitmap_initialize (&live->liveout[bb->index], &live->liveout_obstack);
 
   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;
 }
 
@@ -992,10 +1013,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);
 }
 
@@ -1006,8 +1035,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;
@@ -1025,17 +1053,17 @@ loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited,
       pred_bb = e->src;
       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;
@@ -1053,23 +1081,21 @@ live_worklist (tree_live_info_p live)
   unsigned b;
   basic_block bb;
   sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun) + 1);
-  bitmap tmp = BITMAP_ALLOC (&liveness_bitmap_obstack);
 
   bitmap_clear (visited);
 
   /* Visit all the blocks in reverse order and propagate live on entry values
      into the predecessors blocks.  */
   FOR_EACH_BB_REVERSE_FN (bb, cfun)
-    loe_visit_block (live, bb, visited, tmp);
+    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_FOR_FN (cfun, b), visited, tmp);
+      loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited);
     }
 
-  BITMAP_FREE (tmp);
   sbitmap_free (visited);
 }
 
@@ -1103,6 +1129,10 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
   else
     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.  */
   FOR_EACH_IMM_USE_FAST (use, imm_iter, ssa_name)
@@ -1116,7 +1146,7 @@ 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);
+         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)
@@ -1150,7 +1180,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;
@@ -1164,13 +1194,13 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
   /* Set all the live-on-exit bits for uses in PHIs.  */
   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);
@@ -1201,13 +1231,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++)
     {
@@ -1223,6 +1252,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;
 }
 
@@ -1439,16 +1476,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))
                        {