@@ -162,9 +162,6 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d
/* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */
int frequency;
- /* The discriminator for this block. */
- int discriminator;
-
/* Various flags. See BB_* below. */
int flags;
};
@@ -437,7 +437,6 @@ split_block (basic_block bb, void *i)
new_bb->count = bb->count;
new_bb->frequency = bb->frequency;
new_bb->loop_depth = bb->loop_depth;
- new_bb->discriminator = bb->discriminator;
if (dom_info_available_p (CDI_DOMINATORS))
{
@@ -567,6 +567,16 @@ insn_file (const_rtx insn)
return locator_file (INSN_LOCATOR (insn));
}
+/* Return discriminator of the statement that produced this insn. */
+int
+insn_discriminator (const_rtx insn)
+{
+ int loc = INSN_LOCATOR (insn);
+ if (!loc)
+ return 0;
+ return get_discriminator_from_locus (locator_location (loc));
+}
+
/* Return true if LOC1 and LOC2 locators have the same location and scope. */
bool
locator_eq (int loc1, int loc2)
@@ -134,9 +134,6 @@ static int last_linenum;
/* Last discriminator written to assembly. */
static int last_discriminator;
-/* Discriminator of current block. */
-static int discriminator;
-
/* Highest line number in current block. */
static int high_block_linenum;
@@ -146,9 +143,10 @@ static int high_function_linenum;
/* Filename of last NOTE. */
static const char *last_filename;
-/* Override filename and line number. */
+/* Override filename, line number, and discriminator. */
static const char *override_filename;
static int override_linenum;
+static int override_discriminator;
/* Whether to force emission of a line note before the next insn. */
static bool force_source_line = false;
@@ -1539,7 +1537,7 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
last_filename = locator_file (prologue_locator);
last_linenum = locator_line (prologue_locator);
- last_discriminator = discriminator = 0;
+ last_discriminator = 0;
high_block_linenum = high_function_linenum = last_linenum;
@@ -1943,8 +1941,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
else
*seen |= SEEN_BB;
- discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
-
break;
case NOTE_INSN_EH_REGION_BEG:
@@ -2029,6 +2025,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
{
override_filename = LOCATION_FILE (*locus_ptr);
override_linenum = LOCATION_LINE (*locus_ptr);
+ override_discriminator =
+ get_discriminator_from_locus (*locus_ptr);
}
}
break;
@@ -2062,11 +2060,14 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
{
override_filename = LOCATION_FILE (*locus_ptr);
override_linenum = LOCATION_LINE (*locus_ptr);
+ override_discriminator =
+ get_discriminator_from_locus (*locus_ptr);
}
else
{
override_filename = NULL;
override_linenum = 0;
+ override_discriminator = 0;
}
}
break;
@@ -2788,16 +2789,19 @@ notice_source_line (rtx insn, bool *is_stmt)
{
const char *filename;
int linenum;
+ int discriminator;
if (override_filename)
{
filename = override_filename;
linenum = override_linenum;
+ discriminator = override_discriminator;
}
else
{
filename = insn_file (insn);
linenum = insn_line (insn);
+ discriminator = insn_discriminator (insn);
}
if (filename == NULL)
@@ -1656,7 +1656,9 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
if ((flags & TDF_LINENO) && gimple_has_location (gs))
{
- expanded_location xloc = expand_location (gimple_location (gs));
+ location_t loc = gimple_location (gs);
+ expanded_location xloc = expand_location (loc);
+ int discriminator = get_discriminator_from_locus (loc);
pp_character (buffer, '[');
if (xloc.file)
{
@@ -1666,6 +1668,11 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_decimal_int (buffer, xloc.line);
pp_string (buffer, ":");
pp_decimal_int (buffer, xloc.column);
+ if (discriminator)
+ {
+ pp_string (buffer, " discrim ");
+ pp_decimal_int (buffer, discriminator);
+ }
pp_string (buffer, "] ");
}
@@ -1888,12 +1895,6 @@ dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi)));
break;
}
-
- if (bb->discriminator)
- {
- pp_string (buffer, ", discriminator ");
- pp_decimal_int (buffer, bb->discriminator);
- }
}
newline_and_indent (buffer, indent);
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "intl.h"
#include "input.h"
+#include "vec.h"
+#include "vecprim.h"
/* Current position in real source file. */
@@ -30,10 +32,23 @@ location_t input_location;
struct line_maps *line_table;
+/* Vectors to map a discriminator-enhanced locus to a real locus and
+ discriminator value. */
+static VEC(int,heap) *discriminator_location_locations = NULL;
+static VEC(int,heap) *discriminator_location_discriminators = NULL;
+static location_t min_discriminator_location = UNKNOWN_LOCATION;
+
expanded_location
expand_location (source_location loc)
{
expanded_location xloc;
+
+ /* If LOC describes a location with a discriminator, extract the
+ discriminator and map it to the real location. */
+ if (min_discriminator_location != UNKNOWN_LOCATION
+ && loc >= min_discriminator_location)
+ loc = map_discriminator_location (loc);
+
if (loc <= BUILTINS_LOCATION)
{
xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
@@ -51,3 +66,57 @@ expand_location (source_location loc)
};
return xloc;
}
+
+/* Associate the DISCRIMINATOR with LOCUS, and return a new locus.
+ We associate discriminators with a locus by allocating location_t
+ values beyond those assigned by libcpp. Each new value is mapped
+ directly to a real location_t value, and separately to the
+ discriminator. */
+
+location_t
+location_with_discriminator (location_t locus, int discriminator)
+{
+ static int next_discriminator_location = 0;
+
+ if (min_discriminator_location == UNKNOWN_LOCATION)
+ {
+ min_discriminator_location = line_table->highest_location + 1;
+ next_discriminator_location = min_discriminator_location;
+ }
+
+ VEC_safe_push (int, heap, discriminator_location_locations, (int) locus);
+ VEC_safe_push (int, heap, discriminator_location_discriminators,
+ discriminator);
+ return next_discriminator_location++;
+}
+
+/* Return TRUE if LOCUS represents a location with a discriminator. */
+
+bool
+has_discriminator (location_t locus)
+{
+ return (min_discriminator_location != UNKNOWN_LOCATION
+ && locus >= min_discriminator_location);
+}
+
+/* Return the real location_t value for LOCUS. */
+
+location_t
+map_discriminator_location (location_t locus)
+{
+ if (! has_discriminator (locus))
+ return locus;
+ return (location_t) VEC_index (int, discriminator_location_locations,
+ locus - min_discriminator_location);
+}
+
+/* Return the discriminator for LOCUS. */
+
+int
+get_discriminator_from_locus (location_t locus)
+{
+ if (! has_discriminator (locus))
+ return 0;
+ return VEC_index (int, discriminator_location_discriminators,
+ locus - min_discriminator_location);
+}
@@ -59,6 +59,11 @@ typedef source_location location_t;
extern location_t input_location;
+extern location_t location_with_discriminator (location_t, int);
+extern bool has_discriminator (location_t);
+extern location_t map_discriminator_location (location_t);
+extern int get_discriminator_from_locus (location_t);
+
#define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
#define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
@@ -403,7 +403,13 @@ print_rtx (const_rtx in_rtx)
redundant with line number information and do not print anything
when there is no location information available. */
if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
- fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
+ {
+ int discriminator = insn_discriminator (in_rtx);
+ fprintf (outfile, " %s:%i", insn_file (in_rtx),
+ insn_line (in_rtx));
+ if (discriminator)
+ fprintf (outfile, " discrim %d", discriminator);
+ }
#endif
}
else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
@@ -1751,6 +1751,7 @@ extern rtx prev_cc0_setter (rtx);
/* In cfglayout.c */
extern int insn_line (const_rtx);
extern const char * insn_file (const_rtx);
+extern int insn_discriminator (const_rtx);
extern location_t locator_location (int);
extern int locator_line (int);
extern const char * locator_file (int);
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "output.h"
#include "flags.h"
+#include "input.h"
#include "function.h"
#include "ggc.h"
#include "langhooks.h"
@@ -760,22 +761,59 @@ same_line_p (location_t locus1, location_t locus2)
&& filename_cmp (from.file, to.file) == 0);
}
-/* Assign a unique discriminator value to block BB if it begins at the same
- LOCUS as its predecessor block. */
+/* Assign a unique discriminator value to instructions in block BB that
+ have the same LOCUS as its predecessor block. */
static void
assign_discriminator (location_t locus, basic_block bb)
{
gimple first_in_to_bb, last_in_to_bb;
+ int discriminator = 0;
- if (locus == 0 || bb->discriminator != 0)
+ if (locus == UNKNOWN_LOCATION)
return;
+ if (has_discriminator (locus))
+ locus = map_discriminator_location (locus);
+
+ /* Check the locus of the first (non-label) instruction in the block. */
first_in_to_bb = first_non_label_stmt (bb);
- last_in_to_bb = last_stmt (bb);
- if ((first_in_to_bb && same_line_p (locus, gimple_location (first_in_to_bb)))
- || (last_in_to_bb && same_line_p (locus, gimple_location (last_in_to_bb))))
- bb->discriminator = next_discriminator_for_locus (locus);
+ if (first_in_to_bb)
+ {
+ location_t first_locus = gimple_location (first_in_to_bb);
+ if (! has_discriminator (first_locus)
+ && same_line_p (locus, first_locus))
+ discriminator = next_discriminator_for_locus (locus);
+ }
+
+ /* If the first instruction doesn't trigger a discriminator, check the
+ last instruction of the block. This catches the case where the
+ increment portion of a for loop is placed at the end of the loop
+ body. */
+ if (discriminator == 0)
+ {
+ last_in_to_bb = last_stmt (bb);
+ if (last_in_to_bb)
+ {
+ location_t last_locus = gimple_location (last_in_to_bb);
+ if (! has_discriminator (last_locus)
+ && same_line_p (locus, last_locus))
+ discriminator = next_discriminator_for_locus (locus);
+ }
+ }
+
+ if (discriminator != 0)
+ {
+ location_t new_locus = location_with_discriminator (locus, discriminator);
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (same_line_p (locus, gimple_location (stmt)))
+ gimple_set_location (stmt, new_locus);
+ }
+ }
}
/* Create the edges for a GIMPLE_COND starting at block BB. */
@@ -456,6 +456,7 @@ static void
dump_location (pretty_printer *buffer, location_t loc)
{
expanded_location xloc = expand_location (loc);
+ int discriminator = get_discriminator_from_locus (loc);
pp_character (buffer, '[');
if (xloc.file)
@@ -464,6 +465,11 @@ dump_location (pretty_printer *buffer, location_t loc)
pp_string (buffer, " : ");
}
pp_decimal_int (buffer, xloc.line);
+ if (discriminator)
+ {
+ pp_string (buffer, " discrim ");
+ pp_decimal_int (buffer, discriminator);
+ }
pp_string (buffer, "] ");
}