comparison gcc/trans-mem.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Passes for transactional memory support. 1 /* Passes for transactional memory support.
2 Copyright (C) 2008-2018 Free Software Foundation, Inc. 2 Copyright (C) 2008-2020 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
44 #include "tree-into-ssa.h" 44 #include "tree-into-ssa.h"
45 #include "tree-inline.h" 45 #include "tree-inline.h"
46 #include "demangle.h" 46 #include "demangle.h"
47 #include "output.h" 47 #include "output.h"
48 #include "trans-mem.h" 48 #include "trans-mem.h"
49 #include "params.h"
50 #include "langhooks.h" 49 #include "langhooks.h"
51 #include "cfgloop.h" 50 #include "cfgloop.h"
52 #include "tree-ssa-address.h" 51 #include "tree-ssa-address.h"
53 #include "stringpool.h" 52 #include "stringpool.h"
54 #include "attribs.h" 53 #include "attribs.h"
263 /* Return true if CALL is const, or tm_pure. */ 262 /* Return true if CALL is const, or tm_pure. */
264 263
265 static bool 264 static bool
266 is_tm_pure_call (gimple *call) 265 is_tm_pure_call (gimple *call)
267 { 266 {
268 if (gimple_call_internal_p (call)) 267 return (gimple_call_flags (call) & (ECF_CONST | ECF_TM_PURE)) != 0;
269 return (gimple_call_flags (call) & (ECF_CONST | ECF_TM_PURE)) != 0;
270
271 tree fn = gimple_call_fn (call);
272
273 if (TREE_CODE (fn) == ADDR_EXPR)
274 {
275 fn = TREE_OPERAND (fn, 0);
276 gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
277 }
278 else
279 fn = TREE_TYPE (fn);
280
281 return is_tm_pure (fn);
282 } 268 }
283 269
284 /* Return true if X has been marked TM_CALLABLE. */ 270 /* Return true if X has been marked TM_CALLABLE. */
285 271
286 static bool 272 static bool
765 /* ??? We ought to come up with a way to add attributes to 751 /* ??? We ought to come up with a way to add attributes to
766 asm statements, and then add "transaction_safe" to it. 752 asm statements, and then add "transaction_safe" to it.
767 Either that or get the language spec to resurrect __tm_waiver. */ 753 Either that or get the language spec to resurrect __tm_waiver. */
768 if (d->block_flags & DIAG_TM_SAFE) 754 if (d->block_flags & DIAG_TM_SAFE)
769 error_at (gimple_location (stmt), 755 error_at (gimple_location (stmt),
770 "asm not allowed in atomic transaction"); 756 "%<asm%> not allowed in atomic transaction");
771 else if (d->func_flags & DIAG_TM_SAFE) 757 else if (d->func_flags & DIAG_TM_SAFE)
772 error_at (gimple_location (stmt), 758 error_at (gimple_location (stmt),
773 "asm not allowed in %<transaction_safe%> function"); 759 "%<asm%> not allowed in %<transaction_safe%> function");
774 break; 760 break;
775 761
776 case GIMPLE_TRANSACTION: 762 case GIMPLE_TRANSACTION:
777 { 763 {
778 gtransaction *trans_stmt = as_a <gtransaction *> (stmt); 764 gtransaction *trans_stmt = as_a <gtransaction *> (stmt);
1119 if (entry_block 1105 if (entry_block
1120 && transaction_invariant_address_p (lp->addr, entry_block) 1106 && transaction_invariant_address_p (lp->addr, entry_block)
1121 && TYPE_SIZE_UNIT (type) != NULL 1107 && TYPE_SIZE_UNIT (type) != NULL
1122 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)) 1108 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
1123 && ((HOST_WIDE_INT) tree_to_uhwi (TYPE_SIZE_UNIT (type)) 1109 && ((HOST_WIDE_INT) tree_to_uhwi (TYPE_SIZE_UNIT (type))
1124 < PARAM_VALUE (PARAM_TM_MAX_AGGREGATE_SIZE)) 1110 < param_tm_max_aggregate_size)
1125 /* We must be able to copy this type normally. I.e., no 1111 /* We must be able to copy this type normally. I.e., no
1126 special constructors and the like. */ 1112 special constructors and the like. */
1127 && !TREE_ADDRESSABLE (type)) 1113 && !TREE_ADDRESSABLE (type))
1128 { 1114 {
1129 lp->save_var = create_tmp_reg (TREE_TYPE (lp->addr), "tm_save"); 1115 lp->save_var = create_tmp_reg (TREE_TYPE (lp->addr), "tm_save");
2552 if (repl) 2538 if (repl)
2553 { 2539 {
2554 gimple_call_set_fndecl (stmt, repl); 2540 gimple_call_set_fndecl (stmt, repl);
2555 update_stmt (stmt); 2541 update_stmt (stmt);
2556 node = cgraph_node::create (repl); 2542 node = cgraph_node::create (repl);
2557 node->local.tm_may_enter_irr = false; 2543 node->tm_may_enter_irr = false;
2558 return expand_call_tm (region, gsi); 2544 return expand_call_tm (region, gsi);
2559 } 2545 }
2560 gcc_unreachable (); 2546 gcc_unreachable ();
2561 } 2547 }
2562 if (node->local.tm_may_enter_irr) 2548 if (node->tm_may_enter_irr)
2563 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE); 2549 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2564 2550
2565 if (is_tm_abort (fn_decl)) 2551 if (is_tm_abort (fn_decl))
2566 { 2552 {
2567 transaction_subcode_ior (region, GTMA_HAVE_ABORT); 2553 transaction_subcode_ior (region, GTMA_HAVE_ABORT);
3248 call_stmt = dyn_cast <gcall *> (stmt); 3234 call_stmt = dyn_cast <gcall *> (stmt);
3249 if ((!call_stmt) 3235 if ((!call_stmt)
3250 || (gimple_call_flags (call_stmt) & ECF_TM_BUILTIN) == 0) 3236 || (gimple_call_flags (call_stmt) & ECF_TM_BUILTIN) == 0)
3251 continue; 3237 continue;
3252 3238
3253 if (DECL_FUNCTION_CODE (gimple_call_fndecl (call_stmt)) 3239 if (gimple_call_builtin_p (call_stmt, BUILT_IN_TM_ABORT))
3254 == BUILT_IN_TM_ABORT)
3255 { 3240 {
3256 // If we have a ``_transaction_cancel [[outer]]'', there is only 3241 // If we have a ``_transaction_cancel [[outer]]'', there is only
3257 // one abnormal edge: to the transaction marked OUTER. 3242 // one abnormal edge: to the transaction marked OUTER.
3258 // All compiler-generated instances of BUILT_IN_TM_ABORT have a 3243 // All compiler-generated instances of BUILT_IN_TM_ABORT have a
3259 // constant argument, which we can examine here. Users invoking 3244 // constant argument, which we can examine here. Users invoking
3719 bool changed; 3704 bool changed;
3720 3705
3721 /* Allocate a worklist array/queue. Entries are only added to the 3706 /* Allocate a worklist array/queue. Entries are only added to the
3722 list if they were not already on the list. So the size is 3707 list if they were not already on the list. So the size is
3723 bounded by the number of basic blocks in the region. */ 3708 bounded by the number of basic blocks in the region. */
3709 gcc_assert (!blocks.is_empty ());
3724 qlen = blocks.length () - 1; 3710 qlen = blocks.length () - 1;
3725 qin = qout = worklist = 3711 qin = qout = worklist = XNEWVEC (basic_block, qlen);
3726 XNEWVEC (basic_block, qlen);
3727 3712
3728 /* Put every block in the region on the worklist. */ 3713 /* Put every block in the region on the worklist. */
3729 for (i = 0; blocks.iterate (i, &bb); ++i) 3714 for (i = 0; blocks.iterate (i, &bb); ++i)
3730 { 3715 {
3731 /* Seed AVAIL_OUT with the LOCAL set. */ 3716 /* Seed AVAIL_OUT with the LOCAL set. */
4425 yet implemented, so we can't check for it. */ 4410 yet implemented, so we can't check for it. */
4426 if (is_tm_safe (current_function_decl)) 4411 if (is_tm_safe (current_function_decl))
4427 { 4412 {
4428 tree t = build1 (NOP_EXPR, void_type_node, size_zero_node); 4413 tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
4429 SET_EXPR_LOCATION (t, gimple_location (stmt)); 4414 SET_EXPR_LOCATION (t, gimple_location (stmt));
4430 error ("%Kasm not allowed in %<transaction_safe%> function", t); 4415 error ("%K%<asm%> not allowed in %<transaction_safe%> function",
4416 t);
4431 } 4417 }
4432 return true; 4418 return true;
4433 4419
4434 default: 4420 default:
4435 break; 4421 break;
4733 if (d->irrevocable_blocks_clone) 4719 if (d->irrevocable_blocks_clone)
4734 return true; 4720 return true;
4735 4721
4736 /* We may have previously marked this function as tm_may_enter_irr; 4722 /* We may have previously marked this function as tm_may_enter_irr;
4737 see pass_diagnose_tm_blocks. */ 4723 see pass_diagnose_tm_blocks. */
4738 if (node->local.tm_may_enter_irr) 4724 if (node->tm_may_enter_irr)
4739 return true; 4725 return true;
4740 4726
4741 /* Recurse on the main body for aliases. In general, this will 4727 /* Recurse on the main body for aliases. In general, this will
4742 result in one of the bits above being set so that we will not 4728 result in one of the bits above being set so that we will not
4743 have to recurse next time. */ 4729 have to recurse next time. */
4757 { 4743 {
4758 struct cgraph_edge *e; 4744 struct cgraph_edge *e;
4759 4745
4760 for (e = node->callees; e ; e = e->next_callee) 4746 for (e = node->callees; e ; e = e->next_callee)
4761 if (!is_tm_callable (e->callee->decl) 4747 if (!is_tm_callable (e->callee->decl)
4762 && e->callee->local.tm_may_enter_irr) 4748 && e->callee->tm_may_enter_irr)
4763 error_at (gimple_location (e->call_stmt), 4749 error_at (gimple_location (e->call_stmt),
4764 "unsafe function call %qD within " 4750 "unsafe function call %qD within "
4765 "%<transaction_safe%> function", e->callee->decl); 4751 "%<transaction_safe%> function", e->callee->decl);
4766 } 4752 }
4767 4753
4799 tree fndecl; 4785 tree fndecl;
4800 4786
4801 if (gimple_code (stmt) == GIMPLE_ASM) 4787 if (gimple_code (stmt) == GIMPLE_ASM)
4802 { 4788 {
4803 error_at (gimple_location (stmt), 4789 error_at (gimple_location (stmt),
4804 "asm not allowed in atomic transaction"); 4790 "%<asm%> not allowed in atomic transaction");
4805 continue; 4791 continue;
4806 } 4792 }
4807 4793
4808 if (!is_gimple_call (stmt)) 4794 if (!is_gimple_call (stmt))
4809 continue; 4795 continue;
4825 if (is_tm_pure_call (stmt)) 4811 if (is_tm_pure_call (stmt))
4826 continue; 4812 continue;
4827 if (is_tm_callable (fndecl)) 4813 if (is_tm_callable (fndecl))
4828 continue; 4814 continue;
4829 4815
4830 if (cgraph_node::local_info (fndecl)->tm_may_enter_irr) 4816 if (cgraph_node::local_info_node (fndecl)->tm_may_enter_irr)
4831 error_at (gimple_location (stmt), 4817 error_at (gimple_location (stmt),
4832 "unsafe function call %qD within " 4818 "unsafe function call %qD within "
4833 "atomic transaction", fndecl); 4819 "atomic transaction", fndecl);
4834 } 4820 }
4835 4821
4857 old_asm_name = IDENTIFIER_POINTER (old_asm_id); 4843 old_asm_name = IDENTIFIER_POINTER (old_asm_id);
4858 dc = cplus_demangle_v3_components (old_asm_name, DMGL_NO_OPTS, &alloc); 4844 dc = cplus_demangle_v3_components (old_asm_name, DMGL_NO_OPTS, &alloc);
4859 4845
4860 if (dc == NULL) 4846 if (dc == NULL)
4861 { 4847 {
4862 char length[8]; 4848 char length[12];
4863 4849
4864 do_unencoded: 4850 do_unencoded:
4865 sprintf (length, "%u", IDENTIFIER_LENGTH (old_asm_id)); 4851 sprintf (length, "%u", IDENTIFIER_LENGTH (old_asm_id));
4866 tm_name = concat ("_ZGTt", length, old_asm_name, NULL); 4852 tm_name = concat ("_ZGTt", length, old_asm_name, NULL);
4867 } 4853 }
5000 varpool_node::get (new_decl)->set_comdat_group 4986 varpool_node::get (new_decl)->set_comdat_group
5001 (tm_mangle (DECL_COMDAT_GROUP (old_decl))); 4987 (tm_mangle (DECL_COMDAT_GROUP (old_decl)));
5002 4988
5003 gcc_assert (!old_node->ipa_transforms_to_apply.exists ()); 4989 gcc_assert (!old_node->ipa_transforms_to_apply.exists ());
5004 new_node = old_node->create_version_clone (new_decl, vNULL, NULL); 4990 new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
5005 new_node->local.local = false; 4991 new_node->local = false;
5006 new_node->externally_visible = old_node->externally_visible; 4992 new_node->externally_visible = old_node->externally_visible;
5007 new_node->lowered = true; 4993 new_node->lowered = true;
5008 new_node->tm_clone = 1; 4994 new_node->tm_clone = 1;
5009 if (!old_node->implicit_section) 4995 if (!old_node->implicit_section)
5010 new_node->set_section (old_node->get_section ()); 4996 new_node->set_section (old_node->get_section ());
5020 TREE_PUBLIC (new_decl) = 0; 5006 TREE_PUBLIC (new_decl) = 0;
5021 DECL_WEAK (new_decl) = 0; 5007 DECL_WEAK (new_decl) = 0;
5022 } 5008 }
5023 5009
5024 tree_function_versioning (old_decl, new_decl, 5010 tree_function_versioning (old_decl, new_decl,
5025 NULL, false, NULL, 5011 NULL, NULL, false, NULL, NULL);
5026 false, NULL, NULL);
5027 } 5012 }
5028 5013
5029 record_tm_clone_pair (old_decl, new_decl); 5014 record_tm_clone_pair (old_decl, new_decl);
5030 5015
5031 symtab->call_cgraph_insertion_hooks (new_node); 5016 symtab->call_cgraph_insertion_hooks (new_node);
5221 /* ??? This seems broken. How is it that we're marking the 5206 /* ??? This seems broken. How is it that we're marking the
5222 CALLEE as may_enter_irr? Surely we should be marking the 5207 CALLEE as may_enter_irr? Surely we should be marking the
5223 CALLER. Also note that find_tm_replacement_function also 5208 CALLER. Also note that find_tm_replacement_function also
5224 contains mappings into the TM runtime, e.g. memcpy. These 5209 contains mappings into the TM runtime, e.g. memcpy. These
5225 we know won't go irrevocable. */ 5210 we know won't go irrevocable. */
5226 new_node->local.tm_may_enter_irr = 1; 5211 new_node->tm_may_enter_irr = 1;
5227 } 5212 }
5228 else 5213 else
5229 { 5214 {
5230 struct tm_ipa_cg_data *d; 5215 struct tm_ipa_cg_data *d;
5231 struct cgraph_node *tnode = e->callee; 5216 struct cgraph_node *tnode = e->callee;
5429 /* ... marked tm_pure, record that fact for the runtime by 5414 /* ... marked tm_pure, record that fact for the runtime by
5430 indicating that the pure function is its own tm_callable. 5415 indicating that the pure function is its own tm_callable.
5431 No need to do this if the function's address can't be taken. */ 5416 No need to do this if the function's address can't be taken. */
5432 if (is_tm_pure (node->decl)) 5417 if (is_tm_pure (node->decl))
5433 { 5418 {
5434 if (!node->local.local) 5419 if (!node->local)
5435 record_tm_clone_pair (node->decl, node->decl); 5420 record_tm_clone_pair (node->decl, node->decl);
5436 continue; 5421 continue;
5437 } 5422 }
5438 5423
5439 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 5424 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
5556 } 5541 }
5557 5542
5558 node = irr_worklist[i]; 5543 node = irr_worklist[i];
5559 d = get_cg_data (&node, true); 5544 d = get_cg_data (&node, true);
5560 d->in_worklist = false; 5545 d->in_worklist = false;
5561 node->local.tm_may_enter_irr = true; 5546 node->tm_may_enter_irr = true;
5562 5547
5563 /* Propagate back to normal callers. */ 5548 /* Propagate back to normal callers. */
5564 for (e = node->callers; e ; e = e->next_caller) 5549 for (e = node->callers; e ; e = e->next_caller)
5565 { 5550 {
5566 caller = e->caller; 5551 caller = e->caller;
5567 if (!is_tm_safe_or_pure (caller->decl) 5552 if (!is_tm_safe_or_pure (caller->decl)
5568 && !caller->local.tm_may_enter_irr) 5553 && !caller->tm_may_enter_irr)
5569 { 5554 {
5570 d = get_cg_data (&caller, true); 5555 d = get_cg_data (&caller, true);
5571 maybe_push_queue (caller, &irr_worklist, &d->in_worklist); 5556 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
5572 } 5557 }
5573 } 5558 }
5574 5559
5575 /* Propagate back to referring aliases as well. */ 5560 /* Propagate back to referring aliases as well. */
5576 FOR_EACH_ALIAS (node, ref) 5561 FOR_EACH_ALIAS (node, ref)
5577 { 5562 {
5578 caller = dyn_cast<cgraph_node *> (ref->referring); 5563 caller = dyn_cast<cgraph_node *> (ref->referring);
5579 if (!caller->local.tm_may_enter_irr) 5564 if (!caller->tm_may_enter_irr)
5580 { 5565 {
5581 /* ?? Do not traverse aliases here. */ 5566 /* ?? Do not traverse aliases here. */
5582 d = get_cg_data (&caller, false); 5567 d = get_cg_data (&caller, false);
5583 maybe_push_queue (caller, &irr_worklist, &d->in_worklist); 5568 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
5584 } 5569 }