ipa-inline-analysis.c (eliminated_by_inlining_prob): Handle &this->field expressions.
[official-gcc.git] / gcc / trans-mem.c
blob211c45e48fb70d2c4a216c6ae77b8854c4b810c5
1 /* Passes for transactional memory support.
2 Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tree.h"
24 #include "gimple.h"
25 #include "tree-flow.h"
26 #include "tree-pass.h"
27 #include "tree-inline.h"
28 #include "diagnostic-core.h"
29 #include "demangle.h"
30 #include "output.h"
31 #include "trans-mem.h"
32 #include "params.h"
33 #include "target.h"
34 #include "langhooks.h"
35 #include "gimple-pretty-print.h"
36 #include "cfgloop.h"
39 #define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 2000 - 1)
40 #define PROB_ALWAYS (REG_BR_PROB_BASE)
42 #define A_RUNINSTRUMENTEDCODE 0x0001
43 #define A_RUNUNINSTRUMENTEDCODE 0x0002
44 #define A_SAVELIVEVARIABLES 0x0004
45 #define A_RESTORELIVEVARIABLES 0x0008
46 #define A_ABORTTRANSACTION 0x0010
48 #define AR_USERABORT 0x0001
49 #define AR_USERRETRY 0x0002
50 #define AR_TMCONFLICT 0x0004
51 #define AR_EXCEPTIONBLOCKABORT 0x0008
52 #define AR_OUTERABORT 0x0010
54 #define MODE_SERIALIRREVOCABLE 0x0000
57 /* The representation of a transaction changes several times during the
58 lowering process. In the beginning, in the front-end we have the
59 GENERIC tree TRANSACTION_EXPR. For example,
61 __transaction {
62 local++;
63 if (++global == 10)
64 __tm_abort;
67 During initial gimplification (gimplify.c) the TRANSACTION_EXPR node is
68 trivially replaced with a GIMPLE_TRANSACTION node.
70 During pass_lower_tm, we examine the body of transactions looking
71 for aborts. Transactions that do not contain an abort may be
72 merged into an outer transaction. We also add a TRY-FINALLY node
73 to arrange for the transaction to be committed on any exit.
75 [??? Think about how this arrangement affects throw-with-commit
76 and throw-with-abort operations. In this case we want the TRY to
77 handle gotos, but not to catch any exceptions because the transaction
78 will already be closed.]
80 GIMPLE_TRANSACTION [label=NULL] {
81 try {
82 local = local + 1;
83 t0 = global;
84 t1 = t0 + 1;
85 global = t1;
86 if (t1 == 10)
87 __builtin___tm_abort ();
88 } finally {
89 __builtin___tm_commit ();
93 During pass_lower_eh, we create EH regions for the transactions,
94 intermixed with the regular EH stuff. This gives us a nice persistent
95 mapping (all the way through rtl) from transactional memory operation
96 back to the transaction, which allows us to get the abnormal edges
97 correct to model transaction aborts and restarts:
99 GIMPLE_TRANSACTION [label=over]
100 local = local + 1;
101 t0 = global;
102 t1 = t0 + 1;
103 global = t1;
104 if (t1 == 10)
105 __builtin___tm_abort ();
106 __builtin___tm_commit ();
107 over:
109 This is the end of all_lowering_passes, and so is what is present
110 during the IPA passes, and through all of the optimization passes.
112 During pass_ipa_tm, we examine all GIMPLE_TRANSACTION blocks in all
113 functions and mark functions for cloning.
115 At the end of gimple optimization, before exiting SSA form,
116 pass_tm_edges replaces statements that perform transactional
117 memory operations with the appropriate TM builtins, and swap
118 out function calls with their transactional clones. At this
119 point we introduce the abnormal transaction restart edges and
120 complete lowering of the GIMPLE_TRANSACTION node.
122 x = __builtin___tm_start (MAY_ABORT);
123 eh_label:
124 if (x & abort_transaction)
125 goto over;
126 local = local + 1;
127 t0 = __builtin___tm_load (global);
128 t1 = t0 + 1;
129 __builtin___tm_store (&global, t1);
130 if (t1 == 10)
131 __builtin___tm_abort ();
132 __builtin___tm_commit ();
133 over:
137 /* Return the attributes we want to examine for X, or NULL if it's not
138 something we examine. We look at function types, but allow pointers
139 to function types and function decls and peek through. */
141 static tree
142 get_attrs_for (const_tree x)
144 switch (TREE_CODE (x))
146 case FUNCTION_DECL:
147 return TYPE_ATTRIBUTES (TREE_TYPE (x));
148 break;
150 default:
151 if (TYPE_P (x))
152 return NULL;
153 x = TREE_TYPE (x);
154 if (TREE_CODE (x) != POINTER_TYPE)
155 return NULL;
156 /* FALLTHRU */
158 case POINTER_TYPE:
159 x = TREE_TYPE (x);
160 if (TREE_CODE (x) != FUNCTION_TYPE && TREE_CODE (x) != METHOD_TYPE)
161 return NULL;
162 /* FALLTHRU */
164 case FUNCTION_TYPE:
165 case METHOD_TYPE:
166 return TYPE_ATTRIBUTES (x);
170 /* Return true if X has been marked TM_PURE. */
172 bool
173 is_tm_pure (const_tree x)
175 unsigned flags;
177 switch (TREE_CODE (x))
179 case FUNCTION_DECL:
180 case FUNCTION_TYPE:
181 case METHOD_TYPE:
182 break;
184 default:
185 if (TYPE_P (x))
186 return false;
187 x = TREE_TYPE (x);
188 if (TREE_CODE (x) != POINTER_TYPE)
189 return false;
190 /* FALLTHRU */
192 case POINTER_TYPE:
193 x = TREE_TYPE (x);
194 if (TREE_CODE (x) != FUNCTION_TYPE && TREE_CODE (x) != METHOD_TYPE)
195 return false;
196 break;
199 flags = flags_from_decl_or_type (x);
200 return (flags & ECF_TM_PURE) != 0;
203 /* Return true if X has been marked TM_IRREVOCABLE. */
205 static bool
206 is_tm_irrevocable (tree x)
208 tree attrs = get_attrs_for (x);
210 if (attrs && lookup_attribute ("transaction_unsafe", attrs))
211 return true;
213 /* A call to the irrevocable builtin is by definition,
214 irrevocable. */
215 if (TREE_CODE (x) == ADDR_EXPR)
216 x = TREE_OPERAND (x, 0);
217 if (TREE_CODE (x) == FUNCTION_DECL
218 && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL
219 && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
220 return true;
222 return false;
225 /* Return true if X has been marked TM_SAFE. */
227 bool
228 is_tm_safe (const_tree x)
230 if (flag_tm)
232 tree attrs = get_attrs_for (x);
233 if (attrs)
235 if (lookup_attribute ("transaction_safe", attrs))
236 return true;
237 if (lookup_attribute ("transaction_may_cancel_outer", attrs))
238 return true;
241 return false;
244 /* Return true if CALL is const, or tm_pure. */
246 static bool
247 is_tm_pure_call (gimple call)
249 tree fn = gimple_call_fn (call);
251 if (TREE_CODE (fn) == ADDR_EXPR)
253 fn = TREE_OPERAND (fn, 0);
254 gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
256 else
257 fn = TREE_TYPE (fn);
259 return is_tm_pure (fn);
262 /* Return true if X has been marked TM_CALLABLE. */
264 static bool
265 is_tm_callable (tree x)
267 tree attrs = get_attrs_for (x);
268 if (attrs)
270 if (lookup_attribute ("transaction_callable", attrs))
271 return true;
272 if (lookup_attribute ("transaction_safe", attrs))
273 return true;
274 if (lookup_attribute ("transaction_may_cancel_outer", attrs))
275 return true;
277 return false;
280 /* Return true if X has been marked TRANSACTION_MAY_CANCEL_OUTER. */
282 bool
283 is_tm_may_cancel_outer (tree x)
285 tree attrs = get_attrs_for (x);
286 if (attrs)
287 return lookup_attribute ("transaction_may_cancel_outer", attrs) != NULL;
288 return false;
291 /* Return true for built in functions that "end" a transaction. */
293 bool
294 is_tm_ending_fndecl (tree fndecl)
296 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
297 switch (DECL_FUNCTION_CODE (fndecl))
299 case BUILT_IN_TM_COMMIT:
300 case BUILT_IN_TM_COMMIT_EH:
301 case BUILT_IN_TM_ABORT:
302 case BUILT_IN_TM_IRREVOCABLE:
303 return true;
304 default:
305 break;
308 return false;
311 /* Return true if STMT is a TM load. */
313 static bool
314 is_tm_load (gimple stmt)
316 tree fndecl;
318 if (gimple_code (stmt) != GIMPLE_CALL)
319 return false;
321 fndecl = gimple_call_fndecl (stmt);
322 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
323 && BUILTIN_TM_LOAD_P (DECL_FUNCTION_CODE (fndecl)));
326 /* Same as above, but for simple TM loads, that is, not the
327 after-write, after-read, etc optimized variants. */
329 static bool
330 is_tm_simple_load (gimple stmt)
332 tree fndecl;
334 if (gimple_code (stmt) != GIMPLE_CALL)
335 return false;
337 fndecl = gimple_call_fndecl (stmt);
338 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
340 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
341 return (fcode == BUILT_IN_TM_LOAD_1
342 || fcode == BUILT_IN_TM_LOAD_2
343 || fcode == BUILT_IN_TM_LOAD_4
344 || fcode == BUILT_IN_TM_LOAD_8
345 || fcode == BUILT_IN_TM_LOAD_FLOAT
346 || fcode == BUILT_IN_TM_LOAD_DOUBLE
347 || fcode == BUILT_IN_TM_LOAD_LDOUBLE
348 || fcode == BUILT_IN_TM_LOAD_M64
349 || fcode == BUILT_IN_TM_LOAD_M128
350 || fcode == BUILT_IN_TM_LOAD_M256);
352 return false;
355 /* Return true if STMT is a TM store. */
357 static bool
358 is_tm_store (gimple stmt)
360 tree fndecl;
362 if (gimple_code (stmt) != GIMPLE_CALL)
363 return false;
365 fndecl = gimple_call_fndecl (stmt);
366 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
367 && BUILTIN_TM_STORE_P (DECL_FUNCTION_CODE (fndecl)));
370 /* Same as above, but for simple TM stores, that is, not the
371 after-write, after-read, etc optimized variants. */
373 static bool
374 is_tm_simple_store (gimple stmt)
376 tree fndecl;
378 if (gimple_code (stmt) != GIMPLE_CALL)
379 return false;
381 fndecl = gimple_call_fndecl (stmt);
382 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
384 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
385 return (fcode == BUILT_IN_TM_STORE_1
386 || fcode == BUILT_IN_TM_STORE_2
387 || fcode == BUILT_IN_TM_STORE_4
388 || fcode == BUILT_IN_TM_STORE_8
389 || fcode == BUILT_IN_TM_STORE_FLOAT
390 || fcode == BUILT_IN_TM_STORE_DOUBLE
391 || fcode == BUILT_IN_TM_STORE_LDOUBLE
392 || fcode == BUILT_IN_TM_STORE_M64
393 || fcode == BUILT_IN_TM_STORE_M128
394 || fcode == BUILT_IN_TM_STORE_M256);
396 return false;
399 /* Return true if FNDECL is BUILT_IN_TM_ABORT. */
401 static bool
402 is_tm_abort (tree fndecl)
404 return (fndecl
405 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
406 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
409 /* Build a GENERIC tree for a user abort. This is called by front ends
410 while transforming the __tm_abort statement. */
412 tree
413 build_tm_abort_call (location_t loc, bool is_outer)
415 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TM_ABORT), 1,
416 build_int_cst (integer_type_node,
417 AR_USERABORT
418 | (is_outer ? AR_OUTERABORT : 0)));
421 /* Common gateing function for several of the TM passes. */
423 static bool
424 gate_tm (void)
426 return flag_tm;
429 /* Map for aribtrary function replacement under TM, as created
430 by the tm_wrap attribute. */
432 static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
433 htab_t tm_wrap_map;
435 void
436 record_tm_replacement (tree from, tree to)
438 struct tree_map **slot, *h;
440 /* Do not inline wrapper functions that will get replaced in the TM
441 pass.
443 Suppose you have foo() that will get replaced into tmfoo(). Make
444 sure the inliner doesn't try to outsmart us and inline foo()
445 before we get a chance to do the TM replacement. */
446 DECL_UNINLINABLE (from) = 1;
448 if (tm_wrap_map == NULL)
449 tm_wrap_map = htab_create_ggc (32, tree_map_hash, tree_map_eq, 0);
451 h = ggc_alloc_tree_map ();
452 h->hash = htab_hash_pointer (from);
453 h->base.from = from;
454 h->to = to;
456 slot = (struct tree_map **)
457 htab_find_slot_with_hash (tm_wrap_map, h, h->hash, INSERT);
458 *slot = h;
461 /* Return a TM-aware replacement function for DECL. */
463 static tree
464 find_tm_replacement_function (tree fndecl)
466 if (tm_wrap_map)
468 struct tree_map *h, in;
470 in.base.from = fndecl;
471 in.hash = htab_hash_pointer (fndecl);
472 h = (struct tree_map *) htab_find_with_hash (tm_wrap_map, &in, in.hash);
473 if (h)
474 return h->to;
477 /* ??? We may well want TM versions of most of the common <string.h>
478 functions. For now, we've already these two defined. */
479 /* Adjust expand_call_tm() attributes as necessary for the cases
480 handled here: */
481 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
482 switch (DECL_FUNCTION_CODE (fndecl))
484 case BUILT_IN_MEMCPY:
485 return builtin_decl_explicit (BUILT_IN_TM_MEMCPY);
486 case BUILT_IN_MEMMOVE:
487 return builtin_decl_explicit (BUILT_IN_TM_MEMMOVE);
488 case BUILT_IN_MEMSET:
489 return builtin_decl_explicit (BUILT_IN_TM_MEMSET);
490 default:
491 return NULL;
494 return NULL;
497 /* When appropriate, record TM replacement for memory allocation functions.
499 FROM is the FNDECL to wrap. */
500 void
501 tm_malloc_replacement (tree from)
503 const char *str;
504 tree to;
506 if (TREE_CODE (from) != FUNCTION_DECL)
507 return;
509 /* If we have a previous replacement, the user must be explicitly
510 wrapping malloc/calloc/free. They better know what they're
511 doing... */
512 if (find_tm_replacement_function (from))
513 return;
515 str = IDENTIFIER_POINTER (DECL_NAME (from));
517 if (!strcmp (str, "malloc"))
518 to = builtin_decl_explicit (BUILT_IN_TM_MALLOC);
519 else if (!strcmp (str, "calloc"))
520 to = builtin_decl_explicit (BUILT_IN_TM_CALLOC);
521 else if (!strcmp (str, "free"))
522 to = builtin_decl_explicit (BUILT_IN_TM_FREE);
523 else
524 return;
526 TREE_NOTHROW (to) = 0;
528 record_tm_replacement (from, to);
531 /* Diagnostics for tm_safe functions/regions. Called by the front end
532 once we've lowered the function to high-gimple. */
534 /* Subroutine of diagnose_tm_safe_errors, called through walk_gimple_seq.
535 Process exactly one statement. WI->INFO is set to non-null when in
536 the context of a tm_safe function, and null for a __transaction block. */
538 #define DIAG_TM_OUTER 1
539 #define DIAG_TM_SAFE 2
540 #define DIAG_TM_RELAXED 4
542 struct diagnose_tm
544 unsigned int summary_flags : 8;
545 unsigned int block_flags : 8;
546 unsigned int func_flags : 8;
547 unsigned int saw_volatile : 1;
548 gimple stmt;
551 /* Return true if T is a volatile variable of some kind. */
553 static bool
554 volatile_var_p (tree t)
556 return (SSA_VAR_P (t)
557 && TREE_THIS_VOLATILE (TREE_TYPE (t)));
560 /* Tree callback function for diagnose_tm pass. */
562 static tree
563 diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
564 void *data)
566 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
567 struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
569 if (volatile_var_p (*tp)
570 && d->block_flags & DIAG_TM_SAFE
571 && !d->saw_volatile)
573 d->saw_volatile = 1;
574 error_at (gimple_location (d->stmt),
575 "invalid volatile use of %qD inside transaction",
576 *tp);
579 return NULL_TREE;
582 static tree
583 diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
584 struct walk_stmt_info *wi)
586 gimple stmt = gsi_stmt (*gsi);
587 struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
589 /* Save stmt for use in leaf analysis. */
590 d->stmt = stmt;
592 switch (gimple_code (stmt))
594 case GIMPLE_CALL:
596 tree fn = gimple_call_fn (stmt);
598 if ((d->summary_flags & DIAG_TM_OUTER) == 0
599 && is_tm_may_cancel_outer (fn))
600 error_at (gimple_location (stmt),
601 "%<transaction_may_cancel_outer%> function call not within"
602 " outer transaction or %<transaction_may_cancel_outer%>");
604 if (d->summary_flags & DIAG_TM_SAFE)
606 bool is_safe, direct_call_p;
607 tree replacement;
609 if (TREE_CODE (fn) == ADDR_EXPR
610 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
612 direct_call_p = true;
613 replacement = TREE_OPERAND (fn, 0);
614 replacement = find_tm_replacement_function (replacement);
615 if (replacement)
616 fn = replacement;
618 else
620 direct_call_p = false;
621 replacement = NULL_TREE;
624 if (is_tm_safe_or_pure (fn))
625 is_safe = true;
626 else if (is_tm_callable (fn) || is_tm_irrevocable (fn))
628 /* A function explicitly marked transaction_callable as
629 opposed to transaction_safe is being defined to be
630 unsafe as part of its ABI, regardless of its contents. */
631 is_safe = false;
633 else if (direct_call_p)
635 if (flags_from_decl_or_type (fn) & ECF_TM_BUILTIN)
636 is_safe = true;
637 else if (replacement)
639 /* ??? At present we've been considering replacements
640 merely transaction_callable, and therefore might
641 enter irrevocable. The tm_wrap attribute has not
642 yet made it into the new language spec. */
643 is_safe = false;
645 else
647 /* ??? Diagnostics for unmarked direct calls moved into
648 the IPA pass. Section 3.2 of the spec details how
649 functions not marked should be considered "implicitly
650 safe" based on having examined the function body. */
651 is_safe = true;
654 else
656 /* An unmarked indirect call. Consider it unsafe even
657 though optimization may yet figure out how to inline. */
658 is_safe = false;
661 if (!is_safe)
663 if (TREE_CODE (fn) == ADDR_EXPR)
664 fn = TREE_OPERAND (fn, 0);
665 if (d->block_flags & DIAG_TM_SAFE)
667 if (direct_call_p)
668 error_at (gimple_location (stmt),
669 "unsafe function call %qD within "
670 "atomic transaction", fn);
671 else
673 if (!DECL_P (fn) || DECL_NAME (fn))
674 error_at (gimple_location (stmt),
675 "unsafe function call %qE within "
676 "atomic transaction", fn);
677 else
678 error_at (gimple_location (stmt),
679 "unsafe indirect function call within "
680 "atomic transaction");
683 else
685 if (direct_call_p)
686 error_at (gimple_location (stmt),
687 "unsafe function call %qD within "
688 "%<transaction_safe%> function", fn);
689 else
691 if (!DECL_P (fn) || DECL_NAME (fn))
692 error_at (gimple_location (stmt),
693 "unsafe function call %qE within "
694 "%<transaction_safe%> function", fn);
695 else
696 error_at (gimple_location (stmt),
697 "unsafe indirect function call within "
698 "%<transaction_safe%> function");
704 break;
706 case GIMPLE_ASM:
707 /* ??? We ought to come up with a way to add attributes to
708 asm statements, and then add "transaction_safe" to it.
709 Either that or get the language spec to resurrect __tm_waiver. */
710 if (d->block_flags & DIAG_TM_SAFE)
711 error_at (gimple_location (stmt),
712 "asm not allowed in atomic transaction");
713 else if (d->func_flags & DIAG_TM_SAFE)
714 error_at (gimple_location (stmt),
715 "asm not allowed in %<transaction_safe%> function");
716 break;
718 case GIMPLE_TRANSACTION:
720 unsigned char inner_flags = DIAG_TM_SAFE;
722 if (gimple_transaction_subcode (stmt) & GTMA_IS_RELAXED)
724 if (d->block_flags & DIAG_TM_SAFE)
725 error_at (gimple_location (stmt),
726 "relaxed transaction in atomic transaction");
727 else if (d->func_flags & DIAG_TM_SAFE)
728 error_at (gimple_location (stmt),
729 "relaxed transaction in %<transaction_safe%> function");
730 inner_flags = DIAG_TM_RELAXED;
732 else if (gimple_transaction_subcode (stmt) & GTMA_IS_OUTER)
734 if (d->block_flags)
735 error_at (gimple_location (stmt),
736 "outer transaction in transaction");
737 else if (d->func_flags & DIAG_TM_OUTER)
738 error_at (gimple_location (stmt),
739 "outer transaction in "
740 "%<transaction_may_cancel_outer%> function");
741 else if (d->func_flags & DIAG_TM_SAFE)
742 error_at (gimple_location (stmt),
743 "outer transaction in %<transaction_safe%> function");
744 inner_flags |= DIAG_TM_OUTER;
747 *handled_ops_p = true;
748 if (gimple_transaction_body (stmt))
750 struct walk_stmt_info wi_inner;
751 struct diagnose_tm d_inner;
753 memset (&d_inner, 0, sizeof (d_inner));
754 d_inner.func_flags = d->func_flags;
755 d_inner.block_flags = d->block_flags | inner_flags;
756 d_inner.summary_flags = d_inner.func_flags | d_inner.block_flags;
758 memset (&wi_inner, 0, sizeof (wi_inner));
759 wi_inner.info = &d_inner;
761 walk_gimple_seq (gimple_transaction_body (stmt),
762 diagnose_tm_1, diagnose_tm_1_op, &wi_inner);
765 break;
767 default:
768 break;
771 return NULL_TREE;
774 static unsigned int
775 diagnose_tm_blocks (void)
777 struct walk_stmt_info wi;
778 struct diagnose_tm d;
780 memset (&d, 0, sizeof (d));
781 if (is_tm_may_cancel_outer (current_function_decl))
782 d.func_flags = DIAG_TM_OUTER | DIAG_TM_SAFE;
783 else if (is_tm_safe (current_function_decl))
784 d.func_flags = DIAG_TM_SAFE;
785 d.summary_flags = d.func_flags;
787 memset (&wi, 0, sizeof (wi));
788 wi.info = &d;
790 walk_gimple_seq (gimple_body (current_function_decl),
791 diagnose_tm_1, diagnose_tm_1_op, &wi);
793 return 0;
796 struct gimple_opt_pass pass_diagnose_tm_blocks =
799 GIMPLE_PASS,
800 "*diagnose_tm_blocks", /* name */
801 gate_tm, /* gate */
802 diagnose_tm_blocks, /* execute */
803 NULL, /* sub */
804 NULL, /* next */
805 0, /* static_pass_number */
806 TV_TRANS_MEM, /* tv_id */
807 PROP_gimple_any, /* properties_required */
808 0, /* properties_provided */
809 0, /* properties_destroyed */
810 0, /* todo_flags_start */
811 0, /* todo_flags_finish */
815 /* Instead of instrumenting thread private memory, we save the
816 addresses in a log which we later use to save/restore the addresses
817 upon transaction start/restart.
819 The log is keyed by address, where each element contains individual
820 statements among different code paths that perform the store.
822 This log is later used to generate either plain save/restore of the
823 addresses upon transaction start/restart, or calls to the ITM_L*
824 logging functions.
826 So for something like:
828 struct large { int x[1000]; };
829 struct large lala = { 0 };
830 __transaction {
831 lala.x[i] = 123;
835 We can either save/restore:
837 lala = { 0 };
838 trxn = _ITM_startTransaction ();
839 if (trxn & a_saveLiveVariables)
840 tmp_lala1 = lala.x[i];
841 else if (a & a_restoreLiveVariables)
842 lala.x[i] = tmp_lala1;
844 or use the logging functions:
846 lala = { 0 };
847 trxn = _ITM_startTransaction ();
848 _ITM_LU4 (&lala.x[i]);
850 Obviously, if we use _ITM_L* to log, we prefer to call _ITM_L* as
851 far up the dominator tree to shadow all of the writes to a given
852 location (thus reducing the total number of logging calls), but not
853 so high as to be called on a path that does not perform a
854 write. */
856 /* One individual log entry. We may have multiple statements for the
857 same location if neither dominate each other (on different
858 execution paths). */
859 typedef struct tm_log_entry
861 /* Address to save. */
862 tree addr;
863 /* Entry block for the transaction this address occurs in. */
864 basic_block entry_block;
865 /* Dominating statements the store occurs in. */
866 gimple_vec stmts;
867 /* Initially, while we are building the log, we place a nonzero
868 value here to mean that this address *will* be saved with a
869 save/restore sequence. Later, when generating the save sequence
870 we place the SSA temp generated here. */
871 tree save_var;
872 } *tm_log_entry_t;
874 /* The actual log. */
875 static htab_t tm_log;
877 /* Addresses to log with a save/restore sequence. These should be in
878 dominator order. */
879 static VEC(tree,heap) *tm_log_save_addresses;
881 /* Map for an SSA_NAME originally pointing to a non aliased new piece
882 of memory (malloc, alloc, etc). */
883 static htab_t tm_new_mem_hash;
885 enum thread_memory_type
887 mem_non_local = 0,
888 mem_thread_local,
889 mem_transaction_local,
890 mem_max
893 typedef struct tm_new_mem_map
895 /* SSA_NAME being dereferenced. */
896 tree val;
897 enum thread_memory_type local_new_memory;
898 } tm_new_mem_map_t;
900 /* Htab support. Return hash value for a `tm_log_entry'. */
901 static hashval_t
902 tm_log_hash (const void *p)
904 const struct tm_log_entry *log = (const struct tm_log_entry *) p;
905 return iterative_hash_expr (log->addr, 0);
908 /* Htab support. Return true if two log entries are the same. */
909 static int
910 tm_log_eq (const void *p1, const void *p2)
912 const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1;
913 const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2;
915 /* FIXME:
917 rth: I suggest that we get rid of the component refs etc.
918 I.e. resolve the reference to base + offset.
920 We may need to actually finish a merge with mainline for this,
921 since we'd like to be presented with Richi's MEM_REF_EXPRs more
922 often than not. But in the meantime your tm_log_entry could save
923 the results of get_inner_reference.
925 See: g++.dg/tm/pr46653.C
928 /* Special case plain equality because operand_equal_p() below will
929 return FALSE if the addresses are equal but they have
930 side-effects (e.g. a volatile address). */
931 if (log1->addr == log2->addr)
932 return true;
934 return operand_equal_p (log1->addr, log2->addr, 0);
937 /* Htab support. Free one tm_log_entry. */
938 static void
939 tm_log_free (void *p)
941 struct tm_log_entry *lp = (struct tm_log_entry *) p;
942 VEC_free (gimple, heap, lp->stmts);
943 free (lp);
946 /* Initialize logging data structures. */
947 static void
948 tm_log_init (void)
950 tm_log = htab_create (10, tm_log_hash, tm_log_eq, tm_log_free);
951 tm_new_mem_hash = htab_create (5, struct_ptr_hash, struct_ptr_eq, free);
952 tm_log_save_addresses = VEC_alloc (tree, heap, 5);
955 /* Free logging data structures. */
956 static void
957 tm_log_delete (void)
959 htab_delete (tm_log);
960 htab_delete (tm_new_mem_hash);
961 VEC_free (tree, heap, tm_log_save_addresses);
964 /* Return true if MEM is a transaction invariant memory for the TM
965 region starting at REGION_ENTRY_BLOCK. */
966 static bool
967 transaction_invariant_address_p (const_tree mem, basic_block region_entry_block)
969 if ((TREE_CODE (mem) == INDIRECT_REF || TREE_CODE (mem) == MEM_REF)
970 && TREE_CODE (TREE_OPERAND (mem, 0)) == SSA_NAME)
972 basic_block def_bb;
974 def_bb = gimple_bb (SSA_NAME_DEF_STMT (TREE_OPERAND (mem, 0)));
975 return def_bb != region_entry_block
976 && dominated_by_p (CDI_DOMINATORS, region_entry_block, def_bb);
979 mem = strip_invariant_refs (mem);
980 return mem && (CONSTANT_CLASS_P (mem) || decl_address_invariant_p (mem));
983 /* Given an address ADDR in STMT, find it in the memory log or add it,
984 making sure to keep only the addresses highest in the dominator
985 tree.
987 ENTRY_BLOCK is the entry_block for the transaction.
989 If we find the address in the log, make sure it's either the same
990 address, or an equivalent one that dominates ADDR.
992 If we find the address, but neither ADDR dominates the found
993 address, nor the found one dominates ADDR, we're on different
994 execution paths. Add it.
996 If known, ENTRY_BLOCK is the entry block for the region, otherwise
997 NULL. */
998 static void
999 tm_log_add (basic_block entry_block, tree addr, gimple stmt)
1001 void **slot;
1002 struct tm_log_entry l, *lp;
1004 l.addr = addr;
1005 slot = htab_find_slot (tm_log, &l, INSERT);
1006 if (!*slot)
1008 tree type = TREE_TYPE (addr);
1010 lp = XNEW (struct tm_log_entry);
1011 lp->addr = addr;
1012 *slot = lp;
1014 /* Small invariant addresses can be handled as save/restores. */
1015 if (entry_block
1016 && transaction_invariant_address_p (lp->addr, entry_block)
1017 && TYPE_SIZE_UNIT (type) != NULL
1018 && host_integerp (TYPE_SIZE_UNIT (type), 1)
1019 && (tree_low_cst (TYPE_SIZE_UNIT (type), 1)
1020 < PARAM_VALUE (PARAM_TM_MAX_AGGREGATE_SIZE))
1021 /* We must be able to copy this type normally. I.e., no
1022 special constructors and the like. */
1023 && !TREE_ADDRESSABLE (type))
1025 lp->save_var = create_tmp_reg (TREE_TYPE (lp->addr), "tm_save");
1026 lp->stmts = NULL;
1027 lp->entry_block = entry_block;
1028 /* Save addresses separately in dominator order so we don't
1029 get confused by overlapping addresses in the save/restore
1030 sequence. */
1031 VEC_safe_push (tree, heap, tm_log_save_addresses, lp->addr);
1033 else
1035 /* Use the logging functions. */
1036 lp->stmts = VEC_alloc (gimple, heap, 5);
1037 VEC_quick_push (gimple, lp->stmts, stmt);
1038 lp->save_var = NULL;
1041 else
1043 size_t i;
1044 gimple oldstmt;
1046 lp = (struct tm_log_entry *) *slot;
1048 /* If we're generating a save/restore sequence, we don't care
1049 about statements. */
1050 if (lp->save_var)
1051 return;
1053 for (i = 0; VEC_iterate (gimple, lp->stmts, i, oldstmt); ++i)
1055 if (stmt == oldstmt)
1056 return;
1057 /* We already have a store to the same address, higher up the
1058 dominator tree. Nothing to do. */
1059 if (dominated_by_p (CDI_DOMINATORS,
1060 gimple_bb (stmt), gimple_bb (oldstmt)))
1061 return;
1062 /* We should be processing blocks in dominator tree order. */
1063 gcc_assert (!dominated_by_p (CDI_DOMINATORS,
1064 gimple_bb (oldstmt), gimple_bb (stmt)));
1066 /* Store is on a different code path. */
1067 VEC_safe_push (gimple, heap, lp->stmts, stmt);
1071 /* Gimplify the address of a TARGET_MEM_REF. Return the SSA_NAME
1072 result, insert the new statements before GSI. */
1074 static tree
1075 gimplify_addr (gimple_stmt_iterator *gsi, tree x)
1077 if (TREE_CODE (x) == TARGET_MEM_REF)
1078 x = tree_mem_ref_addr (build_pointer_type (TREE_TYPE (x)), x);
1079 else
1080 x = build_fold_addr_expr (x);
1081 return force_gimple_operand_gsi (gsi, x, true, NULL, true, GSI_SAME_STMT);
1084 /* Instrument one address with the logging functions.
1085 ADDR is the address to save.
1086 STMT is the statement before which to place it. */
1087 static void
1088 tm_log_emit_stmt (tree addr, gimple stmt)
1090 tree type = TREE_TYPE (addr);
1091 tree size = TYPE_SIZE_UNIT (type);
1092 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
1093 gimple log;
1094 enum built_in_function code = BUILT_IN_TM_LOG;
1096 if (type == float_type_node)
1097 code = BUILT_IN_TM_LOG_FLOAT;
1098 else if (type == double_type_node)
1099 code = BUILT_IN_TM_LOG_DOUBLE;
1100 else if (type == long_double_type_node)
1101 code = BUILT_IN_TM_LOG_LDOUBLE;
1102 else if (host_integerp (size, 1))
1104 unsigned int n = tree_low_cst (size, 1);
1105 switch (n)
1107 case 1:
1108 code = BUILT_IN_TM_LOG_1;
1109 break;
1110 case 2:
1111 code = BUILT_IN_TM_LOG_2;
1112 break;
1113 case 4:
1114 code = BUILT_IN_TM_LOG_4;
1115 break;
1116 case 8:
1117 code = BUILT_IN_TM_LOG_8;
1118 break;
1119 default:
1120 code = BUILT_IN_TM_LOG;
1121 if (TREE_CODE (type) == VECTOR_TYPE)
1123 if (n == 8 && builtin_decl_explicit (BUILT_IN_TM_LOG_M64))
1124 code = BUILT_IN_TM_LOG_M64;
1125 else if (n == 16 && builtin_decl_explicit (BUILT_IN_TM_LOG_M128))
1126 code = BUILT_IN_TM_LOG_M128;
1127 else if (n == 32 && builtin_decl_explicit (BUILT_IN_TM_LOG_M256))
1128 code = BUILT_IN_TM_LOG_M256;
1130 break;
1134 addr = gimplify_addr (&gsi, addr);
1135 if (code == BUILT_IN_TM_LOG)
1136 log = gimple_build_call (builtin_decl_explicit (code), 2, addr, size);
1137 else
1138 log = gimple_build_call (builtin_decl_explicit (code), 1, addr);
1139 gsi_insert_before (&gsi, log, GSI_SAME_STMT);
1142 /* Go through the log and instrument address that must be instrumented
1143 with the logging functions. Leave the save/restore addresses for
1144 later. */
1145 static void
1146 tm_log_emit (void)
1148 htab_iterator hi;
1149 struct tm_log_entry *lp;
1151 FOR_EACH_HTAB_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
1153 size_t i;
1154 gimple stmt;
1156 if (dump_file)
1158 fprintf (dump_file, "TM thread private mem logging: ");
1159 print_generic_expr (dump_file, lp->addr, 0);
1160 fprintf (dump_file, "\n");
1163 if (lp->save_var)
1165 if (dump_file)
1166 fprintf (dump_file, "DUMPING to variable\n");
1167 continue;
1169 else
1171 if (dump_file)
1172 fprintf (dump_file, "DUMPING with logging functions\n");
1173 for (i = 0; VEC_iterate (gimple, lp->stmts, i, stmt); ++i)
1174 tm_log_emit_stmt (lp->addr, stmt);
1179 /* Emit the save sequence for the corresponding addresses in the log.
1180 ENTRY_BLOCK is the entry block for the transaction.
1181 BB is the basic block to insert the code in. */
1182 static void
1183 tm_log_emit_saves (basic_block entry_block, basic_block bb)
1185 size_t i;
1186 gimple_stmt_iterator gsi = gsi_last_bb (bb);
1187 gimple stmt;
1188 struct tm_log_entry l, *lp;
1190 for (i = 0; i < VEC_length (tree, tm_log_save_addresses); ++i)
1192 l.addr = VEC_index (tree, tm_log_save_addresses, i);
1193 lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
1194 gcc_assert (lp->save_var != NULL);
1196 /* We only care about variables in the current transaction. */
1197 if (lp->entry_block != entry_block)
1198 continue;
1200 stmt = gimple_build_assign (lp->save_var, unshare_expr (lp->addr));
1202 /* Make sure we can create an SSA_NAME for this type. For
1203 instance, aggregates aren't allowed, in which case the system
1204 will create a VOP for us and everything will just work. */
1205 if (is_gimple_reg_type (TREE_TYPE (lp->save_var)))
1207 lp->save_var = make_ssa_name (lp->save_var, stmt);
1208 gimple_assign_set_lhs (stmt, lp->save_var);
1211 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1215 /* Emit the restore sequence for the corresponding addresses in the log.
1216 ENTRY_BLOCK is the entry block for the transaction.
1217 BB is the basic block to insert the code in. */
1218 static void
1219 tm_log_emit_restores (basic_block entry_block, basic_block bb)
1221 int i;
1222 struct tm_log_entry l, *lp;
1223 gimple_stmt_iterator gsi;
1224 gimple stmt;
1226 for (i = VEC_length (tree, tm_log_save_addresses) - 1; i >= 0; i--)
1228 l.addr = VEC_index (tree, tm_log_save_addresses, i);
1229 lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
1230 gcc_assert (lp->save_var != NULL);
1232 /* We only care about variables in the current transaction. */
1233 if (lp->entry_block != entry_block)
1234 continue;
1236 /* Restores are in LIFO order from the saves in case we have
1237 overlaps. */
1238 gsi = gsi_start_bb (bb);
1240 stmt = gimple_build_assign (unshare_expr (lp->addr), lp->save_var);
1241 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
1245 /* Emit the checks for performing either a save or a restore sequence.
1247 TRXN_PROP is either A_SAVELIVEVARIABLES or A_RESTORELIVEVARIABLES.
1249 The code sequence is inserted in a new basic block created in
1250 END_BB which is inserted between BEFORE_BB and the destination of
1251 FALLTHRU_EDGE.
1253 STATUS is the return value from _ITM_beginTransaction.
1254 ENTRY_BLOCK is the entry block for the transaction.
1255 EMITF is a callback to emit the actual save/restore code.
1257 The basic block containing the conditional checking for TRXN_PROP
1258 is returned. */
1259 static basic_block
1260 tm_log_emit_save_or_restores (basic_block entry_block,
1261 unsigned trxn_prop,
1262 tree status,
1263 void (*emitf)(basic_block, basic_block),
1264 basic_block before_bb,
1265 edge fallthru_edge,
1266 basic_block *end_bb)
1268 basic_block cond_bb, code_bb;
1269 gimple cond_stmt, stmt;
1270 gimple_stmt_iterator gsi;
1271 tree t1, t2;
1272 int old_flags = fallthru_edge->flags;
1274 cond_bb = create_empty_bb (before_bb);
1275 code_bb = create_empty_bb (cond_bb);
1276 *end_bb = create_empty_bb (code_bb);
1277 if (current_loops && before_bb->loop_father)
1279 add_bb_to_loop (cond_bb, before_bb->loop_father);
1280 add_bb_to_loop (code_bb, before_bb->loop_father);
1281 add_bb_to_loop (*end_bb, before_bb->loop_father);
1283 redirect_edge_pred (fallthru_edge, *end_bb);
1284 fallthru_edge->flags = EDGE_FALLTHRU;
1285 make_edge (before_bb, cond_bb, old_flags);
1287 set_immediate_dominator (CDI_DOMINATORS, cond_bb, before_bb);
1288 set_immediate_dominator (CDI_DOMINATORS, code_bb, cond_bb);
1290 gsi = gsi_last_bb (cond_bb);
1292 /* t1 = status & A_{property}. */
1293 t1 = create_tmp_reg (TREE_TYPE (status), NULL);
1294 t2 = build_int_cst (TREE_TYPE (status), trxn_prop);
1295 stmt = gimple_build_assign_with_ops (BIT_AND_EXPR, t1, status, t2);
1296 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
1298 /* if (t1). */
1299 t2 = build_int_cst (TREE_TYPE (status), 0);
1300 cond_stmt = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
1301 gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
1303 emitf (entry_block, code_bb);
1305 make_edge (cond_bb, code_bb, EDGE_TRUE_VALUE);
1306 make_edge (cond_bb, *end_bb, EDGE_FALSE_VALUE);
1307 make_edge (code_bb, *end_bb, EDGE_FALLTHRU);
1309 return cond_bb;
1312 static tree lower_sequence_tm (gimple_stmt_iterator *, bool *,
1313 struct walk_stmt_info *);
1314 static tree lower_sequence_no_tm (gimple_stmt_iterator *, bool *,
1315 struct walk_stmt_info *);
1317 /* Evaluate an address X being dereferenced and determine if it
1318 originally points to a non aliased new chunk of memory (malloc,
1319 alloca, etc).
1321 Return MEM_THREAD_LOCAL if it points to a thread-local address.
1322 Return MEM_TRANSACTION_LOCAL if it points to a transaction-local address.
1323 Return MEM_NON_LOCAL otherwise.
1325 ENTRY_BLOCK is the entry block to the transaction containing the
1326 dereference of X. */
1327 static enum thread_memory_type
1328 thread_private_new_memory (basic_block entry_block, tree x)
1330 gimple stmt = NULL;
1331 enum tree_code code;
1332 void **slot;
1333 tm_new_mem_map_t elt, *elt_p;
1334 tree val = x;
1335 enum thread_memory_type retval = mem_transaction_local;
1337 if (!entry_block
1338 || TREE_CODE (x) != SSA_NAME
1339 /* Possible uninitialized use, or a function argument. In
1340 either case, we don't care. */
1341 || SSA_NAME_IS_DEFAULT_DEF (x))
1342 return mem_non_local;
1344 /* Look in cache first. */
1345 elt.val = x;
1346 slot = htab_find_slot (tm_new_mem_hash, &elt, INSERT);
1347 elt_p = (tm_new_mem_map_t *) *slot;
1348 if (elt_p)
1349 return elt_p->local_new_memory;
1351 /* Optimistically assume the memory is transaction local during
1352 processing. This catches recursion into this variable. */
1353 *slot = elt_p = XNEW (tm_new_mem_map_t);
1354 elt_p->val = val;
1355 elt_p->local_new_memory = mem_transaction_local;
1357 /* Search DEF chain to find the original definition of this address. */
1360 if (ptr_deref_may_alias_global_p (x))
1362 /* Address escapes. This is not thread-private. */
1363 retval = mem_non_local;
1364 goto new_memory_ret;
1367 stmt = SSA_NAME_DEF_STMT (x);
1369 /* If the malloc call is outside the transaction, this is
1370 thread-local. */
1371 if (retval != mem_thread_local
1372 && !dominated_by_p (CDI_DOMINATORS, gimple_bb (stmt), entry_block))
1373 retval = mem_thread_local;
1375 if (is_gimple_assign (stmt))
1377 code = gimple_assign_rhs_code (stmt);
1378 /* x = foo ==> foo */
1379 if (code == SSA_NAME)
1380 x = gimple_assign_rhs1 (stmt);
1381 /* x = foo + n ==> foo */
1382 else if (code == POINTER_PLUS_EXPR)
1383 x = gimple_assign_rhs1 (stmt);
1384 /* x = (cast*) foo ==> foo */
1385 else if (code == VIEW_CONVERT_EXPR || code == NOP_EXPR)
1386 x = gimple_assign_rhs1 (stmt);
1387 /* x = c ? op1 : op2 == > op1 or op2 just like a PHI */
1388 else if (code == COND_EXPR)
1390 tree op1 = gimple_assign_rhs2 (stmt);
1391 tree op2 = gimple_assign_rhs3 (stmt);
1392 enum thread_memory_type mem;
1393 retval = thread_private_new_memory (entry_block, op1);
1394 if (retval == mem_non_local)
1395 goto new_memory_ret;
1396 mem = thread_private_new_memory (entry_block, op2);
1397 retval = MIN (retval, mem);
1398 goto new_memory_ret;
1400 else
1402 retval = mem_non_local;
1403 goto new_memory_ret;
1406 else
1408 if (gimple_code (stmt) == GIMPLE_PHI)
1410 unsigned int i;
1411 enum thread_memory_type mem;
1412 tree phi_result = gimple_phi_result (stmt);
1414 /* If any of the ancestors are non-local, we are sure to
1415 be non-local. Otherwise we can avoid doing anything
1416 and inherit what has already been generated. */
1417 retval = mem_max;
1418 for (i = 0; i < gimple_phi_num_args (stmt); ++i)
1420 tree op = PHI_ARG_DEF (stmt, i);
1422 /* Exclude self-assignment. */
1423 if (phi_result == op)
1424 continue;
1426 mem = thread_private_new_memory (entry_block, op);
1427 if (mem == mem_non_local)
1429 retval = mem;
1430 goto new_memory_ret;
1432 retval = MIN (retval, mem);
1434 goto new_memory_ret;
1436 break;
1439 while (TREE_CODE (x) == SSA_NAME);
1441 if (stmt && is_gimple_call (stmt) && gimple_call_flags (stmt) & ECF_MALLOC)
1442 /* Thread-local or transaction-local. */
1444 else
1445 retval = mem_non_local;
1447 new_memory_ret:
1448 elt_p->local_new_memory = retval;
1449 return retval;
1452 /* Determine whether X has to be instrumented using a read
1453 or write barrier.
1455 ENTRY_BLOCK is the entry block for the region where stmt resides
1456 in. NULL if unknown.
1458 STMT is the statement in which X occurs in. It is used for thread
1459 private memory instrumentation. If no TPM instrumentation is
1460 desired, STMT should be null. */
1461 static bool
1462 requires_barrier (basic_block entry_block, tree x, gimple stmt)
1464 tree orig = x;
1465 while (handled_component_p (x))
1466 x = TREE_OPERAND (x, 0);
1468 switch (TREE_CODE (x))
1470 case INDIRECT_REF:
1471 case MEM_REF:
1473 enum thread_memory_type ret;
1475 ret = thread_private_new_memory (entry_block, TREE_OPERAND (x, 0));
1476 if (ret == mem_non_local)
1477 return true;
1478 if (stmt && ret == mem_thread_local)
1479 /* ?? Should we pass `orig', or the INDIRECT_REF X. ?? */
1480 tm_log_add (entry_block, orig, stmt);
1482 /* Transaction-locals require nothing at all. For malloc, a
1483 transaction restart frees the memory and we reallocate.
1484 For alloca, the stack pointer gets reset by the retry and
1485 we reallocate. */
1486 return false;
1489 case TARGET_MEM_REF:
1490 if (TREE_CODE (TMR_BASE (x)) != ADDR_EXPR)
1491 return true;
1492 x = TREE_OPERAND (TMR_BASE (x), 0);
1493 if (TREE_CODE (x) == PARM_DECL)
1494 return false;
1495 gcc_assert (TREE_CODE (x) == VAR_DECL);
1496 /* FALLTHRU */
1498 case PARM_DECL:
1499 case RESULT_DECL:
1500 case VAR_DECL:
1501 if (DECL_BY_REFERENCE (x))
1503 /* ??? This value is a pointer, but aggregate_value_p has been
1504 jigged to return true which confuses needs_to_live_in_memory.
1505 This ought to be cleaned up generically.
1507 FIXME: Verify this still happens after the next mainline
1508 merge. Testcase ie g++.dg/tm/pr47554.C.
1510 return false;
1513 if (is_global_var (x))
1514 return !TREE_READONLY (x);
1515 if (/* FIXME: This condition should actually go below in the
1516 tm_log_add() call, however is_call_clobbered() depends on
1517 aliasing info which is not available during
1518 gimplification. Since requires_barrier() gets called
1519 during lower_sequence_tm/gimplification, leave the call
1520 to needs_to_live_in_memory until we eliminate
1521 lower_sequence_tm altogether. */
1522 needs_to_live_in_memory (x))
1523 return true;
1524 else
1526 /* For local memory that doesn't escape (aka thread private
1527 memory), we can either save the value at the beginning of
1528 the transaction and restore on restart, or call a tm
1529 function to dynamically save and restore on restart
1530 (ITM_L*). */
1531 if (stmt)
1532 tm_log_add (entry_block, orig, stmt);
1533 return false;
1536 default:
1537 return false;
1541 /* Mark the GIMPLE_ASSIGN statement as appropriate for being inside
1542 a transaction region. */
1544 static void
1545 examine_assign_tm (unsigned *state, gimple_stmt_iterator *gsi)
1547 gimple stmt = gsi_stmt (*gsi);
1549 if (requires_barrier (/*entry_block=*/NULL, gimple_assign_rhs1 (stmt), NULL))
1550 *state |= GTMA_HAVE_LOAD;
1551 if (requires_barrier (/*entry_block=*/NULL, gimple_assign_lhs (stmt), NULL))
1552 *state |= GTMA_HAVE_STORE;
1555 /* Mark a GIMPLE_CALL as appropriate for being inside a transaction. */
1557 static void
1558 examine_call_tm (unsigned *state, gimple_stmt_iterator *gsi)
1560 gimple stmt = gsi_stmt (*gsi);
1561 tree fn;
1563 if (is_tm_pure_call (stmt))
1564 return;
1566 /* Check if this call is a transaction abort. */
1567 fn = gimple_call_fndecl (stmt);
1568 if (is_tm_abort (fn))
1569 *state |= GTMA_HAVE_ABORT;
1571 /* Note that something may happen. */
1572 *state |= GTMA_HAVE_LOAD | GTMA_HAVE_STORE;
1575 /* Lower a GIMPLE_TRANSACTION statement. */
1577 static void
1578 lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi)
1580 gimple g, stmt = gsi_stmt (*gsi);
1581 unsigned int *outer_state = (unsigned int *) wi->info;
1582 unsigned int this_state = 0;
1583 struct walk_stmt_info this_wi;
1585 /* First, lower the body. The scanning that we do inside gives
1586 us some idea of what we're dealing with. */
1587 memset (&this_wi, 0, sizeof (this_wi));
1588 this_wi.info = (void *) &this_state;
1589 walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
1590 lower_sequence_tm, NULL, &this_wi);
1592 /* If there was absolutely nothing transaction related inside the
1593 transaction, we may elide it. Likewise if this is a nested
1594 transaction and does not contain an abort. */
1595 if (this_state == 0
1596 || (!(this_state & GTMA_HAVE_ABORT) && outer_state != NULL))
1598 if (outer_state)
1599 *outer_state |= this_state;
1601 gsi_insert_seq_before (gsi, gimple_transaction_body (stmt),
1602 GSI_SAME_STMT);
1603 gimple_transaction_set_body (stmt, NULL);
1605 gsi_remove (gsi, true);
1606 wi->removed_stmt = true;
1607 return;
1610 /* Wrap the body of the transaction in a try-finally node so that
1611 the commit call is always properly called. */
1612 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT), 0);
1613 if (flag_exceptions)
1615 tree ptr;
1616 gimple_seq n_seq, e_seq;
1618 n_seq = gimple_seq_alloc_with_stmt (g);
1619 e_seq = NULL;
1621 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_EH_POINTER),
1622 1, integer_zero_node);
1623 ptr = create_tmp_var (ptr_type_node, NULL);
1624 gimple_call_set_lhs (g, ptr);
1625 gimple_seq_add_stmt (&e_seq, g);
1627 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT_EH),
1628 1, ptr);
1629 gimple_seq_add_stmt (&e_seq, g);
1631 g = gimple_build_eh_else (n_seq, e_seq);
1634 g = gimple_build_try (gimple_transaction_body (stmt),
1635 gimple_seq_alloc_with_stmt (g), GIMPLE_TRY_FINALLY);
1636 gsi_insert_after (gsi, g, GSI_CONTINUE_LINKING);
1638 gimple_transaction_set_body (stmt, NULL);
1640 /* If the transaction calls abort or if this is an outer transaction,
1641 add an "over" label afterwards. */
1642 if ((this_state & (GTMA_HAVE_ABORT))
1643 || (gimple_transaction_subcode(stmt) & GTMA_IS_OUTER))
1645 tree label = create_artificial_label (UNKNOWN_LOCATION);
1646 gimple_transaction_set_label (stmt, label);
1647 gsi_insert_after (gsi, gimple_build_label (label), GSI_CONTINUE_LINKING);
1650 /* Record the set of operations found for use later. */
1651 this_state |= gimple_transaction_subcode (stmt) & GTMA_DECLARATION_MASK;
1652 gimple_transaction_set_subcode (stmt, this_state);
1655 /* Iterate through the statements in the sequence, lowering them all
1656 as appropriate for being in a transaction. */
1658 static tree
1659 lower_sequence_tm (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1660 struct walk_stmt_info *wi)
1662 unsigned int *state = (unsigned int *) wi->info;
1663 gimple stmt = gsi_stmt (*gsi);
1665 *handled_ops_p = true;
1666 switch (gimple_code (stmt))
1668 case GIMPLE_ASSIGN:
1669 /* Only memory reads/writes need to be instrumented. */
1670 if (gimple_assign_single_p (stmt))
1671 examine_assign_tm (state, gsi);
1672 break;
1674 case GIMPLE_CALL:
1675 examine_call_tm (state, gsi);
1676 break;
1678 case GIMPLE_ASM:
1679 *state |= GTMA_MAY_ENTER_IRREVOCABLE;
1680 break;
1682 case GIMPLE_TRANSACTION:
1683 lower_transaction (gsi, wi);
1684 break;
1686 default:
1687 *handled_ops_p = !gimple_has_substatements (stmt);
1688 break;
1691 return NULL_TREE;
1694 /* Iterate through the statements in the sequence, lowering them all
1695 as appropriate for being outside of a transaction. */
1697 static tree
1698 lower_sequence_no_tm (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1699 struct walk_stmt_info * wi)
1701 gimple stmt = gsi_stmt (*gsi);
1703 if (gimple_code (stmt) == GIMPLE_TRANSACTION)
1705 *handled_ops_p = true;
1706 lower_transaction (gsi, wi);
1708 else
1709 *handled_ops_p = !gimple_has_substatements (stmt);
1711 return NULL_TREE;
1714 /* Main entry point for flattening GIMPLE_TRANSACTION constructs. After
1715 this, GIMPLE_TRANSACTION nodes still exist, but the nested body has
1716 been moved out, and all the data required for constructing a proper
1717 CFG has been recorded. */
1719 static unsigned int
1720 execute_lower_tm (void)
1722 struct walk_stmt_info wi;
1723 gimple_seq body;
1725 /* Transactional clones aren't created until a later pass. */
1726 gcc_assert (!decl_is_tm_clone (current_function_decl));
1728 body = gimple_body (current_function_decl);
1729 memset (&wi, 0, sizeof (wi));
1730 walk_gimple_seq_mod (&body, lower_sequence_no_tm, NULL, &wi);
1731 gimple_set_body (current_function_decl, body);
1733 return 0;
1736 struct gimple_opt_pass pass_lower_tm =
1739 GIMPLE_PASS,
1740 "tmlower", /* name */
1741 gate_tm, /* gate */
1742 execute_lower_tm, /* execute */
1743 NULL, /* sub */
1744 NULL, /* next */
1745 0, /* static_pass_number */
1746 TV_TRANS_MEM, /* tv_id */
1747 PROP_gimple_lcf, /* properties_required */
1748 0, /* properties_provided */
1749 0, /* properties_destroyed */
1750 0, /* todo_flags_start */
1751 0, /* todo_flags_finish */
1755 /* Collect region information for each transaction. */
1757 struct tm_region
1759 /* Link to the next unnested transaction. */
1760 struct tm_region *next;
1762 /* Link to the next inner transaction. */
1763 struct tm_region *inner;
1765 /* Link to the next outer transaction. */
1766 struct tm_region *outer;
1768 /* The GIMPLE_TRANSACTION statement beginning this transaction. */
1769 gimple transaction_stmt;
1771 /* The entry block to this region. */
1772 basic_block entry_block;
1774 /* The set of all blocks that end the region; NULL if only EXIT_BLOCK.
1775 These blocks are still a part of the region (i.e., the border is
1776 inclusive). Note that this set is only complete for paths in the CFG
1777 starting at ENTRY_BLOCK, and that there is no exit block recorded for
1778 the edge to the "over" label. */
1779 bitmap exit_blocks;
1781 /* The set of all blocks that have an TM_IRREVOCABLE call. */
1782 bitmap irr_blocks;
1785 typedef struct tm_region *tm_region_p;
1786 DEF_VEC_P (tm_region_p);
1787 DEF_VEC_ALLOC_P (tm_region_p, heap);
1789 /* True if there are pending edge statements to be committed for the
1790 current function being scanned in the tmmark pass. */
1791 bool pending_edge_inserts_p;
1793 static struct tm_region *all_tm_regions;
1794 static bitmap_obstack tm_obstack;
1797 /* A subroutine of tm_region_init. Record the existence of the
1798 GIMPLE_TRANSACTION statement in a tree of tm_region elements. */
1800 static struct tm_region *
1801 tm_region_init_0 (struct tm_region *outer, basic_block bb, gimple stmt)
1803 struct tm_region *region;
1805 region = (struct tm_region *)
1806 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
1808 if (outer)
1810 region->next = outer->inner;
1811 outer->inner = region;
1813 else
1815 region->next = all_tm_regions;
1816 all_tm_regions = region;
1818 region->inner = NULL;
1819 region->outer = outer;
1821 region->transaction_stmt = stmt;
1823 /* There are either one or two edges out of the block containing
1824 the GIMPLE_TRANSACTION, one to the actual region and one to the
1825 "over" label if the region contains an abort. The former will
1826 always be the one marked FALLTHRU. */
1827 region->entry_block = FALLTHRU_EDGE (bb)->dest;
1829 region->exit_blocks = BITMAP_ALLOC (&tm_obstack);
1830 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
1832 return region;
1835 /* A subroutine of tm_region_init. Record all the exit and
1836 irrevocable blocks in BB into the region's exit_blocks and
1837 irr_blocks bitmaps. Returns the new region being scanned. */
1839 static struct tm_region *
1840 tm_region_init_1 (struct tm_region *region, basic_block bb)
1842 gimple_stmt_iterator gsi;
1843 gimple g;
1845 if (!region
1846 || (!region->irr_blocks && !region->exit_blocks))
1847 return region;
1849 /* Check to see if this is the end of a region by seeing if it
1850 contains a call to __builtin_tm_commit{,_eh}. Note that the
1851 outermost region for DECL_IS_TM_CLONE need not collect this. */
1852 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
1854 g = gsi_stmt (gsi);
1855 if (gimple_code (g) == GIMPLE_CALL)
1857 tree fn = gimple_call_fndecl (g);
1858 if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
1860 if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT
1861 || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH)
1862 && region->exit_blocks)
1864 bitmap_set_bit (region->exit_blocks, bb->index);
1865 region = region->outer;
1866 break;
1868 if (DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_IRREVOCABLE)
1869 bitmap_set_bit (region->irr_blocks, bb->index);
1873 return region;
1876 /* Collect all of the transaction regions within the current function
1877 and record them in ALL_TM_REGIONS. The REGION parameter may specify
1878 an "outermost" region for use by tm clones. */
1880 static void
1881 tm_region_init (struct tm_region *region)
1883 gimple g;
1884 edge_iterator ei;
1885 edge e;
1886 basic_block bb;
1887 VEC(basic_block, heap) *queue = NULL;
1888 bitmap visited_blocks = BITMAP_ALLOC (NULL);
1889 struct tm_region *old_region;
1890 VEC(tm_region_p, heap) *bb_regions = NULL;
1892 all_tm_regions = region;
1893 bb = single_succ (ENTRY_BLOCK_PTR);
1895 /* We could store this information in bb->aux, but we may get called
1896 through get_all_tm_blocks() from another pass that may be already
1897 using bb->aux. */
1898 VEC_safe_grow_cleared (tm_region_p, heap, bb_regions, last_basic_block);
1900 VEC_safe_push (basic_block, heap, queue, bb);
1901 VEC_replace (tm_region_p, bb_regions, bb->index, region);
1904 bb = VEC_pop (basic_block, queue);
1905 region = VEC_index (tm_region_p, bb_regions, bb->index);
1906 VEC_replace (tm_region_p, bb_regions, bb->index, NULL);
1908 /* Record exit and irrevocable blocks. */
1909 region = tm_region_init_1 (region, bb);
1911 /* Check for the last statement in the block beginning a new region. */
1912 g = last_stmt (bb);
1913 old_region = region;
1914 if (g && gimple_code (g) == GIMPLE_TRANSACTION)
1915 region = tm_region_init_0 (region, bb, g);
1917 /* Process subsequent blocks. */
1918 FOR_EACH_EDGE (e, ei, bb->succs)
1919 if (!bitmap_bit_p (visited_blocks, e->dest->index))
1921 bitmap_set_bit (visited_blocks, e->dest->index);
1922 VEC_safe_push (basic_block, heap, queue, e->dest);
1924 /* If the current block started a new region, make sure that only
1925 the entry block of the new region is associated with this region.
1926 Other successors are still part of the old region. */
1927 if (old_region != region && e->dest != region->entry_block)
1928 VEC_replace (tm_region_p, bb_regions, e->dest->index, old_region);
1929 else
1930 VEC_replace (tm_region_p, bb_regions, e->dest->index, region);
1933 while (!VEC_empty (basic_block, queue));
1934 VEC_free (basic_block, heap, queue);
1935 BITMAP_FREE (visited_blocks);
1936 VEC_free (tm_region_p, heap, bb_regions);
1939 /* The "gate" function for all transactional memory expansion and optimization
1940 passes. We collect region information for each top-level transaction, and
1941 if we don't find any, we skip all of the TM passes. Each region will have
1942 all of the exit blocks recorded, and the originating statement. */
1944 static bool
1945 gate_tm_init (void)
1947 if (!flag_tm)
1948 return false;
1950 calculate_dominance_info (CDI_DOMINATORS);
1951 bitmap_obstack_initialize (&tm_obstack);
1953 /* If the function is a TM_CLONE, then the entire function is the region. */
1954 if (decl_is_tm_clone (current_function_decl))
1956 struct tm_region *region = (struct tm_region *)
1957 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
1958 memset (region, 0, sizeof (*region));
1959 region->entry_block = single_succ (ENTRY_BLOCK_PTR);
1960 /* For a clone, the entire function is the region. But even if
1961 we don't need to record any exit blocks, we may need to
1962 record irrevocable blocks. */
1963 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
1965 tm_region_init (region);
1967 else
1969 tm_region_init (NULL);
1971 /* If we didn't find any regions, cleanup and skip the whole tree
1972 of tm-related optimizations. */
1973 if (all_tm_regions == NULL)
1975 bitmap_obstack_release (&tm_obstack);
1976 return false;
1980 return true;
1983 struct gimple_opt_pass pass_tm_init =
1986 GIMPLE_PASS,
1987 "*tminit", /* name */
1988 gate_tm_init, /* gate */
1989 NULL, /* execute */
1990 NULL, /* sub */
1991 NULL, /* next */
1992 0, /* static_pass_number */
1993 TV_TRANS_MEM, /* tv_id */
1994 PROP_ssa | PROP_cfg, /* properties_required */
1995 0, /* properties_provided */
1996 0, /* properties_destroyed */
1997 0, /* todo_flags_start */
1998 0, /* todo_flags_finish */
2002 /* Add FLAGS to the GIMPLE_TRANSACTION subcode for the transaction region
2003 represented by STATE. */
2005 static inline void
2006 transaction_subcode_ior (struct tm_region *region, unsigned flags)
2008 if (region && region->transaction_stmt)
2010 flags |= gimple_transaction_subcode (region->transaction_stmt);
2011 gimple_transaction_set_subcode (region->transaction_stmt, flags);
2015 /* Construct a memory load in a transactional context. Return the
2016 gimple statement performing the load, or NULL if there is no
2017 TM_LOAD builtin of the appropriate size to do the load.
2019 LOC is the location to use for the new statement(s). */
2021 static gimple
2022 build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2024 enum built_in_function code = END_BUILTINS;
2025 tree t, type = TREE_TYPE (rhs), decl;
2026 gimple gcall;
2028 if (type == float_type_node)
2029 code = BUILT_IN_TM_LOAD_FLOAT;
2030 else if (type == double_type_node)
2031 code = BUILT_IN_TM_LOAD_DOUBLE;
2032 else if (type == long_double_type_node)
2033 code = BUILT_IN_TM_LOAD_LDOUBLE;
2034 else if (TYPE_SIZE_UNIT (type) != NULL
2035 && host_integerp (TYPE_SIZE_UNIT (type), 1))
2037 switch (tree_low_cst (TYPE_SIZE_UNIT (type), 1))
2039 case 1:
2040 code = BUILT_IN_TM_LOAD_1;
2041 break;
2042 case 2:
2043 code = BUILT_IN_TM_LOAD_2;
2044 break;
2045 case 4:
2046 code = BUILT_IN_TM_LOAD_4;
2047 break;
2048 case 8:
2049 code = BUILT_IN_TM_LOAD_8;
2050 break;
2054 if (code == END_BUILTINS)
2056 decl = targetm.vectorize.builtin_tm_load (type);
2057 if (!decl)
2058 return NULL;
2060 else
2061 decl = builtin_decl_explicit (code);
2063 t = gimplify_addr (gsi, rhs);
2064 gcall = gimple_build_call (decl, 1, t);
2065 gimple_set_location (gcall, loc);
2067 t = TREE_TYPE (TREE_TYPE (decl));
2068 if (useless_type_conversion_p (type, t))
2070 gimple_call_set_lhs (gcall, lhs);
2071 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2073 else
2075 gimple g;
2076 tree temp;
2078 temp = create_tmp_reg (t, NULL);
2079 gimple_call_set_lhs (gcall, temp);
2080 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2082 t = fold_build1 (VIEW_CONVERT_EXPR, type, temp);
2083 g = gimple_build_assign (lhs, t);
2084 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2087 return gcall;
2091 /* Similarly for storing TYPE in a transactional context. */
2093 static gimple
2094 build_tm_store (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2096 enum built_in_function code = END_BUILTINS;
2097 tree t, fn, type = TREE_TYPE (rhs), simple_type;
2098 gimple gcall;
2100 if (type == float_type_node)
2101 code = BUILT_IN_TM_STORE_FLOAT;
2102 else if (type == double_type_node)
2103 code = BUILT_IN_TM_STORE_DOUBLE;
2104 else if (type == long_double_type_node)
2105 code = BUILT_IN_TM_STORE_LDOUBLE;
2106 else if (TYPE_SIZE_UNIT (type) != NULL
2107 && host_integerp (TYPE_SIZE_UNIT (type), 1))
2109 switch (tree_low_cst (TYPE_SIZE_UNIT (type), 1))
2111 case 1:
2112 code = BUILT_IN_TM_STORE_1;
2113 break;
2114 case 2:
2115 code = BUILT_IN_TM_STORE_2;
2116 break;
2117 case 4:
2118 code = BUILT_IN_TM_STORE_4;
2119 break;
2120 case 8:
2121 code = BUILT_IN_TM_STORE_8;
2122 break;
2126 if (code == END_BUILTINS)
2128 fn = targetm.vectorize.builtin_tm_store (type);
2129 if (!fn)
2130 return NULL;
2132 else
2133 fn = builtin_decl_explicit (code);
2135 simple_type = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))));
2137 if (TREE_CODE (rhs) == CONSTRUCTOR)
2139 /* Handle the easy initialization to zero. */
2140 if (CONSTRUCTOR_ELTS (rhs) == 0)
2141 rhs = build_int_cst (simple_type, 0);
2142 else
2144 /* ...otherwise punt to the caller and probably use
2145 BUILT_IN_TM_MEMMOVE, because we can't wrap a
2146 VIEW_CONVERT_EXPR around a CONSTRUCTOR (below) and produce
2147 valid gimple. */
2148 return NULL;
2151 else if (!useless_type_conversion_p (simple_type, type))
2153 gimple g;
2154 tree temp;
2156 temp = create_tmp_reg (simple_type, NULL);
2157 t = fold_build1 (VIEW_CONVERT_EXPR, simple_type, rhs);
2158 g = gimple_build_assign (temp, t);
2159 gimple_set_location (g, loc);
2160 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2162 rhs = temp;
2165 t = gimplify_addr (gsi, lhs);
2166 gcall = gimple_build_call (fn, 2, t, rhs);
2167 gimple_set_location (gcall, loc);
2168 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2170 return gcall;
2174 /* Expand an assignment statement into transactional builtins. */
2176 static void
2177 expand_assign_tm (struct tm_region *region, gimple_stmt_iterator *gsi)
2179 gimple stmt = gsi_stmt (*gsi);
2180 location_t loc = gimple_location (stmt);
2181 tree lhs = gimple_assign_lhs (stmt);
2182 tree rhs = gimple_assign_rhs1 (stmt);
2183 bool store_p = requires_barrier (region->entry_block, lhs, NULL);
2184 bool load_p = requires_barrier (region->entry_block, rhs, NULL);
2185 gimple gcall = NULL;
2187 if (!load_p && !store_p)
2189 /* Add thread private addresses to log if applicable. */
2190 requires_barrier (region->entry_block, lhs, stmt);
2191 gsi_next (gsi);
2192 return;
2195 gsi_remove (gsi, true);
2197 if (load_p && !store_p)
2199 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2200 gcall = build_tm_load (loc, lhs, rhs, gsi);
2202 else if (store_p && !load_p)
2204 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2205 gcall = build_tm_store (loc, lhs, rhs, gsi);
2207 if (!gcall)
2209 tree lhs_addr, rhs_addr, tmp;
2211 if (load_p)
2212 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2213 if (store_p)
2214 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2216 /* ??? Figure out if there's any possible overlap between the LHS
2217 and the RHS and if not, use MEMCPY. */
2219 if (load_p && is_gimple_reg (lhs))
2221 tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
2222 lhs_addr = build_fold_addr_expr (tmp);
2224 else
2226 tmp = NULL_TREE;
2227 lhs_addr = gimplify_addr (gsi, lhs);
2229 rhs_addr = gimplify_addr (gsi, rhs);
2230 gcall = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_MEMMOVE),
2231 3, lhs_addr, rhs_addr,
2232 TYPE_SIZE_UNIT (TREE_TYPE (lhs)));
2233 gimple_set_location (gcall, loc);
2234 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2236 if (tmp)
2238 gcall = gimple_build_assign (lhs, tmp);
2239 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2243 /* Now that we have the load/store in its instrumented form, add
2244 thread private addresses to the log if applicable. */
2245 if (!store_p)
2246 requires_barrier (region->entry_block, lhs, gcall);
2248 /* add_stmt_to_tm_region (region, gcall); */
2252 /* Expand a call statement as appropriate for a transaction. That is,
2253 either verify that the call does not affect the transaction, or
2254 redirect the call to a clone that handles transactions, or change
2255 the transaction state to IRREVOCABLE. Return true if the call is
2256 one of the builtins that end a transaction. */
2258 static bool
2259 expand_call_tm (struct tm_region *region,
2260 gimple_stmt_iterator *gsi)
2262 gimple stmt = gsi_stmt (*gsi);
2263 tree lhs = gimple_call_lhs (stmt);
2264 tree fn_decl;
2265 struct cgraph_node *node;
2266 bool retval = false;
2268 fn_decl = gimple_call_fndecl (stmt);
2270 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMCPY)
2271 || fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMMOVE))
2272 transaction_subcode_ior (region, GTMA_HAVE_STORE | GTMA_HAVE_LOAD);
2273 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMSET))
2274 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2276 if (is_tm_pure_call (stmt))
2277 return false;
2279 if (fn_decl)
2280 retval = is_tm_ending_fndecl (fn_decl);
2281 if (!retval)
2283 /* Assume all non-const/pure calls write to memory, except
2284 transaction ending builtins. */
2285 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2288 /* For indirect calls, we already generated a call into the runtime. */
2289 if (!fn_decl)
2291 tree fn = gimple_call_fn (stmt);
2293 /* We are guaranteed never to go irrevocable on a safe or pure
2294 call, and the pure call was handled above. */
2295 if (is_tm_safe (fn))
2296 return false;
2297 else
2298 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2300 return false;
2303 node = cgraph_get_node (fn_decl);
2304 /* All calls should have cgraph here. */
2305 if (!node)
2307 /* We can have a nodeless call here if some pass after IPA-tm
2308 added uninstrumented calls. For example, loop distribution
2309 can transform certain loop constructs into __builtin_mem*
2310 calls. In this case, see if we have a suitable TM
2311 replacement and fill in the gaps. */
2312 gcc_assert (DECL_BUILT_IN_CLASS (fn_decl) == BUILT_IN_NORMAL);
2313 enum built_in_function code = DECL_FUNCTION_CODE (fn_decl);
2314 gcc_assert (code == BUILT_IN_MEMCPY
2315 || code == BUILT_IN_MEMMOVE
2316 || code == BUILT_IN_MEMSET);
2318 tree repl = find_tm_replacement_function (fn_decl);
2319 if (repl)
2321 gimple_call_set_fndecl (stmt, repl);
2322 update_stmt (stmt);
2323 node = cgraph_create_node (repl);
2324 node->local.tm_may_enter_irr = false;
2325 return expand_call_tm (region, gsi);
2327 gcc_unreachable ();
2329 if (node->local.tm_may_enter_irr)
2330 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2332 if (is_tm_abort (fn_decl))
2334 transaction_subcode_ior (region, GTMA_HAVE_ABORT);
2335 return true;
2338 /* Instrument the store if needed.
2340 If the assignment happens inside the function call (return slot
2341 optimization), there is no instrumentation to be done, since
2342 the callee should have done the right thing. */
2343 if (lhs && requires_barrier (region->entry_block, lhs, stmt)
2344 && !gimple_call_return_slot_opt_p (stmt))
2346 tree tmp = create_tmp_reg (TREE_TYPE (lhs), NULL);
2347 location_t loc = gimple_location (stmt);
2348 edge fallthru_edge = NULL;
2350 /* Remember if the call was going to throw. */
2351 if (stmt_can_throw_internal (stmt))
2353 edge_iterator ei;
2354 edge e;
2355 basic_block bb = gimple_bb (stmt);
2357 FOR_EACH_EDGE (e, ei, bb->succs)
2358 if (e->flags & EDGE_FALLTHRU)
2360 fallthru_edge = e;
2361 break;
2365 gimple_call_set_lhs (stmt, tmp);
2366 update_stmt (stmt);
2367 stmt = gimple_build_assign (lhs, tmp);
2368 gimple_set_location (stmt, loc);
2370 /* We cannot throw in the middle of a BB. If the call was going
2371 to throw, place the instrumentation on the fallthru edge, so
2372 the call remains the last statement in the block. */
2373 if (fallthru_edge)
2375 gimple_seq fallthru_seq = gimple_seq_alloc_with_stmt (stmt);
2376 gimple_stmt_iterator fallthru_gsi = gsi_start (fallthru_seq);
2377 expand_assign_tm (region, &fallthru_gsi);
2378 gsi_insert_seq_on_edge (fallthru_edge, fallthru_seq);
2379 pending_edge_inserts_p = true;
2381 else
2383 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
2384 expand_assign_tm (region, gsi);
2387 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2390 return retval;
2394 /* Expand all statements in BB as appropriate for being inside
2395 a transaction. */
2397 static void
2398 expand_block_tm (struct tm_region *region, basic_block bb)
2400 gimple_stmt_iterator gsi;
2402 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2404 gimple stmt = gsi_stmt (gsi);
2405 switch (gimple_code (stmt))
2407 case GIMPLE_ASSIGN:
2408 /* Only memory reads/writes need to be instrumented. */
2409 if (gimple_assign_single_p (stmt)
2410 && !gimple_clobber_p (stmt))
2412 expand_assign_tm (region, &gsi);
2413 continue;
2415 break;
2417 case GIMPLE_CALL:
2418 if (expand_call_tm (region, &gsi))
2419 return;
2420 break;
2422 case GIMPLE_ASM:
2423 gcc_unreachable ();
2425 default:
2426 break;
2428 if (!gsi_end_p (gsi))
2429 gsi_next (&gsi);
2433 /* Return the list of basic-blocks in REGION.
2435 STOP_AT_IRREVOCABLE_P is true if caller is uninterested in blocks
2436 following a TM_IRREVOCABLE call. */
2438 static VEC (basic_block, heap) *
2439 get_tm_region_blocks (basic_block entry_block,
2440 bitmap exit_blocks,
2441 bitmap irr_blocks,
2442 bitmap all_region_blocks,
2443 bool stop_at_irrevocable_p)
2445 VEC(basic_block, heap) *bbs = NULL;
2446 unsigned i;
2447 edge e;
2448 edge_iterator ei;
2449 bitmap visited_blocks = BITMAP_ALLOC (NULL);
2451 i = 0;
2452 VEC_safe_push (basic_block, heap, bbs, entry_block);
2453 bitmap_set_bit (visited_blocks, entry_block->index);
2457 basic_block bb = VEC_index (basic_block, bbs, i++);
2459 if (exit_blocks &&
2460 bitmap_bit_p (exit_blocks, bb->index))
2461 continue;
2463 if (stop_at_irrevocable_p
2464 && irr_blocks
2465 && bitmap_bit_p (irr_blocks, bb->index))
2466 continue;
2468 FOR_EACH_EDGE (e, ei, bb->succs)
2469 if (!bitmap_bit_p (visited_blocks, e->dest->index))
2471 bitmap_set_bit (visited_blocks, e->dest->index);
2472 VEC_safe_push (basic_block, heap, bbs, e->dest);
2475 while (i < VEC_length (basic_block, bbs));
2477 if (all_region_blocks)
2478 bitmap_ior_into (all_region_blocks, visited_blocks);
2480 BITMAP_FREE (visited_blocks);
2481 return bbs;
2484 /* Set the IN_TRANSACTION for all gimple statements that appear in a
2485 transaction. */
2487 void
2488 compute_transaction_bits (void)
2490 struct tm_region *region;
2491 VEC (basic_block, heap) *queue;
2492 unsigned int i;
2493 basic_block bb;
2495 /* ?? Perhaps we need to abstract gate_tm_init further, because we
2496 certainly don't need it to calculate CDI_DOMINATOR info. */
2497 gate_tm_init ();
2499 FOR_EACH_BB (bb)
2500 bb->flags &= ~BB_IN_TRANSACTION;
2502 for (region = all_tm_regions; region; region = region->next)
2504 queue = get_tm_region_blocks (region->entry_block,
2505 region->exit_blocks,
2506 region->irr_blocks,
2507 NULL,
2508 /*stop_at_irr_p=*/true);
2509 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2510 bb->flags |= BB_IN_TRANSACTION;
2511 VEC_free (basic_block, heap, queue);
2514 if (all_tm_regions)
2515 bitmap_obstack_release (&tm_obstack);
2518 /* Entry point to the MARK phase of TM expansion. Here we replace
2519 transactional memory statements with calls to builtins, and function
2520 calls with their transactional clones (if available). But we don't
2521 yet lower GIMPLE_TRANSACTION or add the transaction restart back-edges. */
2523 static unsigned int
2524 execute_tm_mark (void)
2526 struct tm_region *region;
2527 basic_block bb;
2528 VEC (basic_block, heap) *queue;
2529 size_t i;
2531 queue = VEC_alloc (basic_block, heap, 10);
2532 pending_edge_inserts_p = false;
2534 for (region = all_tm_regions; region ; region = region->next)
2536 tm_log_init ();
2537 /* If we have a transaction... */
2538 if (region->exit_blocks)
2540 unsigned int subcode
2541 = gimple_transaction_subcode (region->transaction_stmt);
2543 /* Collect a new SUBCODE set, now that optimizations are done... */
2544 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2545 subcode &= (GTMA_DECLARATION_MASK | GTMA_DOES_GO_IRREVOCABLE
2546 | GTMA_MAY_ENTER_IRREVOCABLE);
2547 else
2548 subcode &= GTMA_DECLARATION_MASK;
2549 gimple_transaction_set_subcode (region->transaction_stmt, subcode);
2552 queue = get_tm_region_blocks (region->entry_block,
2553 region->exit_blocks,
2554 region->irr_blocks,
2555 NULL,
2556 /*stop_at_irr_p=*/true);
2557 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2558 expand_block_tm (region, bb);
2559 VEC_free (basic_block, heap, queue);
2561 tm_log_emit ();
2564 if (pending_edge_inserts_p)
2565 gsi_commit_edge_inserts ();
2566 return 0;
2569 struct gimple_opt_pass pass_tm_mark =
2572 GIMPLE_PASS,
2573 "tmmark", /* name */
2574 NULL, /* gate */
2575 execute_tm_mark, /* execute */
2576 NULL, /* sub */
2577 NULL, /* next */
2578 0, /* static_pass_number */
2579 TV_TRANS_MEM, /* tv_id */
2580 PROP_ssa | PROP_cfg, /* properties_required */
2581 0, /* properties_provided */
2582 0, /* properties_destroyed */
2583 0, /* todo_flags_start */
2584 TODO_update_ssa
2585 | TODO_verify_ssa, /* todo_flags_finish */
2589 /* Create an abnormal call edge from BB to the first block of the region
2590 represented by STATE. Also record the edge in the TM_RESTART map. */
2592 static inline void
2593 make_tm_edge (gimple stmt, basic_block bb, struct tm_region *region)
2595 void **slot;
2596 struct tm_restart_node *n, dummy;
2598 if (cfun->gimple_df->tm_restart == NULL)
2599 cfun->gimple_df->tm_restart = htab_create_ggc (31, struct_ptr_hash,
2600 struct_ptr_eq, ggc_free);
2602 dummy.stmt = stmt;
2603 dummy.label_or_list = gimple_block_label (region->entry_block);
2604 slot = htab_find_slot (cfun->gimple_df->tm_restart, &dummy, INSERT);
2605 n = (struct tm_restart_node *) *slot;
2606 if (n == NULL)
2608 n = ggc_alloc_tm_restart_node ();
2609 *n = dummy;
2611 else
2613 tree old = n->label_or_list;
2614 if (TREE_CODE (old) == LABEL_DECL)
2615 old = tree_cons (NULL, old, NULL);
2616 n->label_or_list = tree_cons (NULL, dummy.label_or_list, old);
2619 make_edge (bb, region->entry_block, EDGE_ABNORMAL);
2623 /* Split block BB as necessary for every builtin function we added, and
2624 wire up the abnormal back edges implied by the transaction restart. */
2626 static void
2627 expand_block_edges (struct tm_region *region, basic_block bb)
2629 gimple_stmt_iterator gsi;
2631 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2633 bool do_next = true;
2634 gimple stmt = gsi_stmt (gsi);
2636 /* ??? TM_COMMIT (and any other tm builtin function) in a nested
2637 transaction has an abnormal edge back to the outer-most transaction
2638 (there are no nested retries), while a TM_ABORT also has an abnormal
2639 backedge to the inner-most transaction. We haven't actually saved
2640 the inner-most transaction here. We should be able to get to it
2641 via the region_nr saved on STMT, and read the transaction_stmt from
2642 that, and find the first region block from there. */
2643 /* ??? Shouldn't we split for any non-pure, non-irrevocable function? */
2644 if (gimple_code (stmt) == GIMPLE_CALL
2645 && (gimple_call_flags (stmt) & ECF_TM_BUILTIN) != 0)
2647 if (gsi_one_before_end_p (gsi))
2648 make_tm_edge (stmt, bb, region);
2649 else
2651 edge e = split_block (bb, stmt);
2652 make_tm_edge (stmt, bb, region);
2653 bb = e->dest;
2654 gsi = gsi_start_bb (bb);
2655 do_next = false;
2658 /* Delete any tail-call annotation that may have been added.
2659 The tail-call pass may have mis-identified the commit as being
2660 a candidate because we had not yet added this restart edge. */
2661 gimple_call_set_tail (stmt, false);
2664 if (do_next)
2665 gsi_next (&gsi);
2669 /* Expand the GIMPLE_TRANSACTION statement into the STM library call. */
2671 static void
2672 expand_transaction (struct tm_region *region)
2674 tree status, tm_start;
2675 basic_block atomic_bb, slice_bb;
2676 gimple_stmt_iterator gsi;
2677 tree t1, t2;
2678 gimple g;
2679 int flags, subcode;
2681 tm_start = builtin_decl_explicit (BUILT_IN_TM_START);
2682 status = create_tmp_reg (TREE_TYPE (TREE_TYPE (tm_start)), "tm_state");
2684 /* ??? There are plenty of bits here we're not computing. */
2685 subcode = gimple_transaction_subcode (region->transaction_stmt);
2686 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2687 flags = PR_DOESGOIRREVOCABLE | PR_UNINSTRUMENTEDCODE;
2688 else
2689 flags = PR_INSTRUMENTEDCODE;
2690 if ((subcode & GTMA_MAY_ENTER_IRREVOCABLE) == 0)
2691 flags |= PR_HASNOIRREVOCABLE;
2692 /* If the transaction does not have an abort in lexical scope and is not
2693 marked as an outer transaction, then it will never abort. */
2694 if ((subcode & GTMA_HAVE_ABORT) == 0
2695 && (subcode & GTMA_IS_OUTER) == 0)
2696 flags |= PR_HASNOABORT;
2697 if ((subcode & GTMA_HAVE_STORE) == 0)
2698 flags |= PR_READONLY;
2699 t2 = build_int_cst (TREE_TYPE (status), flags);
2700 g = gimple_build_call (tm_start, 1, t2);
2701 gimple_call_set_lhs (g, status);
2702 gimple_set_location (g, gimple_location (region->transaction_stmt));
2704 atomic_bb = gimple_bb (region->transaction_stmt);
2706 if (!VEC_empty (tree, tm_log_save_addresses))
2707 tm_log_emit_saves (region->entry_block, atomic_bb);
2709 gsi = gsi_last_bb (atomic_bb);
2710 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2711 gsi_remove (&gsi, true);
2713 if (!VEC_empty (tree, tm_log_save_addresses))
2714 region->entry_block =
2715 tm_log_emit_save_or_restores (region->entry_block,
2716 A_RESTORELIVEVARIABLES,
2717 status,
2718 tm_log_emit_restores,
2719 atomic_bb,
2720 FALLTHRU_EDGE (atomic_bb),
2721 &slice_bb);
2722 else
2723 slice_bb = atomic_bb;
2725 /* If we have an ABORT statement, create a test following the start
2726 call to perform the abort. */
2727 if (gimple_transaction_label (region->transaction_stmt))
2729 edge e;
2730 basic_block test_bb;
2732 test_bb = create_empty_bb (slice_bb);
2733 if (current_loops && slice_bb->loop_father)
2734 add_bb_to_loop (test_bb, slice_bb->loop_father);
2735 if (VEC_empty (tree, tm_log_save_addresses))
2736 region->entry_block = test_bb;
2737 gsi = gsi_last_bb (test_bb);
2739 t1 = create_tmp_reg (TREE_TYPE (status), NULL);
2740 t2 = build_int_cst (TREE_TYPE (status), A_ABORTTRANSACTION);
2741 g = gimple_build_assign_with_ops (BIT_AND_EXPR, t1, status, t2);
2742 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
2744 t2 = build_int_cst (TREE_TYPE (status), 0);
2745 g = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
2746 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
2748 e = FALLTHRU_EDGE (slice_bb);
2749 redirect_edge_pred (e, test_bb);
2750 e->flags = EDGE_FALSE_VALUE;
2751 e->probability = PROB_ALWAYS - PROB_VERY_UNLIKELY;
2753 e = BRANCH_EDGE (atomic_bb);
2754 redirect_edge_pred (e, test_bb);
2755 e->flags = EDGE_TRUE_VALUE;
2756 e->probability = PROB_VERY_UNLIKELY;
2758 e = make_edge (slice_bb, test_bb, EDGE_FALLTHRU);
2761 /* If we've no abort, but we do have PHIs at the beginning of the atomic
2762 region, that means we've a loop at the beginning of the atomic region
2763 that shares the first block. This can cause problems with the abnormal
2764 edges we're about to add for the transaction restart. Solve this by
2765 adding a new empty block to receive the abnormal edges. */
2766 else if (phi_nodes (region->entry_block))
2768 edge e;
2769 basic_block empty_bb;
2771 region->entry_block = empty_bb = create_empty_bb (atomic_bb);
2772 if (current_loops && atomic_bb->loop_father)
2773 add_bb_to_loop (empty_bb, atomic_bb->loop_father);
2775 e = FALLTHRU_EDGE (atomic_bb);
2776 redirect_edge_pred (e, empty_bb);
2778 e = make_edge (atomic_bb, empty_bb, EDGE_FALLTHRU);
2781 /* The GIMPLE_TRANSACTION statement no longer exists. */
2782 region->transaction_stmt = NULL;
2785 static void expand_regions (struct tm_region *);
2787 /* Helper function for expand_regions. Expand REGION and recurse to
2788 the inner region. */
2790 static void
2791 expand_regions_1 (struct tm_region *region)
2793 if (region->exit_blocks)
2795 unsigned int i;
2796 basic_block bb;
2797 VEC (basic_block, heap) *queue;
2799 /* Collect the set of blocks in this region. Do this before
2800 splitting edges, so that we don't have to play with the
2801 dominator tree in the middle. */
2802 queue = get_tm_region_blocks (region->entry_block,
2803 region->exit_blocks,
2804 region->irr_blocks,
2805 NULL,
2806 /*stop_at_irr_p=*/false);
2807 expand_transaction (region);
2808 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2809 expand_block_edges (region, bb);
2810 VEC_free (basic_block, heap, queue);
2812 if (region->inner)
2813 expand_regions (region->inner);
2816 /* Expand regions starting at REGION. */
2818 static void
2819 expand_regions (struct tm_region *region)
2821 while (region)
2823 expand_regions_1 (region);
2824 region = region->next;
2828 /* Entry point to the final expansion of transactional nodes. */
2830 static unsigned int
2831 execute_tm_edges (void)
2833 expand_regions (all_tm_regions);
2834 tm_log_delete ();
2836 /* We've got to release the dominance info now, to indicate that it
2837 must be rebuilt completely. Otherwise we'll crash trying to update
2838 the SSA web in the TODO section following this pass. */
2839 free_dominance_info (CDI_DOMINATORS);
2840 bitmap_obstack_release (&tm_obstack);
2841 all_tm_regions = NULL;
2843 return 0;
2846 struct gimple_opt_pass pass_tm_edges =
2849 GIMPLE_PASS,
2850 "tmedge", /* name */
2851 NULL, /* gate */
2852 execute_tm_edges, /* execute */
2853 NULL, /* sub */
2854 NULL, /* next */
2855 0, /* static_pass_number */
2856 TV_TRANS_MEM, /* tv_id */
2857 PROP_ssa | PROP_cfg, /* properties_required */
2858 0, /* properties_provided */
2859 0, /* properties_destroyed */
2860 0, /* todo_flags_start */
2861 TODO_update_ssa
2862 | TODO_verify_ssa, /* todo_flags_finish */
2866 /* A unique TM memory operation. */
2867 typedef struct tm_memop
2869 /* Unique ID that all memory operations to the same location have. */
2870 unsigned int value_id;
2871 /* Address of load/store. */
2872 tree addr;
2873 } *tm_memop_t;
2875 /* Sets for solving data flow equations in the memory optimization pass. */
2876 struct tm_memopt_bitmaps
2878 /* Stores available to this BB upon entry. Basically, stores that
2879 dominate this BB. */
2880 bitmap store_avail_in;
2881 /* Stores available at the end of this BB. */
2882 bitmap store_avail_out;
2883 bitmap store_antic_in;
2884 bitmap store_antic_out;
2885 /* Reads available to this BB upon entry. Basically, reads that
2886 dominate this BB. */
2887 bitmap read_avail_in;
2888 /* Reads available at the end of this BB. */
2889 bitmap read_avail_out;
2890 /* Reads performed in this BB. */
2891 bitmap read_local;
2892 /* Writes performed in this BB. */
2893 bitmap store_local;
2895 /* Temporary storage for pass. */
2896 /* Is the current BB in the worklist? */
2897 bool avail_in_worklist_p;
2898 /* Have we visited this BB? */
2899 bool visited_p;
2902 static bitmap_obstack tm_memopt_obstack;
2904 /* Unique counter for TM loads and stores. Loads and stores of the
2905 same address get the same ID. */
2906 static unsigned int tm_memopt_value_id;
2907 static htab_t tm_memopt_value_numbers;
2909 #define STORE_AVAIL_IN(BB) \
2910 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in
2911 #define STORE_AVAIL_OUT(BB) \
2912 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_out
2913 #define STORE_ANTIC_IN(BB) \
2914 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_in
2915 #define STORE_ANTIC_OUT(BB) \
2916 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_out
2917 #define READ_AVAIL_IN(BB) \
2918 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_in
2919 #define READ_AVAIL_OUT(BB) \
2920 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_out
2921 #define READ_LOCAL(BB) \
2922 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_local
2923 #define STORE_LOCAL(BB) \
2924 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_local
2925 #define AVAIL_IN_WORKLIST_P(BB) \
2926 ((struct tm_memopt_bitmaps *) ((BB)->aux))->avail_in_worklist_p
2927 #define BB_VISITED_P(BB) \
2928 ((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p
2930 /* Htab support. Return a hash value for a `tm_memop'. */
2931 static hashval_t
2932 tm_memop_hash (const void *p)
2934 const struct tm_memop *mem = (const struct tm_memop *) p;
2935 tree addr = mem->addr;
2936 /* We drill down to the SSA_NAME/DECL for the hash, but equality is
2937 actually done with operand_equal_p (see tm_memop_eq). */
2938 if (TREE_CODE (addr) == ADDR_EXPR)
2939 addr = TREE_OPERAND (addr, 0);
2940 return iterative_hash_expr (addr, 0);
2943 /* Htab support. Return true if two tm_memop's are the same. */
2944 static int
2945 tm_memop_eq (const void *p1, const void *p2)
2947 const struct tm_memop *mem1 = (const struct tm_memop *) p1;
2948 const struct tm_memop *mem2 = (const struct tm_memop *) p2;
2950 return operand_equal_p (mem1->addr, mem2->addr, 0);
2953 /* Given a TM load/store in STMT, return the value number for the address
2954 it accesses. */
2956 static unsigned int
2957 tm_memopt_value_number (gimple stmt, enum insert_option op)
2959 struct tm_memop tmpmem, *mem;
2960 void **slot;
2962 gcc_assert (is_tm_load (stmt) || is_tm_store (stmt));
2963 tmpmem.addr = gimple_call_arg (stmt, 0);
2964 slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op);
2965 if (*slot)
2966 mem = (struct tm_memop *) *slot;
2967 else if (op == INSERT)
2969 mem = XNEW (struct tm_memop);
2970 *slot = mem;
2971 mem->value_id = tm_memopt_value_id++;
2972 mem->addr = tmpmem.addr;
2974 else
2975 gcc_unreachable ();
2976 return mem->value_id;
2979 /* Accumulate TM memory operations in BB into STORE_LOCAL and READ_LOCAL. */
2981 static void
2982 tm_memopt_accumulate_memops (basic_block bb)
2984 gimple_stmt_iterator gsi;
2986 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2988 gimple stmt = gsi_stmt (gsi);
2989 bitmap bits;
2990 unsigned int loc;
2992 if (is_tm_store (stmt))
2993 bits = STORE_LOCAL (bb);
2994 else if (is_tm_load (stmt))
2995 bits = READ_LOCAL (bb);
2996 else
2997 continue;
2999 loc = tm_memopt_value_number (stmt, INSERT);
3000 bitmap_set_bit (bits, loc);
3001 if (dump_file)
3003 fprintf (dump_file, "TM memopt (%s): value num=%d, BB=%d, addr=",
3004 is_tm_load (stmt) ? "LOAD" : "STORE", loc,
3005 gimple_bb (stmt)->index);
3006 print_generic_expr (dump_file, gimple_call_arg (stmt, 0), 0);
3007 fprintf (dump_file, "\n");
3012 /* Prettily dump one of the memopt sets. BITS is the bitmap to dump. */
3014 static void
3015 dump_tm_memopt_set (const char *set_name, bitmap bits)
3017 unsigned i;
3018 bitmap_iterator bi;
3019 const char *comma = "";
3021 fprintf (dump_file, "TM memopt: %s: [", set_name);
3022 EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
3024 htab_iterator hi;
3025 struct tm_memop *mem;
3027 /* Yeah, yeah, yeah. Whatever. This is just for debugging. */
3028 FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
3029 if (mem->value_id == i)
3030 break;
3031 gcc_assert (mem->value_id == i);
3032 fprintf (dump_file, "%s", comma);
3033 comma = ", ";
3034 print_generic_expr (dump_file, mem->addr, 0);
3036 fprintf (dump_file, "]\n");
3039 /* Prettily dump all of the memopt sets in BLOCKS. */
3041 static void
3042 dump_tm_memopt_sets (VEC (basic_block, heap) *blocks)
3044 size_t i;
3045 basic_block bb;
3047 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3049 fprintf (dump_file, "------------BB %d---------\n", bb->index);
3050 dump_tm_memopt_set ("STORE_LOCAL", STORE_LOCAL (bb));
3051 dump_tm_memopt_set ("READ_LOCAL", READ_LOCAL (bb));
3052 dump_tm_memopt_set ("STORE_AVAIL_IN", STORE_AVAIL_IN (bb));
3053 dump_tm_memopt_set ("STORE_AVAIL_OUT", STORE_AVAIL_OUT (bb));
3054 dump_tm_memopt_set ("READ_AVAIL_IN", READ_AVAIL_IN (bb));
3055 dump_tm_memopt_set ("READ_AVAIL_OUT", READ_AVAIL_OUT (bb));
3059 /* Compute {STORE,READ}_AVAIL_IN for the basic block BB. */
3061 static void
3062 tm_memopt_compute_avin (basic_block bb)
3064 edge e;
3065 unsigned ix;
3067 /* Seed with the AVOUT of any predecessor. */
3068 for (ix = 0; ix < EDGE_COUNT (bb->preds); ix++)
3070 e = EDGE_PRED (bb, ix);
3071 /* Make sure we have already visited this BB, and is thus
3072 initialized.
3074 If e->src->aux is NULL, this predecessor is actually on an
3075 enclosing transaction. We only care about the current
3076 transaction, so ignore it. */
3077 if (e->src->aux && BB_VISITED_P (e->src))
3079 bitmap_copy (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3080 bitmap_copy (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3081 break;
3085 for (; ix < EDGE_COUNT (bb->preds); ix++)
3087 e = EDGE_PRED (bb, ix);
3088 if (e->src->aux && BB_VISITED_P (e->src))
3090 bitmap_and_into (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3091 bitmap_and_into (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3095 BB_VISITED_P (bb) = true;
3098 /* Compute the STORE_ANTIC_IN for the basic block BB. */
3100 static void
3101 tm_memopt_compute_antin (basic_block bb)
3103 edge e;
3104 unsigned ix;
3106 /* Seed with the ANTIC_OUT of any successor. */
3107 for (ix = 0; ix < EDGE_COUNT (bb->succs); ix++)
3109 e = EDGE_SUCC (bb, ix);
3110 /* Make sure we have already visited this BB, and is thus
3111 initialized. */
3112 if (BB_VISITED_P (e->dest))
3114 bitmap_copy (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3115 break;
3119 for (; ix < EDGE_COUNT (bb->succs); ix++)
3121 e = EDGE_SUCC (bb, ix);
3122 if (BB_VISITED_P (e->dest))
3123 bitmap_and_into (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3126 BB_VISITED_P (bb) = true;
3129 /* Compute the AVAIL sets for every basic block in BLOCKS.
3131 We compute {STORE,READ}_AVAIL_{OUT,IN} as follows:
3133 AVAIL_OUT[bb] = union (AVAIL_IN[bb], LOCAL[bb])
3134 AVAIL_IN[bb] = intersect (AVAIL_OUT[predecessors])
3136 This is basically what we do in lcm's compute_available(), but here
3137 we calculate two sets of sets (one for STOREs and one for READs),
3138 and we work on a region instead of the entire CFG.
3140 REGION is the TM region.
3141 BLOCKS are the basic blocks in the region. */
3143 static void
3144 tm_memopt_compute_available (struct tm_region *region,
3145 VEC (basic_block, heap) *blocks)
3147 edge e;
3148 basic_block *worklist, *qin, *qout, *qend, bb;
3149 unsigned int qlen, i;
3150 edge_iterator ei;
3151 bool changed;
3153 /* Allocate a worklist array/queue. Entries are only added to the
3154 list if they were not already on the list. So the size is
3155 bounded by the number of basic blocks in the region. */
3156 qlen = VEC_length (basic_block, blocks) - 1;
3157 qin = qout = worklist =
3158 XNEWVEC (basic_block, qlen);
3160 /* Put every block in the region on the worklist. */
3161 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3163 /* Seed AVAIL_OUT with the LOCAL set. */
3164 bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_LOCAL (bb));
3165 bitmap_ior_into (READ_AVAIL_OUT (bb), READ_LOCAL (bb));
3167 AVAIL_IN_WORKLIST_P (bb) = true;
3168 /* No need to insert the entry block, since it has an AVIN of
3169 null, and an AVOUT that has already been seeded in. */
3170 if (bb != region->entry_block)
3171 *qin++ = bb;
3174 /* The entry block has been initialized with the local sets. */
3175 BB_VISITED_P (region->entry_block) = true;
3177 qin = worklist;
3178 qend = &worklist[qlen];
3180 /* Iterate until the worklist is empty. */
3181 while (qlen)
3183 /* Take the first entry off the worklist. */
3184 bb = *qout++;
3185 qlen--;
3187 if (qout >= qend)
3188 qout = worklist;
3190 /* This block can be added to the worklist again if necessary. */
3191 AVAIL_IN_WORKLIST_P (bb) = false;
3192 tm_memopt_compute_avin (bb);
3194 /* Note: We do not add the LOCAL sets here because we already
3195 seeded the AVAIL_OUT sets with them. */
3196 changed = bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_AVAIL_IN (bb));
3197 changed |= bitmap_ior_into (READ_AVAIL_OUT (bb), READ_AVAIL_IN (bb));
3198 if (changed
3199 && (region->exit_blocks == NULL
3200 || !bitmap_bit_p (region->exit_blocks, bb->index)))
3201 /* If the out state of this block changed, then we need to add
3202 its successors to the worklist if they are not already in. */
3203 FOR_EACH_EDGE (e, ei, bb->succs)
3204 if (!AVAIL_IN_WORKLIST_P (e->dest) && e->dest != EXIT_BLOCK_PTR)
3206 *qin++ = e->dest;
3207 AVAIL_IN_WORKLIST_P (e->dest) = true;
3208 qlen++;
3210 if (qin >= qend)
3211 qin = worklist;
3215 free (worklist);
3217 if (dump_file)
3218 dump_tm_memopt_sets (blocks);
3221 /* Compute ANTIC sets for every basic block in BLOCKS.
3223 We compute STORE_ANTIC_OUT as follows:
3225 STORE_ANTIC_OUT[bb] = union(STORE_ANTIC_IN[bb], STORE_LOCAL[bb])
3226 STORE_ANTIC_IN[bb] = intersect(STORE_ANTIC_OUT[successors])
3228 REGION is the TM region.
3229 BLOCKS are the basic blocks in the region. */
3231 static void
3232 tm_memopt_compute_antic (struct tm_region *region,
3233 VEC (basic_block, heap) *blocks)
3235 edge e;
3236 basic_block *worklist, *qin, *qout, *qend, bb;
3237 unsigned int qlen;
3238 int i;
3239 edge_iterator ei;
3241 /* Allocate a worklist array/queue. Entries are only added to the
3242 list if they were not already on the list. So the size is
3243 bounded by the number of basic blocks in the region. */
3244 qin = qout = worklist =
3245 XNEWVEC (basic_block, VEC_length (basic_block, blocks));
3247 for (qlen = 0, i = VEC_length (basic_block, blocks) - 1; i >= 0; --i)
3249 bb = VEC_index (basic_block, blocks, i);
3251 /* Seed ANTIC_OUT with the LOCAL set. */
3252 bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_LOCAL (bb));
3254 /* Put every block in the region on the worklist. */
3255 AVAIL_IN_WORKLIST_P (bb) = true;
3256 /* No need to insert exit blocks, since their ANTIC_IN is NULL,
3257 and their ANTIC_OUT has already been seeded in. */
3258 if (region->exit_blocks
3259 && !bitmap_bit_p (region->exit_blocks, bb->index))
3261 qlen++;
3262 *qin++ = bb;
3266 /* The exit blocks have been initialized with the local sets. */
3267 if (region->exit_blocks)
3269 unsigned int i;
3270 bitmap_iterator bi;
3271 EXECUTE_IF_SET_IN_BITMAP (region->exit_blocks, 0, i, bi)
3272 BB_VISITED_P (BASIC_BLOCK (i)) = true;
3275 qin = worklist;
3276 qend = &worklist[qlen];
3278 /* Iterate until the worklist is empty. */
3279 while (qlen)
3281 /* Take the first entry off the worklist. */
3282 bb = *qout++;
3283 qlen--;
3285 if (qout >= qend)
3286 qout = worklist;
3288 /* This block can be added to the worklist again if necessary. */
3289 AVAIL_IN_WORKLIST_P (bb) = false;
3290 tm_memopt_compute_antin (bb);
3292 /* Note: We do not add the LOCAL sets here because we already
3293 seeded the ANTIC_OUT sets with them. */
3294 if (bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_ANTIC_IN (bb))
3295 && bb != region->entry_block)
3296 /* If the out state of this block changed, then we need to add
3297 its predecessors to the worklist if they are not already in. */
3298 FOR_EACH_EDGE (e, ei, bb->preds)
3299 if (!AVAIL_IN_WORKLIST_P (e->src))
3301 *qin++ = e->src;
3302 AVAIL_IN_WORKLIST_P (e->src) = true;
3303 qlen++;
3305 if (qin >= qend)
3306 qin = worklist;
3310 free (worklist);
3312 if (dump_file)
3313 dump_tm_memopt_sets (blocks);
3316 /* Offsets of load variants from TM_LOAD. For example,
3317 BUILT_IN_TM_LOAD_RAR* is an offset of 1 from BUILT_IN_TM_LOAD*.
3318 See gtm-builtins.def. */
3319 #define TRANSFORM_RAR 1
3320 #define TRANSFORM_RAW 2
3321 #define TRANSFORM_RFW 3
3322 /* Offsets of store variants from TM_STORE. */
3323 #define TRANSFORM_WAR 1
3324 #define TRANSFORM_WAW 2
3326 /* Inform about a load/store optimization. */
3328 static void
3329 dump_tm_memopt_transform (gimple stmt)
3331 if (dump_file)
3333 fprintf (dump_file, "TM memopt: transforming: ");
3334 print_gimple_stmt (dump_file, stmt, 0, 0);
3335 fprintf (dump_file, "\n");
3339 /* Perform a read/write optimization. Replaces the TM builtin in STMT
3340 by a builtin that is OFFSET entries down in the builtins table in
3341 gtm-builtins.def. */
3343 static void
3344 tm_memopt_transform_stmt (unsigned int offset,
3345 gimple stmt,
3346 gimple_stmt_iterator *gsi)
3348 tree fn = gimple_call_fn (stmt);
3349 gcc_assert (TREE_CODE (fn) == ADDR_EXPR);
3350 TREE_OPERAND (fn, 0)
3351 = builtin_decl_explicit ((enum built_in_function)
3352 (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0))
3353 + offset));
3354 gimple_call_set_fn (stmt, fn);
3355 gsi_replace (gsi, stmt, true);
3356 dump_tm_memopt_transform (stmt);
3359 /* Perform the actual TM memory optimization transformations in the
3360 basic blocks in BLOCKS. */
3362 static void
3363 tm_memopt_transform_blocks (VEC (basic_block, heap) *blocks)
3365 size_t i;
3366 basic_block bb;
3367 gimple_stmt_iterator gsi;
3369 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3371 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3373 gimple stmt = gsi_stmt (gsi);
3374 bitmap read_avail = READ_AVAIL_IN (bb);
3375 bitmap store_avail = STORE_AVAIL_IN (bb);
3376 bitmap store_antic = STORE_ANTIC_OUT (bb);
3377 unsigned int loc;
3379 if (is_tm_simple_load (stmt))
3381 loc = tm_memopt_value_number (stmt, NO_INSERT);
3382 if (store_avail && bitmap_bit_p (store_avail, loc))
3383 tm_memopt_transform_stmt (TRANSFORM_RAW, stmt, &gsi);
3384 else if (store_antic && bitmap_bit_p (store_antic, loc))
3386 tm_memopt_transform_stmt (TRANSFORM_RFW, stmt, &gsi);
3387 bitmap_set_bit (store_avail, loc);
3389 else if (read_avail && bitmap_bit_p (read_avail, loc))
3390 tm_memopt_transform_stmt (TRANSFORM_RAR, stmt, &gsi);
3391 else
3392 bitmap_set_bit (read_avail, loc);
3394 else if (is_tm_simple_store (stmt))
3396 loc = tm_memopt_value_number (stmt, NO_INSERT);
3397 if (store_avail && bitmap_bit_p (store_avail, loc))
3398 tm_memopt_transform_stmt (TRANSFORM_WAW, stmt, &gsi);
3399 else
3401 if (read_avail && bitmap_bit_p (read_avail, loc))
3402 tm_memopt_transform_stmt (TRANSFORM_WAR, stmt, &gsi);
3403 bitmap_set_bit (store_avail, loc);
3410 /* Return a new set of bitmaps for a BB. */
3412 static struct tm_memopt_bitmaps *
3413 tm_memopt_init_sets (void)
3415 struct tm_memopt_bitmaps *b
3416 = XOBNEW (&tm_memopt_obstack.obstack, struct tm_memopt_bitmaps);
3417 b->store_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3418 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3419 b->store_antic_in = BITMAP_ALLOC (&tm_memopt_obstack);
3420 b->store_antic_out = BITMAP_ALLOC (&tm_memopt_obstack);
3421 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3422 b->read_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3423 b->read_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3424 b->read_local = BITMAP_ALLOC (&tm_memopt_obstack);
3425 b->store_local = BITMAP_ALLOC (&tm_memopt_obstack);
3426 return b;
3429 /* Free sets computed for each BB. */
3431 static void
3432 tm_memopt_free_sets (VEC (basic_block, heap) *blocks)
3434 size_t i;
3435 basic_block bb;
3437 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3438 bb->aux = NULL;
3441 /* Clear the visited bit for every basic block in BLOCKS. */
3443 static void
3444 tm_memopt_clear_visited (VEC (basic_block, heap) *blocks)
3446 size_t i;
3447 basic_block bb;
3449 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3450 BB_VISITED_P (bb) = false;
3453 /* Replace TM load/stores with hints for the runtime. We handle
3454 things like read-after-write, write-after-read, read-after-read,
3455 read-for-write, etc. */
3457 static unsigned int
3458 execute_tm_memopt (void)
3460 struct tm_region *region;
3461 VEC (basic_block, heap) *bbs;
3463 tm_memopt_value_id = 0;
3464 tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free);
3466 for (region = all_tm_regions; region; region = region->next)
3468 /* All the TM stores/loads in the current region. */
3469 size_t i;
3470 basic_block bb;
3472 bitmap_obstack_initialize (&tm_memopt_obstack);
3474 /* Save all BBs for the current region. */
3475 bbs = get_tm_region_blocks (region->entry_block,
3476 region->exit_blocks,
3477 region->irr_blocks,
3478 NULL,
3479 false);
3481 /* Collect all the memory operations. */
3482 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i)
3484 bb->aux = tm_memopt_init_sets ();
3485 tm_memopt_accumulate_memops (bb);
3488 /* Solve data flow equations and transform each block accordingly. */
3489 tm_memopt_clear_visited (bbs);
3490 tm_memopt_compute_available (region, bbs);
3491 tm_memopt_clear_visited (bbs);
3492 tm_memopt_compute_antic (region, bbs);
3493 tm_memopt_transform_blocks (bbs);
3495 tm_memopt_free_sets (bbs);
3496 VEC_free (basic_block, heap, bbs);
3497 bitmap_obstack_release (&tm_memopt_obstack);
3498 htab_empty (tm_memopt_value_numbers);
3501 htab_delete (tm_memopt_value_numbers);
3502 return 0;
3505 static bool
3506 gate_tm_memopt (void)
3508 return flag_tm && optimize > 0;
3511 struct gimple_opt_pass pass_tm_memopt =
3514 GIMPLE_PASS,
3515 "tmmemopt", /* name */
3516 gate_tm_memopt, /* gate */
3517 execute_tm_memopt, /* execute */
3518 NULL, /* sub */
3519 NULL, /* next */
3520 0, /* static_pass_number */
3521 TV_TRANS_MEM, /* tv_id */
3522 PROP_ssa | PROP_cfg, /* properties_required */
3523 0, /* properties_provided */
3524 0, /* properties_destroyed */
3525 0, /* todo_flags_start */
3526 0, /* todo_flags_finish */
3531 /* Interprocedual analysis for the creation of transactional clones.
3532 The aim of this pass is to find which functions are referenced in
3533 a non-irrevocable transaction context, and for those over which
3534 we have control (or user directive), create a version of the
3535 function which uses only the transactional interface to reference
3536 protected memories. This analysis proceeds in several steps:
3538 (1) Collect the set of all possible transactional clones:
3540 (a) For all local public functions marked tm_callable, push
3541 it onto the tm_callee queue.
3543 (b) For all local functions, scan for calls in transaction blocks.
3544 Push the caller and callee onto the tm_caller and tm_callee
3545 queues. Count the number of callers for each callee.
3547 (c) For each local function on the callee list, assume we will
3548 create a transactional clone. Push *all* calls onto the
3549 callee queues; count the number of clone callers separately
3550 to the number of original callers.
3552 (2) Propagate irrevocable status up the dominator tree:
3554 (a) Any external function on the callee list that is not marked
3555 tm_callable is irrevocable. Push all callers of such onto
3556 a worklist.
3558 (b) For each function on the worklist, mark each block that
3559 contains an irrevocable call. Use the AND operator to
3560 propagate that mark up the dominator tree.
3562 (c) If we reach the entry block for a possible transactional
3563 clone, then the transactional clone is irrevocable, and
3564 we should not create the clone after all. Push all
3565 callers onto the worklist.
3567 (d) Place tm_irrevocable calls at the beginning of the relevant
3568 blocks. Special case here is the entry block for the entire
3569 transaction region; there we mark it GTMA_DOES_GO_IRREVOCABLE for
3570 the library to begin the region in serial mode. Decrement
3571 the call count for all callees in the irrevocable region.
3573 (3) Create the transactional clones:
3575 Any tm_callee that still has a non-zero call count is cloned.
3578 /* This structure is stored in the AUX field of each cgraph_node. */
3579 struct tm_ipa_cg_data
3581 /* The clone of the function that got created. */
3582 struct cgraph_node *clone;
3584 /* The tm regions in the normal function. */
3585 struct tm_region *all_tm_regions;
3587 /* The blocks of the normal/clone functions that contain irrevocable
3588 calls, or blocks that are post-dominated by irrevocable calls. */
3589 bitmap irrevocable_blocks_normal;
3590 bitmap irrevocable_blocks_clone;
3592 /* The blocks of the normal function that are involved in transactions. */
3593 bitmap transaction_blocks_normal;
3595 /* The number of callers to the transactional clone of this function
3596 from normal and transactional clones respectively. */
3597 unsigned tm_callers_normal;
3598 unsigned tm_callers_clone;
3600 /* True if all calls to this function's transactional clone
3601 are irrevocable. Also automatically true if the function
3602 has no transactional clone. */
3603 bool is_irrevocable;
3605 /* Flags indicating the presence of this function in various queues. */
3606 bool in_callee_queue;
3607 bool in_worklist;
3609 /* Flags indicating the kind of scan desired while in the worklist. */
3610 bool want_irr_scan_normal;
3613 typedef VEC (cgraph_node_p, heap) *cgraph_node_queue;
3615 /* Return the ipa data associated with NODE, allocating zeroed memory
3616 if necessary. TRAVERSE_ALIASES is true if we must traverse aliases
3617 and set *NODE accordingly. */
3619 static struct tm_ipa_cg_data *
3620 get_cg_data (struct cgraph_node **node, bool traverse_aliases)
3622 struct tm_ipa_cg_data *d;
3624 if (traverse_aliases && (*node)->alias)
3625 *node = cgraph_get_node ((*node)->thunk.alias);
3627 d = (struct tm_ipa_cg_data *) (*node)->symbol.aux;
3629 if (d == NULL)
3631 d = (struct tm_ipa_cg_data *)
3632 obstack_alloc (&tm_obstack.obstack, sizeof (*d));
3633 (*node)->symbol.aux = (void *) d;
3634 memset (d, 0, sizeof (*d));
3637 return d;
3640 /* Add NODE to the end of QUEUE, unless IN_QUEUE_P indicates that
3641 it is already present. */
3643 static void
3644 maybe_push_queue (struct cgraph_node *node,
3645 cgraph_node_queue *queue_p, bool *in_queue_p)
3647 if (!*in_queue_p)
3649 *in_queue_p = true;
3650 VEC_safe_push (cgraph_node_p, heap, *queue_p, node);
3654 /* A subroutine of ipa_tm_scan_calls_transaction and ipa_tm_scan_calls_clone.
3655 Queue all callees within block BB. */
3657 static void
3658 ipa_tm_scan_calls_block (cgraph_node_queue *callees_p,
3659 basic_block bb, bool for_clone)
3661 gimple_stmt_iterator gsi;
3663 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3665 gimple stmt = gsi_stmt (gsi);
3666 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
3668 tree fndecl = gimple_call_fndecl (stmt);
3669 if (fndecl)
3671 struct tm_ipa_cg_data *d;
3672 unsigned *pcallers;
3673 struct cgraph_node *node;
3675 if (is_tm_ending_fndecl (fndecl))
3676 continue;
3677 if (find_tm_replacement_function (fndecl))
3678 continue;
3680 node = cgraph_get_node (fndecl);
3681 gcc_assert (node != NULL);
3682 d = get_cg_data (&node, true);
3684 pcallers = (for_clone ? &d->tm_callers_clone
3685 : &d->tm_callers_normal);
3686 *pcallers += 1;
3688 maybe_push_queue (node, callees_p, &d->in_callee_queue);
3694 /* Scan all calls in NODE that are within a transaction region,
3695 and push the resulting nodes into the callee queue. */
3697 static void
3698 ipa_tm_scan_calls_transaction (struct tm_ipa_cg_data *d,
3699 cgraph_node_queue *callees_p)
3701 struct tm_region *r;
3703 d->transaction_blocks_normal = BITMAP_ALLOC (&tm_obstack);
3704 d->all_tm_regions = all_tm_regions;
3706 for (r = all_tm_regions; r; r = r->next)
3708 VEC (basic_block, heap) *bbs;
3709 basic_block bb;
3710 unsigned i;
3712 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks, NULL,
3713 d->transaction_blocks_normal, false);
3715 FOR_EACH_VEC_ELT (basic_block, bbs, i, bb)
3716 ipa_tm_scan_calls_block (callees_p, bb, false);
3718 VEC_free (basic_block, heap, bbs);
3722 /* Scan all calls in NODE as if this is the transactional clone,
3723 and push the destinations into the callee queue. */
3725 static void
3726 ipa_tm_scan_calls_clone (struct cgraph_node *node,
3727 cgraph_node_queue *callees_p)
3729 struct function *fn = DECL_STRUCT_FUNCTION (node->symbol.decl);
3730 basic_block bb;
3732 FOR_EACH_BB_FN (bb, fn)
3733 ipa_tm_scan_calls_block (callees_p, bb, true);
3736 /* The function NODE has been detected to be irrevocable. Push all
3737 of its callers onto WORKLIST for the purpose of re-scanning them. */
3739 static void
3740 ipa_tm_note_irrevocable (struct cgraph_node *node,
3741 cgraph_node_queue *worklist_p)
3743 struct tm_ipa_cg_data *d = get_cg_data (&node, true);
3744 struct cgraph_edge *e;
3746 d->is_irrevocable = true;
3748 for (e = node->callers; e ; e = e->next_caller)
3750 basic_block bb;
3751 struct cgraph_node *caller;
3753 /* Don't examine recursive calls. */
3754 if (e->caller == node)
3755 continue;
3756 /* Even if we think we can go irrevocable, believe the user
3757 above all. */
3758 if (is_tm_safe_or_pure (e->caller->symbol.decl))
3759 continue;
3761 caller = e->caller;
3762 d = get_cg_data (&caller, true);
3764 /* Check if the callee is in a transactional region. If so,
3765 schedule the function for normal re-scan as well. */
3766 bb = gimple_bb (e->call_stmt);
3767 gcc_assert (bb != NULL);
3768 if (d->transaction_blocks_normal
3769 && bitmap_bit_p (d->transaction_blocks_normal, bb->index))
3770 d->want_irr_scan_normal = true;
3772 maybe_push_queue (caller, worklist_p, &d->in_worklist);
3776 /* A subroutine of ipa_tm_scan_irr_blocks; return true iff any statement
3777 within the block is irrevocable. */
3779 static bool
3780 ipa_tm_scan_irr_block (basic_block bb)
3782 gimple_stmt_iterator gsi;
3783 tree fn;
3785 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3787 gimple stmt = gsi_stmt (gsi);
3788 switch (gimple_code (stmt))
3790 case GIMPLE_ASSIGN:
3791 if (gimple_assign_single_p (stmt))
3793 tree lhs = gimple_assign_lhs (stmt);
3794 tree rhs = gimple_assign_rhs1 (stmt);
3795 if (volatile_var_p (lhs) || volatile_var_p (rhs))
3796 return true;
3798 break;
3800 case GIMPLE_CALL:
3802 tree lhs = gimple_call_lhs (stmt);
3803 if (lhs && volatile_var_p (lhs))
3804 return true;
3806 if (is_tm_pure_call (stmt))
3807 break;
3809 fn = gimple_call_fn (stmt);
3811 /* Functions with the attribute are by definition irrevocable. */
3812 if (is_tm_irrevocable (fn))
3813 return true;
3815 /* For direct function calls, go ahead and check for replacement
3816 functions, or transitive irrevocable functions. For indirect
3817 functions, we'll ask the runtime. */
3818 if (TREE_CODE (fn) == ADDR_EXPR)
3820 struct tm_ipa_cg_data *d;
3821 struct cgraph_node *node;
3823 fn = TREE_OPERAND (fn, 0);
3824 if (is_tm_ending_fndecl (fn))
3825 break;
3826 if (find_tm_replacement_function (fn))
3827 break;
3829 node = cgraph_get_node(fn);
3830 d = get_cg_data (&node, true);
3832 /* Return true if irrevocable, but above all, believe
3833 the user. */
3834 if (d->is_irrevocable
3835 && !is_tm_safe_or_pure (fn))
3836 return true;
3838 break;
3841 case GIMPLE_ASM:
3842 /* ??? The Approved Method of indicating that an inline
3843 assembly statement is not relevant to the transaction
3844 is to wrap it in a __tm_waiver block. This is not
3845 yet implemented, so we can't check for it. */
3846 if (is_tm_safe (current_function_decl))
3848 tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
3849 SET_EXPR_LOCATION (t, gimple_location (stmt));
3850 error ("%Kasm not allowed in %<transaction_safe%> function", t);
3852 return true;
3854 default:
3855 break;
3859 return false;
3862 /* For each of the blocks seeded witin PQUEUE, walk the CFG looking
3863 for new irrevocable blocks, marking them in NEW_IRR. Don't bother
3864 scanning past OLD_IRR or EXIT_BLOCKS. */
3866 static bool
3867 ipa_tm_scan_irr_blocks (VEC (basic_block, heap) **pqueue, bitmap new_irr,
3868 bitmap old_irr, bitmap exit_blocks)
3870 bool any_new_irr = false;
3871 edge e;
3872 edge_iterator ei;
3873 bitmap visited_blocks = BITMAP_ALLOC (NULL);
3877 basic_block bb = VEC_pop (basic_block, *pqueue);
3879 /* Don't re-scan blocks we know already are irrevocable. */
3880 if (old_irr && bitmap_bit_p (old_irr, bb->index))
3881 continue;
3883 if (ipa_tm_scan_irr_block (bb))
3885 bitmap_set_bit (new_irr, bb->index);
3886 any_new_irr = true;
3888 else if (exit_blocks == NULL || !bitmap_bit_p (exit_blocks, bb->index))
3890 FOR_EACH_EDGE (e, ei, bb->succs)
3891 if (!bitmap_bit_p (visited_blocks, e->dest->index))
3893 bitmap_set_bit (visited_blocks, e->dest->index);
3894 VEC_safe_push (basic_block, heap, *pqueue, e->dest);
3898 while (!VEC_empty (basic_block, *pqueue));
3900 BITMAP_FREE (visited_blocks);
3902 return any_new_irr;
3905 /* Propagate the irrevocable property both up and down the dominator tree.
3906 BB is the current block being scanned; EXIT_BLOCKS are the edges of the
3907 TM regions; OLD_IRR are the results of a previous scan of the dominator
3908 tree which has been fully propagated; NEW_IRR is the set of new blocks
3909 which are gaining the irrevocable property during the current scan. */
3911 static void
3912 ipa_tm_propagate_irr (basic_block entry_block, bitmap new_irr,
3913 bitmap old_irr, bitmap exit_blocks)
3915 VEC (basic_block, heap) *bbs;
3916 bitmap all_region_blocks;
3918 /* If this block is in the old set, no need to rescan. */
3919 if (old_irr && bitmap_bit_p (old_irr, entry_block->index))
3920 return;
3922 all_region_blocks = BITMAP_ALLOC (&tm_obstack);
3923 bbs = get_tm_region_blocks (entry_block, exit_blocks, NULL,
3924 all_region_blocks, false);
3927 basic_block bb = VEC_pop (basic_block, bbs);
3928 bool this_irr = bitmap_bit_p (new_irr, bb->index);
3929 bool all_son_irr = false;
3930 edge_iterator ei;
3931 edge e;
3933 /* Propagate up. If my children are, I am too, but we must have
3934 at least one child that is. */
3935 if (!this_irr)
3937 FOR_EACH_EDGE (e, ei, bb->succs)
3939 if (!bitmap_bit_p (new_irr, e->dest->index))
3941 all_son_irr = false;
3942 break;
3944 else
3945 all_son_irr = true;
3947 if (all_son_irr)
3949 /* Add block to new_irr if it hasn't already been processed. */
3950 if (!old_irr || !bitmap_bit_p (old_irr, bb->index))
3952 bitmap_set_bit (new_irr, bb->index);
3953 this_irr = true;
3958 /* Propagate down to everyone we immediately dominate. */
3959 if (this_irr)
3961 basic_block son;
3962 for (son = first_dom_son (CDI_DOMINATORS, bb);
3963 son;
3964 son = next_dom_son (CDI_DOMINATORS, son))
3966 /* Make sure block is actually in a TM region, and it
3967 isn't already in old_irr. */
3968 if ((!old_irr || !bitmap_bit_p (old_irr, son->index))
3969 && bitmap_bit_p (all_region_blocks, son->index))
3970 bitmap_set_bit (new_irr, son->index);
3974 while (!VEC_empty (basic_block, bbs));
3976 BITMAP_FREE (all_region_blocks);
3977 VEC_free (basic_block, heap, bbs);
3980 static void
3981 ipa_tm_decrement_clone_counts (basic_block bb, bool for_clone)
3983 gimple_stmt_iterator gsi;
3985 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3987 gimple stmt = gsi_stmt (gsi);
3988 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
3990 tree fndecl = gimple_call_fndecl (stmt);
3991 if (fndecl)
3993 struct tm_ipa_cg_data *d;
3994 unsigned *pcallers;
3995 struct cgraph_node *tnode;
3997 if (is_tm_ending_fndecl (fndecl))
3998 continue;
3999 if (find_tm_replacement_function (fndecl))
4000 continue;
4002 tnode = cgraph_get_node (fndecl);
4003 d = get_cg_data (&tnode, true);
4005 pcallers = (for_clone ? &d->tm_callers_clone
4006 : &d->tm_callers_normal);
4008 gcc_assert (*pcallers > 0);
4009 *pcallers -= 1;
4015 /* (Re-)Scan the transaction blocks in NODE for calls to irrevocable functions,
4016 as well as other irrevocable actions such as inline assembly. Mark all
4017 such blocks as irrevocable and decrement the number of calls to
4018 transactional clones. Return true if, for the transactional clone, the
4019 entire function is irrevocable. */
4021 static bool
4022 ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
4024 struct tm_ipa_cg_data *d;
4025 bitmap new_irr, old_irr;
4026 VEC (basic_block, heap) *queue;
4027 bool ret = false;
4029 /* Builtin operators (operator new, and such). */
4030 if (DECL_STRUCT_FUNCTION (node->symbol.decl) == NULL
4031 || DECL_STRUCT_FUNCTION (node->symbol.decl)->cfg == NULL)
4032 return false;
4034 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
4035 calculate_dominance_info (CDI_DOMINATORS);
4037 d = get_cg_data (&node, true);
4038 queue = VEC_alloc (basic_block, heap, 10);
4039 new_irr = BITMAP_ALLOC (&tm_obstack);
4041 /* Scan each tm region, propagating irrevocable status through the tree. */
4042 if (for_clone)
4044 old_irr = d->irrevocable_blocks_clone;
4045 VEC_quick_push (basic_block, queue, single_succ (ENTRY_BLOCK_PTR));
4046 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr, NULL))
4048 ipa_tm_propagate_irr (single_succ (ENTRY_BLOCK_PTR), new_irr,
4049 old_irr, NULL);
4050 ret = bitmap_bit_p (new_irr, single_succ (ENTRY_BLOCK_PTR)->index);
4053 else
4055 struct tm_region *region;
4057 old_irr = d->irrevocable_blocks_normal;
4058 for (region = d->all_tm_regions; region; region = region->next)
4060 VEC_quick_push (basic_block, queue, region->entry_block);
4061 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr,
4062 region->exit_blocks))
4063 ipa_tm_propagate_irr (region->entry_block, new_irr, old_irr,
4064 region->exit_blocks);
4068 /* If we found any new irrevocable blocks, reduce the call count for
4069 transactional clones within the irrevocable blocks. Save the new
4070 set of irrevocable blocks for next time. */
4071 if (!bitmap_empty_p (new_irr))
4073 bitmap_iterator bmi;
4074 unsigned i;
4076 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
4077 ipa_tm_decrement_clone_counts (BASIC_BLOCK (i), for_clone);
4079 if (old_irr)
4081 bitmap_ior_into (old_irr, new_irr);
4082 BITMAP_FREE (new_irr);
4084 else if (for_clone)
4085 d->irrevocable_blocks_clone = new_irr;
4086 else
4087 d->irrevocable_blocks_normal = new_irr;
4089 if (dump_file && new_irr)
4091 const char *dname;
4092 bitmap_iterator bmi;
4093 unsigned i;
4095 dname = lang_hooks.decl_printable_name (current_function_decl, 2);
4096 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
4097 fprintf (dump_file, "%s: bb %d goes irrevocable\n", dname, i);
4100 else
4101 BITMAP_FREE (new_irr);
4103 VEC_free (basic_block, heap, queue);
4104 pop_cfun ();
4106 return ret;
4109 /* Return true if, for the transactional clone of NODE, any call
4110 may enter irrevocable mode. */
4112 static bool
4113 ipa_tm_mayenterirr_function (struct cgraph_node *node)
4115 struct tm_ipa_cg_data *d;
4116 tree decl;
4117 unsigned flags;
4119 d = get_cg_data (&node, true);
4120 decl = node->symbol.decl;
4121 flags = flags_from_decl_or_type (decl);
4123 /* Handle some TM builtins. Ordinarily these aren't actually generated
4124 at this point, but handling these functions when written in by the
4125 user makes it easier to build unit tests. */
4126 if (flags & ECF_TM_BUILTIN)
4127 return false;
4129 /* Filter out all functions that are marked. */
4130 if (flags & ECF_TM_PURE)
4131 return false;
4132 if (is_tm_safe (decl))
4133 return false;
4134 if (is_tm_irrevocable (decl))
4135 return true;
4136 if (is_tm_callable (decl))
4137 return true;
4138 if (find_tm_replacement_function (decl))
4139 return true;
4141 /* If we aren't seeing the final version of the function we don't
4142 know what it will contain at runtime. */
4143 if (cgraph_function_body_availability (node) < AVAIL_AVAILABLE)
4144 return true;
4146 /* If the function must go irrevocable, then of course true. */
4147 if (d->is_irrevocable)
4148 return true;
4150 /* If there are any blocks marked irrevocable, then the function
4151 as a whole may enter irrevocable. */
4152 if (d->irrevocable_blocks_clone)
4153 return true;
4155 /* We may have previously marked this function as tm_may_enter_irr;
4156 see pass_diagnose_tm_blocks. */
4157 if (node->local.tm_may_enter_irr)
4158 return true;
4160 /* Recurse on the main body for aliases. In general, this will
4161 result in one of the bits above being set so that we will not
4162 have to recurse next time. */
4163 if (node->alias)
4164 return ipa_tm_mayenterirr_function (cgraph_get_node (node->thunk.alias));
4166 /* What remains is unmarked local functions without items that force
4167 the function to go irrevocable. */
4168 return false;
4171 /* Diagnose calls from transaction_safe functions to unmarked
4172 functions that are determined to not be safe. */
4174 static void
4175 ipa_tm_diagnose_tm_safe (struct cgraph_node *node)
4177 struct cgraph_edge *e;
4179 for (e = node->callees; e ; e = e->next_callee)
4180 if (!is_tm_callable (e->callee->symbol.decl)
4181 && e->callee->local.tm_may_enter_irr)
4182 error_at (gimple_location (e->call_stmt),
4183 "unsafe function call %qD within "
4184 "%<transaction_safe%> function", e->callee->symbol.decl);
4187 /* Diagnose call from atomic transactions to unmarked functions
4188 that are determined to not be safe. */
4190 static void
4191 ipa_tm_diagnose_transaction (struct cgraph_node *node,
4192 struct tm_region *all_tm_regions)
4194 struct tm_region *r;
4196 for (r = all_tm_regions; r ; r = r->next)
4197 if (gimple_transaction_subcode (r->transaction_stmt) & GTMA_IS_RELAXED)
4199 /* Atomic transactions can be nested inside relaxed. */
4200 if (r->inner)
4201 ipa_tm_diagnose_transaction (node, r->inner);
4203 else
4205 VEC (basic_block, heap) *bbs;
4206 gimple_stmt_iterator gsi;
4207 basic_block bb;
4208 size_t i;
4210 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks,
4211 r->irr_blocks, NULL, false);
4213 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i)
4214 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4216 gimple stmt = gsi_stmt (gsi);
4217 tree fndecl;
4219 if (gimple_code (stmt) == GIMPLE_ASM)
4221 error_at (gimple_location (stmt),
4222 "asm not allowed in atomic transaction");
4223 continue;
4226 if (!is_gimple_call (stmt))
4227 continue;
4228 fndecl = gimple_call_fndecl (stmt);
4230 /* Indirect function calls have been diagnosed already. */
4231 if (!fndecl)
4232 continue;
4234 /* Stop at the end of the transaction. */
4235 if (is_tm_ending_fndecl (fndecl))
4237 if (bitmap_bit_p (r->exit_blocks, bb->index))
4238 break;
4239 continue;
4242 /* Marked functions have been diagnosed already. */
4243 if (is_tm_pure_call (stmt))
4244 continue;
4245 if (is_tm_callable (fndecl))
4246 continue;
4248 if (cgraph_local_info (fndecl)->tm_may_enter_irr)
4249 error_at (gimple_location (stmt),
4250 "unsafe function call %qD within "
4251 "atomic transaction", fndecl);
4254 VEC_free (basic_block, heap, bbs);
4258 /* Return a transactional mangled name for the DECL_ASSEMBLER_NAME in
4259 OLD_DECL. The returned value is a freshly malloced pointer that
4260 should be freed by the caller. */
4262 static tree
4263 tm_mangle (tree old_asm_id)
4265 const char *old_asm_name;
4266 char *tm_name;
4267 void *alloc = NULL;
4268 struct demangle_component *dc;
4269 tree new_asm_id;
4271 /* Determine if the symbol is already a valid C++ mangled name. Do this
4272 even for C, which might be interfacing with C++ code via appropriately
4273 ugly identifiers. */
4274 /* ??? We could probably do just as well checking for "_Z" and be done. */
4275 old_asm_name = IDENTIFIER_POINTER (old_asm_id);
4276 dc = cplus_demangle_v3_components (old_asm_name, DMGL_NO_OPTS, &alloc);
4278 if (dc == NULL)
4280 char length[8];
4282 do_unencoded:
4283 sprintf (length, "%u", IDENTIFIER_LENGTH (old_asm_id));
4284 tm_name = concat ("_ZGTt", length, old_asm_name, NULL);
4286 else
4288 old_asm_name += 2; /* Skip _Z */
4290 switch (dc->type)
4292 case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
4293 case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
4294 /* Don't play silly games, you! */
4295 goto do_unencoded;
4297 case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
4298 /* I'd really like to know if we can ever be passed one of
4299 these from the C++ front end. The Logical Thing would
4300 seem that hidden-alias should be outer-most, so that we
4301 get hidden-alias of a transaction-clone and not vice-versa. */
4302 old_asm_name += 2;
4303 break;
4305 default:
4306 break;
4309 tm_name = concat ("_ZGTt", old_asm_name, NULL);
4311 free (alloc);
4313 new_asm_id = get_identifier (tm_name);
4314 free (tm_name);
4316 return new_asm_id;
4319 static inline void
4320 ipa_tm_mark_force_output_node (struct cgraph_node *node)
4322 cgraph_mark_force_output_node (node);
4323 /* ??? function_and_variable_visibility will reset
4324 the needed bit, without actually checking. */
4325 node->analyzed = 1;
4328 /* Callback data for ipa_tm_create_version_alias. */
4329 struct create_version_alias_info
4331 struct cgraph_node *old_node;
4332 tree new_decl;
4335 /* A subroutine of ipa_tm_create_version, called via
4336 cgraph_for_node_and_aliases. Create new tm clones for each of
4337 the existing aliases. */
4338 static bool
4339 ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
4341 struct create_version_alias_info *info
4342 = (struct create_version_alias_info *)data;
4343 tree old_decl, new_decl, tm_name;
4344 struct cgraph_node *new_node;
4346 if (!node->same_body_alias)
4347 return false;
4349 old_decl = node->symbol.decl;
4350 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4351 new_decl = build_decl (DECL_SOURCE_LOCATION (old_decl),
4352 TREE_CODE (old_decl), tm_name,
4353 TREE_TYPE (old_decl));
4355 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4356 SET_DECL_RTL (new_decl, NULL);
4358 /* Based loosely on C++'s make_alias_for(). */
4359 TREE_PUBLIC (new_decl) = TREE_PUBLIC (old_decl);
4360 DECL_CONTEXT (new_decl) = DECL_CONTEXT (old_decl);
4361 DECL_LANG_SPECIFIC (new_decl) = DECL_LANG_SPECIFIC (old_decl);
4362 TREE_READONLY (new_decl) = TREE_READONLY (old_decl);
4363 DECL_EXTERNAL (new_decl) = 0;
4364 DECL_ARTIFICIAL (new_decl) = 1;
4365 TREE_ADDRESSABLE (new_decl) = 1;
4366 TREE_USED (new_decl) = 1;
4367 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4369 /* Perform the same remapping to the comdat group. */
4370 if (DECL_ONE_ONLY (new_decl))
4371 DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
4373 new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
4374 new_node->tm_clone = true;
4375 new_node->symbol.externally_visible = info->old_node->symbol.externally_visible;
4376 /* ?? Do not traverse aliases here. */
4377 get_cg_data (&node, false)->clone = new_node;
4379 record_tm_clone_pair (old_decl, new_decl);
4381 if (info->old_node->symbol.force_output
4382 || ipa_ref_list_first_referring (&info->old_node->symbol.ref_list))
4383 ipa_tm_mark_force_output_node (new_node);
4384 return false;
4387 /* Create a copy of the function (possibly declaration only) of OLD_NODE,
4388 appropriate for the transactional clone. */
4390 static void
4391 ipa_tm_create_version (struct cgraph_node *old_node)
4393 tree new_decl, old_decl, tm_name;
4394 struct cgraph_node *new_node;
4396 old_decl = old_node->symbol.decl;
4397 new_decl = copy_node (old_decl);
4399 /* DECL_ASSEMBLER_NAME needs to be set before we call
4400 cgraph_copy_node_for_versioning below, because cgraph_node will
4401 fill the assembler_name_hash. */
4402 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4403 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4404 SET_DECL_RTL (new_decl, NULL);
4405 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4407 /* Perform the same remapping to the comdat group. */
4408 if (DECL_ONE_ONLY (new_decl))
4409 DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
4411 new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL);
4412 new_node->symbol.externally_visible = old_node->symbol.externally_visible;
4413 new_node->lowered = true;
4414 new_node->tm_clone = 1;
4415 get_cg_data (&old_node, true)->clone = new_node;
4417 if (cgraph_function_body_availability (old_node) >= AVAIL_OVERWRITABLE)
4419 /* Remap extern inline to static inline. */
4420 /* ??? Is it worth trying to use make_decl_one_only? */
4421 if (DECL_DECLARED_INLINE_P (new_decl) && DECL_EXTERNAL (new_decl))
4423 DECL_EXTERNAL (new_decl) = 0;
4424 TREE_PUBLIC (new_decl) = 0;
4425 DECL_WEAK (new_decl) = 0;
4428 tree_function_versioning (old_decl, new_decl, NULL, false, NULL, false,
4429 NULL, NULL);
4432 record_tm_clone_pair (old_decl, new_decl);
4434 cgraph_call_function_insertion_hooks (new_node);
4435 if (old_node->symbol.force_output
4436 || ipa_ref_list_first_referring (&old_node->symbol.ref_list))
4437 ipa_tm_mark_force_output_node (new_node);
4439 /* Do the same thing, but for any aliases of the original node. */
4441 struct create_version_alias_info data;
4442 data.old_node = old_node;
4443 data.new_decl = new_decl;
4444 cgraph_for_node_and_aliases (old_node, ipa_tm_create_version_alias,
4445 &data, true);
4449 /* Construct a call to TM_IRREVOCABLE and insert it at the beginning of BB. */
4451 static void
4452 ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region,
4453 basic_block bb)
4455 gimple_stmt_iterator gsi;
4456 gimple g;
4458 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4460 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE),
4461 1, build_int_cst (NULL_TREE, MODE_SERIALIRREVOCABLE));
4463 split_block_after_labels (bb);
4464 gsi = gsi_after_labels (bb);
4465 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
4467 cgraph_create_edge (node,
4468 cgraph_get_create_node
4469 (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE)),
4470 g, 0,
4471 compute_call_stmt_bb_frequency (node->symbol.decl,
4472 gimple_bb (g)));
4475 /* Construct a call to TM_GETTMCLONE and insert it before GSI. */
4477 static bool
4478 ipa_tm_insert_gettmclone_call (struct cgraph_node *node,
4479 struct tm_region *region,
4480 gimple_stmt_iterator *gsi, gimple stmt)
4482 tree gettm_fn, ret, old_fn, callfn;
4483 gimple g, g2;
4484 bool safe;
4486 old_fn = gimple_call_fn (stmt);
4488 if (TREE_CODE (old_fn) == ADDR_EXPR)
4490 tree fndecl = TREE_OPERAND (old_fn, 0);
4491 tree clone = get_tm_clone_pair (fndecl);
4493 /* By transforming the call into a TM_GETTMCLONE, we are
4494 technically taking the address of the original function and
4495 its clone. Explain this so inlining will know this function
4496 is needed. */
4497 cgraph_mark_address_taken_node (cgraph_get_node (fndecl));
4498 if (clone)
4499 cgraph_mark_address_taken_node (cgraph_get_node (clone));
4502 safe = is_tm_safe (TREE_TYPE (old_fn));
4503 gettm_fn = builtin_decl_explicit (safe ? BUILT_IN_TM_GETTMCLONE_SAFE
4504 : BUILT_IN_TM_GETTMCLONE_IRR);
4505 ret = create_tmp_var (ptr_type_node, NULL);
4507 if (!safe)
4508 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4510 /* Discard OBJ_TYPE_REF, since we weren't able to fold it. */
4511 if (TREE_CODE (old_fn) == OBJ_TYPE_REF)
4512 old_fn = OBJ_TYPE_REF_EXPR (old_fn);
4514 g = gimple_build_call (gettm_fn, 1, old_fn);
4515 ret = make_ssa_name (ret, g);
4516 gimple_call_set_lhs (g, ret);
4518 gsi_insert_before (gsi, g, GSI_SAME_STMT);
4520 cgraph_create_edge (node, cgraph_get_create_node (gettm_fn), g, 0,
4521 compute_call_stmt_bb_frequency (node->symbol.decl,
4522 gimple_bb(g)));
4524 /* Cast return value from tm_gettmclone* into appropriate function
4525 pointer. */
4526 callfn = create_tmp_var (TREE_TYPE (old_fn), NULL);
4527 g2 = gimple_build_assign (callfn,
4528 fold_build1 (NOP_EXPR, TREE_TYPE (callfn), ret));
4529 callfn = make_ssa_name (callfn, g2);
4530 gimple_assign_set_lhs (g2, callfn);
4531 gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4533 /* ??? This is a hack to preserve the NOTHROW bit on the call,
4534 which we would have derived from the decl. Failure to save
4535 this bit means we might have to split the basic block. */
4536 if (gimple_call_nothrow_p (stmt))
4537 gimple_call_set_nothrow (stmt, true);
4539 gimple_call_set_fn (stmt, callfn);
4541 /* Discarding OBJ_TYPE_REF above may produce incompatible LHS and RHS
4542 for a call statement. Fix it. */
4544 tree lhs = gimple_call_lhs (stmt);
4545 tree rettype = TREE_TYPE (gimple_call_fntype (stmt));
4546 if (lhs
4547 && !useless_type_conversion_p (TREE_TYPE (lhs), rettype))
4549 tree temp;
4551 temp = create_tmp_reg (rettype, 0);
4552 gimple_call_set_lhs (stmt, temp);
4554 g2 = gimple_build_assign (lhs,
4555 fold_build1 (VIEW_CONVERT_EXPR,
4556 TREE_TYPE (lhs), temp));
4557 gsi_insert_after (gsi, g2, GSI_SAME_STMT);
4561 update_stmt (stmt);
4563 return true;
4566 /* Helper function for ipa_tm_transform_calls*. Given a call
4567 statement in GSI which resides inside transaction REGION, redirect
4568 the call to either its wrapper function, or its clone. */
4570 static void
4571 ipa_tm_transform_calls_redirect (struct cgraph_node *node,
4572 struct tm_region *region,
4573 gimple_stmt_iterator *gsi,
4574 bool *need_ssa_rename_p)
4576 gimple stmt = gsi_stmt (*gsi);
4577 struct cgraph_node *new_node;
4578 struct cgraph_edge *e = cgraph_edge (node, stmt);
4579 tree fndecl = gimple_call_fndecl (stmt);
4581 /* For indirect calls, pass the address through the runtime. */
4582 if (fndecl == NULL)
4584 *need_ssa_rename_p |=
4585 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
4586 return;
4589 /* Handle some TM builtins. Ordinarily these aren't actually generated
4590 at this point, but handling these functions when written in by the
4591 user makes it easier to build unit tests. */
4592 if (flags_from_decl_or_type (fndecl) & ECF_TM_BUILTIN)
4593 return;
4595 /* Fixup recursive calls inside clones. */
4596 /* ??? Why did cgraph_copy_node_for_versioning update the call edges
4597 for recursion but not update the call statements themselves? */
4598 if (e->caller == e->callee && decl_is_tm_clone (current_function_decl))
4600 gimple_call_set_fndecl (stmt, current_function_decl);
4601 return;
4604 /* If there is a replacement, use it. */
4605 fndecl = find_tm_replacement_function (fndecl);
4606 if (fndecl)
4608 new_node = cgraph_get_create_node (fndecl);
4610 /* ??? Mark all transaction_wrap functions tm_may_enter_irr.
4612 We can't do this earlier in record_tm_replacement because
4613 cgraph_remove_unreachable_nodes is called before we inject
4614 references to the node. Further, we can't do this in some
4615 nice central place in ipa_tm_execute because we don't have
4616 the exact list of wrapper functions that would be used.
4617 Marking more wrappers than necessary results in the creation
4618 of unnecessary cgraph_nodes, which can cause some of the
4619 other IPA passes to crash.
4621 We do need to mark these nodes so that we get the proper
4622 result in expand_call_tm. */
4623 /* ??? This seems broken. How is it that we're marking the
4624 CALLEE as may_enter_irr? Surely we should be marking the
4625 CALLER. Also note that find_tm_replacement_function also
4626 contains mappings into the TM runtime, e.g. memcpy. These
4627 we know won't go irrevocable. */
4628 new_node->local.tm_may_enter_irr = 1;
4630 else
4632 struct tm_ipa_cg_data *d;
4633 struct cgraph_node *tnode = e->callee;
4635 d = get_cg_data (&tnode, true);
4636 new_node = d->clone;
4638 /* As we've already skipped pure calls and appropriate builtins,
4639 and we've already marked irrevocable blocks, if we can't come
4640 up with a static replacement, then ask the runtime. */
4641 if (new_node == NULL)
4643 *need_ssa_rename_p |=
4644 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
4645 return;
4648 fndecl = new_node->symbol.decl;
4651 cgraph_redirect_edge_callee (e, new_node);
4652 gimple_call_set_fndecl (stmt, fndecl);
4655 /* Helper function for ipa_tm_transform_calls. For a given BB,
4656 install calls to tm_irrevocable when IRR_BLOCKS are reached,
4657 redirect other calls to the generated transactional clone. */
4659 static bool
4660 ipa_tm_transform_calls_1 (struct cgraph_node *node, struct tm_region *region,
4661 basic_block bb, bitmap irr_blocks)
4663 gimple_stmt_iterator gsi;
4664 bool need_ssa_rename = false;
4666 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
4668 ipa_tm_insert_irr_call (node, region, bb);
4669 return true;
4672 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4674 gimple stmt = gsi_stmt (gsi);
4676 if (!is_gimple_call (stmt))
4677 continue;
4678 if (is_tm_pure_call (stmt))
4679 continue;
4681 /* Redirect edges to the appropriate replacement or clone. */
4682 ipa_tm_transform_calls_redirect (node, region, &gsi, &need_ssa_rename);
4685 return need_ssa_rename;
4688 /* Walk the CFG for REGION, beginning at BB. Install calls to
4689 tm_irrevocable when IRR_BLOCKS are reached, redirect other calls to
4690 the generated transactional clone. */
4692 static bool
4693 ipa_tm_transform_calls (struct cgraph_node *node, struct tm_region *region,
4694 basic_block bb, bitmap irr_blocks)
4696 bool need_ssa_rename = false;
4697 edge e;
4698 edge_iterator ei;
4699 VEC(basic_block, heap) *queue = NULL;
4700 bitmap visited_blocks = BITMAP_ALLOC (NULL);
4702 VEC_safe_push (basic_block, heap, queue, bb);
4705 bb = VEC_pop (basic_block, queue);
4707 need_ssa_rename |=
4708 ipa_tm_transform_calls_1 (node, region, bb, irr_blocks);
4710 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
4711 continue;
4713 if (region && bitmap_bit_p (region->exit_blocks, bb->index))
4714 continue;
4716 FOR_EACH_EDGE (e, ei, bb->succs)
4717 if (!bitmap_bit_p (visited_blocks, e->dest->index))
4719 bitmap_set_bit (visited_blocks, e->dest->index);
4720 VEC_safe_push (basic_block, heap, queue, e->dest);
4723 while (!VEC_empty (basic_block, queue));
4725 VEC_free (basic_block, heap, queue);
4726 BITMAP_FREE (visited_blocks);
4728 return need_ssa_rename;
4731 /* Transform the calls within the TM regions within NODE. */
4733 static void
4734 ipa_tm_transform_transaction (struct cgraph_node *node)
4736 struct tm_ipa_cg_data *d;
4737 struct tm_region *region;
4738 bool need_ssa_rename = false;
4740 d = get_cg_data (&node, true);
4742 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
4743 calculate_dominance_info (CDI_DOMINATORS);
4745 for (region = d->all_tm_regions; region; region = region->next)
4747 /* If we're sure to go irrevocable, don't transform anything. */
4748 if (d->irrevocable_blocks_normal
4749 && bitmap_bit_p (d->irrevocable_blocks_normal,
4750 region->entry_block->index))
4752 transaction_subcode_ior (region, GTMA_DOES_GO_IRREVOCABLE);
4753 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4754 continue;
4757 need_ssa_rename |=
4758 ipa_tm_transform_calls (node, region, region->entry_block,
4759 d->irrevocable_blocks_normal);
4762 if (need_ssa_rename)
4763 update_ssa (TODO_update_ssa_only_virtuals);
4765 pop_cfun ();
4768 /* Transform the calls within the transactional clone of NODE. */
4770 static void
4771 ipa_tm_transform_clone (struct cgraph_node *node)
4773 struct tm_ipa_cg_data *d;
4774 bool need_ssa_rename;
4776 d = get_cg_data (&node, true);
4778 /* If this function makes no calls and has no irrevocable blocks,
4779 then there's nothing to do. */
4780 /* ??? Remove non-aborting top-level transactions. */
4781 if (!node->callees && !node->indirect_calls && !d->irrevocable_blocks_clone)
4782 return;
4784 push_cfun (DECL_STRUCT_FUNCTION (d->clone->symbol.decl));
4785 calculate_dominance_info (CDI_DOMINATORS);
4787 need_ssa_rename =
4788 ipa_tm_transform_calls (d->clone, NULL, single_succ (ENTRY_BLOCK_PTR),
4789 d->irrevocable_blocks_clone);
4791 if (need_ssa_rename)
4792 update_ssa (TODO_update_ssa_only_virtuals);
4794 pop_cfun ();
4797 /* Main entry point for the transactional memory IPA pass. */
4799 static unsigned int
4800 ipa_tm_execute (void)
4802 cgraph_node_queue tm_callees = NULL;
4803 /* List of functions that will go irrevocable. */
4804 cgraph_node_queue irr_worklist = NULL;
4806 struct cgraph_node *node;
4807 struct tm_ipa_cg_data *d;
4808 enum availability a;
4809 unsigned int i;
4811 #ifdef ENABLE_CHECKING
4812 verify_cgraph ();
4813 #endif
4815 bitmap_obstack_initialize (&tm_obstack);
4817 /* For all local functions marked tm_callable, queue them. */
4818 FOR_EACH_DEFINED_FUNCTION (node)
4819 if (is_tm_callable (node->symbol.decl)
4820 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4822 d = get_cg_data (&node, true);
4823 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
4826 /* For all local reachable functions... */
4827 FOR_EACH_DEFINED_FUNCTION (node)
4828 if (node->lowered
4829 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4831 /* ... marked tm_pure, record that fact for the runtime by
4832 indicating that the pure function is its own tm_callable.
4833 No need to do this if the function's address can't be taken. */
4834 if (is_tm_pure (node->symbol.decl))
4836 if (!node->local.local)
4837 record_tm_clone_pair (node->symbol.decl, node->symbol.decl);
4838 continue;
4841 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
4842 calculate_dominance_info (CDI_DOMINATORS);
4844 tm_region_init (NULL);
4845 if (all_tm_regions)
4847 d = get_cg_data (&node, true);
4849 /* Scan for calls that are in each transaction. */
4850 ipa_tm_scan_calls_transaction (d, &tm_callees);
4852 /* Put it in the worklist so we can scan the function
4853 later (ipa_tm_scan_irr_function) and mark the
4854 irrevocable blocks. */
4855 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4856 d->want_irr_scan_normal = true;
4859 pop_cfun ();
4862 /* For every local function on the callee list, scan as if we will be
4863 creating a transactional clone, queueing all new functions we find
4864 along the way. */
4865 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4867 node = VEC_index (cgraph_node_p, tm_callees, i);
4868 a = cgraph_function_body_availability (node);
4869 d = get_cg_data (&node, true);
4871 /* Put it in the worklist so we can scan the function later
4872 (ipa_tm_scan_irr_function) and mark the irrevocable
4873 blocks. */
4874 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4876 /* Some callees cannot be arbitrarily cloned. These will always be
4877 irrevocable. Mark these now, so that we need not scan them. */
4878 if (is_tm_irrevocable (node->symbol.decl))
4879 ipa_tm_note_irrevocable (node, &irr_worklist);
4880 else if (a <= AVAIL_NOT_AVAILABLE
4881 && !is_tm_safe_or_pure (node->symbol.decl))
4882 ipa_tm_note_irrevocable (node, &irr_worklist);
4883 else if (a >= AVAIL_OVERWRITABLE)
4885 if (!tree_versionable_function_p (node->symbol.decl))
4886 ipa_tm_note_irrevocable (node, &irr_worklist);
4887 else if (!d->is_irrevocable)
4889 /* If this is an alias, make sure its base is queued as well.
4890 we need not scan the callees now, as the base will do. */
4891 if (node->alias)
4893 node = cgraph_get_node (node->thunk.alias);
4894 d = get_cg_data (&node, true);
4895 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
4896 continue;
4899 /* Add all nodes called by this function into
4900 tm_callees as well. */
4901 ipa_tm_scan_calls_clone (node, &tm_callees);
4906 /* Iterate scans until no more work to be done. Prefer not to use
4907 VEC_pop because the worklist tends to follow a breadth-first
4908 search of the callgraph, which should allow convergance with a
4909 minimum number of scans. But we also don't want the worklist
4910 array to grow without bound, so we shift the array up periodically. */
4911 for (i = 0; i < VEC_length (cgraph_node_p, irr_worklist); ++i)
4913 if (i > 256 && i == VEC_length (cgraph_node_p, irr_worklist) / 8)
4915 VEC_block_remove (cgraph_node_p, irr_worklist, 0, i);
4916 i = 0;
4919 node = VEC_index (cgraph_node_p, irr_worklist, i);
4920 d = get_cg_data (&node, true);
4921 d->in_worklist = false;
4923 if (d->want_irr_scan_normal)
4925 d->want_irr_scan_normal = false;
4926 ipa_tm_scan_irr_function (node, false);
4928 if (d->in_callee_queue && ipa_tm_scan_irr_function (node, true))
4929 ipa_tm_note_irrevocable (node, &irr_worklist);
4932 /* For every function on the callee list, collect the tm_may_enter_irr
4933 bit on the node. */
4934 VEC_truncate (cgraph_node_p, irr_worklist, 0);
4935 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4937 node = VEC_index (cgraph_node_p, tm_callees, i);
4938 if (ipa_tm_mayenterirr_function (node))
4940 d = get_cg_data (&node, true);
4941 gcc_assert (d->in_worklist == false);
4942 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4946 /* Propagate the tm_may_enter_irr bit to callers until stable. */
4947 for (i = 0; i < VEC_length (cgraph_node_p, irr_worklist); ++i)
4949 struct cgraph_node *caller;
4950 struct cgraph_edge *e;
4951 struct ipa_ref *ref;
4952 unsigned j;
4954 if (i > 256 && i == VEC_length (cgraph_node_p, irr_worklist) / 8)
4956 VEC_block_remove (cgraph_node_p, irr_worklist, 0, i);
4957 i = 0;
4960 node = VEC_index (cgraph_node_p, irr_worklist, i);
4961 d = get_cg_data (&node, true);
4962 d->in_worklist = false;
4963 node->local.tm_may_enter_irr = true;
4965 /* Propagate back to normal callers. */
4966 for (e = node->callers; e ; e = e->next_caller)
4968 caller = e->caller;
4969 if (!is_tm_safe_or_pure (caller->symbol.decl)
4970 && !caller->local.tm_may_enter_irr)
4972 d = get_cg_data (&caller, true);
4973 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
4977 /* Propagate back to referring aliases as well. */
4978 for (j = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, j, ref); j++)
4980 caller = cgraph (ref->referring);
4981 if (ref->use == IPA_REF_ALIAS
4982 && !caller->local.tm_may_enter_irr)
4984 /* ?? Do not traverse aliases here. */
4985 d = get_cg_data (&caller, false);
4986 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
4991 /* Now validate all tm_safe functions, and all atomic regions in
4992 other functions. */
4993 FOR_EACH_DEFINED_FUNCTION (node)
4994 if (node->lowered
4995 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4997 d = get_cg_data (&node, true);
4998 if (is_tm_safe (node->symbol.decl))
4999 ipa_tm_diagnose_tm_safe (node);
5000 else if (d->all_tm_regions)
5001 ipa_tm_diagnose_transaction (node, d->all_tm_regions);
5004 /* Create clones. Do those that are not irrevocable and have a
5005 positive call count. Do those publicly visible functions that
5006 the user directed us to clone. */
5007 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
5009 bool doit = false;
5011 node = VEC_index (cgraph_node_p, tm_callees, i);
5012 if (node->same_body_alias)
5013 continue;
5015 a = cgraph_function_body_availability (node);
5016 d = get_cg_data (&node, true);
5018 if (a <= AVAIL_NOT_AVAILABLE)
5019 doit = is_tm_callable (node->symbol.decl);
5020 else if (a <= AVAIL_AVAILABLE && is_tm_callable (node->symbol.decl))
5021 doit = true;
5022 else if (!d->is_irrevocable
5023 && d->tm_callers_normal + d->tm_callers_clone > 0)
5024 doit = true;
5026 if (doit)
5027 ipa_tm_create_version (node);
5030 /* Redirect calls to the new clones, and insert irrevocable marks. */
5031 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
5033 node = VEC_index (cgraph_node_p, tm_callees, i);
5034 if (node->analyzed)
5036 d = get_cg_data (&node, true);
5037 if (d->clone)
5038 ipa_tm_transform_clone (node);
5041 FOR_EACH_DEFINED_FUNCTION (node)
5042 if (node->lowered
5043 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
5045 d = get_cg_data (&node, true);
5046 if (d->all_tm_regions)
5047 ipa_tm_transform_transaction (node);
5050 /* Free and clear all data structures. */
5051 VEC_free (cgraph_node_p, heap, tm_callees);
5052 VEC_free (cgraph_node_p, heap, irr_worklist);
5053 bitmap_obstack_release (&tm_obstack);
5055 FOR_EACH_FUNCTION (node)
5056 node->symbol.aux = NULL;
5058 #ifdef ENABLE_CHECKING
5059 verify_cgraph ();
5060 #endif
5062 return 0;
5065 struct simple_ipa_opt_pass pass_ipa_tm =
5068 SIMPLE_IPA_PASS,
5069 "tmipa", /* name */
5070 gate_tm, /* gate */
5071 ipa_tm_execute, /* execute */
5072 NULL, /* sub */
5073 NULL, /* next */
5074 0, /* static_pass_number */
5075 TV_TRANS_MEM, /* tv_id */
5076 PROP_ssa | PROP_cfg, /* properties_required */
5077 0, /* properties_provided */
5078 0, /* properties_destroyed */
5079 0, /* todo_flags_start */
5080 0, /* todo_flags_finish */
5084 #include "gt-trans-mem.h"