2005-08-10 Jakub Jelinek * dwarf2out.c (concat_loc_descriptor): Add can_use_fbreg argument, pass it down to loc_descriptor. (loc_descriptor): Pass can_use_fbreg to concat_loc_descriptor. (containing_function_has_frame_base): Move earlier in the file. (loc_descriptor_from_tree_1): Use containing_function_has_frame_base instead of always assuming fbreg can't be used. --- gcc/dwarf2out.c.jj 2005-08-06 10:39:55.000000000 +0200 +++ gcc/dwarf2out.c 2005-08-10 10:23:26.000000000 +0200 @@ -3982,7 +3982,7 @@ static dw_loc_descr_ref int_loc_descript static dw_loc_descr_ref based_loc_descr (unsigned, HOST_WIDE_INT, bool); static int is_based_loc (rtx); static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode, bool); -static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx); +static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx, bool); static dw_loc_descr_ref loc_descriptor (rtx, bool); static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int); static dw_loc_descr_ref loc_descriptor_from_tree (tree); @@ -8806,11 +8806,11 @@ mem_loc_descriptor (rtx rtl, enum machin This is typically a complex variable. */ static dw_loc_descr_ref -concat_loc_descriptor (rtx x0, rtx x1) +concat_loc_descriptor (rtx x0, rtx x1, bool can_use_fbreg) { dw_loc_descr_ref cc_loc_result = NULL; - dw_loc_descr_ref x0_ref = loc_descriptor (x0, false); - dw_loc_descr_ref x1_ref = loc_descriptor (x1, false); + dw_loc_descr_ref x0_ref = loc_descriptor (x0, can_use_fbreg); + dw_loc_descr_ref x1_ref = loc_descriptor (x1, can_use_fbreg); if (x0_ref == 0 || x1_ref == 0) return 0; @@ -8824,6 +8824,29 @@ concat_loc_descriptor (rtx x0, rtx x1) return cc_loc_result; } +/* Return true if DECL's containing function has a frame base attribute. + Return false otherwise. */ + +static bool +containing_function_has_frame_base (tree decl) +{ + tree declcontext = decl_function_context (decl); + dw_die_ref context; + dw_attr_ref attr; + + if (!declcontext) + return false; + + context = lookup_decl_die (declcontext); + if (!context) + return false; + + for (attr = context->die_attr; attr; attr = attr->dw_attr_next) + if (attr->dw_attr == DW_AT_frame_base) + return true; + return false; +} + /* Output a proper Dwarf location descriptor for a variable or parameter which is either allocated in a register or in a memory location. For a register, we just generate an OP_REG and the register number. For a @@ -8859,7 +8882,8 @@ loc_descriptor (rtx rtl, bool can_use_fb break; case CONCAT: - loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1)); + loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1), + can_use_fbreg); break; case VAR_LOCATION: @@ -9019,10 +9043,11 @@ loc_descriptor_from_tree_1 (tree loc, in else { enum machine_mode mode; + bool can_use_fb = containing_function_has_frame_base (loc); /* Certain constructs can only be represented at top-level. */ if (want_address == 2) - return loc_descriptor (rtl, false); + return loc_descriptor (rtl, can_use_fb); mode = GET_MODE (rtl); if (MEM_P (rtl)) @@ -9030,7 +9055,7 @@ loc_descriptor_from_tree_1 (tree loc, in rtl = XEXP (rtl, 0); have_address = 1; } - ret = mem_loc_descriptor (rtl, mode, false); + ret = mem_loc_descriptor (rtl, mode, can_use_fb); } } break; @@ -9104,12 +9129,14 @@ loc_descriptor_from_tree_1 (tree loc, in /* Get an RTL for this, if something has been emitted. */ rtx rtl = lookup_constant_def (loc); enum machine_mode mode; + bool can_use_fb; if (!rtl || !MEM_P (rtl)) return 0; + can_use_fb = containing_function_has_frame_base (loc); mode = GET_MODE (rtl); rtl = XEXP (rtl, 0); - ret = mem_loc_descriptor (rtl, mode, false); + ret = mem_loc_descriptor (rtl, mode, can_use_fb); have_address = 1; break; } @@ -10073,29 +10100,6 @@ rtl_for_decl_location (tree decl) return rtl; } -/* Return true if DECL's containing function has a frame base attribute. - Return false otherwise. */ - -static bool -containing_function_has_frame_base (tree decl) -{ - tree declcontext = decl_function_context (decl); - dw_die_ref context; - dw_attr_ref attr; - - if (!declcontext) - return false; - - context = lookup_decl_die (declcontext); - if (!context) - return false; - - for (attr = context->die_attr; attr; attr = attr->dw_attr_next) - if (attr->dw_attr == DW_AT_frame_base) - return true; - return false; -} - /* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value data attribute for a variable or a parameter. We generate the DW_AT_const_value attribute only in those cases where the given variable