comparison gcc/trans-mem.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Passes for transactional memory support. 1 /* Passes for transactional memory support.
2 Copyright (C) 2008-2017 Free Software Foundation, Inc. 2 Copyright (C) 2008-2018 Free Software Foundation, Inc.
3 Contributed by Richard Henderson <rth@redhat.com> 3 Contributed by Richard Henderson <rth@redhat.com>
4 and Aldy Hernandez <aldyh@redhat.com>. 4 and Aldy Hernandez <aldyh@redhat.com>.
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
233 /* A call to the irrevocable builtin is by definition, 233 /* A call to the irrevocable builtin is by definition,
234 irrevocable. */ 234 irrevocable. */
235 if (TREE_CODE (x) == ADDR_EXPR) 235 if (TREE_CODE (x) == ADDR_EXPR)
236 x = TREE_OPERAND (x, 0); 236 x = TREE_OPERAND (x, 0);
237 if (TREE_CODE (x) == FUNCTION_DECL 237 if (TREE_CODE (x) == FUNCTION_DECL
238 && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL 238 && fndecl_built_in_p (x, BUILT_IN_TM_IRREVOCABLE))
239 && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
240 return true; 239 return true;
241 240
242 return false; 241 return false;
243 } 242 }
244 243
356 355
357 if (gimple_code (stmt) != GIMPLE_CALL) 356 if (gimple_code (stmt) != GIMPLE_CALL)
358 return false; 357 return false;
359 358
360 fndecl = gimple_call_fndecl (stmt); 359 fndecl = gimple_call_fndecl (stmt);
361 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 360 return (fndecl
361 && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
362 && BUILTIN_TM_LOAD_P (DECL_FUNCTION_CODE (fndecl))); 362 && BUILTIN_TM_LOAD_P (DECL_FUNCTION_CODE (fndecl)));
363 } 363 }
364 364
365 /* Same as above, but for simple TM loads, that is, not the 365 /* Same as above, but for simple TM loads, that is, not the
366 after-write, after-read, etc optimized variants. */ 366 after-write, after-read, etc optimized variants. */
372 372
373 if (gimple_code (stmt) != GIMPLE_CALL) 373 if (gimple_code (stmt) != GIMPLE_CALL)
374 return false; 374 return false;
375 375
376 fndecl = gimple_call_fndecl (stmt); 376 fndecl = gimple_call_fndecl (stmt);
377 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) 377 if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
378 { 378 {
379 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 379 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
380 return (fcode == BUILT_IN_TM_LOAD_1 380 return (fcode == BUILT_IN_TM_LOAD_1
381 || fcode == BUILT_IN_TM_LOAD_2 381 || fcode == BUILT_IN_TM_LOAD_2
382 || fcode == BUILT_IN_TM_LOAD_4 382 || fcode == BUILT_IN_TM_LOAD_4
400 400
401 if (gimple_code (stmt) != GIMPLE_CALL) 401 if (gimple_code (stmt) != GIMPLE_CALL)
402 return false; 402 return false;
403 403
404 fndecl = gimple_call_fndecl (stmt); 404 fndecl = gimple_call_fndecl (stmt);
405 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL 405 return (fndecl
406 && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
406 && BUILTIN_TM_STORE_P (DECL_FUNCTION_CODE (fndecl))); 407 && BUILTIN_TM_STORE_P (DECL_FUNCTION_CODE (fndecl)));
407 } 408 }
408 409
409 /* Same as above, but for simple TM stores, that is, not the 410 /* Same as above, but for simple TM stores, that is, not the
410 after-write, after-read, etc optimized variants. */ 411 after-write, after-read, etc optimized variants. */
416 417
417 if (gimple_code (stmt) != GIMPLE_CALL) 418 if (gimple_code (stmt) != GIMPLE_CALL)
418 return false; 419 return false;
419 420
420 fndecl = gimple_call_fndecl (stmt); 421 fndecl = gimple_call_fndecl (stmt);
421 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) 422 if (fndecl
423 && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
422 { 424 {
423 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 425 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
424 return (fcode == BUILT_IN_TM_STORE_1 426 return (fcode == BUILT_IN_TM_STORE_1
425 || fcode == BUILT_IN_TM_STORE_2 427 || fcode == BUILT_IN_TM_STORE_2
426 || fcode == BUILT_IN_TM_STORE_4 428 || fcode == BUILT_IN_TM_STORE_4
438 /* Return true if FNDECL is BUILT_IN_TM_ABORT. */ 440 /* Return true if FNDECL is BUILT_IN_TM_ABORT. */
439 441
440 static bool 442 static bool
441 is_tm_abort (tree fndecl) 443 is_tm_abort (tree fndecl)
442 { 444 {
443 return (fndecl 445 return (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_TM_ABORT));
444 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
445 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
446 } 446 }
447 447
448 /* Build a GENERIC tree for a user abort. This is called by front ends 448 /* Build a GENERIC tree for a user abort. This is called by front ends
449 while transforming the __tm_abort statement. */ 449 while transforming the __tm_abort statement. */
450 450
2005 { 2005 {
2006 g = gsi_stmt (gsi); 2006 g = gsi_stmt (gsi);
2007 if (gimple_code (g) == GIMPLE_CALL) 2007 if (gimple_code (g) == GIMPLE_CALL)
2008 { 2008 {
2009 tree fn = gimple_call_fndecl (g); 2009 tree fn = gimple_call_fndecl (g);
2010 if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL) 2010 if (fn && fndecl_built_in_p (fn, BUILT_IN_NORMAL))
2011 { 2011 {
2012 if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT 2012 if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT
2013 || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH) 2013 || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH)
2014 && region->exit_blocks) 2014 && region->exit_blocks)
2015 { 2015 {
2580 location_t loc = gimple_location (stmt); 2580 location_t loc = gimple_location (stmt);
2581 edge fallthru_edge = NULL; 2581 edge fallthru_edge = NULL;
2582 gassign *assign_stmt; 2582 gassign *assign_stmt;
2583 2583
2584 /* Remember if the call was going to throw. */ 2584 /* Remember if the call was going to throw. */
2585 if (stmt_can_throw_internal (stmt)) 2585 if (stmt_can_throw_internal (cfun, stmt))
2586 { 2586 {
2587 edge_iterator ei; 2587 edge_iterator ei;
2588 edge e; 2588 edge e;
2589 basic_block bb = gimple_bb (stmt); 2589 basic_block bb = gimple_bb (stmt);
2590 2590
2930 edge ei = make_edge (transaction_bb, test_bb, EDGE_FALLTHRU); 2930 edge ei = make_edge (transaction_bb, test_bb, EDGE_FALLTHRU);
2931 edge et = make_edge (test_bb, code_bb, EDGE_TRUE_VALUE); 2931 edge et = make_edge (test_bb, code_bb, EDGE_TRUE_VALUE);
2932 edge ef = make_edge (test_bb, join_bb, EDGE_FALSE_VALUE); 2932 edge ef = make_edge (test_bb, join_bb, EDGE_FALSE_VALUE);
2933 redirect_edge_pred (fallthru_edge, join_bb); 2933 redirect_edge_pred (fallthru_edge, join_bb);
2934 2934
2935 join_bb->frequency = test_bb->frequency = transaction_bb->frequency;
2936 join_bb->count = test_bb->count = transaction_bb->count; 2935 join_bb->count = test_bb->count = transaction_bb->count;
2937 2936
2938 ei->probability = profile_probability::always (); 2937 ei->probability = profile_probability::always ();
2939 et->probability = profile_probability::likely (); 2938 et->probability = profile_probability::likely ();
2940 ef->probability = profile_probability::unlikely (); 2939 ef->probability = profile_probability::unlikely ();
2941 2940
2942 code_bb->count = et->count (); 2941 code_bb->count = et->count ();
2943 code_bb->frequency = EDGE_FREQUENCY (et);
2944 2942
2945 transaction_bb = join_bb; 2943 transaction_bb = join_bb;
2946 } 2944 }
2947 2945
2948 // If we have an ABORT edge, create a test to perform the abort. 2946 // If we have an ABORT edge, create a test to perform the abort.
2962 t2 = build_int_cst (tm_state_type, 0); 2960 t2 = build_int_cst (tm_state_type, 0);
2963 stmt = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL); 2961 stmt = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
2964 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING); 2962 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2965 2963
2966 edge ei = make_edge (transaction_bb, test_bb, EDGE_FALLTHRU); 2964 edge ei = make_edge (transaction_bb, test_bb, EDGE_FALLTHRU);
2967 test_bb->frequency = transaction_bb->frequency;
2968 test_bb->count = transaction_bb->count; 2965 test_bb->count = transaction_bb->count;
2969 ei->probability = profile_probability::always (); 2966 ei->probability = profile_probability::always ();
2970 2967
2971 // Not abort edge. If both are live, chose one at random as we'll 2968 // Not abort edge. If both are live, chose one at random as we'll
2972 // we'll be fixing that up below. 2969 // we'll be fixing that up below.
3004 // Create the edge into test_bb first, as we want to copy values 3001 // Create the edge into test_bb first, as we want to copy values
3005 // out of the fallthru edge. 3002 // out of the fallthru edge.
3006 edge e = make_edge (transaction_bb, test_bb, fallthru_edge->flags); 3003 edge e = make_edge (transaction_bb, test_bb, fallthru_edge->flags);
3007 e->probability = fallthru_edge->probability; 3004 e->probability = fallthru_edge->probability;
3008 test_bb->count = fallthru_edge->count (); 3005 test_bb->count = fallthru_edge->count ();
3009 test_bb->frequency = EDGE_FREQUENCY (e);
3010 3006
3011 // Now update the edges to the inst/uninist implementations. 3007 // Now update the edges to the inst/uninist implementations.
3012 // For now assume that the paths are equally likely. When using HTM, 3008 // For now assume that the paths are equally likely. When using HTM,
3013 // we'll try the uninst path first and fallback to inst path if htm 3009 // we'll try the uninst path first and fallback to inst path if htm
3014 // buffers are exceeded. Without HTM we start with the inst path and 3010 // buffers are exceeded. Without HTM we start with the inst path and
5067 gsi = gsi_after_labels (bb); 5063 gsi = gsi_after_labels (bb);
5068 gsi_insert_before (&gsi, g, GSI_SAME_STMT); 5064 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
5069 5065
5070 node->create_edge (cgraph_node::get_create 5066 node->create_edge (cgraph_node::get_create
5071 (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE)), 5067 (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE)),
5072 g, gimple_bb (g)->count, 5068 g, gimple_bb (g)->count);
5073 compute_call_stmt_bb_frequency (node->decl,
5074 gimple_bb (g)));
5075 } 5069 }
5076 5070
5077 /* Construct a call to TM_GETTMCLONE and insert it before GSI. */ 5071 /* Construct a call to TM_GETTMCLONE and insert it before GSI. */
5078 5072
5079 static bool 5073 static bool
5118 ret = make_ssa_name (ret, g); 5112 ret = make_ssa_name (ret, g);
5119 gimple_call_set_lhs (g, ret); 5113 gimple_call_set_lhs (g, ret);
5120 5114
5121 gsi_insert_before (gsi, g, GSI_SAME_STMT); 5115 gsi_insert_before (gsi, g, GSI_SAME_STMT);
5122 5116
5123 node->create_edge (cgraph_node::get_create (gettm_fn), g, gimple_bb (g)->count, 5117 node->create_edge (cgraph_node::get_create (gettm_fn), g, gimple_bb (g)->count);
5124 compute_call_stmt_bb_frequency (node->decl,
5125 gimple_bb (g)));
5126 5118
5127 /* Cast return value from tm_gettmclone* into appropriate function 5119 /* Cast return value from tm_gettmclone* into appropriate function
5128 pointer. */ 5120 pointer. */
5129 callfn = create_tmp_var (TREE_TYPE (old_fn)); 5121 callfn = create_tmp_var (TREE_TYPE (old_fn));
5130 g2 = gimple_build_assign (callfn, 5122 g2 = gimple_build_assign (callfn,