diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3ec03fc5b70..c14d3c392fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2009-11-18 Jakub Jelinek + * dwarf2out.c (loc_list_from_tree): Don't call rtl_for_decl_location + unnecessarily. + (rtl_for_decl_location): Try harder to get a rtl for TREE_STATIC vars. + PR c++/3187 * cgraph.h (struct cgraph_node): Add same_body and same_body_alias fields. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 2ebe0ae522b..3db2092b4ee 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -14309,13 +14309,17 @@ loc_list_from_tree (tree loc, int want_address) case RESULT_DECL: case FUNCTION_DECL: { - rtx rtl = rtl_for_decl_location (loc); + rtx rtl; var_loc_list *loc_list = lookup_decl_loc (loc); if (loc_list && loc_list->first && (list_ret = dw_loc_list (loc_list, loc, want_address))) - have_address = want_address != 0; - else if (rtl == NULL_RTX) + { + have_address = want_address != 0; + break; + } + rtl = rtl_for_decl_location (loc); + if (rtl == NULL_RTX) { expansion_failed (loc, NULL_RTX, "DECL has no RTL"); return 0; @@ -15605,6 +15609,27 @@ rtl_for_decl_location (tree decl) if (rtl) rtl = avoid_constant_pool_reference (rtl); + /* Try harder to get a rtl. If this symbol ends up not being emitted + in the current CU, resolve_addr will remove the expression referencing + it. */ + if (rtl == NULL_RTX + && TREE_CODE (decl) == VAR_DECL + && !DECL_EXTERNAL (decl) + && TREE_STATIC (decl) + && DECL_NAME (decl) + && !DECL_HARD_REGISTER (decl) + && DECL_MODE (decl) != VOIDmode) + { + rtl = DECL_RTL (decl); + /* Reset DECL_RTL back, as various parts of the compiler expects + DECL_RTL set meaning it is actually going to be output. */ + SET_DECL_RTL (decl, NULL); + if (!MEM_P (rtl) + || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF + || SYMBOL_REF_DECL (XEXP (rtl, 0)) != decl) + rtl = NULL_RTX; + } + return rtl; }