/* Convert RTL to assembler code and output it, for GNU compiler.
- Copyright (C) 1987-2018 Free Software Foundation, Inc.
+ Copyright (C) 1987-2019 Free Software Foundation, Inc.
This file is part of GCC.
/* Column number of last NOTE. */
static int last_columnnum;
-/* Last discriminator written to assembly. */
+/* Discriminator written to assembly. */
static int last_discriminator;
-/* Discriminator of current block. */
+/* Discriminator to be written to assembly for current instruction.
+ Note: actual usage depends on loc_discriminator_kind setting. */
static int discriminator;
+static inline int compute_discriminator (location_t loc);
+
+/* Discriminator identifying current basic block among others sharing
+ the same locus. */
+static int bb_discriminator;
+
+/* Basic block discriminator for previous instruction. */
+static int last_bb_discriminator;
/* Highest line number in current block. */
static int high_block_linenum;
static const char *override_filename;
static int override_linenum;
static int override_columnnum;
+static int override_discriminator;
/* Whether to force emission of a line note before the next insn. */
static bool force_source_line = false;
last_linenum = LOCATION_LINE (prologue_location);
last_columnnum = LOCATION_COLUMN (prologue_location);
last_discriminator = discriminator = 0;
+ last_bb_discriminator = bb_discriminator = 0;
high_block_linenum = high_function_linenum = last_linenum;
ASM_OUTPUT_LABEL (asm_out_file,
IDENTIFIER_POINTER (cold_function_name));
#endif
+ if (dwarf2out_do_frame ()
+ && cfun->fde->dw_fde_second_begin != NULL)
+ ASM_OUTPUT_LABEL (asm_out_file, cfun->fde->dw_fde_second_begin);
}
break;
if (targetm.asm_out.unwind_emit)
targetm.asm_out.unwind_emit (asm_out_file, insn);
- discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
-
+ bb_discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
break;
case NOTE_INSN_EH_REGION_BEG:
override_filename = LOCATION_FILE (*locus_ptr);
override_linenum = LOCATION_LINE (*locus_ptr);
override_columnnum = LOCATION_COLUMN (*locus_ptr);
+ override_discriminator = compute_discriminator (*locus_ptr);
}
}
break;
override_filename = LOCATION_FILE (*locus_ptr);
override_linenum = LOCATION_LINE (*locus_ptr);
override_columnnum = LOCATION_COLUMN (*locus_ptr);
+ override_discriminator = compute_discriminator (*locus_ptr);
}
else
{
override_filename = NULL;
override_linenum = 0;
override_columnnum = 0;
+ override_discriminator = 0;
}
}
break;
case NOTE_INSN_INLINE_ENTRY:
gcc_checking_assert (cfun->debug_nonbind_markers);
- if (!DECL_IGNORED_P (current_function_decl))
+ if (!DECL_IGNORED_P (current_function_decl)
+ && notice_source_line (insn, NULL))
{
- if (!notice_source_line (insn, NULL))
- break;
(*debug_hooks->inline_entry) (LOCATION_BLOCK
(NOTE_MARKER_LOCATION (insn)));
goto output_source_line;
}
\f
+
+/* Map DECLs to instance discriminators. This is allocated and
+ defined in ada/gcc-interfaces/trans.c, when compiling with -gnateS.
+ Mappings from this table are saved and restored for LTO, so
+ link-time compilation will have this map set, at least in
+ partitions containing at least one DECL with an associated instance
+ discriminator. */
+
+decl_to_instance_map_t *decl_to_instance_map;
+
+/* Return the instance number assigned to DECL. */
+
+static inline int
+map_decl_to_instance (const_tree decl)
+{
+ int *inst;
+
+ if (!decl_to_instance_map || !decl || !DECL_P (decl))
+ return 0;
+
+ inst = decl_to_instance_map->get (decl);
+
+ if (!inst)
+ return 0;
+
+ return *inst;
+}
+
+/* Set DISCRIMINATOR to the appropriate value, possibly derived from LOC. */
+
+static inline int
+compute_discriminator (location_t loc)
+{
+ int discriminator;
+
+ if (!decl_to_instance_map)
+ discriminator = bb_discriminator;
+ else
+ {
+ tree block = LOCATION_BLOCK (loc);
+
+ while (block && TREE_CODE (block) == BLOCK
+ && !inlined_function_outer_scope_p (block))
+ block = BLOCK_SUPERCONTEXT (block);
+
+ tree decl;
+
+ if (!block)
+ decl = current_function_decl;
+ else if (DECL_P (block))
+ decl = block;
+ else
+ decl = block_ultimate_origin (block);
+
+ discriminator = map_decl_to_instance (decl);
+ }
+
+ return discriminator;
+}
+
/* 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. */
if (NOTE_MARKER_P (insn))
{
location_t loc = NOTE_MARKER_LOCATION (insn);
- /* The inline entry markers (gimple, insn, note) carry the
- location of the call, because that's what we want to carry
- during compilation, but the location we want to output in
- debug information for the inline entry point is the location
- of the function itself. */
- if (NOTE_KIND (insn) == NOTE_INSN_INLINE_ENTRY)
- {
- tree block = LOCATION_BLOCK (loc);
- tree fn = block_ultimate_origin (block);
- loc = DECL_SOURCE_LOCATION (fn);
- }
expanded_location xloc = expand_location (loc);
if (xloc.line == 0)
{
filename = xloc.file;
linenum = xloc.line;
columnnum = xloc.column;
+ discriminator = compute_discriminator (loc);
force_source_line = true;
}
else if (override_filename)
filename = override_filename;
linenum = override_linenum;
columnnum = override_columnnum;
+ discriminator = override_discriminator;
}
else if (INSN_HAS_LOCATION (insn))
{
filename = xloc.file;
linenum = xloc.line;
columnnum = xloc.column;
+ discriminator = compute_discriminator (INSN_LOCATION (insn));
}
else
{
filename = NULL;
linenum = 0;
columnnum = 0;
+ discriminator = 0;
}
if (filename == NULL)
final_start_function_1 (&first, asm_out_file, &seen, optimize);
final_1 (first, asm_out_file, seen, optimize);
if (flag_ipa_ra
- && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl)))
+ && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))
+ /* Functions with naked attributes are supported only with basic asm
+ statements in the body, thus for supported use cases the information
+ on clobbered registers is not available. */
+ && !lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)))
collect_fn_hard_reg_usage ();
final_end_function ();
/* We can reduce stack alignment on call site only when we are sure that
the function body just produced will be actually used in the final
executable. */
- if (decl_binds_to_current_def_p (current_function_decl))
+ if (flag_ipa_stack_alignment
+ && decl_binds_to_current_def_p (current_function_decl))
{
unsigned int pref = crtl->preferred_stack_boundary;
if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary)