IA MCU psABI support: changes to libraries
[gcc.git] / gcc / tree-ssa.c
index 25354617a18a596dc0996718b9093055f08c7d35..cab627daa1534665cdca4c4c6812126942737f12 100644 (file)
@@ -1,5 +1,5 @@
 /* Miscellaneous SSA utility functions.
-   Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   Copyright (C) 2001-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -21,19 +21,17 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "alias.h"
+#include "symtab.h"
 #include "tree.h"
+#include "fold-const.h"
 #include "stor-layout.h"
 #include "flags.h"
 #include "tm_p.h"
 #include "target.h"
 #include "langhooks.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"
@@ -43,7 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "internal-fn.h"
 #include "gimple-fold.h"
 #include "gimple-expr.h"
-#include "is-a.h"
 #include "gimple.h"
 #include "gimplify.h"
 #include "gimple-iterator.h"
@@ -57,7 +54,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-into-ssa.h"
 #include "tree-ssa.h"
 #include "tree-inline.h"
-#include "hash-map.h"
 #include "tree-pass.h"
 #include "diagnostic-core.h"
 #include "cfgloop.h"
@@ -157,8 +153,8 @@ redirect_edge_var_map_destroy (void)
 edge
 ssa_redirect_edge (edge e, basic_block dest)
 {
-  gimple_stmt_iterator gsi;
-  gimple phi;
+  gphi_iterator gsi;
+  gphi *phi;
 
   redirect_edge_var_map_clear (e);
 
@@ -168,7 +164,7 @@ ssa_redirect_edge (edge e, basic_block dest)
       tree def;
       source_location locus ;
 
-      phi = gsi_stmt (gsi);
+      phi = gsi.phi ();
       def = gimple_phi_arg_def (phi, e->dest_idx);
       locus = gimple_phi_arg_location (phi, e->dest_idx);
 
@@ -190,10 +186,10 @@ ssa_redirect_edge (edge e, basic_block dest)
 void
 flush_pending_stmts (edge e)
 {
-  gimple phi;
+  gphi *phi;
   edge_var_map *vm;
   int i;
-  gimple_stmt_iterator gsi;
+  gphi_iterator gsi;
 
   vec<edge_var_map> *v = redirect_edge_var_map_vector (e);
   if (!v)
@@ -205,7 +201,7 @@ flush_pending_stmts (edge e)
     {
       tree def;
 
-      phi = gsi_stmt (gsi);
+      phi = gsi.phi ();
       def = redirect_edge_var_map_def (vm);
       add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
     }
@@ -366,7 +362,7 @@ insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
      we'll have to drop debug information.  */
   if (gimple_code (def_stmt) == GIMPLE_PHI)
     {
-      value = degenerate_phi_result (def_stmt);
+      value = degenerate_phi_result (as_a <gphi *> (def_stmt));
       if (value && walk_tree (&value, find_released_ssa_name, NULL, NULL))
        value = NULL;
       /* error_mark_node is what fixup_noreturn_call changes PHI arguments
@@ -444,7 +440,7 @@ insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
        ;
       else
        {
-         gimple def_temp;
+         gdebug *def_temp;
          tree vexpr = make_node (DEBUG_EXPR_DECL);
 
          def_temp = gimple_build_debug_bind (vexpr,
@@ -838,7 +834,7 @@ verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
       definition of SSA_NAME.  */
 
 static bool
-verify_phi_args (gimple phi, basic_block bb, basic_block *definition_block)
+verify_phi_args (gphi *phi, basic_block bb, basic_block *definition_block)
 {
   edge e;
   bool err = false;
@@ -969,9 +965,7 @@ verify_ssa (bool check_modified_stmt, bool check_ssa_operands)
   FOR_EACH_BB_FN (bb, cfun)
     {
       edge e;
-      gimple phi;
       edge_iterator ei;
-      gimple_stmt_iterator gsi;
 
       /* Make sure that all edges have a clear 'aux' field.  */
       FOR_EACH_EDGE (e, ei, bb->preds)
@@ -985,9 +979,9 @@ verify_ssa (bool check_modified_stmt, bool check_ssa_operands)
        }
 
       /* Verify the arguments for every PHI node in the block.  */
-      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         phi = gsi_stmt (gsi);
+         gphi *phi = gsi.phi ();
          if (verify_phi_args (phi, bb, definition_block))
            goto err;
 
@@ -996,7 +990,8 @@ verify_ssa (bool check_modified_stmt, bool check_ssa_operands)
        }
 
       /* Now verify all the uses and vuses in every statement of the block.  */
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+          gsi_next (&gsi))
        {
          gimple stmt = gsi_stmt (gsi);
          use_operand_p use_p;
@@ -1331,6 +1326,13 @@ non_rewritable_lvalue_p (tree lhs)
   if (DECL_P (lhs))
     return false;
 
+  /* We can re-write REALPART_EXPR and IMAGPART_EXPR sets in
+     a reasonably efficient manner... */
+  if ((TREE_CODE (lhs) == REALPART_EXPR
+       || TREE_CODE (lhs) == IMAGPART_EXPR)
+      && DECL_P (TREE_OPERAND (lhs, 0)))
+    return false;
+
   /* A decl that is wrapped inside a MEM-REF that covers
      it full is also rewritable.
      ???  The following could be relaxed allowing component
@@ -1406,7 +1408,6 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs,
 void
 execute_update_addresses_taken (void)
 {
-  gimple_stmt_iterator gsi;
   basic_block bb;
   bitmap addresses_taken = BITMAP_ALLOC (NULL);
   bitmap not_reg_needs = BITMAP_ALLOC (NULL);
@@ -1420,7 +1421,8 @@ execute_update_addresses_taken (void)
      the function body.  */
   FOR_EACH_BB_FN (bb, cfun)
     {
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+          gsi_next (&gsi))
        {
          gimple stmt = gsi_stmt (gsi);
          enum gimple_code code = gimple_code (stmt);
@@ -1463,9 +1465,10 @@ execute_update_addresses_taken (void)
 
          else if (code == GIMPLE_ASM)
            {
-             for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+             gasm *asm_stmt = as_a <gasm *> (stmt);
+             for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
                {
-                 tree link = gimple_asm_output_op (stmt, i);
+                 tree link = gimple_asm_output_op (asm_stmt, i);
                  tree lhs = TREE_VALUE (link);
                  if (TREE_CODE (lhs) != SSA_NAME)
                    {
@@ -1480,19 +1483,20 @@ execute_update_addresses_taken (void)
                        bitmap_set_bit (not_reg_needs, DECL_UID (decl));
                    }
                }
-             for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+             for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
                {
-                 tree link = gimple_asm_input_op (stmt, i);
+                 tree link = gimple_asm_input_op (asm_stmt, i);
                  if ((decl = non_rewritable_mem_ref_base (TREE_VALUE (link))))
                    bitmap_set_bit (not_reg_needs, DECL_UID (decl));
                }
            }
        }
 
-      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
+          gsi_next (&gsi))
        {
          size_t i;
-         gimple phi = gsi_stmt (gsi);
+         gphi *phi = gsi.phi ();
 
          for (i = 0; i < gimple_phi_num_args (phi); i++)
            {
@@ -1521,7 +1525,7 @@ execute_update_addresses_taken (void)
   if (!bitmap_empty_p (suitable_for_renaming))
     {
       FOR_EACH_BB_FN (bb, cfun)
-       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+       for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
          {
            gimple stmt = gsi_stmt (gsi);
 
@@ -1533,6 +1537,37 @@ execute_update_addresses_taken (void)
                tree rhs, *rhsp = gimple_assign_rhs1_ptr (stmt);
                tree sym;
 
+               /* Rewrite LHS IMAG/REALPART_EXPR similar to
+                  gimplify_modify_expr_complex_part.  */
+               if ((TREE_CODE (lhs) == IMAGPART_EXPR
+                    || TREE_CODE (lhs) == REALPART_EXPR)
+                   && DECL_P (TREE_OPERAND (lhs, 0))
+                   && bitmap_bit_p (suitable_for_renaming,
+                                    DECL_UID (TREE_OPERAND (lhs, 0))))
+                 {
+                   tree other = make_ssa_name (TREE_TYPE (lhs));
+                   tree lrhs = build1 (TREE_CODE (lhs) == IMAGPART_EXPR
+                                       ? REALPART_EXPR : IMAGPART_EXPR,
+                                       TREE_TYPE (other),
+                                       TREE_OPERAND (lhs, 0));
+                   gimple load = gimple_build_assign (other, lrhs);
+                   location_t loc = gimple_location (stmt);
+                   gimple_set_location (load, loc);
+                   gimple_set_vuse (load, gimple_vuse (stmt));
+                   gsi_insert_before (&gsi, load, GSI_SAME_STMT);
+                   gimple_assign_set_lhs (stmt, TREE_OPERAND (lhs, 0));
+                   gimple_assign_set_rhs_with_ops
+                     (&gsi, COMPLEX_EXPR,
+                      TREE_CODE (lhs) == IMAGPART_EXPR
+                      ? other : gimple_assign_rhs1 (stmt),
+                      TREE_CODE (lhs) == IMAGPART_EXPR
+                      ? gimple_assign_rhs1 (stmt) : other, NULL_TREE);
+                   stmt = gsi_stmt (gsi);
+                   unlink_stmt_vdef (stmt);
+                   update_stmt (stmt);
+                   continue;
+                 }
+
                /* We shouldn't have any fancy wrapping of
                   component-refs on the LHS, but look through
                   VIEW_CONVERT_EXPRs as that is easy.  */
@@ -1581,16 +1616,17 @@ execute_update_addresses_taken (void)
 
            else if (gimple_code (stmt) == GIMPLE_ASM)
              {
+               gasm *asm_stmt = as_a <gasm *> (stmt);
                unsigned i;
-               for (i = 0; i < gimple_asm_noutputs (stmt); ++i)
+               for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
                  {
-                   tree link = gimple_asm_output_op (stmt, i);
+                   tree link = gimple_asm_output_op (asm_stmt, i);
                    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
                                                suitable_for_renaming);
                  }
-               for (i = 0; i < gimple_asm_ninputs (stmt); ++i)
+               for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
                  {
-                   tree link = gimple_asm_input_op (stmt, i);
+                   tree link = gimple_asm_input_op (asm_stmt, i);
                    maybe_rewrite_mem_ref_base (&TREE_VALUE (link),
                                                suitable_for_renaming);
                  }