re PR debug/39267 (gdb testsuite regressions)
authorJan Hubicka <jh@suse.cz>
Fri, 27 Feb 2009 19:49:42 +0000 (20:49 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 27 Feb 2009 19:49:42 +0000 (19:49 +0000)
PR debug/39267
* tree.h (TREE_PROTECTED): Fix comment.
(BLOCK_HANDLER_BLOCK): Remove.
(struct tree_block): Remove handler_block add body_block.
(inlined_function_outer_scope_p): New.
(is_body_block): Remove.
* dbxout.c (dbxout_block): Remove BLOCK_HANDLER_BLOCK.
* dwarf2out.c (is_inlined_entry_point): Remove.
(add_high_low_attributes): Use inlined_function_outer_scope_p.
(gen_block_die): Use is_inlined_entry_point check; remove body block code.
* langhooks.h (struct lang_hooks): Remove no_bodu_blocks.
* gimplify.c (gimplify_expr): Gimplify body blocks.
* tree-ssa-live.c (remove_unused_scope_block_p): Allow removing wrapper block
with multiple subblocks.
(dump_scope_block): Prettier output; dump more flags and info.
(dump_scope_blocks): New.
(remove_unused_locals): Use dump_scope_blocks.
* tree-flow.h (dump_scope_blocks): Declare.
* tree-cfg.c (execute_build_cfg): Dump scope blocks.
* stmt.c (is_body_block): Remove.
* tree-inline.c (remap_block): Copy BODY_BLOCK info.
* langhooks-def.h (LANG_HOOKS_NO_BODY_BLOCKS): Remove.

From-SVN: r144474

12 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-objc-common.h
gcc/dbxout.c
gcc/dwarf2out.c
gcc/langhooks-def.h
gcc/langhooks.h
gcc/stmt.c
gcc/tree-cfg.c
gcc/tree-flow.h
gcc/tree-ssa-live.c
gcc/tree.h

index 1f1bbd0..17ffc76 100644 (file)
@@ -1,3 +1,28 @@
+2009-02-27  Jan Hubicka  <jh@suse.cz>
+
+       PR debug/39267
+       * tree.h (TREE_PROTECTED): Fix comment.
+       (BLOCK_HANDLER_BLOCK): Remove.
+       (struct tree_block): Remove handler_block add body_block.
+       (inlined_function_outer_scope_p): New.
+       (is_body_block): Remove.
+       * dbxout.c (dbxout_block): Remove BLOCK_HANDLER_BLOCK.
+       * dwarf2out.c (is_inlined_entry_point): Remove.
+       (add_high_low_attributes): Use inlined_function_outer_scope_p.
+       (gen_block_die): Use is_inlined_entry_point check; remove body block code.
+       * langhooks.h (struct lang_hooks): Remove no_bodu_blocks.
+       * gimplify.c (gimplify_expr): Gimplify body blocks.
+       * tree-ssa-live.c (remove_unused_scope_block_p): Allow removing wrapper block
+       with multiple subblocks.
+       (dump_scope_block): Prettier output; dump more flags and info.
+       (dump_scope_blocks): New.
+       (remove_unused_locals): Use dump_scope_blocks.
+       * tree-flow.h (dump_scope_blocks): Declare.
+       * tree-cfg.c (execute_build_cfg): Dump scope blocks.
+       * stmt.c (is_body_block): Remove.
+       * tree-inline.c (remap_block): Copy BODY_BLOCK info.
+       * langhooks-def.h (LANG_HOOKS_NO_BODY_BLOCKS): Remove.
+
 2009-02-27  Sebastian Pop  <sebastian.pop@amd.com>
 
        PR middle-end/39308
index f19976b..a84113f 100644 (file)
@@ -7740,6 +7740,7 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
              tree curindex;
              unsigned HOST_WIDE_INT cnt;
              constructor_elt *ce;
+             bool fold_p = false;
 
              if (VEC_index (constructor_elt, v, 0)->index)
                maxindex = fold_convert (sizetype,
@@ -7751,14 +7752,20 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
                   VEC_iterate (constructor_elt, v, cnt, ce);
                   cnt++)
                {
+                 bool curfold_p = false;
                  if (ce->index)
-                   curindex = fold_convert (sizetype, ce->index);
+                   curindex = ce->index, curfold_p = true;
                  else
-                   curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
-
+                   {
+                     if (fold_p)
+                       curindex = fold_convert (sizetype, curindex);
+                     curindex = size_binop (PLUS_EXPR, curindex, size_one_node);
+                   }
                  if (tree_int_cst_lt (maxindex, curindex))
-                   maxindex = curindex;
+                   maxindex = curindex, fold_p = curfold_p;
                }
+              if (fold_p)
+                maxindex = fold_convert (sizetype, maxindex);
            }
        }
       else
