diff options
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 157 |
1 files changed, 150 insertions, 7 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index cdc70258c29..9961332947e 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -248,6 +248,15 @@ typedef struct dw_fde_struct GTY(()) const char *dw_fde_end; dw_cfi_ref dw_fde_cfi; unsigned funcdef_number; + /* APPLE LOCAL begin coalescing */ + const char *dw_real_name; + /* Is this symbol coalesced? */ + unsigned coalesced : 1; + /* Is this symbol an explicit instantiation? */ + unsigned explicit : 1; + unsigned public : 1; + unsigned private_extern : 1; + /* APPLE LOCAL end coalescing */ unsigned all_throwers_are_sibcalls : 1; unsigned nothrow : 1; unsigned uses_eh_lsda : 1; @@ -391,7 +400,9 @@ static void def_cfa_1 (const char *, dw_cfa_location *); #define FUNC_END_LABEL "LFE" #endif +#ifndef FRAME_BEGIN_LABEL #define FRAME_BEGIN_LABEL "Lframe" +#endif #define CIE_AFTER_SIZE_LABEL "LSCIE" #define CIE_END_LABEL "LECIE" #define FDE_LABEL "LSFDE" @@ -1589,9 +1600,100 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label) case PLUS: case MINUS: case LO_SUM: - if (GET_CODE (XEXP (XEXP (dest, 0), 1)) != CONST_INT) + /* APPLE LOCAL begin 'reg + index' reg case. */ + /* MERGE fixme 3537126 */ + offset = 0x696b6c6c; + if (GET_CODE (XEXP (XEXP (dest, 0), 1)) == CONST_INT) + offset = INTVAL (XEXP (XEXP (dest, 0), 1)); +#if 1 + /* If it's a 'reg + index', we need to find out what value + the index reg has at this point. (This can happen because + some architectures have registers which can only be stored + using a "reg + index" mode.) + This method of finding out the index value is VERY FRAGILE. + Ideally we'd try to add a note to the save insn, but... */ + else if (GET_CODE (XEXP (XEXP (dest, 0), 1)) == REG) + { + unsigned the_reg = REGNO (XEXP (XEXP (dest, 0), 1)); + rtx insn; + + /* The REG_FRAME_RELATED_EXPR can sometimes be out-of-date + after the optimiser/inliner has done its stuff. For example, + + (insn: (set (mem:V16QI (plus:SI (reg/f:SI 1 r1) + (reg:SI 6 r6)) [0 S16 A8]) + (reg:V16QI 108 v31)) + ... + (expr_list:REG_FRAME_RELATED_EXPR + (set (mem:V16QI (plus:SI (reg/f:SI 1 r1) + (reg:SI 0 r0)) [0 S16 A8]) + (reg:V16QI 108 v31)) + + Note that the optimiser has used R6 instead of the original + R0 to store the SP offset. Alas, we blindly look for R0 + here, since DEST is the REG_FRAME_RELATED_EXPR, so we need + to check for that. + + This needs a rework from scratch, but it'll do for now. */ + + insn = XEXP (XEXP (XEXP (PATTERN (current_output_insn), + 0), 0), 1); + if (GET_CODE (insn) == REG) + the_reg = REGNO (insn); + + insn = PREV_INSN (current_output_insn); + for (; insn != NULL; insn = PREV_INSN (insn)) + { + if (GET_CODE (insn) != INSN + || PATTERN (insn) == NULL) + ; + else if (GET_CODE (PATTERN (insn)) == SET) + { + rtx p = PATTERN (insn); + if (SET_DEST (p) != NULL + && GET_CODE (SET_DEST (p)) == REG + && REGNO (SET_DEST (p)) == the_reg) + { + if (GET_CODE (SET_SRC (p)) == CONST_INT) + { + offset = INTVAL (SET_SRC (p)); + break; + } + else + abort (); + } + } + else + /* A label? All bets are off. */ + if (GET_CODE (PATTERN (insn)) == CODE_LABEL) + abort (); + } + + /* DEST can also be something like: + + (mem:V16QI (plus:SI (plus:SI (reg/f:SI 1 r1) + (const_int 147792 [0x24150])) + (reg:SI 0 r0)) [0 S16 A8]) + + This is handled here by adjusting the offset appropriately. */ + + insn = XEXP (XEXP (dest, 0), 0); + if (GET_CODE (insn) == PLUS && GET_CODE (XEXP (insn, 0)) == REG + && GET_CODE (XEXP (insn, 1)) == CONST_INT) + { + offset += INTVAL (XEXP (insn, 1)); + + /* Set DEST to be the inner PLUS so that + REGNO (XEXP (XEXP (dest, 0), 0) will be sensible. */ + + dest = XEXP (dest, 0); + } + } +#endif + else abort (); - offset = INTVAL (XEXP (XEXP (dest, 0), 1)); + /* APPLE LOCAL end 'reg + index' case. */ + if (GET_CODE (XEXP (dest, 0)) == MINUS) offset = -offset; @@ -2004,7 +2106,11 @@ output_call_frame_info (int for_eh) P Indicates the presence of an encoding + language personality routine in the CIE augmentation. */ - fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0); + /* APPLE LOCAL coalescing */ + fde_encoding = flag_export_coalesced + ? ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1) + : ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0); + /* APPLE LOCAL end coalescing */ per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1); lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); @@ -2098,6 +2204,19 @@ output_call_frame_info (int for_eh) && !fde->uses_eh_lsda) continue; + /* APPLE LOCAL begin coalescing */ +#ifdef COALESCED_UNWIND_INFO + ASM_OUTPUT_COAL_UNWIND_LABEL (asm_out_file, fde->dw_real_name, + fde->coalesced, + fde->public && !fde->private_extern, + fde->coalesced + || fde->public + || fde->private_extern + || fde->explicit, + for_eh); +#endif + /* APPLE LOCAL end coalescing */ + (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2); ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2); @@ -2113,6 +2232,15 @@ output_call_frame_info (int for_eh) if (for_eh) { + /* APPLE LOCAL begin coalescing */ +#ifdef COALESCED_UNWIND_INFO + if (fde->coalesced) + dw2_asm_output_encoded_addr_rtx (fde_encoding, + gen_rtx_SYMBOL_REF (Pmode, fde->dw_real_name), + "FDE initial location"); + else +#endif + /* APPLE LOCAL end coalescing */ dw2_asm_output_encoded_addr_rtx (fde_encoding, gen_rtx_SYMBOL_REF (Pmode, fde->dw_fde_begin), "FDE initial location"); @@ -2257,6 +2385,22 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, fde->uses_eh_lsda = cfun->uses_eh_lsda; fde->all_throwers_are_sibcalls = cfun->all_throwers_are_sibcalls; + /* APPLE LOCAL begin coalescing */ +#ifdef COALESCED_UNWIND_INFO + fde->coalesced = DECL_COALESCED (current_function_decl); + /* Sorry about this hackery: this is the only way I can figure out + whether this is an explicit template instantiation. Ick. + DECL_LANG_FLAG_1 is DECL_TEMPLATE_INSTANTIATED in cp-tree.h. */ + fde->explicit = !fde->coalesced && TREE_PUBLIC (current_function_decl) + && (strstr (lang_hooks.name, "C++") != NULL) + && DECL_LANG_FLAG_1 (current_function_decl); + fde->dw_real_name = xstrdup (IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (current_function_decl))); + fde->public = TREE_PUBLIC(current_function_decl); + fde->private_extern = DECL_VISIBILITY(current_function_decl) == VISIBILITY_HIDDEN; +#endif + /* APPLE LOCAL end coalescing */ + args_size = old_args_size = 0; /* We only want to output line number information for the genuine dwarf2 @@ -3286,6 +3430,9 @@ const struct gcc_debug_hooks dwarf2_debug_hooks = dwarf2out_abstract_function, /* outlining_inline_function */ debug_nothing_rtx, /* label */ debug_nothing_int, /* handle_pch */ + /* APPLE LOCAL begin Symbol Separation */ + NULL, NULL, NULL, NULL, + /* APPLE LOCAL end Symbol Separation */ dwarf2out_var_location }; #endif @@ -3489,7 +3636,6 @@ struct var_loc_node GTY ((chain_next ("%h.next"))) const char * GTY (()) label; struct var_loc_node * GTY (()) next; }; - /* Variable location list. */ struct var_loc_list_def GTY (()) { @@ -3504,7 +3650,6 @@ struct var_loc_list_def GTY (()) }; typedef struct var_loc_list_def var_loc_list; - /* Table of decl location linked lists. */ static GTY ((param_is (var_loc_list))) htab_t decl_loc_table; @@ -5314,7 +5459,6 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die) } /* Add a variable location node to the linked list for DECL. */ - static void add_var_loc_to_decl (tree decl, struct var_loc_node *loc) { @@ -7997,7 +8141,6 @@ subrange_type_die (tree type, dw_die_ref context_die) subtype_die = gen_enumeration_type_die (TREE_TYPE (type), context_die); else subtype_die = base_type_die (TREE_TYPE (type)); - subrange_die = new_die (DW_TAG_subrange_type, context_die, type); if (name != NULL) |