re PR target/54061 (gcc.c-torture/compile/mipscop-*.c ICEs with -g)
[gcc.git] / gcc / cgraphbuild.c
index 6b8116a612a53bc1de2c2c8625a890f3705d6707..024424d0671b1057384077bc1e8da775094433ea 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "ipa-utils.h"
 #include "except.h"
+#include "ipa-inline.h"
 
 /* Context of record_reference.  */
 struct record_reference_ctx
@@ -53,6 +54,12 @@ record_reference (tree *tp, int *walk_subtrees, void *data)
   tree decl;
   struct record_reference_ctx *ctx = (struct record_reference_ctx *)data;
 
+  t = canonicalize_constructor_val (t, NULL);
+  if (!t)
+    t = *tp;
+  else if (t != *tp)
+    *tp = t;
+
   switch (TREE_CODE (t))
     {
     case VAR_DECL:
@@ -67,23 +74,19 @@ record_reference (tree *tp, int *walk_subtrees, void *data)
       decl = get_base_var (*tp);
       if (TREE_CODE (decl) == FUNCTION_DECL)
        {
+         struct cgraph_node *node = cgraph_get_create_node (decl);
          if (!ctx->only_vars)
-         cgraph_mark_address_taken_node (cgraph_node (decl));
-         ipa_record_reference (NULL, ctx->varpool_node,
-                               cgraph_node (decl), NULL,
+           cgraph_mark_address_taken_node (node);
+         ipa_record_reference ((symtab_node)ctx->varpool_node,
+                               (symtab_node)node,
                                IPA_REF_ADDR, NULL);
        }
 
       if (TREE_CODE (decl) == VAR_DECL)
        {
-         struct varpool_node *vnode = varpool_node (decl);
-         if (lang_hooks.callgraph.analyze_expr)
-           lang_hooks.callgraph.analyze_expr (&decl, walk_subtrees);
-         varpool_mark_needed_node (vnode);
-         if (vnode->alias && vnode->extra_name)
-           vnode = vnode->extra_name;
-         ipa_record_reference (NULL, ctx->varpool_node,
-                               NULL, vnode,
+         struct varpool_node *vnode = varpool_node_for_decl (decl);
+         ipa_record_reference ((symtab_node)ctx->varpool_node,
+                               (symtab_node)vnode,
                                IPA_REF_ADDR, NULL);
        }
       *walk_subtrees = 0;
@@ -97,9 +100,6 @@ record_reference (tree *tp, int *walk_subtrees, void *data)
          *walk_subtrees = 0;
          break;
        }
-
-      if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
-       return lang_hooks.callgraph.analyze_expr (tp, walk_subtrees);
       break;
     }
 
@@ -123,10 +123,9 @@ record_type_list (struct cgraph_node *node, tree list)
          type = TREE_OPERAND (type, 0);
          if (TREE_CODE (type) == VAR_DECL)
            {
-             struct varpool_node *vnode = varpool_node (type);
-             varpool_mark_needed_node (vnode);
-             ipa_record_reference (node, NULL,
-                                   NULL, vnode,
+             struct varpool_node *vnode = varpool_node_for_decl (type);
+             ipa_record_reference ((symtab_node)node,
+                                   (symtab_node)vnode,
                                    IPA_REF_ADDR, NULL);
            }
        }
@@ -141,10 +140,14 @@ record_eh_tables (struct cgraph_node *node, struct function *fun)
 {
   eh_region i;
 
-  if (DECL_FUNCTION_PERSONALITY (node->decl))
-    ipa_record_reference (node, NULL,
-                         cgraph_node (DECL_FUNCTION_PERSONALITY (node->decl)),
-                         NULL, IPA_REF_ADDR, NULL);
+  if (DECL_FUNCTION_PERSONALITY (node->symbol.decl))
+    {
+      struct cgraph_node *per_node;
+
+      per_node = cgraph_get_create_node (DECL_FUNCTION_PERSONALITY (node->symbol.decl));
+      ipa_record_reference ((symtab_node)node, (symtab_node)per_node, IPA_REF_ADDR, NULL);
+      cgraph_mark_address_taken_node (per_node);
+    }
 
   i = fun->eh->region_tree;
   if (!i)
@@ -191,29 +194,6 @@ record_eh_tables (struct cgraph_node *node, struct function *fun)
     }
 }
 
