re PR lto/56515 (location references block not in block tree, verify_gimple failed...
authorRichard Biener <rguenther@suse.de>
Tue, 5 Mar 2013 09:20:30 +0000 (09:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 5 Mar 2013 09:20:30 +0000 (09:20 +0000)
2013-03-05  Richard Biener  <rguenther@suse.de>

PR lto/56515
* tree-inline.c (remap_blocks_to_null): New function.
(expand_call_inline): When expanding a call stmt without
an associated block inline remap all callee blocks to NULL.

From-SVN: r196452

gcc/ChangeLog
gcc/tree-inline.c

index 2678b16fb8bbec3f151c25e745ab53178616849d..56d6b41f629735e9a6a6df19a7525aa3775ff21a 100644 (file)
@@ -1,3 +1,10 @@
+2013-03-05  Richard Biener  <rguenther@suse.de>
+
+       PR lto/56515
+       * tree-inline.c (remap_blocks_to_null): New function.
+       (expand_call_inline): When expanding a call stmt without
+       an associated block inline remap all callee blocks to NULL.
+
 2013-03-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/56494
index 2a1b6923996625b1bd157e9e19b9e34bfb1d9dcb..714bcf0fcb043dd941eec6730ea9bce2c8651476 100644 (file)
@@ -651,6 +651,16 @@ remap_blocks (tree block, copy_body_data *id)
   return new_tree;
 }
 
+/* Remap the block tree rooted at BLOCK to nothing.  */
+static void
+remap_blocks_to_null (tree block, copy_body_data *id)
+{
+  tree t;
+  insert_decl_map (id, block, NULL_TREE);
+  for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t))
+    remap_blocks_to_null (t, id);
+}
+
 static void
 copy_statement_list (tree *tp)
 {
@@ -3908,12 +3918,20 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
   /* Build a block containing code to initialize the arguments, the
      actual inline expansion of the body, and a label for the return
      statements within the function to jump to.  The type of the
-     statement expression is the return type of the function call.  */
-  id->block = make_node (BLOCK);
-  BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
-  BLOCK_SOURCE_LOCATION (id->block) = input_location;
+     statement expression is the return type of the function call.
+     ???  If the call does not have an associated block then we will
+     remap all callee blocks to NULL, effectively dropping most of
+     its debug information.  This should only happen for calls to
+     artificial decls inserted by the compiler itself.  We need to
+     either link the inlined blocks into the caller block tree or
+     not refer to them in any way to not break GC for locations.  */
   if (gimple_block (stmt))
-    prepend_lexical_block (gimple_block (stmt), id->block);
+    {
+      id->block = make_node (BLOCK);
+      BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
+      BLOCK_SOURCE_LOCATION (id->block) = input_location;
+      prepend_lexical_block (gimple_block (stmt), id->block);
+    }
 
   /* Local declarations will be replaced by their equivalents in this
      map.  */
@@ -3942,27 +3960,33 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
 
   if (DECL_INITIAL (fn))
     {
-      tree *var;
-
-      prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id));
-      gcc_checking_assert (BLOCK_SUBBLOCKS (id->block)
-                          && (BLOCK_CHAIN (BLOCK_SUBBLOCKS (id->block))
-                              == NULL_TREE));
-      /* Move vars for PARM_DECLs from DECL_INITIAL block to id->block,
-        otherwise for DWARF DW_TAG_formal_parameter will not be children of
-        DW_TAG_inlined_subroutine, but of a DW_TAG_lexical_block
-        under it.  The parameters can be then evaluated in the debugger,
-        but don't show in backtraces.  */
-      for (var = &BLOCK_VARS (BLOCK_SUBBLOCKS (id->block)); *var; )
-       if (TREE_CODE (DECL_ORIGIN (*var)) == PARM_DECL)
-         {
-           tree v = *var;
-           *var = TREE_CHAIN (v);
-           TREE_CHAIN (v) = BLOCK_VARS (id->block);
-           BLOCK_VARS (id->block) = v;
-         }
-       else
-         var = &TREE_CHAIN (*var);
+      if (gimple_block (stmt))
+       {
+         tree *var;
+
+         prepend_lexical_block (id->block,
+                                remap_blocks (DECL_INITIAL (fn), id));
+         gcc_checking_assert (BLOCK_SUBBLOCKS (id->block)
+                              && (BLOCK_CHAIN (BLOCK_SUBBLOCKS (id->block))
+                                  == NULL_TREE));
+         /* Move vars for PARM_DECLs from DECL_INITIAL block to id->block,
+            otherwise for DWARF DW_TAG_formal_parameter will not be children of
+            DW_TAG_inlined_subroutine, but of a DW_TAG_lexical_block
+            under it.  The parameters can be then evaluated in the debugger,
+            but don't show in backtraces.  */
+         for (var = &BLOCK_VARS (BLOCK_SUBBLOCKS (id->block)); *var; )
+           if (TREE_CODE (DECL_ORIGIN (*var)) == PARM_DECL)
+             {
+               tree v = *var;
+               *var = TREE_CHAIN (v);
+               TREE_CHAIN (v) = BLOCK_VARS (id->block);
+               BLOCK_VARS (id->block) = v;
+             }
+           else
+             var = &TREE_CHAIN (*var);
+       }
+      else
+       remap_blocks_to_null (DECL_INITIAL (fn), id);
     }
 
   /* Return statements in the function body will be replaced by jumps
@@ -4106,7 +4130,8 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
      inlined.  If we don't do this now, we can lose the information about the
      variables in the function when the blocks get blown away as soon as we
      remove the cgraph node.  */
-  (*debug_hooks->outlining_inline_function) (cg_edge->callee->symbol.decl);
+  if (gimple_block (stmt))
+    (*debug_hooks->outlining_inline_function) (cg_edge->callee->symbol.decl);
 
   /* Update callgraph if needed.  */
   cgraph_remove_node (cg_edge->callee);