mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			Cherry-pick fprofile-generate-atomic from google/gcc-4_9
Cherry picked (and modified) from google-4_7 branch 2012-12-26 Rong Xu <xur@google.com> * common.opt (fprofile-update): Add new flag. * coretypes.h: Define enum profile_update. * doc/invoke.texi: Document -fprofile-update. * gcov-io.h: Declare GCOV_TYPE_ATOMIC_FETCH_ADD and GCOV_TYPE_ATOMIC_FETCH_ADD_FN. * tree-profile.c (gimple_init_edge_profiler): Generate also atomic profiler update. (gimple_gen_edge_profiler): Likewise. * g++.dg/gcov/gcov-threads-1.C: New test. From-SVN: r239323
This commit is contained in:
		
							parent
							
								
									5a39e998c8
								
							
						
					
					
						commit
						22063dbc90
					
				|  | @ -1,3 +1,16 @@ | ||||||
|  | 2016-08-10  Martin Liska  <mliska@suse.cz> | ||||||
|  | 
 | ||||||
|  | 	Cherry picked (and modified) from google-4_7 branch | ||||||
|  | 	2012-12-26  Rong Xu  <xur@google.com> | ||||||
|  | 	* common.opt (fprofile-update): Add new flag. | ||||||
|  | 	* coretypes.h: Define enum profile_update. | ||||||
|  | 	* doc/invoke.texi: Document -fprofile-update. | ||||||
|  | 	* gcov-io.h: Declare GCOV_TYPE_ATOMIC_FETCH_ADD and | ||||||
|  | 	GCOV_TYPE_ATOMIC_FETCH_ADD_FN. | ||||||
|  | 	* tree-profile.c (gimple_init_edge_profiler): Generate | ||||||
|  | 	also atomic profiler update. | ||||||
|  | 	(gimple_gen_edge_profiler): Likewise. | ||||||
|  | 
 | ||||||
| 2016-08-10  David Malcolm  <dmalcolm@redhat.com> | 2016-08-10  David Malcolm  <dmalcolm@redhat.com> | ||||||
| 
 | 
 | ||||||
| 	* toplev.c (finalize): Set aux_info_file, asm_out_file, and | 	* toplev.c (finalize): Set aux_info_file, asm_out_file, and | ||||||
|  |  | ||||||
|  | @ -1916,6 +1916,19 @@ fprofile-correction | ||||||
| Common Report Var(flag_profile_correction) | Common Report Var(flag_profile_correction) | ||||||
| Enable correction of flow inconsistent profile data input. | Enable correction of flow inconsistent profile data input. | ||||||
| 
 | 
 | ||||||
|  | fprofile-update= | ||||||
|  | Common Joined RejectNegative Enum(profile_update) Var(flag_profile_update) Init(PROFILE_UPDATE_SINGLE) | ||||||
|  | -fprofile-update=[single|atomic]	Set the profile update method. | ||||||
|  | 
 | ||||||
|  | Enum | ||||||
|  | Name(profile_update) Type(enum profile_update) UnknownError(unknown profile update method %qs) | ||||||
|  | 
 | ||||||
|  | EnumValue | ||||||
|  | Enum(profile_update) String(single) Value(PROFILE_UPDATE_SINGLE) | ||||||
|  | 
 | ||||||
|  | EnumValue | ||||||
|  | Enum(profile_update) String(atomic) Value(PROFILE_UPDATE_ATOMIC) | ||||||
|  | 
 | ||||||
