#include "input.h"
#ifdef DWARF2_DEBUGGING_INFO
-static void dwarf2out_source_line (unsigned int, const char *, int);
+static void dwarf2out_source_line (unsigned int, const char *, int, bool);
static rtx last_var_location_insn;
#endif
unsigned stack_realign : 1;
/* Whether dynamic realign argument pointer register has been saved. */
unsigned drap_reg_saved: 1;
+ /* True iff dw_fde_begin label is in text_section or cold_text_section. */
+ unsigned in_std_section : 1;
+ /* True iff dw_fde_unlikely_section_label is in text_section or
+ cold_text_section. */
+ unsigned cold_in_std_section : 1;
}
dw_fde_node;
the CFA register did not change but the offset did. The data
factoring for DW_CFA_def_cfa_offset_sf happens in output_cfi, or
in the assembler via the .cfi_def_cfa_offset directive. */
- if (need_data_align_sf_opcode (loc.offset))
+ if (loc.offset < 0)
cfi->dw_cfi_opc = DW_CFA_def_cfa_offset_sf;
else
cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
the specified offset. The data factoring for DW_CFA_def_cfa_sf
happens in output_cfi, or in the assembler via the .cfi_def_cfa
directive. */
- if (need_data_align_sf_opcode (loc.offset))
+ if (loc.offset < 0)
cfi->dw_cfi_opc = DW_CFA_def_cfa_sf;
else
cfi->dw_cfi_opc = DW_CFA_def_cfa;
/* The return address is at some offset from any value we can
actually load. For instance, on the SPARC it is in %i7+8. Just
ignore the offset for now; it doesn't matter for unwinding frames. */
- gcc_assert (GET_CODE (XEXP (rtl, 1)) == CONST_INT);
+ gcc_assert (CONST_INT_P (XEXP (rtl, 1)));
initial_return_save (XEXP (rtl, 0));
return;
if (! (code == PLUS || code == MINUS)
|| XEXP (src, 0) != stack_pointer_rtx
- || GET_CODE (XEXP (src, 1)) != CONST_INT)
+ || !CONST_INT_P (XEXP (src, 1)))
return 0;
/* (set (reg sp) (plus (reg sp) (const_int))) */
rtx val = XEXP (XEXP (src, 1), 1);
/* We handle only adjustments by constant amount. */
gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS
- && GET_CODE (val) == CONST_INT);
+ && CONST_INT_P (val));
offset = -INTVAL (val);
break;
}
fde = current_fde ();
- if (GET_CODE (src) == REG
+ if (REG_P (src)
&& fde
&& fde->drap_reg == REGNO (src)
&& (fde->drap_reg_saved
- || GET_CODE (dest) == REG))
+ || REG_P (dest)))
{
/* Rule 20 */
/* If we are saving dynamic realign argument pointer to a
register, the destination is virtual dynamic realign
argument pointer. It may be used to access argument. */
- if (GET_CODE (dest) == REG)
+ if (REG_P (dest))
{
gcc_assert (fde->vdrap_reg == INVALID_REGNUM);
fde->vdrap_reg = REGNO (dest);
gcc_assert (REG_P (XEXP (src, 0))
&& (unsigned) REGNO (XEXP (src, 0)) == cfa.reg
- && GET_CODE (XEXP (src, 1)) == CONST_INT);
+ && CONST_INT_P (XEXP (src, 1)));
offset = INTVAL (XEXP (src, 1));
if (GET_CODE (src) != MINUS)
offset = -offset;
/* Rule 4 */
if (REG_P (XEXP (src, 0))
&& REGNO (XEXP (src, 0)) == cfa.reg
- && GET_CODE (XEXP (src, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (src, 1)))
{
/* Setting a temporary CFA register that will be copied
into the FP later on. */
/* Rule 9 */
else if (GET_CODE (src) == LO_SUM
- && GET_CODE (XEXP (src, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (src, 1)))
{
cfa_temp.reg = REGNO (dest);
cfa_temp.offset = INTVAL (XEXP (src, 1));
case IOR:
gcc_assert (REG_P (XEXP (src, 0))
&& (unsigned) REGNO (XEXP (src, 0)) == cfa_temp.reg
- && GET_CODE (XEXP (src, 1)) == CONST_INT);
+ && CONST_INT_P (XEXP (src, 1)));
if ((unsigned) REGNO (dest) != cfa_temp.reg)
cfa_temp.reg = REGNO (dest);
{
int regno;
- gcc_assert (GET_CODE (XEXP (XEXP (dest, 0), 1)) == CONST_INT
+ gcc_assert (CONST_INT_P (XEXP (XEXP (dest, 0), 1))
&& REG_P (XEXP (XEXP (dest, 0), 0)));
offset = INTVAL (XEXP (XEXP (dest, 0), 1));
if (GET_CODE (XEXP (dest, 0)) == MINUS)
if (CALL_P (i) && SIBLING_CALL_P (i))
break;
+ if (GET_CODE (PATTERN (i)) == SEQUENCE)
+ {
+ int idx;
+ rtx seq = PATTERN (i);
+
+ if (returnjump_p (XVECEXP (seq, 0, 0)))
+ break;
+ if (CALL_P (XVECEXP (seq, 0, 0))
+ && SIBLING_CALL_P (XVECEXP (seq, 0, 0)))
+ break;
+
+ for (idx = 0; idx < XVECLEN (seq, 0); idx++)
+ if (RTX_FRAME_RELATED_P (XVECEXP (seq, 0, idx)))
+ saw_frp = true;
+ }
+
if (RTX_FRAME_RELATED_P (i))
saw_frp = true;
}
char label[MAX_ARTIFICIAL_LABEL_BYTES];
char * dup_label;
dw_fde_ref fde;
+ section *fnsec;
current_function_func_begin_label = NULL;
return;
#endif
- switch_to_section (function_section (current_function_decl));
+ fnsec = function_section (current_function_decl);
+ switch_to_section (fnsec);
ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
current_function_funcdef_no);
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, FUNC_BEGIN_LABEL,
fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
fde->drap_reg = INVALID_REGNUM;
fde->vdrap_reg = INVALID_REGNUM;
+ if (flag_reorder_blocks_and_partition)
+ {
+ section *unlikelysec;
+ if (first_function_block_is_cold)
+ fde->in_std_section = 1;
+ else
+ fde->in_std_section
+ = (fnsec == text_section
+ || (cold_text_section && fnsec == cold_text_section));
+ unlikelysec = unlikely_text_section ();
+ fde->cold_in_std_section
+ = (unlikelysec == text_section
+ || (cold_text_section && unlikelysec == cold_text_section));
+ }
+ else
+ {
+ fde->in_std_section
+ = (fnsec == text_section
+ || (cold_text_section && fnsec == cold_text_section));
+ fde->cold_in_std_section = 0;
+ }
args_size = old_args_size = 0;
prologue case, not the eh frame case. */
#ifdef DWARF2_DEBUGGING_INFO
if (file)
- dwarf2out_source_line (line, file, 0);
+ dwarf2out_source_line (line, file, 0, true);
#endif
if (dwarf2out_do_cfi_asm ())
typedef struct GTY(()) dw_loc_descr_struct {
dw_loc_descr_ref dw_loc_next;
- enum dwarf_location_atom dw_loc_opc;
+ ENUM_BITFIELD (dwarf_location_atom) dw_loc_opc : 8;
+ /* Used to distinguish DW_OP_addr with a direct symbol relocation
+ from DW_OP_addr with a dtp-relative symbol relocation. */
+ unsigned int dtprel : 1;
int dw_loc_addr;
dw_val_node dw_loc_oprnd1;
dw_val_node dw_loc_oprnd2;
switch (op)
{
case DW_OP_addr:
- case INTERNAL_DW_OP_tls_addr:
return "DW_OP_addr";
case DW_OP_deref:
return "DW_OP_deref";
switch (loc->dw_loc_opc)
{
case DW_OP_addr:
- case INTERNAL_DW_OP_tls_addr:
size += DWARF2_ADDR_SIZE;
break;
case DW_OP_const1u:
switch (loc->dw_loc_opc)
{
#ifdef DWARF2_DEBUGGING_INFO
- case DW_OP_addr:
- dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, val1->v.val_addr, NULL);
- break;
case DW_OP_const2u:
case DW_OP_const2s:
dw2_asm_output_data (2, val1->v.val_int, NULL);
}
break;
#else
- case DW_OP_addr:
case DW_OP_const2u:
case DW_OP_const2s:
case DW_OP_const4u:
dw2_asm_output_data (1, val1->v.val_int, NULL);
break;
- case INTERNAL_DW_OP_tls_addr:
- if (targetm.asm_out.output_dwarf_dtprel)
+ case DW_OP_addr:
+ if (loc->dtprel)
{
- targetm.asm_out.output_dwarf_dtprel (asm_out_file,
- DWARF2_ADDR_SIZE,
- val1->v.val_addr);
- fputc ('\n', asm_out_file);
+ if (targetm.asm_out.output_dwarf_dtprel)
+ {
+ targetm.asm_out.output_dwarf_dtprel (asm_out_file,
+ DWARF2_ADDR_SIZE,
+ val1->v.val_addr);
+ fputc ('\n', asm_out_file);
+ }
+ else
+ gcc_unreachable ();
}
else
- gcc_unreachable ();
+ {
+#ifdef DWARF2_DEBUGGING_INFO
+ dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, val1->v.val_addr, NULL);
+#else
+ gcc_unreachable ();
+#endif
+ }
break;
default:
dw2_asm_output_data_sleb128_raw (val2->v.val_int);
break;
- case INTERNAL_DW_OP_tls_addr:
- gcc_unreachable ();
-
default:
/* Other codes have no operands. */
break;
static inline void
loc_checksum (dw_loc_descr_ref loc, struct md5_ctx *ctx)
{
- CHECKSUM (loc->dw_loc_opc);
+ int tem;
+
+ tem = (loc->dtprel << 8) | ((unsigned int) loc->dw_loc_opc);
+ CHECKSUM (tem);
CHECKSUM (loc->dw_loc_oprnd1);
CHECKSUM (loc->dw_loc_oprnd2);
}
is aligned without drap, use stack pointer + offset to
access stack variables. */
if (crtl->stack_realign_tried
- && cfa.reg == HARD_FRAME_POINTER_REGNUM
&& reg == frame_pointer_rtx)
{
int base_reg
- = DWARF_FRAME_REGNUM (cfa.indirect
+ = DWARF_FRAME_REGNUM ((fde && fde->drap_reg != INVALID_REGNUM)
? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM);
return new_reg_loc_descr (base_reg, offset);
return (GET_CODE (rtl) == PLUS
&& ((REG_P (XEXP (rtl, 0))
&& REGNO (XEXP (rtl, 0)) < FIRST_PSEUDO_REGISTER
- && GET_CODE (XEXP (rtl, 1)) == CONST_INT)));
+ && CONST_INT_P (XEXP (rtl, 1)))));
}
/* Return a descriptor that describes the concatenation of N locations
if (mem_loc_result == 0)
break;
- if (GET_CODE (XEXP (rtl, 1)) == CONST_INT)
+ if (CONST_INT_P (XEXP (rtl, 1)))
loc_descr_plus_const (&mem_loc_result, INTVAL (XEXP (rtl, 1)));
else
{
rtx rtl;
enum dwarf_location_atom first_op;
enum dwarf_location_atom second_op;
+ bool dtprel = false;
if (targetm.have_tls)
{
module. */
if (DECL_EXTERNAL (loc) && !targetm.binds_local_p (loc))
return 0;
- first_op = (enum dwarf_location_atom) INTERNAL_DW_OP_tls_addr;
+ first_op = DW_OP_addr;
+ dtprel = true;
second_op = DW_OP_GNU_push_tls_address;
}
else
ret = new_loc_descr (first_op, 0, 0);
ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
ret->dw_loc_oprnd1.v.val_addr = rtl;
+ ret->dtprel = dtprel;
ret1 = new_loc_descr (second_op, 0, 0);
add_loc_descr (&ret, ret1);
if (rtl == NULL_RTX)
return 0;
- else if (GET_CODE (rtl) == CONST_INT)
+ else if (CONST_INT_P (rtl))
{
HOST_WIDE_INT val = INTVAL (rtl);
if (TYPE_UNSIGNED (TREE_TYPE (loc)))
if (! loc_descr)
{
- enum dwarf_location_atom op;
-
- /* The DWARF2 standard says that we should assume that the structure
- address is already on the stack, so we can specify a structure field
- address by using DW_OP_plus_uconst. */
-
+ if (dwarf_version > 2)
+ {
+ /* Don't need to output a location expression, just the constant. */
+ add_AT_int (die, DW_AT_data_member_location, offset);
+ return;
+ }
+ else
+ {
+ enum dwarf_location_atom op;
+
+ /* The DWARF2 standard says that we should assume that the structure
+ address is already on the stack, so we can specify a structure
+ field address by using DW_OP_plus_uconst. */
+
#ifdef MIPS_DEBUGGING_INFO
- /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst
- operator correctly. It works only if we leave the offset on the
- stack. */
- op = DW_OP_constu;
+ /* ??? The SGI dwarf reader does not handle the DW_OP_plus_uconst
+ operator correctly. It works only if we leave the offset on the
+ stack. */
+ op = DW_OP_constu;
#else
- op = DW_OP_plus_uconst;
+ op = DW_OP_plus_uconst;
#endif
-
- loc_descr = new_loc_descr (op, offset, 0);
+
+ loc_descr = new_loc_descr (op, offset, 0);
+ }
}
add_AT_loc (die, DW_AT_data_member_location, loc_descr);
add_AT_flag (parm_die, DW_AT_artificial, 1);
}
- if (node)
+ if (node && node != origin)
equate_decl_number_to_die (node, parm_die);
if (! DECL_ABSTRACT (node_or_origin))
add_location_or_const_value_attribute (parm_die, node_or_origin,
static void
dwarf2out_source_line (unsigned int line, const char *filename,
- int discriminator ATTRIBUTE_UNUSED)
+ int discriminator, bool is_stmt)
{
+ static bool last_is_stmt = true;
+
if (debug_info_level >= DINFO_LEVEL_NORMAL
&& line != 0)
{
{
/* Emit the .loc directive understood by GNU as. */
fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line);
-#ifdef HAVE_GAS_DISCRIMINATOR
- if (discriminator != 0)
+ if (is_stmt != last_is_stmt)
+ {
+ fprintf (asm_out_file, " is_stmt %d", is_stmt ? 1 : 0);
+ last_is_stmt = is_stmt;
+ }
+ if (SUPPORTS_DISCRIMINATOR && discriminator != 0)
fprintf (asm_out_file, " discriminator %d", discriminator);
-#endif /* HAVE_GAS_DISCRIMINATOR */
fputc ('\n', asm_out_file);
/* Indicate that line number info exists. */
if (fde->dw_fde_switched_sections)
{
- add_ranges_by_labels (fde->dw_fde_hot_section_label,
- fde->dw_fde_hot_section_end_label);
- add_ranges_by_labels (fde->dw_fde_unlikely_section_label,
- fde->dw_fde_unlikely_section_end_label);
+ if (!fde->in_std_section)
+ add_ranges_by_labels (fde->dw_fde_hot_section_label,
+ fde->dw_fde_hot_section_end_label);
+ if (!fde->cold_in_std_section)
+ add_ranges_by_labels (fde->dw_fde_unlikely_section_label,
+ fde->dw_fde_unlikely_section_end_label);
}
- else
+ else if (!fde->in_std_section)
add_ranges_by_labels (fde->dw_fde_begin,
fde->dw_fde_end);
}
#else
/* This should never be used, but its address is needed for comparisons. */
-const struct gcc_debug_hooks dwarf2_debug_hooks;
+const struct gcc_debug_hooks dwarf2_debug_hooks =
+{
+ 0, /* init */
+ 0, /* finish */
+ 0, /* define */
+ 0, /* undef */
+ 0, /* start_source_file */
+ 0, /* end_source_file */
+ 0, /* begin_block */
+ 0, /* end_block */
+ 0, /* ignore_block */
+ 0, /* source_line */
+ 0, /* begin_prologue */
+ 0, /* end_prologue */
+ 0, /* end_epilogue */
+ 0, /* begin_function */
+ 0, /* end_function */
+ 0, /* function_decl */
+ 0, /* global_decl */
+ 0, /* type_decl */
+ 0, /* imported_module_or_decl */
+ 0, /* deferred_inline_function */
+ 0, /* outlining_inline_function */
+ 0, /* label */
+ 0, /* handle_pch */
+ 0, /* var_location */
+ 0, /* switch_text_section */
+ 0, /* set_name */
+ 0 /* start_end_main_source_file */
+};
#endif /* DWARF2_DEBUGGING_INFO */