-/* Reset inlining information of all incoming call edges of NODE.  */
-
-void
-reset_inline_failed (struct cgraph_node *node)
-{
-  struct cgraph_edge *e;
-
-  for (e = node->callers; e; e = e->next_caller)
-    {
-      e->callee->global.inlined_to = NULL;
-      if (!node->analyzed)
-       e->inline_failed = CIF_BODY_NOT_AVAILABLE;
-      else if (node->local.redefined_extern_inline)
-       e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
-      else if (!node->local.inlinable)
-       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
-      else if (e->call_stmt_cannot_inline_p)
-       e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
-      else
-       e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
-    }
-}
-
 /* Computes the frequency of the call statement so that it can be stored in
    cgraph_edge.  BB is the basic block of the call statement.  */
 int
@@ -244,25 +224,19 @@ mark_address (gimple stmt, tree addr, void *data)
   addr = get_base_address (addr);
   if (TREE_CODE (addr) == FUNCTION_DECL)
     {
-      struct cgraph_node *node = cgraph_node (addr);
+      struct cgraph_node *node = cgraph_get_create_node (addr);
       cgraph_mark_address_taken_node (node);
-      ipa_record_reference ((struct cgraph_node *)data, NULL,
-                           node, NULL,
+      ipa_record_reference ((symtab_node)data,
+                           (symtab_node)node,
                            IPA_REF_ADDR, stmt);
     }
   else if (addr && TREE_CODE (addr) == VAR_DECL
           && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
     {
-      struct varpool_node *vnode = varpool_node (addr);
-      int walk_subtrees;
-
-      if (lang_hooks.callgraph.analyze_expr)
-       lang_hooks.callgraph.analyze_expr (&addr, &walk_subtrees);
-      varpool_mark_needed_node (vnode);
-      if (vnode->alias && vnode->extra_name)
-       vnode = vnode->extra_name;
-      ipa_record_reference ((struct cgraph_node *)data, NULL,
-                           NULL, vnode,
+      struct varpool_node *vnode = varpool_node_for_decl (addr);
+
+      ipa_record_reference ((symtab_node)data,
+                           (symtab_node)vnode,
                            IPA_REF_ADDR, stmt);
     }
 
@@ -279,25 +253,19 @@ mark_load (gimple stmt, tree t, void *data)
     {
       /* ??? This can happen on platforms with descriptors when these are
         directly manipulated in the code.  Pretend that it's an address.  */
-      struct cgraph_node *node = cgraph_node (t);
+      struct cgraph_node *node = cgraph_get_create_node (t);
       cgraph_mark_address_taken_node (node);
-      ipa_record_reference ((struct cgraph_node *)data, NULL,
-                           node, NULL,
+      ipa_record_reference ((symtab_node)data,
+                           (symtab_node)node,
                            IPA_REF_ADDR, stmt);
     }
   else if (t && TREE_CODE (t) == VAR_DECL
           && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     {
-      struct varpool_node *vnode = varpool_node (t);
-      int walk_subtrees;
-
-      if (lang_hooks.callgraph.analyze_expr)
-       lang_hooks.callgraph.analyze_expr (&t, &walk_subtrees);
-      varpool_mark_needed_node (vnode);
-      if (vnode->alias && vnode->extra_name)
-       vnode = vnode->extra_name;
-      ipa_record_reference ((struct cgraph_node *)data, NULL,
-                           NULL, vnode,
+      struct varpool_node *vnode = varpool_node_for_decl (t);
+
+      ipa_record_reference ((symtab_node)data,
+                           (symtab_node)vnode,
                            IPA_REF_LOAD, stmt);
     }
   return false;
@@ -312,16 +280,10 @@ mark_store (gimple stmt, tree t, void *data)
   if (t && TREE_CODE (t) == VAR_DECL
       && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
     {
-      struct varpool_node *vnode = varpool_node (t);
-      int walk_subtrees;
-
-      if (lang_hooks.callgraph.analyze_expr)
-       lang_hooks.callgraph.analyze_expr (&t, &walk_subtrees);
-      varpool_mark_needed_node (vnode);
-      if (vnode->alias && vnode->extra_name)
-       vnode = vnode->extra_name;
-      ipa_record_reference ((struct cgraph_node *)data, NULL,
-                           NULL, vnode,
+      struct varpool_node *vnode = varpool_node_for_decl (t);
+
+      ipa_record_reference ((symtab_node)data,
+                           (symtab_node)vnode,
                            IPA_REF_STORE, stmt);
      }
   return false;
@@ -334,7 +296,7 @@ static unsigned int
 build_cgraph_edges (void)
 {
   basic_block bb;
-  struct cgraph_node *node = cgraph_node (current_function_decl);
+  struct cgraph_node *node = cgraph_get_node (current_function_decl);
   struct pointer_set_t *visited_nodes = pointer_set_create ();
   gimple_stmt_iterator gsi;
   tree decl;
@@ -355,14 +317,12 @@ build_cgraph_edges (void)
                                                         bb);
              decl = gimple_call_fndecl (stmt);
              if (decl)
-               cgraph_create_edge (node, cgraph_node (decl), stmt,
-                                   bb->count, freq,
-                                   bb->loop_depth);
+               cgraph_create_edge (node, cgraph_get_create_node (decl),
+                                   stmt, bb->count, freq);
              else
                cgraph_create_indirect_edge (node, stmt,
                                             gimple_call_flags (stmt),
-                                            bb->count, freq,
-                                            bb->loop_depth);
+                                            bb->count, freq);
            }
          walk_stmt_load_store_addr_ops (stmt, node, mark_load,
                                         mark_store, mark_address);
@@ -370,22 +330,25 @@ build_cgraph_edges (void)
              && gimple_omp_parallel_child_fn (stmt))
            {
              tree fn = gimple_omp_parallel_child_fn (stmt);
-             ipa_record_reference (node, NULL, cgraph_node (fn),
-                                   NULL, IPA_REF_ADDR, stmt);
+             ipa_record_reference ((symtab_node)node,
+                                   (symtab_node)cgraph_get_create_node (fn),
+                                   IPA_REF_ADDR, stmt);
            }
          if (gimple_code (stmt) == GIMPLE_OMP_TASK)
            {
              tree fn = gimple_omp_task_child_fn (stmt);
              if (fn)
-               ipa_record_reference (node, NULL, cgraph_node (fn),
-                                     NULL, IPA_REF_ADDR, stmt);
+               ipa_record_reference ((symtab_node)node,
+                                     (symtab_node) cgraph_get_create_node (fn),
+                                     IPA_REF_ADDR, stmt);
              fn = gimple_omp_task_copy_fn (stmt);
              if (fn)
-               ipa_record_reference (node, NULL, cgraph_node (fn),
-                                     NULL, IPA_REF_ADDR, stmt);
+               ipa_record_reference ((symtab_node)node,
+                                     (symtab_node)cgraph_get_create_node (fn),
+                                     IPA_REF_ADDR, stmt);
            }
        }
-      for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
                                       mark_load, mark_store, mark_address);
    }
@@ -393,7 +356,8 @@ build_cgraph_edges (void)
   /* Look for initializers of constant variables and private statics.  */
   FOR_EACH_LOCAL_DECL (cfun, ix, decl)
     if (TREE_CODE (decl) == VAR_DECL
-       && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
+       && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
+       && !DECL_HAS_VALUE_EXPR_P (decl))
       varpool_finalize_decl (decl);
   record_eh_tables (node, cfun);
 
@@ -406,6 +370,7 @@ struct gimple_opt_pass pass_build_cgraph_edges =
  {
   GIMPLE_PASS,
   "*build_cgraph_edges",                       /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   NULL,                                        /* gate */
   build_cgraph_edges,                  /* execute */
   NULL,                                        /* sub */
@@ -428,7 +393,7 @@ void
 record_references_in_initializer (tree decl, bool only_vars)
 {
   struct pointer_set_t *visited_nodes = pointer_set_create ();
-  struct varpool_node *node = varpool_node (decl);
+  struct varpool_node *node = varpool_node_for_decl (decl);
   struct record_reference_ctx ctx = {false, NULL};
 
   ctx.varpool_node = node;
@@ -445,11 +410,11 @@ unsigned int
 rebuild_cgraph_edges (void)
 {
   basic_block bb;
-  struct cgraph_node *node = cgraph_node (current_function_decl);
+  struct cgraph_node *node = cgraph_get_node (current_function_decl);
   gimple_stmt_iterator gsi;
 
   cgraph_node_remove_callees (node);
-  ipa_remove_all_references (&node->ref_list);
+  ipa_remove_all_references (&node->symbol.ref_list);
 
   node->count = ENTRY_BLOCK_PTR->count;
 
@@ -466,20 +431,18 @@ rebuild_cgraph_edges (void)
                                                         bb);
              decl = gimple_call_fndecl (stmt);
              if (decl)
-               cgraph_create_edge (node, cgraph_node (decl), stmt,
-                                   bb->count, freq,
-                                   bb->loop_depth);
+               cgraph_create_edge (node, cgraph_get_create_node (decl), stmt,
+                                   bb->count, freq);
              else
                cgraph_create_indirect_edge (node, stmt,
                                             gimple_call_flags (stmt),
-                                            bb->count, freq,
-                                            bb->loop_depth);
+                                            bb->count, freq);
            }
          walk_stmt_load_store_addr_ops (stmt, node, mark_load,
                                         mark_store, mark_address);
 
        }
-      for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
                                       mark_load, mark_store, mark_address);
     }
