diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 116 |
2 files changed, 71 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a3d521e43cb..3a04aaf9506 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-09-03 Richard Biener <rguenther@suse.de> + + * dwarf2out.c (flush_limbo_die_list): Split out from ... + (dwarf2out_early_finish): ... here. + (dwarf2out_finish): Do not call dwarf2out_early_finish but + flush_limbo_die_list. Assert we have no deferred asm names. + 2015-09-03 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * optabs.c (expand_binop): Don't create a broadcast vector with a diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index d9d3063be1d..b6ab869e0d1 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -25127,6 +25127,62 @@ optimize_location_lists (dw_die_ref die) optimize_location_lists_1 (die, &htab); } +/* Traverse the limbo die list, and add parent/child links. The only + dies without parents that should be here are concrete instances of + inline functions, and the comp_unit_die. We can ignore the comp_unit_die. + For concrete instances, we can get the parent die from the abstract + instance. */ + +static void +flush_limbo_die_list (void) +{ + limbo_die_node *node, *next_node; + + for (node = limbo_die_list; node; node = next_node) + { + dw_die_ref die = node->die; + next_node = node->next; + + if (die->die_parent == NULL) + { + dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); + + if (origin && origin->die_parent) + add_child_die (origin->die_parent, die); + else if (is_cu_die (die)) + ; + else if (seen_error ()) + /* It's OK to be confused by errors in the input. */ + add_child_die (comp_unit_die (), die); + else + { + /* In certain situations, the lexical block containing a + nested function can be optimized away, which results + in the nested function die being orphaned. Likewise + with the return type of that nested function. Force + this to be a child of the containing function. + + It may happen that even the containing function got fully + inlined and optimized out. In that case we are lost and + assign the empty child. This should not be big issue as + the function is likely unreachable too. */ + gcc_assert (node->created_for); + + if (DECL_P (node->created_for)) + origin = get_context_die (DECL_CONTEXT (node->created_for)); + else if (TYPE_P (node->created_for)) + origin = scope_die_for (node->created_for, comp_unit_die ()); + else + origin = comp_unit_die (); + + add_child_die (origin, die); + } + } + } + + limbo_die_list = NULL; +} + /* Output stuff that dwarf requires at the end of every file, and generate the DWARF-2 debugging info. */ @@ -25137,7 +25193,11 @@ dwarf2out_finish (const char *filename) dw_die_ref main_comp_unit_die; /* Flush out any latecomers to the limbo party. */ - dwarf2out_early_finish (); + flush_limbo_die_list (); + + /* We shouldn't have any symbols with delayed asm names for + DIEs generated after early finish. */ + gcc_assert (deferred_asm_name == NULL); /* PCH might result in DW_AT_producer string being restored from the header compilation, so always fill it with empty string initially @@ -25483,7 +25543,7 @@ dwarf2out_finish (const char *filename) static void dwarf2out_early_finish (void) { - limbo_die_node *node, *next_node; + limbo_die_node *node; /* Add DW_AT_linkage_name for all deferred DIEs. */ for (node = deferred_asm_name; node; node = node->next) @@ -25501,57 +25561,9 @@ dwarf2out_early_finish (void) } deferred_asm_name = NULL; - /* Traverse the limbo die list, and add parent/child links. The only - dies without parents that should be here are concrete instances of - inline functions, and the comp_unit_die. We can ignore the comp_unit_die. - For concrete instances, we can get the parent die from the abstract - instance. - - The point here is to flush out the limbo list so that it is empty + /* The point here is to flush out the limbo list so that it is empty and we don't need to stream it for LTO. */ - for (node = limbo_die_list; node; node = next_node) - { - dw_die_ref die = node->die; - next_node = node->next; - - if (die->die_parent == NULL) - { - dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin); - - if (origin && origin->die_parent) - add_child_die (origin->die_parent, die); - else if (is_cu_die (die)) - ; - else if (seen_error ()) - /* It's OK to be confused by errors in the input. */ - add_child_die (comp_unit_die (), die); - else - { - /* In certain situations, the lexical block containing a - nested function can be optimized away, which results - in the nested function die being orphaned. Likewise - with the return type of that nested function. Force - this to be a child of the containing function. - - It may happen that even the containing function got fully - inlined and optimized out. In that case we are lost and - assign the empty child. This should not be big issue as - the function is likely unreachable too. */ - gcc_assert (node->created_for); - - if (DECL_P (node->created_for)) - origin = get_context_die (DECL_CONTEXT (node->created_for)); - else if (TYPE_P (node->created_for)) - origin = scope_die_for (node->created_for, comp_unit_die ()); - else - origin = comp_unit_die (); - - add_child_die (origin, die); - } - } - } - - limbo_die_list = NULL; + flush_limbo_die_list (); } /* Reset all state within dwarf2out.c so that we can rerun the compiler |