index b9568c9..2a98150 100644 (file)
@@ -53,8 +53,6 @@ extern void c_initialize_diagnostics (diagnostic_context *);
 #define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
 #undef LANG_HOOKS_STATICP
 #define LANG_HOOKS_STATICP c_staticp
-#undef LANG_HOOKS_NO_BODY_BLOCKS
-#define LANG_HOOKS_NO_BODY_BLOCKS true
 #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
 #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
 #undef LANG_HOOKS_PRINT_IDENTIFIER
index 6cfa55f..babba15 100644 (file)
@@ -3625,20 +3625,6 @@ dbxout_block (tree block, int depth, tree args)
                  scope_start = buf;
                }
 
-             if (BLOCK_HANDLER_BLOCK (block))
-               {
-                 /* A catch block.  Must precede N_LBRAC.  */
-                 tree decl = BLOCK_VARS (block);
-                 while (decl)
-                   {
-                     dbxout_begin_complex_stabs ();
-                     stabstr_I (DECL_NAME (decl));
-                     stabstr_S (":C1");
-                     dbxout_finish_complex_stabs (0, N_CATCH, 0,
-                                                  scope_start, 0);
-                     decl = TREE_CHAIN (decl);
-                   }
-               }
              dbx_output_lbrac (scope_start, begin_label);
            }
 
index ed165c8..9d39a45 100644 (file)
@@ -14135,35 +14135,6 @@ add_call_src_coords_attributes (tree stmt, dw_die_ref die)
 }
 
 
-/* If STMT's abstract origin is a function declaration and STMT's
-   first subblock's abstract origin is the function's outermost block,
-   then we're looking at the main entry point.  */
-static bool
-is_inlined_entry_point (const_tree stmt)
-{
-  tree decl, block;
-
-  if (!stmt || TREE_CODE (stmt) != BLOCK)
-    return false;
-
-  decl = block_ultimate_origin (stmt);
-
-  if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
-    return false;
-
-  block = BLOCK_SUBBLOCKS (stmt);
-
-  if (block)
-    {
-      if (TREE_CODE (block) != BLOCK)
-       return false;
-
-      block = block_ultimate_origin (block);
-    }
-
-  return block == DECL_INITIAL (decl);
-}
-
 /* A helper function for gen_lexical_block_die and gen_inlined_subroutine_die.
    Add low_pc and high_pc attributes to the DIE for a block STMT.  */
 