@@ -496,10 +459,10 @@ void
 cgraph_rebuild_references (void)
 {
   basic_block bb;
-  struct cgraph_node *node = cgraph_node (current_function_decl);
+  struct cgraph_node *node = cgraph_get_node (current_function_decl);
   gimple_stmt_iterator gsi;
 
-  ipa_remove_all_references (&node->ref_list);
+  ipa_remove_all_references (&node->symbol.ref_list);
 
   node->count = ENTRY_BLOCK_PTR->count;
 
@@ -513,7 +476,7 @@ cgraph_rebuild_references (void)
                                         mark_store, mark_address);
 
        }
-      for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
                                       mark_load, mark_store, mark_address);
     }
@@ -525,6 +488,7 @@ struct gimple_opt_pass pass_rebuild_cgraph_edges =
  {
   GIMPLE_PASS,
   "*rebuild_cgraph_edges",             /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   NULL,                                        /* gate */
   rebuild_cgraph_edges,                        /* execute */
   NULL,                                        /* sub */
@@ -543,7 +507,7 @@ struct gimple_opt_pass pass_rebuild_cgraph_edges =
 static unsigned int
 remove_cgraph_callee_edges (void)
 {
-  cgraph_node_remove_callees (cgraph_node (current_function_decl));
+  cgraph_node_remove_callees (cgraph_get_node (current_function_decl));
   return 0;
 }
 
@@ -552,6 +516,7 @@ struct gimple_opt_pass pass_remove_cgraph_callee_edges =
  {
   GIMPLE_PASS,
   "*remove_cgraph_callee_edges",               /* name */
+  OPTGROUP_NONE,                        /* optinfo_flags */
   NULL,                                        /* gate */
   remove_cgraph_callee_edges,          /* execute */
   NULL,                                        /* sub */