Add instruction level discriminator support.

This is the first in a series of patches to enable discriminator support
in AutoFDO.

This patch switches to tracking discriminators per statement/instruction
instead of per basic block. Tracking per basic block was problematic since
not all statements in a basic block needed a discriminator and, also, later
optimizations could move statements between basic blocks making correlation
during AutoFDO compilation unreliable. Tracking per statement also allows
us to assign different discriminators to multiple function calls in the same
basic block. A subsequent patch will add that support.

The idea of this patch is based on commit 4c311d95cf6d9519c3c20f641cc77af7df491fdf
by Dehao Chen in vendors/google/heads/gcc-4_8 but uses a slightly different
approach. In Dehao's work special (normally unused) location ids and side tables
were used to keep track of locations with discriminators. Things have changed
since then and I don't think we have unused location ids anymore. Instead,
I made discriminators a part of ad-hoc locations.

The difference from Dehao's work also includes support for discriminator
reading/writing in lto streaming and in modules.

Tested on x86_64-pc-linux-gnu.

gcc/ChangeLog:

	* basic-block.h: Remove discriminator from basic blocks.
	* cfghooks.cc (split_block_1): Remove discriminator from basic blocks.
	* final.cc (final_start_function_1): Switch from per-bb to per statement
	discriminator.
	(final_scan_insn_1): Don't keep track of basic block discriminators.
	(compute_discriminator): Switch from basic block discriminators to
	instruction discriminators.
	(insn_discriminator): New function to return instruction discriminator.
	(notice_source_line): Use insn_discriminator.
	* gimple-pretty-print.cc (dump_gimple_bb_header): Remove dumping of
	basic block discriminators.
	* gimple-streamer-in.cc (input_bb): Remove reading of basic block
	discriminators.
	* gimple-streamer-out.cc (output_bb): Remove writing of basic block
	discriminators.
	* input.cc (make_location): Pass 0 discriminator to COMBINE_LOCATION_DATA.
	(location_with_discriminator): New function to combine locus with
	a discriminator.
	(has_discriminator): New function to check if a location has a discriminator.
	(get_discriminator_from_loc): New function to get the discriminator
	from a location.
	* input.h: Declarations of new functions.
	* lto-streamer-in.cc (cmp_loc): Use discriminators in location comparison.
	(apply_location_cache): Keep track of current discriminator.
	(input_location_and_block): Read discriminator from stream.
	* lto-streamer-out.cc (clear_line_info): Set current discriminator to
	UINT_MAX.
	(lto_output_location_1): Write discriminator to stream.
	* lto-streamer.h: Add discriminator to cached_location.
	Add current_discr to lto_location_cache.
	Add current_discr to output_block.
	* print-rtl.cc (print_rtx_operand_code_i): Print discriminator.
	* rtl.h: Add extern declaration of insn_discriminator.
	* tree-cfg.cc (assign_discriminator): New function to assign a unique
	discriminator value to all statements in a basic block that have the given
	line number.
	(assign_discriminators): Assign discriminators to statement locations.
	* tree-pretty-print.cc (dump_location): Dump discriminators.
	* tree.cc (set_block): Preserve discriminator when setting block.
	(set_source_range): Preserve discriminator when setting source range.

gcc/cp/ChangeLog:
	* module.cc (write_location): Write discriminator.
	(read_location): Read discriminator.

libcpp/ChangeLog:

	* include/line-map.h: Add discriminator to location_adhoc_data.
	(get_combined_adhoc_loc): Add discriminator parameter.
	(get_discriminator_from_adhoc_loc): Add external declaration.
	(get_discriminator_from_loc): Add external declaration.
	(COMBINE_LOCATION_DATA): Add discriminator parameter.
	* lex.cc (get_location_for_byte_range_in_cur_line) Pass 0 discriminator
	in a call to COMBINE_LOCATION_DATA.
	(warn_about_normalization): Pass 0 discriminator in a call to
	COMBINE_LOCATION_DATA.
	(_cpp_lex_direct): Pass 0 discriminator in a call to
	COMBINE_LOCATION_DATA.
	* line-map.cc (location_adhoc_data_hash): Use discriminator compute
	location_adhoc_data hash.
	(location_adhoc_data_eq): Use discriminator when comparing
	location_adhoc_data.
	(can_be_stored_compactly_p): Check discriminator to determine
	compact storage.
	(get_combined_adhoc_loc): Add discriminator parameter.
	(get_discriminator_from_adhoc_loc): New function to get the discriminator
	from an ad-hoc location.
	(get_discriminator_from_loc): New function to get the discriminator
	from a location.

gcc/testsuite/ChangeLog:

	* c-c++-common/ubsan/pr85213.c: Pass -gno-statement-frontiers.
This commit is contained in:
Eugene Rozenfeld
2022-04-21 15:42:15 -07:00
parent 9f65eecdbe
commit f1adf45b17
21 changed files with 187 additions and 55 deletions

View File