@@ -14176,7 +14147,7 @@ add_high_low_attributes (tree stmt, dw_die_ref die)
     {
       tree chain;
 
-      if (is_inlined_entry_point (stmt))
+      if (inlined_function_outer_scope_p (stmt))
        {
          ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
                                       BLOCK_NUMBER (stmt));
@@ -14861,14 +14832,15 @@ static void
 gen_block_die (tree stmt, dw_die_ref context_die, int depth)
 {
   int must_output_die = 0;
-  tree origin;
   tree decl;
-  enum tree_code origin_code;
+  bool inlined_func;
 
   /* Ignore blocks that are NULL.  */
   if (stmt == NULL_TREE)
     return;
 
+  inlined_func = inlined_function_outer_scope_p (stmt);
+
   /* If the block is one fragment of a non-contiguous block, do not
      process the variables, since they will have been done by the
      origin block.  Do process subblocks.  */
@@ -14882,52 +14854,34 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
       return;
     }
 
-  /* Determine the "ultimate origin" of this block.  This block may be an
-     inlined instance of an inlined instance of inline function, so we have
-     to trace all of the way back through the origin chain to find out what
-     sort of node actually served as the original seed for the creation of
-     the current block.  */
-  origin = block_ultimate_origin (stmt);
-  origin_code = (origin != NULL) ? TREE_CODE (origin) : ERROR_MARK;
-
   /* Determine if we need to output any Dwarf DIEs at all to represent this
      block.  */
-  if (origin_code == FUNCTION_DECL)
+  if (inlined_func)
     /* The outer scopes for inlinings *must* always be represented.  We
        generate DW_TAG_inlined_subroutine DIEs for them.  (See below.) */
     must_output_die = 1;
   else
     {
-      /* In the case where the current block represents an inlining of the
-        "body block" of an inline function, we must *NOT* output any DIE for
-        this block because we have already output a DIE to represent the whole
-        inlined function scope and the "body block" of any function doesn't
-        really represent a different scope according to ANSI C rules.  So we
-        check here to make sure that this block does not represent a "body
-        block inlining" before trying to set the MUST_OUTPUT_DIE flag.  */
-      if (! is_body_block (origin ? origin : stmt))
-       {
-         /* Determine if this block directly contains any "significant"
-            local declarations which we will need to output DIEs for.  */
-         if (debug_info_level > DINFO_LEVEL_TERSE)
-           /* We are not in terse mode so *any* local declaration counts
-              as being a "significant" one.  */
-           must_output_die = (BLOCK_VARS (stmt) != NULL
-                              && (TREE_USED (stmt)
-                                  || TREE_ASM_WRITTEN (stmt)
-                                  || BLOCK_ABSTRACT (stmt)));
-         else
-           /* We are in terse mode, so only local (nested) function
-              definitions count as "significant" local declarations.  */
-           for (decl = BLOCK_VARS (stmt);
-                decl != NULL; decl = TREE_CHAIN (decl))
-             if (TREE_CODE (decl) == FUNCTION_DECL
-                 && DECL_INITIAL (decl))
-               {
-                 must_output_die = 1;
-                 break;
-               }
-       }
+      /* Determine if this block directly contains any "significant"
+        local declarations which we will need to output DIEs for.  */
+      if (debug_info_level > DINFO_LEVEL_TERSE)
+       /* We are not in terse mode so *any* local declaration counts
+          as being a "significant" one.  */
+       must_output_die = (BLOCK_VARS (stmt) != NULL
+                          && (TREE_USED (stmt)
+                              || TREE_ASM_WRITTEN (stmt)
+                              || BLOCK_ABSTRACT (stmt)));
+      else
+       /* We are in terse mode, so only local (nested) function
+          definitions count as "significant" local declarations.  */
+       for (decl = BLOCK_VARS (stmt);
+            decl != NULL; decl = TREE_CHAIN (decl))
+         if (TREE_CODE (decl) == FUNCTION_DECL
+             && DECL_INITIAL (decl))
+           {
+             must_output_die = 1;
+             break;
+           }
     }
 
   /* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
@@ -14939,7 +14893,7 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
      instances and local (nested) function definitions.  */
   if (must_output_die)
     {
-      if (origin_code == FUNCTION_DECL)
+      if (inlined_func)
        gen_inlined_subroutine_die (stmt, context_die, depth);
       else
        gen_lexical_block_die (stmt, context_die, depth);
index 9c85b58..f9f8cde 100644 (file)
@@ -97,7 +97,6 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
 #define LANG_HOOKS_STATICP             lhd_staticp
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
 #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
-#define LANG_HOOKS_NO_BODY_BLOCKS      false
 #define LANG_HOOKS_PRINT_STATISTICS    lhd_do_nothing
 #define LANG_HOOKS_PRINT_XNODE         lhd_print_tree_nothing
 #define LANG_HOOKS_PRINT_DECL          lhd_print_tree_nothing
@@ -246,7 +245,6 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_STATICP, \
   LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
   LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, \
-  LANG_HOOKS_NO_BODY_BLOCKS, \
   LANG_HOOKS_PRINT_STATISTICS, \
   LANG_HOOKS_PRINT_XNODE, \
   LANG_HOOKS_PRINT_DECL, \
index 752ad99..52d1f24 100644 (file)
@@ -317,11 +317,6 @@ struct lang_hooks
      assembler does not talk about it.  */
   void (*set_decl_assembler_name) (tree);
 
-  /* Nonzero if this front end does not generate a dummy BLOCK between
-     the outermost scope of the function and the FUNCTION_DECL.  See
-     is_body_block in stmt.c, and its callers.  */
-  bool no_body_blocks;
-
   /* The front end can add its own statistics to -fmem-report with
      this hook.  It should output to stderr.  */
   void (*print_statistics) (void);
index c536906..96e63fa 100644 (file)
@@ -1724,38 +1724,6 @@ expand_return (tree retval)
     }
 }
 \f