| fprofile-generate | fprofile-generate | ||||||
| Common | Common | ||||||
| Enable common options for generating profile info for profile feedback directed optimizations. | Enable common options for generating profile info for profile feedback directed optimizations. | ||||||
|  |  | ||||||
|  | @ -174,6 +174,12 @@ enum offload_abi { | ||||||
|   OFFLOAD_ABI_ILP32 |   OFFLOAD_ABI_ILP32 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /* Types of profile update methods.  */ | ||||||
|  | enum profile_update { | ||||||
|  |   PROFILE_UPDATE_SINGLE, | ||||||
|  |   PROFILE_UPDATE_ATOMIC | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /* Types of unwind/exception handling info that can be generated.  */ | /* Types of unwind/exception handling info that can be generated.  */ | ||||||
| 
 | 
 | ||||||
| enum unwind_info_type | enum unwind_info_type | ||||||
|  |  | ||||||
|  | @ -9933,6 +9933,18 @@ the profile feedback data files. See @option{-fprofile-dir}. | ||||||
| To optimize the program based on the collected profile information, use | To optimize the program based on the collected profile information, use | ||||||
| @option{-fprofile-use}.  @xref{Optimize Options}, for more information. | @option{-fprofile-use}.  @xref{Optimize Options}, for more information. | ||||||
| 
 | 
 | ||||||
|  | @item -fprofile-update=@var{method} | ||||||
|  | @opindex fprofile-update | ||||||
|  | 
 | ||||||
|  | Alter the update method for an application instrumented for profile | ||||||
|  | feedback based optimization.  The @var{method} argument should be one of | ||||||
|  | @samp{single} or @samp{atomic}.  The first one is useful for single-threaded | ||||||
|  | applications, while the second one prevents profile corruption by emitting | ||||||
|  | thread-safe code. | ||||||
|  | 
 | ||||||
|  | @strong{Warning:} When an application does not properly join all threads | ||||||
|  | (or creates an detached thread), a profile file can be still corrupted. | ||||||
|  | 
 | ||||||
| @item -fsanitize=address | @item -fsanitize=address | ||||||
| @opindex fsanitize=address | @opindex fsanitize=address | ||||||
| Enable AddressSanitizer, a fast memory error detector. | Enable AddressSanitizer, a fast memory error detector. | ||||||
|  |  | ||||||
|  | @ -164,6 +164,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | ||||||
| #ifndef GCC_GCOV_IO_H | #ifndef GCC_GCOV_IO_H | ||||||
| #define GCC_GCOV_IO_H | #define GCC_GCOV_IO_H | ||||||
| 
 | 
 | ||||||
|  | #if LONG_LONG_TYPE_SIZE > 32 | ||||||
|  | #define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_8 | ||||||
|  | #define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_8 | ||||||
|  | #else | ||||||
|  | #define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_4 | ||||||
|  | #define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_4 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #ifndef IN_LIBGCOV | #ifndef IN_LIBGCOV | ||||||
| /* About the host */ | /* About the host */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,3 +1,7 @@ | ||||||
|  | 2016-08-10  Martin Liska  <mliska@suse.cz> | ||||||
|  | 
 | ||||||
|  | 	* g++.dg/gcov/gcov-threads-1.C: New test. | ||||||
|  | 
 | ||||||
| 2016-08-10  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com> | 2016-08-10  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com> | ||||||
| 
 | 
 | ||||||
| 	PR target/71873 | 	PR target/71873 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,46 @@ | ||||||
|  | /* { dg-options "-fprofile-arcs -ftest-coverage -pthread -fprofile-update=atomic" } */ | ||||||
|  | /* { dg-do run { target native } } */ | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <pthread.h> | ||||||
|  | #include <assert.h> | ||||||
|  | 
 | ||||||
|  | #define NR 5 | ||||||
|  | 
 | ||||||
|  | pthread_mutex_t cndMs[NR]; | ||||||
|  | static void *ContentionNoDeadlock_thread(void *start) | ||||||
|  | { | ||||||
|  |   for (uint32_t k = 0; k < 100000; ++k)		/* count(500005) */ | ||||||
|  |     { | ||||||
|  |       int starti = *(int*)start;		/* count(500000) */ | ||||||
|  |       for (uint32_t i = starti; i < NR; ++i)  | ||||||
|  | 	pthread_mutex_lock (&cndMs[i]); | ||||||
|  |       for (int32_t i = NR - 1; i >= starti; --i) | ||||||
|  | 	pthread_mutex_unlock (&cndMs[i]); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | int main(int argc, char **argv) { | ||||||
|  |   for (unsigned i = 0; i < NR; i++) | ||||||
|  |     cndMs[i] = PTHREAD_MUTEX_INITIALIZER; | ||||||
|  | 
 | ||||||
|  |   pthread_t t[NR]; | ||||||
|  |   int ids[NR]; | ||||||
|  | 
 | ||||||
|  |   for (int i = 0; i < NR; i++) | ||||||
|  |   { | ||||||
|  |     ids[i] = i; | ||||||
|  |     int r = pthread_create (&t[i], NULL, ContentionNoDeadlock_thread, &ids[i]); | ||||||
|  |     assert (r == 0);				/* count(5) */ | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   int ret; | ||||||
|  |   for (int i = 0; i < NR; i++) | ||||||
|  |     { | ||||||
|  |       int r = pthread_join (t[i], (void**)&ret); | ||||||
|  |       assert (r == 0);				/* count(5) */ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   return 0;					/* count(1) */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* { dg-final { run-gcov gcov-threads-1.C } } */ | ||||||
|  | @ -127,6 +127,7 @@ gimple_init_edge_profiler (void) | ||||||
|   tree ic_profiler_fn_type; |   tree ic_profiler_fn_type; | ||||||
|   tree average_profiler_fn_type; |   tree average_profiler_fn_type; | ||||||
|   tree time_profiler_fn_type; |   tree time_profiler_fn_type; | ||||||
|  |   const char *profiler_fn_name; | ||||||
| 
 | 
 | ||||||
|   if (!gcov_type_node) |   if (!gcov_type_node) | ||||||
|     { |     { | ||||||
|  | @ -180,11 +181,12 @@ gimple_init_edge_profiler (void) | ||||||
| 					  gcov_type_node, | 					  gcov_type_node, | ||||||
| 					  ptr_void, | 					  ptr_void, | ||||||
| 					  NULL_TREE); | 					  NULL_TREE); | ||||||
|  |       profiler_fn_name = "__gcov_indirect_call_profiler_v2"; | ||||||
|  |       if (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE)) | ||||||
|  | 	profiler_fn_name = "__gcov_indirect_call_topn_profiler"; | ||||||
|  | 
 | ||||||
|       tree_indirect_call_profiler_fn |       tree_indirect_call_profiler_fn | ||||||
| 	      = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? | 	      = build_fn_decl (profiler_fn_name, ic_profiler_fn_type); | ||||||
| 				 "__gcov_indirect_call_topn_profiler": |  | ||||||
| 				 "__gcov_indirect_call_profiler_v2"), |  | ||||||
| 			       ic_profiler_fn_type); |  | ||||||
| 
 | 
 | ||||||
|       TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1; |       TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1; | ||||||
|       DECL_ATTRIBUTES (tree_indirect_call_profiler_fn) |       DECL_ATTRIBUTES (tree_indirect_call_profiler_fn) | ||||||
|  | @ -241,22 +243,37 @@ gimple_init_edge_profiler (void) | ||||||
| void | void | ||||||
| gimple_gen_edge_profiler (int edgeno, edge e) | gimple_gen_edge_profiler (int edgeno, edge e) | ||||||
| { | { | ||||||
|   tree ref, one, gcov_type_tmp_var; |   tree one; | ||||||
|   gassign *stmt1, *stmt2, *stmt3; |  | ||||||
| 
 | 
 | ||||||
|   ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno); |  | ||||||
|   one = build_int_cst (gcov_type_node, 1); |   one = build_int_cst (gcov_type_node, 1); | ||||||
|  | 
 | ||||||
|  |   if (flag_profile_update == PROFILE_UPDATE_ATOMIC) | ||||||
|  |     { | ||||||
|  |       /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */ | ||||||
|  |       tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno); | ||||||
|  |       gcall *stmt | ||||||
|  | 	= gimple_build_call (builtin_decl_explicit (GCOV_TYPE_ATOMIC_FETCH_ADD), | ||||||
|  | 			     3, addr, one, | ||||||
|  | 			     build_int_cst (integer_type_node, | ||||||
|  | 					    MEMMODEL_RELAXED)); | ||||||
|  |       gsi_insert_on_edge (e, stmt); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       tree ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno); | ||||||
|  |       tree gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, | ||||||
|  | 						   NULL, "PROF_edge_counter"); | ||||||
|  |       gassign *stmt1 = gimple_build_assign (gcov_type_tmp_var, ref); | ||||||
|       gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, |       gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, | ||||||
| 					      NULL, "PROF_edge_counter"); | 					      NULL, "PROF_edge_counter"); | ||||||
|   stmt1 = gimple_build_assign (gcov_type_tmp_var, ref); |       gassign *stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR, | ||||||
|   gcov_type_tmp_var = make_temp_ssa_name (gcov_type_node, |  | ||||||
| 					  NULL, "PROF_edge_counter"); |  | ||||||
|   stmt2 = gimple_build_assign (gcov_type_tmp_var, PLUS_EXPR, |  | ||||||
| 					    gimple_assign_lhs (stmt1), one); | 					    gimple_assign_lhs (stmt1), one); | ||||||
|   stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2)); |       gassign *stmt3 = gimple_build_assign (unshare_expr (ref), | ||||||
|  | 					    gimple_assign_lhs (stmt2)); | ||||||
|       gsi_insert_on_edge (e, stmt1); |       gsi_insert_on_edge (e, stmt1); | ||||||
|       gsi_insert_on_edge (e, stmt2); |       gsi_insert_on_edge (e, stmt2); | ||||||
|       gsi_insert_on_edge (e, stmt3); |       gsi_insert_on_edge (e, stmt3); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Emits code to get VALUE to instrument at GSI, and returns the
 | /* Emits code to get VALUE to instrument at GSI, and returns the
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Martin Liska
						Martin Liska