#include "expr.h"
#include "cfglayout.h"
#include "tree-pass.h"
+#include "tree-flow.h"
#include "timevar.h"
#include "cgraph.h"
#include "coverage.h"
#endif
static void profile_function (FILE *);
static void profile_after_prologue (FILE *);
-static bool notice_source_line (rtx);
+static bool notice_source_line (rtx, bool *);
static rtx walk_alter_subreg (rtx *, bool *);
static void output_asm_name (void);
static void output_alternate_entry_point (FILE *, rtx);
return;
}
map = XNEW (debug_prefix_map);
- map->old_prefix = ggc_alloc_string (arg, p - arg);
+ map->old_prefix = xstrndup (arg, p - arg);
map->old_len = p - arg;
p++;
- map->new_prefix = ggc_strdup (p);
+ map->new_prefix = xstrdup (p);
map->new_len = strlen (p);
map->next = debug_prefix_maps;
debug_prefix_maps = map;
rtx body = PATTERN (insn);
int insn_code_number;
const char *templ;
+ bool is_stmt;
#ifdef HAVE_conditional_execution
/* Reset this early so it is correct for ASM statements. */
}
/* Output this line note if it is the first or the last line
note in a row. */
- if (notice_source_line (insn))
+ if (notice_source_line (insn, &is_stmt))
{
(*debug_hooks->source_line) (last_linenum,
last_filename,
- last_discriminator);
+ last_discriminator,
+ is_stmt);
}
if (GET_CODE (body) == ASM_INPUT)
return NEXT_INSN (insn);
}
\f
-/* Return whether a source line note needs to be emitted before INSN. */
+/* Return whether a source line note needs to be emitted before INSN.
+ Sets IS_STMT to TRUE if the line should be marked as a possible
+ breakpoint location. */
static bool
-notice_source_line (rtx insn)
+notice_source_line (rtx insn, bool *is_stmt)
{
const char *filename;
int linenum;
linenum = insn_line (insn);
}
- if (filename
- && (force_source_line
- || filename != last_filename
- || last_linenum != linenum
- || last_discriminator != discriminator))
+ if (filename == NULL)
+ return false;
+
+ if (force_source_line
+ || filename != last_filename
+ || last_linenum != linenum)
{
force_source_line = false;
last_filename = filename;
last_linenum = linenum;
last_discriminator = discriminator;
+ *is_stmt = true;
high_block_linenum = MAX (last_linenum, high_block_linenum);
high_function_linenum = MAX (last_linenum, high_function_linenum);
return true;
}
+
+ if (SUPPORTS_DISCRIMINATOR && last_discriminator != discriminator)
+ {
+ /* If the discriminator changed, but the line number did not,
+ output the line table entry with is_stmt false so the
+ debugger does not treat this as a breakpoint location. */
+ last_discriminator = discriminator;
+ *is_stmt = false;
+ return true;
+ }
+
return false;
}
\f
&& (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp)))
return expr;
- while (GET_RTX_CLASS (GET_CODE (op)) == RTX_UNARY
+ while (UNARY_P (op)
|| GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH)
op = XEXP (op, 0);
}
else if (letter == 'n')
{
- if (GET_CODE (operands[opnum]) == CONST_INT)
+ if (CONST_INT_P (operands[opnum]))
fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
- INTVAL (operands[opnum]));
else
case PLUS:
/* Some assemblers need integer constants to appear last (eg masm). */
- if (GET_CODE (XEXP (x, 0)) == CONST_INT)
+ if (CONST_INT_P (XEXP (x, 0)))
{
output_addr_const (file, XEXP (x, 1));
if (INTVAL (XEXP (x, 0)) >= 0)
else
{
output_addr_const (file, XEXP (x, 0));
- if (GET_CODE (XEXP (x, 1)) != CONST_INT
+ if (!CONST_INT_P (XEXP (x, 1))
|| INTVAL (XEXP (x, 1)) >= 0)
fprintf (file, "+");
output_addr_const (file, XEXP (x, 1));
output_addr_const (file, XEXP (x, 0));
fprintf (file, "-");
- if ((GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0)
+ if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0)
|| GET_CODE (XEXP (x, 1)) == PC
|| GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
output_addr_const (file, XEXP (x, 1));
void
split_double (rtx value, rtx *first, rtx *second)
{
- if (GET_CODE (value) == CONST_INT)
+ if (CONST_INT_P (value))
{
if (HOST_BITS_PER_WIDE_INT >= (2 * BITS_PER_WORD))
{
rest_of_clean_state (void)
{
rtx insn, next;
+ FILE *final_output = NULL;
+ int save_unnumbered = flag_dump_unnumbered;
+ int save_noaddr = flag_dump_noaddr;
+
+ if (flag_dump_final_insns)
+ {
+ final_output = fopen (flag_dump_final_insns, "a");
+ if (!final_output)
+ {
+ error ("could not open final insn dump file %qs: %s",
+ flag_dump_final_insns, strerror (errno));
+ flag_dump_final_insns = NULL;
+ }
+ else
+ {
+ const char *aname;
+
+ aname = (IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (current_function_decl)));
+ fprintf (final_output, "\n;; Function (%s) %s\n\n", aname,
+ cfun->function_frequency == FUNCTION_FREQUENCY_HOT
+ ? " (hot)"
+ : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
+ ? " (unlikely executed)"
+ : "");
+
+ flag_dump_noaddr = flag_dump_unnumbered = 1;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (LABEL_P (insn))
+ INSN_UID (insn) = CODE_LABEL_NUMBER (insn);
+ else
+ INSN_UID (insn) = 0;
+ }
+ }
/* It is very important to decompose the RTL instruction chain here:
debug information keeps pointing into CODE_LABEL insns inside the function
next = NEXT_INSN (insn);
NEXT_INSN (insn) = NULL;
PREV_INSN (insn) = NULL;
+
+ if (final_output
+ && (!NOTE_P (insn) ||
+ (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
+ && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
+ && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END)))
+ print_rtl_single (final_output, insn);
+
+ }
+
+ if (final_output)
+ {
+ flag_dump_noaddr = save_noaddr;
+ flag_dump_unnumbered = save_unnumbered;
+
+ if (fclose (final_output))
+ {
+ error ("could not close final insn dump file %qs: %s",
+ flag_dump_final_insns, strerror (errno));
+ flag_dump_final_insns = NULL;
+ }
}
/* In case the function was not output,
free_bb_for_insn ();
+ delete_tree_ssa ();
+
if (targetm.binds_local_p (current_function_decl))
{
unsigned int pref = crtl->preferred_stack_boundary;
{
{
RTL_PASS,
- NULL, /* name */
+ "*clean_state", /* name */
NULL, /* gate */
rest_of_clean_state, /* execute */
NULL, /* sub */