-/* Given a pointer to a BLOCK node return nonzero if (and only if) the node
-   in question represents the outermost pair of curly braces (i.e. the "body
-   block") of a function or method.
-
-   For any BLOCK node representing a "body block" of a function or method, the
-   BLOCK_SUPERCONTEXT of the node will point to another BLOCK node which
-   represents the outermost (function) scope for the function or method (i.e.
-   the one which includes the formal parameters).  The BLOCK_SUPERCONTEXT of
-   *that* node in turn will point to the relevant FUNCTION_DECL node.  */
-
-int
-is_body_block (const_tree stmt)
-{
-  if (lang_hooks.no_body_blocks)
-    return 0;
-
-  if (TREE_CODE (stmt) == BLOCK)
-    {
-      tree parent = BLOCK_SUPERCONTEXT (stmt);
-
-      if (parent && TREE_CODE (parent) == BLOCK)
-       {
-         tree grandparent = BLOCK_SUPERCONTEXT (parent);
-
-         if (grandparent && TREE_CODE (grandparent) == FUNCTION_DECL)
-           return 1;
-       }
-    }
-
-  return 0;
-}
-
 /* Emit code to restore vital registers at the beginning of a nonlocal goto
    handler.  */
 static void
index 106c58f..5632a89 100644 (file)
@@ -221,6 +221,11 @@ execute_build_cfg (void)
 
   build_gimple_cfg (body);
   gimple_set_body (current_function_decl, NULL);
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Scope blocks:\n");
+      dump_scope_blocks (dump_file, dump_flags);
+    }
   return 0;
 }
 
index 96c098e..3bedd35 100644 (file)
@@ -1153,6 +1153,7 @@ void compute_call_used_vars (void);
 
 /* In tree-ssa-live.c */
 extern void remove_unused_locals (void);
+extern void dump_scope_blocks (FILE *, int);
 
 /* In tree-ssa-address.c  */
 
index 81e65f7..15166cc 100644 (file)
@@ -541,8 +541,13 @@ remove_unused_scope_block_p (tree scope)
          {
            tree next = BLOCK_CHAIN (*t);
            tree supercontext = BLOCK_SUPERCONTEXT (*t);
+
            *t = BLOCK_SUBBLOCKS (*t);
-           gcc_assert (!BLOCK_CHAIN (*t));
+           while (BLOCK_CHAIN (*t))
+             {
+               BLOCK_SUPERCONTEXT (*t) = supercontext;
+               t = &BLOCK_CHAIN (*t);
+             }
            BLOCK_CHAIN (*t) = next;
            BLOCK_SUPERCONTEXT (*t) = supercontext;
            t = &BLOCK_CHAIN (*t);
@@ -556,23 +561,40 @@ remove_unused_scope_block_p (tree scope)
         t = &BLOCK_CHAIN (*t);
        nsubblocks ++;
       }
+
+
+   if (!unused)
+     ;
    /* Outer scope is always used.  */
-   if (!BLOCK_SUPERCONTEXT (scope)
-       || TREE_CODE (BLOCK_SUPERCONTEXT (scope)) == FUNCTION_DECL)
+   else if (!BLOCK_SUPERCONTEXT (scope)
+            || TREE_CODE (BLOCK_SUPERCONTEXT (scope)) == FUNCTION_DECL)
+     unused = false;
+   /* Innermost blocks with no live variables nor statements can be always
+      eliminated.  */
+   else if (!nsubblocks)
+     ;
+   /* If there are live subblocks and we still have some unused variables
+      or types declared, we must keep them.
+      Before inliing we must not depend on debug info verbosity to keep
+      DECL_UIDs stable.  */
+   else if (!cfun->after_inlining && BLOCK_VARS (scope))
      unused = false;
-   /* If there are more than one live subblocks, it is used.  */
-   else if (nsubblocks > 1)
+   /* 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)
+     ;
+   else if (BLOCK_VARS (scope))
      unused = false;
-   /* When there is only one subblock, see if it is just wrapper we can
-      ignore.  Wrappers are not declaring any variables and not changing
-      abstract origin.  */
-   else if (nsubblocks == 1
-           && (BLOCK_VARS (scope)
-               || ((debug_info_level == DINFO_LEVEL_NORMAL
-                    || debug_info_level == DINFO_LEVEL_VERBOSE)
-                   && ((BLOCK_ABSTRACT_ORIGIN (scope)
-                       != BLOCK_ABSTRACT_ORIGIN (BLOCK_SUPERCONTEXT (scope)))))))
+   /* See if this block is important for representation of inlined function.
+      Inlined functions are always represented by block with
+      block_ultimate_origin being set to FUNCTION_DECL and DECL_SOURCE_LOCATION
+      set...  */
+   else if (inlined_function_outer_scope_p (scope))
      unused = false;
+   else
+   /* Verfify that only blocks with source location set
+      are entry points to the inlined functions.  */
+     gcc_assert (BLOCK_SOURCE_LOCATION (scope) == UNKNOWN_LOCATION);
    return unused;
 }
 