@@ -757,6 +757,7 @@ struct GTY(()) location_adhoc_data {
location_t locus;
source_range src_range;
void * GTY((skip)) data;
unsigned discriminator;
};
struct htab;
@@ -1034,12 +1035,14 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
}
extern location_t get_combined_adhoc_loc (line_maps *, location_t,
source_range, void *);
source_range, void *, unsigned);
extern void *get_data_from_adhoc_loc (const line_maps *, location_t);
extern unsigned get_discriminator_from_adhoc_loc (const line_maps *, location_t);
extern location_t get_location_from_adhoc_loc (const line_maps *,
location_t);
extern source_range get_range_from_loc (line_maps *set, location_t loc);
extern unsigned get_discriminator_from_loc (line_maps *set, location_t loc);
/* Get whether location LOC is a "pure" location, or
whether it is an ad-hoc location, or embeds range information. */
@@ -1058,9 +1061,10 @@ inline location_t
COMBINE_LOCATION_DATA (class line_maps *set,
location_t loc,
source_range src_range,
void *block)
void *block,
unsigned discriminator)
{
return get_combined_adhoc_loc (set, loc, src_range, block);
return get_combined_adhoc_loc (set, loc, src_range, block, discriminator);
}
extern void rebuild_location_adhoc_htab (class line_maps *);

View File

@@ -1362,7 +1362,8 @@ get_location_for_byte_range_in_cur_line (cpp_reader *pfile,
location_t combined_loc = COMBINE_LOCATION_DATA (pfile->line_table,
start_loc,
src_range,
NULL);
NULL,
0);
return combined_loc;
}
@@ -2028,7 +2029,7 @@ warn_about_normalization (cpp_reader *pfile,
CPP_BUF_COLUMN (pfile->buffer,
pfile->buffer->cur));
loc = COMBINE_LOCATION_DATA (pfile->line_table,
loc, tok_range, NULL);
loc, tok_range, NULL, 0);
}
encoding_rich_location rich_loc (pfile, loc);
@@ -4256,7 +4257,7 @@ _cpp_lex_direct (cpp_reader *pfile)
result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table,
result->src_loc,
tok_range, NULL);
tok_range, NULL, 0);
}
return result;

View File

@@ -67,7 +67,8 @@ location_adhoc_data_hash (const void *l)
return ((hashval_t) lb->locus
+ (hashval_t) lb->src_range.m_start
+ (hashval_t) lb->src_range.m_finish
+ (size_t) lb->data);
+ (size_t) lb->data
+ lb->discriminator);
}
/* Compare function for location_adhoc_data hashtable. */
@@ -82,7 +83,8 @@ location_adhoc_data_eq (const void *l1, const void *l2)
return (lb1->locus == lb2->locus
&& lb1->src_range.m_start == lb2->src_range.m_start
&& lb1->src_range.m_finish == lb2->src_range.m_finish
&& lb1->data == lb2->data);
&& lb1->data == lb2->data
&& lb1->discriminator == lb2->discriminator);
}
/* Update the hashtable when location_adhoc_data_map::data is reallocated.
@@ -127,13 +129,17 @@ static bool
can_be_stored_compactly_p (line_maps *set,
location_t locus,
source_range src_range,
void *data)
void *data,
unsigned discriminator)
{
/* If there's an ad-hoc pointer, we can't store it directly in the
location_t, we need the lookaside. */
if (data)
return false;
if (discriminator != 0)
return false;
/* We only store ranges that begin at the locus and that are sufficiently
"sane". */
if (src_range.m_start != locus)
@@ -168,7 +174,8 @@ location_t
get_combined_adhoc_loc (line_maps *set,
location_t locus,
source_range src_range,
void *data)
void *data,
unsigned discriminator)
{
struct location_adhoc_data lb;
struct location_adhoc_data **slot;
@@ -186,7 +193,7 @@ get_combined_adhoc_loc (line_maps *set,
|| pure_location_p (set, locus));
/* Consider short-range optimization. */
if (can_be_stored_compactly_p (set, locus, src_range, data))
if (can_be_stored_compactly_p (set, locus, src_range, data, discriminator))
{
/* The low bits ought to be clear. */
linemap_assert (pure_location_p (set, locus));
@@ -206,15 +213,16 @@ get_combined_adhoc_loc (line_maps *set,
when locus == start == finish (and data is NULL). */
if (locus == src_range.m_start
&& locus == src_range.m_finish
&& !data)
&& !data && discriminator == 0)
return locus;
if (!data)
if (!data && discriminator == 0)
set->num_unoptimized_ranges++;
lb.locus = locus;
lb.src_range = src_range;
lb.data = data;
lb.discriminator = discriminator;
slot = (struct location_adhoc_data **)
htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
if (*slot == NULL)
@@ -261,6 +269,13 @@ get_data_from_adhoc_loc (const class line_maps *set, location_t loc)
return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data;
}
unsigned
get_discriminator_from_adhoc_loc (const class line_maps *set, location_t loc)
{
linemap_assert (IS_ADHOC_LOC (loc));
return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].discriminator;
}
/* Return the location for the adhoc loc. */
location_t
@@ -306,6 +321,15 @@ get_range_from_loc (line_maps *set,
return source_range::from_location (loc);
}
unsigned
get_discriminator_from_loc (line_maps *set,
location_t loc)
{
if (IS_ADHOC_LOC (loc))
return get_discriminator_from_adhoc_loc (set, loc);
return 0;
}
/* Get whether location LOC is a "pure" location, or
whether it is an ad-hoc location, or embeds range information. */