@@ -592,14 +614,27 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
 {
   tree var, t;
 
-  fprintf (file, "\n%*sScope block #%i %s\n",indent, "" , BLOCK_NUMBER (scope),
-          TREE_USED (scope) ? "" : "(unused)");
-  if (BLOCK_ABSTRACT_ORIGIN (scope) && DECL_P (block_ultimate_origin (scope)))
+  fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope),
+          TREE_USED (scope) ? "" : " (unused)",
+          BLOCK_ABSTRACT (scope) ? " (abstract)": "");
+  if (BLOCK_SOURCE_LOCATION (scope) != UNKNOWN_LOCATION)
+    {
+      expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
+      fprintf (file, " %s:%i", s.file, s.line);
+    }
+  if (BLOCK_ABSTRACT_ORIGIN (scope))
     {
-      fprintf (file, "\n%*sOriginating from ",indent + 1, "");
-      print_generic_decl (file, block_ultimate_origin (scope), flags);
-      fprintf (file, "\n");
+      tree origin = block_ultimate_origin (scope);
+      if (origin)
+       {
+         fprintf (file, " Originating from :");
+         if (DECL_P (origin))
+           print_generic_decl (file, origin, flags);
+         else
+           fprintf (file, "#%i", BLOCK_NUMBER (origin));
+       }
     }
+  fprintf (file, " \n");
   for (var = BLOCK_VARS (scope); var; var = TREE_CHAIN (var))
     {
       bool used = false;
@@ -615,8 +650,14 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
     }
   for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
     dump_scope_block (file, indent + 2, t, flags);
+  fprintf (file, "\n%*s}\n",indent, "");
 }
 
+void
+dump_scope_blocks (FILE *file, int flags)
+{
+  dump_scope_block (file, 0, DECL_INITIAL (current_function_decl), flags);
+}
 
 /* Remove local variables that are not referenced in the IL.  */
 
@@ -760,7 +801,7 @@ remove_unused_locals (void)
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "Scope blocks after cleanups:\n");
-      dump_scope_block (dump_file, 0, DECL_INITIAL (current_function_decl), false);
+      dump_scope_blocks (dump_file, dump_flags);
     }
 }
 
index ae42913..1e86bf9 100644 (file)
@@ -1324,8 +1324,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 
 /* Used in classes in C++.  */
 #define TREE_PRIVATE(NODE) ((NODE)->base.private_flag)
-/* Used in classes in C++.
-   In a BLOCK node, this is BLOCK_HANDLER_BLOCK.  */
+/* Used in classes in C++. */
 #define TREE_PROTECTED(NODE) ((NODE)->base.protected_flag)
 
 /* Nonzero in a _DECL if the use of the name is defined as a
@@ -1977,11 +1976,6 @@ struct varray_head_tag;
 #define BLOCK_ABSTRACT_ORIGIN(NODE) (BLOCK_CHECK (NODE)->block.abstract_origin)
 #define BLOCK_ABSTRACT(NODE) (BLOCK_CHECK (NODE)->block.abstract_flag)
 
-/* Nonzero means that this block is prepared to handle exceptions
-   listed in the BLOCK_VARS slot.  */
-#define BLOCK_HANDLER_BLOCK(NODE) \
-  (BLOCK_CHECK (NODE)->block.handler_block_flag)
-
 /* An index number for this block.  These values are not guaranteed to
    be unique across functions -- whether or not they are depends on
    the debugging output format in use.  */
@@ -2022,9 +2016,8 @@ struct tree_block GTY(())
 {
   struct tree_common common;
 
-  unsigned handler_block_flag : 1;
   unsigned abstract_flag : 1;
-  unsigned block_num : 30;
+  unsigned block_num : 31;
 
   location_t locus;
 
@@ -4657,6 +4650,14 @@ function_args_iter_next (function_args_iterator *i)
   i->next = TREE_CHAIN (i->next);
 }
 
+/* We set BLOCK_SOURCE_LOCATION only to inlined function entry points.  */
+
+static inline bool
+inlined_function_outer_scope_p (const_tree block)
+{
+ return BLOCK_SOURCE_LOCATION (block) != UNKNOWN_LOCATION;
+}
+
 /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
    to point to the next tree element.  ITER is an instance of
    function_args_iterator used to iterate the arguments.  */
@@ -4710,7 +4711,6 @@ extern void expand_goto (tree);
 extern rtx expand_stack_save (void);
 extern void expand_stack_restore (tree);
 extern void expand_return (tree);
-extern int is_body_block (const_tree);
 
 /* In tree-eh.c */
 extern void using_eh_for_cleanups (void);