2012-05-17 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc.git] / gcc / trans-mem.c
blob51dd7fe13eda5dd53ce1d32f9a1d712408681a29
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 "tree-pretty-print.h"
36 #include "gimple-pretty-print.h"
37 #include "cfgloop.h"
40 #define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 2000 - 1)
41 #define PROB_ALWAYS (REG_BR_PROB_BASE)
43 #define A_RUNINSTRUMENTEDCODE 0x0001
44 #define A_RUNUNINSTRUMENTEDCODE 0x0002
45 #define A_SAVELIVEVARIABLES 0x0004
46 #define A_RESTORELIVEVARIABLES 0x0008
47 #define A_ABORTTRANSACTION 0x0010
49 #define AR_USERABORT 0x0001
50 #define AR_USERRETRY 0x0002
51 #define AR_TMCONFLICT 0x0004
52 #define AR_EXCEPTIONBLOCKABORT 0x0008
53 #define AR_OUTERABORT 0x0010
55 #define MODE_SERIALIRREVOCABLE 0x0000
58 /* The representation of a transaction changes several times during the
59 lowering process. In the beginning, in the front-end we have the
60 GENERIC tree TRANSACTION_EXPR. For example,
62 __transaction {
63 local++;
64 if (++global == 10)
65 __tm_abort;
68 During initial gimplification (gimplify.c) the TRANSACTION_EXPR node is
69 trivially replaced with a GIMPLE_TRANSACTION node.
71 During pass_lower_tm, we examine the body of transactions looking
72 for aborts. Transactions that do not contain an abort may be
73 merged into an outer transaction. We also add a TRY-FINALLY node
74 to arrange for the transaction to be committed on any exit.
76 [??? Think about how this arrangement affects throw-with-commit
77 and throw-with-abort operations. In this case we want the TRY to
78 handle gotos, but not to catch any exceptions because the transaction
79 will already be closed.]
81 GIMPLE_TRANSACTION [label=NULL] {
82 try {
83 local = local + 1;
84 t0 = global;
85 t1 = t0 + 1;
86 global = t1;
87 if (t1 == 10)
88 __builtin___tm_abort ();
89 } finally {
90 __builtin___tm_commit ();
94 During pass_lower_eh, we create EH regions for the transactions,
95 intermixed with the regular EH stuff. This gives us a nice persistent
96 mapping (all the way through rtl) from transactional memory operation
97 back to the transaction, which allows us to get the abnormal edges
98 correct to model transaction aborts and restarts:
100 GIMPLE_TRANSACTION [label=over]
101 local = local + 1;
102 t0 = global;
103 t1 = t0 + 1;
104 global = t1;
105 if (t1 == 10)
106 __builtin___tm_abort ();
107 __builtin___tm_commit ();
108 over:
110 This is the end of all_lowering_passes, and so is what is present
111 during the IPA passes, and through all of the optimization passes.
113 During pass_ipa_tm, we examine all GIMPLE_TRANSACTION blocks in all
114 functions and mark functions for cloning.
116 At the end of gimple optimization, before exiting SSA form,
117 pass_tm_edges replaces statements that perform transactional
118 memory operations with the appropriate TM builtins, and swap
119 out function calls with their transactional clones. At this
120 point we introduce the abnormal transaction restart edges and
121 complete lowering of the GIMPLE_TRANSACTION node.
123 x = __builtin___tm_start (MAY_ABORT);
124 eh_label:
125 if (x & abort_transaction)
126 goto over;
127 local = local + 1;
128 t0 = __builtin___tm_load (global);
129 t1 = t0 + 1;
130 __builtin___tm_store (&global, t1);
131 if (t1 == 10)
132 __builtin___tm_abort ();
133 __builtin___tm_commit ();
134 over:
138 /* Return the attributes we want to examine for X, or NULL if it's not
139 something we examine. We look at function types, but allow pointers
140 to function types and function decls and peek through. */
142 static tree
143 get_attrs_for (const_tree x)
145 switch (TREE_CODE (x))
147 case FUNCTION_DECL:
148 return TYPE_ATTRIBUTES (TREE_TYPE (x));
149 break;
151 default:
152 if (TYPE_P (x))
153 return NULL;
154 x = TREE_TYPE (x);
155 if (TREE_CODE (x) != POINTER_TYPE)
156 return NULL;
157 /* FALLTHRU */
159 case POINTER_TYPE:
160 x = TREE_TYPE (x);
161 if (TREE_CODE (x) != FUNCTION_TYPE && TREE_CODE (x) != METHOD_TYPE)
162 return NULL;
163 /* FALLTHRU */
165 case FUNCTION_TYPE:
166 case METHOD_TYPE:
167 return TYPE_ATTRIBUTES (x);
171 /* Return true if X has been marked TM_PURE. */
173 bool
174 is_tm_pure (const_tree x)
176 unsigned flags;
178 switch (TREE_CODE (x))
180 case FUNCTION_DECL:
181 case FUNCTION_TYPE:
182 case METHOD_TYPE:
183 break;
185 default:
186 if (TYPE_P (x))
187 return false;
188 x = TREE_TYPE (x);
189 if (TREE_CODE (x) != POINTER_TYPE)
190 return false;
191 /* FALLTHRU */
193 case POINTER_TYPE:
194 x = TREE_TYPE (x);
195 if (TREE_CODE (x) != FUNCTION_TYPE && TREE_CODE (x) != METHOD_TYPE)
196 return false;
197 break;
200 flags = flags_from_decl_or_type (x);
201 return (flags & ECF_TM_PURE) != 0;
204 /* Return true if X has been marked TM_IRREVOCABLE. */
206 static bool
207 is_tm_irrevocable (tree x)
209 tree attrs = get_attrs_for (x);
211 if (attrs && lookup_attribute ("transaction_unsafe", attrs))
212 return true;
214 /* A call to the irrevocable builtin is by definition,
215 irrevocable. */
216 if (TREE_CODE (x) == ADDR_EXPR)
217 x = TREE_OPERAND (x, 0);
218 if (TREE_CODE (x) == FUNCTION_DECL
219 && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL
220 && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
221 return true;
223 return false;
226 /* Return true if X has been marked TM_SAFE. */
228 bool
229 is_tm_safe (const_tree x)
231 if (flag_tm)
233 tree attrs = get_attrs_for (x);
234 if (attrs)
236 if (lookup_attribute ("transaction_safe", attrs))
237 return true;
238 if (lookup_attribute ("transaction_may_cancel_outer", attrs))
239 return true;
242 return false;
245 /* Return true if CALL is const, or tm_pure. */
247 static bool
248 is_tm_pure_call (gimple call)
250 tree fn = gimple_call_fn (call);
252 if (TREE_CODE (fn) == ADDR_EXPR)
254 fn = TREE_OPERAND (fn, 0);
255 gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
257 else
258 fn = TREE_TYPE (fn);
260 return is_tm_pure (fn);
263 /* Return true if X has been marked TM_CALLABLE. */
265 static bool
266 is_tm_callable (tree x)
268 tree attrs = get_attrs_for (x);
269 if (attrs)
271 if (lookup_attribute ("transaction_callable", attrs))
272 return true;
273 if (lookup_attribute ("transaction_safe", attrs))
274 return true;
275 if (lookup_attribute ("transaction_may_cancel_outer", attrs))
276 return true;
278 return false;
281 /* Return true if X has been marked TRANSACTION_MAY_CANCEL_OUTER. */
283 bool
284 is_tm_may_cancel_outer (tree x)
286 tree attrs = get_attrs_for (x);
287 if (attrs)
288 return lookup_attribute ("transaction_may_cancel_outer", attrs) != NULL;
289 return false;
292 /* Return true for built in functions that "end" a transaction. */
294 bool
295 is_tm_ending_fndecl (tree fndecl)
297 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
298 switch (DECL_FUNCTION_CODE (fndecl))
300 case BUILT_IN_TM_COMMIT:
301 case BUILT_IN_TM_COMMIT_EH:
302 case BUILT_IN_TM_ABORT:
303 case BUILT_IN_TM_IRREVOCABLE:
304 return true;
305 default:
306 break;
309 return false;
312 /* Return true if STMT is a TM load. */
314 static bool
315 is_tm_load (gimple stmt)
317 tree fndecl;
319 if (gimple_code (stmt) != GIMPLE_CALL)
320 return false;
322 fndecl = gimple_call_fndecl (stmt);
323 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
324 && BUILTIN_TM_LOAD_P (DECL_FUNCTION_CODE (fndecl)));
327 /* Same as above, but for simple TM loads, that is, not the
328 after-write, after-read, etc optimized variants. */
330 static bool
331 is_tm_simple_load (gimple stmt)
333 tree fndecl;
335 if (gimple_code (stmt) != GIMPLE_CALL)
336 return false;
338 fndecl = gimple_call_fndecl (stmt);
339 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
341 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
342 return (fcode == BUILT_IN_TM_LOAD_1
343 || fcode == BUILT_IN_TM_LOAD_2
344 || fcode == BUILT_IN_TM_LOAD_4
345 || fcode == BUILT_IN_TM_LOAD_8
346 || fcode == BUILT_IN_TM_LOAD_FLOAT
347 || fcode == BUILT_IN_TM_LOAD_DOUBLE
348 || fcode == BUILT_IN_TM_LOAD_LDOUBLE
349 || fcode == BUILT_IN_TM_LOAD_M64
350 || fcode == BUILT_IN_TM_LOAD_M128
351 || fcode == BUILT_IN_TM_LOAD_M256);
353 return false;
356 /* Return true if STMT is a TM store. */
358 static bool
359 is_tm_store (gimple stmt)
361 tree fndecl;
363 if (gimple_code (stmt) != GIMPLE_CALL)
364 return false;
366 fndecl = gimple_call_fndecl (stmt);
367 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
368 && BUILTIN_TM_STORE_P (DECL_FUNCTION_CODE (fndecl)));
371 /* Same as above, but for simple TM stores, that is, not the
372 after-write, after-read, etc optimized variants. */
374 static bool
375 is_tm_simple_store (gimple stmt)
377 tree fndecl;
379 if (gimple_code (stmt) != GIMPLE_CALL)
380 return false;
382 fndecl = gimple_call_fndecl (stmt);
383 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
385 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
386 return (fcode == BUILT_IN_TM_STORE_1
387 || fcode == BUILT_IN_TM_STORE_2
388 || fcode == BUILT_IN_TM_STORE_4
389 || fcode == BUILT_IN_TM_STORE_8
390 || fcode == BUILT_IN_TM_STORE_FLOAT
391 || fcode == BUILT_IN_TM_STORE_DOUBLE
392 || fcode == BUILT_IN_TM_STORE_LDOUBLE
393 || fcode == BUILT_IN_TM_STORE_M64
394 || fcode == BUILT_IN_TM_STORE_M128
395 || fcode == BUILT_IN_TM_STORE_M256);
397 return false;
400 /* Return true if FNDECL is BUILT_IN_TM_ABORT. */
402 static bool
403 is_tm_abort (tree fndecl)
405 return (fndecl
406 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
407 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
410 /* Build a GENERIC tree for a user abort. This is called by front ends
411 while transforming the __tm_abort statement. */
413 tree
414 build_tm_abort_call (location_t loc, bool is_outer)
416 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TM_ABORT), 1,
417 build_int_cst (integer_type_node,
418 AR_USERABORT
419 | (is_outer ? AR_OUTERABORT : 0)));
422 /* Common gateing function for several of the TM passes. */
424 static bool
425 gate_tm (void)
427 return flag_tm;
430 /* Map for aribtrary function replacement under TM, as created
431 by the tm_wrap attribute. */
433 static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
434 htab_t tm_wrap_map;
436 void
437 record_tm_replacement (tree from, tree to)
439 struct tree_map **slot, *h;
441 /* Do not inline wrapper functions that will get replaced in the TM
442 pass.
444 Suppose you have foo() that will get replaced into tmfoo(). Make
445 sure the inliner doesn't try to outsmart us and inline foo()
446 before we get a chance to do the TM replacement. */
447 DECL_UNINLINABLE (from) = 1;
449 if (tm_wrap_map == NULL)
450 tm_wrap_map = htab_create_ggc (32, tree_map_hash, tree_map_eq, 0);
452 h = ggc_alloc_tree_map ();
453 h->hash = htab_hash_pointer (from);
454 h->base.from = from;
455 h->to = to;
457 slot = (struct tree_map **)
458 htab_find_slot_with_hash (tm_wrap_map, h, h->hash, INSERT);
459 *slot = h;
462 /* Return a TM-aware replacement function for DECL. */
464 static tree
465 find_tm_replacement_function (tree fndecl)
467 if (tm_wrap_map)
469 struct tree_map *h, in;
471 in.base.from = fndecl;
472 in.hash = htab_hash_pointer (fndecl);
473 h = (struct tree_map *) htab_find_with_hash (tm_wrap_map, &in, in.hash);
474 if (h)
475 return h->to;
478 /* ??? We may well want TM versions of most of the common <string.h>
479 functions. For now, we've already these two defined. */
480 /* Adjust expand_call_tm() attributes as necessary for the cases
481 handled here: */
482 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
483 switch (DECL_FUNCTION_CODE (fndecl))
485 case BUILT_IN_MEMCPY:
486 return builtin_decl_explicit (BUILT_IN_TM_MEMCPY);
487 case BUILT_IN_MEMMOVE:
488 return builtin_decl_explicit (BUILT_IN_TM_MEMMOVE);
489 case BUILT_IN_MEMSET:
490 return builtin_decl_explicit (BUILT_IN_TM_MEMSET);
491 default:
492 return NULL;
495 return NULL;
498 /* When appropriate, record TM replacement for memory allocation functions.
500 FROM is the FNDECL to wrap. */
501 void
502 tm_malloc_replacement (tree from)
504 const char *str;
505 tree to;
507 if (TREE_CODE (from) != FUNCTION_DECL)
508 return;
510 /* If we have a previous replacement, the user must be explicitly
511 wrapping malloc/calloc/free. They better know what they're
512 doing... */
513 if (find_tm_replacement_function (from))
514 return;
516 str = IDENTIFIER_POINTER (DECL_NAME (from));
518 if (!strcmp (str, "malloc"))
519 to = builtin_decl_explicit (BUILT_IN_TM_MALLOC);
520 else if (!strcmp (str, "calloc"))
521 to = builtin_decl_explicit (BUILT_IN_TM_CALLOC);
522 else if (!strcmp (str, "free"))
523 to = builtin_decl_explicit (BUILT_IN_TM_FREE);
524 else
525 return;
527 TREE_NOTHROW (to) = 0;
529 record_tm_replacement (from, to);
532 /* Diagnostics for tm_safe functions/regions. Called by the front end
533 once we've lowered the function to high-gimple. */
535 /* Subroutine of diagnose_tm_safe_errors, called through walk_gimple_seq.
536 Process exactly one statement. WI->INFO is set to non-null when in
537 the context of a tm_safe function, and null for a __transaction block. */
539 #define DIAG_TM_OUTER 1
540 #define DIAG_TM_SAFE 2
541 #define DIAG_TM_RELAXED 4
543 struct diagnose_tm
545 unsigned int summary_flags : 8;
546 unsigned int block_flags : 8;
547 unsigned int func_flags : 8;
548 unsigned int saw_volatile : 1;
549 gimple stmt;
552 /* Tree callback function for diagnose_tm pass. */
554 static tree
555 diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
556 void *data)
558 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
559 struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
560 enum tree_code code = TREE_CODE (*tp);
562 if ((code == VAR_DECL
563 || code == RESULT_DECL
564 || code == PARM_DECL)
565 && d->block_flags & (DIAG_TM_SAFE | DIAG_TM_RELAXED)
566 && TREE_THIS_VOLATILE (TREE_TYPE (*tp))
567 && !d->saw_volatile)
569 d->saw_volatile = 1;
570 error_at (gimple_location (d->stmt),
571 "invalid volatile use of %qD inside transaction",
572 *tp);
575 return NULL_TREE;
578 static tree
579 diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
580 struct walk_stmt_info *wi)
582 gimple stmt = gsi_stmt (*gsi);
583 struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
585 /* Save stmt for use in leaf analysis. */
586 d->stmt = stmt;
588 switch (gimple_code (stmt))
590 case GIMPLE_CALL:
592 tree fn = gimple_call_fn (stmt);
594 if ((d->summary_flags & DIAG_TM_OUTER) == 0
595 && is_tm_may_cancel_outer (fn))
596 error_at (gimple_location (stmt),
597 "%<transaction_may_cancel_outer%> function call not within"
598 " outer transaction or %<transaction_may_cancel_outer%>");
600 if (d->summary_flags & DIAG_TM_SAFE)
602 bool is_safe, direct_call_p;
603 tree replacement;
605 if (TREE_CODE (fn) == ADDR_EXPR
606 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
608 direct_call_p = true;
609 replacement = TREE_OPERAND (fn, 0);
610 replacement = find_tm_replacement_function (replacement);
611 if (replacement)
612 fn = replacement;
614 else
616 direct_call_p = false;
617 replacement = NULL_TREE;
620 if (is_tm_safe_or_pure (fn))
621 is_safe = true;
622 else if (is_tm_callable (fn) || is_tm_irrevocable (fn))
624 /* A function explicitly marked transaction_callable as
625 opposed to transaction_safe is being defined to be
626 unsafe as part of its ABI, regardless of its contents. */
627 is_safe = false;
629 else if (direct_call_p)
631 if (flags_from_decl_or_type (fn) & ECF_TM_BUILTIN)
632 is_safe = true;
633 else if (replacement)
635 /* ??? At present we've been considering replacements
636 merely transaction_callable, and therefore might
637 enter irrevocable. The tm_wrap attribute has not
638 yet made it into the new language spec. */
639 is_safe = false;
641 else
643 /* ??? Diagnostics for unmarked direct calls moved into
644 the IPA pass. Section 3.2 of the spec details how
645 functions not marked should be considered "implicitly
646 safe" based on having examined the function body. */
647 is_safe = true;
650 else
652 /* An unmarked indirect call. Consider it unsafe even
653 though optimization may yet figure out how to inline. */
654 is_safe = false;
657 if (!is_safe)
659 if (TREE_CODE (fn) == ADDR_EXPR)
660 fn = TREE_OPERAND (fn, 0);
661 if (d->block_flags & DIAG_TM_SAFE)
663 if (direct_call_p)
664 error_at (gimple_location (stmt),
665 "unsafe function call %qD within "
666 "atomic transaction", fn);
667 else
669 if (!DECL_P (fn) || DECL_NAME (fn))
670 error_at (gimple_location (stmt),
671 "unsafe function call %qE within "
672 "atomic transaction", fn);
673 else
674 error_at (gimple_location (stmt),
675 "unsafe indirect function call within "
676 "atomic transaction");
679 else
681 if (direct_call_p)
682 error_at (gimple_location (stmt),
683 "unsafe function call %qD within "
684 "%<transaction_safe%> function", fn);
685 else
687 if (!DECL_P (fn) || DECL_NAME (fn))
688 error_at (gimple_location (stmt),
689 "unsafe function call %qE within "
690 "%<transaction_safe%> function", fn);
691 else
692 error_at (gimple_location (stmt),
693 "unsafe indirect function call within "
694 "%<transaction_safe%> function");
700 break;
702 case GIMPLE_ASM:
703 /* ??? We ought to come up with a way to add attributes to
704 asm statements, and then add "transaction_safe" to it.
705 Either that or get the language spec to resurrect __tm_waiver. */
706 if (d->block_flags & DIAG_TM_SAFE)
707 error_at (gimple_location (stmt),
708 "asm not allowed in atomic transaction");
709 else if (d->func_flags & DIAG_TM_SAFE)
710 error_at (gimple_location (stmt),
711 "asm not allowed in %<transaction_safe%> function");
712 break;
714 case GIMPLE_TRANSACTION:
716 unsigned char inner_flags = DIAG_TM_SAFE;
718 if (gimple_transaction_subcode (stmt) & GTMA_IS_RELAXED)
720 if (d->block_flags & DIAG_TM_SAFE)
721 error_at (gimple_location (stmt),
722 "relaxed transaction in atomic transaction");
723 else if (d->func_flags & DIAG_TM_SAFE)
724 error_at (gimple_location (stmt),
725 "relaxed transaction in %<transaction_safe%> function");
726 inner_flags = DIAG_TM_RELAXED;
728 else if (gimple_transaction_subcode (stmt) & GTMA_IS_OUTER)
730 if (d->block_flags)
731 error_at (gimple_location (stmt),
732 "outer transaction in transaction");
733 else if (d->func_flags & DIAG_TM_OUTER)
734 error_at (gimple_location (stmt),
735 "outer transaction in "
736 "%<transaction_may_cancel_outer%> function");
737 else if (d->func_flags & DIAG_TM_SAFE)
738 error_at (gimple_location (stmt),
739 "outer transaction in %<transaction_safe%> function");
740 inner_flags |= DIAG_TM_OUTER;
743 *handled_ops_p = true;
744 if (gimple_transaction_body (stmt))
746 struct walk_stmt_info wi_inner;
747 struct diagnose_tm d_inner;
749 memset (&d_inner, 0, sizeof (d_inner));
750 d_inner.func_flags = d->func_flags;
751 d_inner.block_flags = d->block_flags | inner_flags;
752 d_inner.summary_flags = d_inner.func_flags | d_inner.block_flags;
754 memset (&wi_inner, 0, sizeof (wi_inner));
755 wi_inner.info = &d_inner;
757 walk_gimple_seq (gimple_transaction_body (stmt),
758 diagnose_tm_1, diagnose_tm_1_op, &wi_inner);
761 break;
763 default:
764 break;
767 return NULL_TREE;
770 static unsigned int
771 diagnose_tm_blocks (void)
773 struct walk_stmt_info wi;
774 struct diagnose_tm d;
776 memset (&d, 0, sizeof (d));
777 if (is_tm_may_cancel_outer (current_function_decl))
778 d.func_flags = DIAG_TM_OUTER | DIAG_TM_SAFE;
779 else if (is_tm_safe (current_function_decl))
780 d.func_flags = DIAG_TM_SAFE;
781 d.summary_flags = d.func_flags;
783 memset (&wi, 0, sizeof (wi));
784 wi.info = &d;
786 walk_gimple_seq (gimple_body (current_function_decl),
787 diagnose_tm_1, diagnose_tm_1_op, &wi);
789 return 0;
792 struct gimple_opt_pass pass_diagnose_tm_blocks =
795 GIMPLE_PASS,
796 "*diagnose_tm_blocks", /* name */
797 gate_tm, /* gate */
798 diagnose_tm_blocks, /* execute */
799 NULL, /* sub */
800 NULL, /* next */
801 0, /* static_pass_number */
802 TV_TRANS_MEM, /* tv_id */
803 PROP_gimple_any, /* properties_required */
804 0, /* properties_provided */
805 0, /* properties_destroyed */
806 0, /* todo_flags_start */
807 0, /* todo_flags_finish */
811 /* Instead of instrumenting thread private memory, we save the
812 addresses in a log which we later use to save/restore the addresses
813 upon transaction start/restart.
815 The log is keyed by address, where each element contains individual
816 statements among different code paths that perform the store.
818 This log is later used to generate either plain save/restore of the
819 addresses upon transaction start/restart, or calls to the ITM_L*
820 logging functions.
822 So for something like:
824 struct large { int x[1000]; };
825 struct large lala = { 0 };
826 __transaction {
827 lala.x[i] = 123;
831 We can either save/restore:
833 lala = { 0 };
834 trxn = _ITM_startTransaction ();
835 if (trxn & a_saveLiveVariables)
836 tmp_lala1 = lala.x[i];
837 else if (a & a_restoreLiveVariables)
838 lala.x[i] = tmp_lala1;
840 or use the logging functions:
842 lala = { 0 };
843 trxn = _ITM_startTransaction ();
844 _ITM_LU4 (&lala.x[i]);
846 Obviously, if we use _ITM_L* to log, we prefer to call _ITM_L* as
847 far up the dominator tree to shadow all of the writes to a given
848 location (thus reducing the total number of logging calls), but not
849 so high as to be called on a path that does not perform a
850 write. */
852 /* One individual log entry. We may have multiple statements for the
853 same location if neither dominate each other (on different
854 execution paths). */
855 typedef struct tm_log_entry
857 /* Address to save. */
858 tree addr;
859 /* Entry block for the transaction this address occurs in. */
860 basic_block entry_block;
861 /* Dominating statements the store occurs in. */
862 gimple_vec stmts;
863 /* Initially, while we are building the log, we place a nonzero
864 value here to mean that this address *will* be saved with a
865 save/restore sequence. Later, when generating the save sequence
866 we place the SSA temp generated here. */
867 tree save_var;
868 } *tm_log_entry_t;
870 /* The actual log. */
871 static htab_t tm_log;
873 /* Addresses to log with a save/restore sequence. These should be in
874 dominator order. */
875 static VEC(tree,heap) *tm_log_save_addresses;
877 /* Map for an SSA_NAME originally pointing to a non aliased new piece
878 of memory (malloc, alloc, etc). */
879 static htab_t tm_new_mem_hash;
881 enum thread_memory_type
883 mem_non_local = 0,
884 mem_thread_local,
885 mem_transaction_local,
886 mem_max
889 typedef struct tm_new_mem_map
891 /* SSA_NAME being dereferenced. */
892 tree val;
893 enum thread_memory_type local_new_memory;
894 } tm_new_mem_map_t;
896 /* Htab support. Return hash value for a `tm_log_entry'. */
897 static hashval_t
898 tm_log_hash (const void *p)
900 const struct tm_log_entry *log = (const struct tm_log_entry *) p;
901 return iterative_hash_expr (log->addr, 0);
904 /* Htab support. Return true if two log entries are the same. */
905 static int
906 tm_log_eq (const void *p1, const void *p2)
908 const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1;
909 const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2;
911 /* FIXME:
913 rth: I suggest that we get rid of the component refs etc.
914 I.e. resolve the reference to base + offset.
916 We may need to actually finish a merge with mainline for this,
917 since we'd like to be presented with Richi's MEM_REF_EXPRs more
918 often than not. But in the meantime your tm_log_entry could save
919 the results of get_inner_reference.
921 See: g++.dg/tm/pr46653.C
924 /* Special case plain equality because operand_equal_p() below will
925 return FALSE if the addresses are equal but they have
926 side-effects (e.g. a volatile address). */
927 if (log1->addr == log2->addr)
928 return true;
930 return operand_equal_p (log1->addr, log2->addr, 0);
933 /* Htab support. Free one tm_log_entry. */
934 static void
935 tm_log_free (void *p)
937 struct tm_log_entry *lp = (struct tm_log_entry *) p;
938 VEC_free (gimple, heap, lp->stmts);
939 free (lp);
942 /* Initialize logging data structures. */
943 static void
944 tm_log_init (void)
946 tm_log = htab_create (10, tm_log_hash, tm_log_eq, tm_log_free);
947 tm_new_mem_hash = htab_create (5, struct_ptr_hash, struct_ptr_eq, free);
948 tm_log_save_addresses = VEC_alloc (tree, heap, 5);
951 /* Free logging data structures. */
952 static void
953 tm_log_delete (void)
955 htab_delete (tm_log);
956 htab_delete (tm_new_mem_hash);
957 VEC_free (tree, heap, tm_log_save_addresses);
960 /* Return true if MEM is a transaction invariant memory for the TM
961 region starting at REGION_ENTRY_BLOCK. */
962 static bool
963 transaction_invariant_address_p (const_tree mem, basic_block region_entry_block)
965 if ((TREE_CODE (mem) == INDIRECT_REF || TREE_CODE (mem) == MEM_REF)
966 && TREE_CODE (TREE_OPERAND (mem, 0)) == SSA_NAME)
968 basic_block def_bb;
970 def_bb = gimple_bb (SSA_NAME_DEF_STMT (TREE_OPERAND (mem, 0)));
971 return def_bb != region_entry_block
972 && dominated_by_p (CDI_DOMINATORS, region_entry_block, def_bb);
975 mem = strip_invariant_refs (mem);
976 return mem && (CONSTANT_CLASS_P (mem) || decl_address_invariant_p (mem));
979 /* Given an address ADDR in STMT, find it in the memory log or add it,
980 making sure to keep only the addresses highest in the dominator
981 tree.
983 ENTRY_BLOCK is the entry_block for the transaction.
985 If we find the address in the log, make sure it's either the same
986 address, or an equivalent one that dominates ADDR.
988 If we find the address, but neither ADDR dominates the found
989 address, nor the found one dominates ADDR, we're on different
990 execution paths. Add it.
992 If known, ENTRY_BLOCK is the entry block for the region, otherwise
993 NULL. */
994 static void
995 tm_log_add (basic_block entry_block, tree addr, gimple stmt)
997 void **slot;
998 struct tm_log_entry l, *lp;
1000 l.addr = addr;
1001 slot = htab_find_slot (tm_log, &l, INSERT);
1002 if (!*slot)
1004 tree type = TREE_TYPE (addr);
1006 lp = XNEW (struct tm_log_entry);
1007 lp->addr = addr;
1008 *slot = lp;
1010 /* Small invariant addresses can be handled as save/restores. */
1011 if (entry_block
1012 && transaction_invariant_address_p (lp->addr, entry_block)
1013 && TYPE_SIZE_UNIT (type) != NULL
1014 && host_integerp (TYPE_SIZE_UNIT (type), 1)
1015 && (tree_low_cst (TYPE_SIZE_UNIT (type), 1)
1016 < PARAM_VALUE (PARAM_TM_MAX_AGGREGATE_SIZE))
1017 /* We must be able to copy this type normally. I.e., no
1018 special constructors and the like. */
1019 && !TREE_ADDRESSABLE (type))
1021 lp->save_var = create_tmp_reg (TREE_TYPE (lp->addr), "tm_save");
1022 add_referenced_var (lp->save_var);
1023 lp->stmts = NULL;
1024 lp->entry_block = entry_block;
1025 /* Save addresses separately in dominator order so we don't
1026 get confused by overlapping addresses in the save/restore
1027 sequence. */
1028 VEC_safe_push (tree, heap, tm_log_save_addresses, lp->addr);
1030 else
1032 /* Use the logging functions. */
1033 lp->stmts = VEC_alloc (gimple, heap, 5);
1034 VEC_quick_push (gimple, lp->stmts, stmt);
1035 lp->save_var = NULL;
1038 else
1040 size_t i;
1041 gimple oldstmt;
1043 lp = (struct tm_log_entry *) *slot;
1045 /* If we're generating a save/restore sequence, we don't care
1046 about statements. */
1047 if (lp->save_var)
1048 return;
1050 for (i = 0; VEC_iterate (gimple, lp->stmts, i, oldstmt); ++i)
1052 if (stmt == oldstmt)
1053 return;
1054 /* We already have a store to the same address, higher up the
1055 dominator tree. Nothing to do. */
1056 if (dominated_by_p (CDI_DOMINATORS,
1057 gimple_bb (stmt), gimple_bb (oldstmt)))
1058 return;
1059 /* We should be processing blocks in dominator tree order. */
1060 gcc_assert (!dominated_by_p (CDI_DOMINATORS,
1061 gimple_bb (oldstmt), gimple_bb (stmt)));
1063 /* Store is on a different code path. */
1064 VEC_safe_push (gimple, heap, lp->stmts, stmt);
1068 /* Gimplify the address of a TARGET_MEM_REF. Return the SSA_NAME
1069 result, insert the new statements before GSI. */
1071 static tree
1072 gimplify_addr (gimple_stmt_iterator *gsi, tree x)
1074 if (TREE_CODE (x) == TARGET_MEM_REF)
1075 x = tree_mem_ref_addr (build_pointer_type (TREE_TYPE (x)), x);
1076 else
1077 x = build_fold_addr_expr (x);
1078 return force_gimple_operand_gsi (gsi, x, true, NULL, true, GSI_SAME_STMT);
1081 /* Instrument one address with the logging functions.
1082 ADDR is the address to save.
1083 STMT is the statement before which to place it. */
1084 static void
1085 tm_log_emit_stmt (tree addr, gimple stmt)
1087 tree type = TREE_TYPE (addr);
1088 tree size = TYPE_SIZE_UNIT (type);
1089 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
1090 gimple log;
1091 enum built_in_function code = BUILT_IN_TM_LOG;
1093 if (type == float_type_node)
1094 code = BUILT_IN_TM_LOG_FLOAT;
1095 else if (type == double_type_node)
1096 code = BUILT_IN_TM_LOG_DOUBLE;
1097 else if (type == long_double_type_node)
1098 code = BUILT_IN_TM_LOG_LDOUBLE;
1099 else if (host_integerp (size, 1))
1101 unsigned int n = tree_low_cst (size, 1);
1102 switch (n)
1104 case 1:
1105 code = BUILT_IN_TM_LOG_1;
1106 break;
1107 case 2:
1108 code = BUILT_IN_TM_LOG_2;
1109 break;
1110 case 4:
1111 code = BUILT_IN_TM_LOG_4;
1112 break;
1113 case 8:
1114 code = BUILT_IN_TM_LOG_8;
1115 break;
1116 default:
1117 code = BUILT_IN_TM_LOG;
1118 if (TREE_CODE (type) == VECTOR_TYPE)
1120 if (n == 8 && builtin_decl_explicit (BUILT_IN_TM_LOG_M64))
1121 code = BUILT_IN_TM_LOG_M64;
1122 else if (n == 16 && builtin_decl_explicit (BUILT_IN_TM_LOG_M128))
1123 code = BUILT_IN_TM_LOG_M128;
1124 else if (n == 32 && builtin_decl_explicit (BUILT_IN_TM_LOG_M256))
1125 code = BUILT_IN_TM_LOG_M256;
1127 break;
1131 addr = gimplify_addr (&gsi, addr);
1132 if (code == BUILT_IN_TM_LOG)
1133 log = gimple_build_call (builtin_decl_explicit (code), 2, addr, size);
1134 else
1135 log = gimple_build_call (builtin_decl_explicit (code), 1, addr);
1136 gsi_insert_before (&gsi, log, GSI_SAME_STMT);
1139 /* Go through the log and instrument address that must be instrumented
1140 with the logging functions. Leave the save/restore addresses for
1141 later. */
1142 static void
1143 tm_log_emit (void)
1145 htab_iterator hi;
1146 struct tm_log_entry *lp;
1148 FOR_EACH_HTAB_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
1150 size_t i;
1151 gimple stmt;
1153 if (dump_file)
1155 fprintf (dump_file, "TM thread private mem logging: ");
1156 print_generic_expr (dump_file, lp->addr, 0);
1157 fprintf (dump_file, "\n");
1160 if (lp->save_var)
1162 if (dump_file)
1163 fprintf (dump_file, "DUMPING to variable\n");
1164 continue;
1166 else
1168 if (dump_file)
1169 fprintf (dump_file, "DUMPING with logging functions\n");
1170 for (i = 0; VEC_iterate (gimple, lp->stmts, i, stmt); ++i)
1171 tm_log_emit_stmt (lp->addr, stmt);
1176 /* Emit the save sequence for the corresponding addresses in the log.
1177 ENTRY_BLOCK is the entry block for the transaction.
1178 BB is the basic block to insert the code in. */
1179 static void
1180 tm_log_emit_saves (basic_block entry_block, basic_block bb)
1182 size_t i;
1183 gimple_stmt_iterator gsi = gsi_last_bb (bb);
1184 gimple stmt;
1185 struct tm_log_entry l, *lp;
1187 for (i = 0; i < VEC_length (tree, tm_log_save_addresses); ++i)
1189 l.addr = VEC_index (tree, tm_log_save_addresses, i);
1190 lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
1191 gcc_assert (lp->save_var != NULL);
1193 /* We only care about variables in the current transaction. */
1194 if (lp->entry_block != entry_block)
1195 continue;
1197 stmt = gimple_build_assign (lp->save_var, unshare_expr (lp->addr));
1199 /* Make sure we can create an SSA_NAME for this type. For
1200 instance, aggregates aren't allowed, in which case the system
1201 will create a VOP for us and everything will just work. */
1202 if (is_gimple_reg_type (TREE_TYPE (lp->save_var)))
1204 lp->save_var = make_ssa_name (lp->save_var, stmt);
1205 gimple_assign_set_lhs (stmt, lp->save_var);
1208 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1212 /* Emit the restore sequence for the corresponding addresses in the log.
1213 ENTRY_BLOCK is the entry block for the transaction.
1214 BB is the basic block to insert the code in. */
1215 static void
1216 tm_log_emit_restores (basic_block entry_block, basic_block bb)
1218 int i;
1219 struct tm_log_entry l, *lp;
1220 gimple_stmt_iterator gsi;
1221 gimple stmt;
1223 for (i = VEC_length (tree, tm_log_save_addresses) - 1; i >= 0; i--)
1225 l.addr = VEC_index (tree, tm_log_save_addresses, i);
1226 lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
1227 gcc_assert (lp->save_var != NULL);
1229 /* We only care about variables in the current transaction. */
1230 if (lp->entry_block != entry_block)
1231 continue;
1233 /* Restores are in LIFO order from the saves in case we have
1234 overlaps. */
1235 gsi = gsi_start_bb (bb);
1237 stmt = gimple_build_assign (unshare_expr (lp->addr), lp->save_var);
1238 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
1242 /* Emit the checks for performing either a save or a restore sequence.
1244 TRXN_PROP is either A_SAVELIVEVARIABLES or A_RESTORELIVEVARIABLES.
1246 The code sequence is inserted in a new basic block created in
1247 END_BB which is inserted between BEFORE_BB and the destination of
1248 FALLTHRU_EDGE.
1250 STATUS is the return value from _ITM_beginTransaction.
1251 ENTRY_BLOCK is the entry block for the transaction.
1252 EMITF is a callback to emit the actual save/restore code.
1254 The basic block containing the conditional checking for TRXN_PROP
1255 is returned. */
1256 static basic_block
1257 tm_log_emit_save_or_restores (basic_block entry_block,
1258 unsigned trxn_prop,
1259 tree status,
1260 void (*emitf)(basic_block, basic_block),
1261 basic_block before_bb,
1262 edge fallthru_edge,
1263 basic_block *end_bb)
1265 basic_block cond_bb, code_bb;
1266 gimple cond_stmt, stmt;
1267 gimple_stmt_iterator gsi;
1268 tree t1, t2;
1269 int old_flags = fallthru_edge->flags;
1271 cond_bb = create_empty_bb (before_bb);
1272 code_bb = create_empty_bb (cond_bb);
1273 *end_bb = create_empty_bb (code_bb);
1274 if (current_loops && before_bb->loop_father)
1276 add_bb_to_loop (cond_bb, before_bb->loop_father);
1277 add_bb_to_loop (code_bb, before_bb->loop_father);
1278 add_bb_to_loop (*end_bb, before_bb->loop_father);
1280 redirect_edge_pred (fallthru_edge, *end_bb);
1281 fallthru_edge->flags = EDGE_FALLTHRU;
1282 make_edge (before_bb, cond_bb, old_flags);
1284 set_immediate_dominator (CDI_DOMINATORS, cond_bb, before_bb);
1285 set_immediate_dominator (CDI_DOMINATORS, code_bb, cond_bb);
1287 gsi = gsi_last_bb (cond_bb);
1289 /* t1 = status & A_{property}. */
1290 t1 = make_rename_temp (TREE_TYPE (status), NULL);
1291 t2 = build_int_cst (TREE_TYPE (status), trxn_prop);
1292 stmt = gimple_build_assign_with_ops (BIT_AND_EXPR, t1, status, t2);
1293 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
1295 /* if (t1). */
1296 t2 = build_int_cst (TREE_TYPE (status), 0);
1297 cond_stmt = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
1298 gsi_insert_after (&gsi, cond_stmt, GSI_CONTINUE_LINKING);
1300 emitf (entry_block, code_bb);
1302 make_edge (cond_bb, code_bb, EDGE_TRUE_VALUE);
1303 make_edge (cond_bb, *end_bb, EDGE_FALSE_VALUE);
1304 make_edge (code_bb, *end_bb, EDGE_FALLTHRU);
1306 return cond_bb;
1309 static tree lower_sequence_tm (gimple_stmt_iterator *, bool *,
1310 struct walk_stmt_info *);
1311 static tree lower_sequence_no_tm (gimple_stmt_iterator *, bool *,
1312 struct walk_stmt_info *);
1314 /* Evaluate an address X being dereferenced and determine if it
1315 originally points to a non aliased new chunk of memory (malloc,
1316 alloca, etc).
1318 Return MEM_THREAD_LOCAL if it points to a thread-local address.
1319 Return MEM_TRANSACTION_LOCAL if it points to a transaction-local address.
1320 Return MEM_NON_LOCAL otherwise.
1322 ENTRY_BLOCK is the entry block to the transaction containing the
1323 dereference of X. */
1324 static enum thread_memory_type
1325 thread_private_new_memory (basic_block entry_block, tree x)
1327 gimple stmt = NULL;
1328 enum tree_code code;
1329 void **slot;
1330 tm_new_mem_map_t elt, *elt_p;
1331 tree val = x;
1332 enum thread_memory_type retval = mem_transaction_local;
1334 if (!entry_block
1335 || TREE_CODE (x) != SSA_NAME
1336 /* Possible uninitialized use, or a function argument. In
1337 either case, we don't care. */
1338 || SSA_NAME_IS_DEFAULT_DEF (x))
1339 return mem_non_local;
1341 /* Look in cache first. */
1342 elt.val = x;
1343 slot = htab_find_slot (tm_new_mem_hash, &elt, INSERT);
1344 elt_p = (tm_new_mem_map_t *) *slot;
1345 if (elt_p)
1346 return elt_p->local_new_memory;
1348 /* Optimistically assume the memory is transaction local during
1349 processing. This catches recursion into this variable. */
1350 *slot = elt_p = XNEW (tm_new_mem_map_t);
1351 elt_p->val = val;
1352 elt_p->local_new_memory = mem_transaction_local;
1354 /* Search DEF chain to find the original definition of this address. */
1357 if (ptr_deref_may_alias_global_p (x))
1359 /* Address escapes. This is not thread-private. */
1360 retval = mem_non_local;
1361 goto new_memory_ret;
1364 stmt = SSA_NAME_DEF_STMT (x);
1366 /* If the malloc call is outside the transaction, this is
1367 thread-local. */
1368 if (retval != mem_thread_local
1369 && !dominated_by_p (CDI_DOMINATORS, gimple_bb (stmt), entry_block))
1370 retval = mem_thread_local;
1372 if (is_gimple_assign (stmt))
1374 code = gimple_assign_rhs_code (stmt);
1375 /* x = foo ==> foo */
1376 if (code == SSA_NAME)
1377 x = gimple_assign_rhs1 (stmt);
1378 /* x = foo + n ==> foo */
1379 else if (code == POINTER_PLUS_EXPR)
1380 x = gimple_assign_rhs1 (stmt);
1381 /* x = (cast*) foo ==> foo */
1382 else if (code == VIEW_CONVERT_EXPR || code == NOP_EXPR)
1383 x = gimple_assign_rhs1 (stmt);
1384 else
1386 retval = mem_non_local;
1387 goto new_memory_ret;
1390 else
1392 if (gimple_code (stmt) == GIMPLE_PHI)
1394 unsigned int i;
1395 enum thread_memory_type mem;
1396 tree phi_result = gimple_phi_result (stmt);
1398 /* If any of the ancestors are non-local, we are sure to
1399 be non-local. Otherwise we can avoid doing anything
1400 and inherit what has already been generated. */
1401 retval = mem_max;
1402 for (i = 0; i < gimple_phi_num_args (stmt); ++i)
1404 tree op = PHI_ARG_DEF (stmt, i);
1406 /* Exclude self-assignment. */
1407 if (phi_result == op)
1408 continue;
1410 mem = thread_private_new_memory (entry_block, op);
1411 if (mem == mem_non_local)
1413 retval = mem;
1414 goto new_memory_ret;
1416 retval = MIN (retval, mem);
1418 goto new_memory_ret;
1420 break;
1423 while (TREE_CODE (x) == SSA_NAME);
1425 if (stmt && is_gimple_call (stmt) && gimple_call_flags (stmt) & ECF_MALLOC)
1426 /* Thread-local or transaction-local. */
1428 else
1429 retval = mem_non_local;
1431 new_memory_ret:
1432 elt_p->local_new_memory = retval;
1433 return retval;
1436 /* Determine whether X has to be instrumented using a read
1437 or write barrier.
1439 ENTRY_BLOCK is the entry block for the region where stmt resides
1440 in. NULL if unknown.
1442 STMT is the statement in which X occurs in. It is used for thread
1443 private memory instrumentation. If no TPM instrumentation is
1444 desired, STMT should be null. */
1445 static bool
1446 requires_barrier (basic_block entry_block, tree x, gimple stmt)
1448 tree orig = x;
1449 while (handled_component_p (x))
1450 x = TREE_OPERAND (x, 0);
1452 switch (TREE_CODE (x))
1454 case INDIRECT_REF:
1455 case MEM_REF:
1457 enum thread_memory_type ret;
1459 ret = thread_private_new_memory (entry_block, TREE_OPERAND (x, 0));
1460 if (ret == mem_non_local)
1461 return true;
1462 if (stmt && ret == mem_thread_local)
1463 /* ?? Should we pass `orig', or the INDIRECT_REF X. ?? */
1464 tm_log_add (entry_block, orig, stmt);
1466 /* Transaction-locals require nothing at all. For malloc, a
1467 transaction restart frees the memory and we reallocate.
1468 For alloca, the stack pointer gets reset by the retry and
1469 we reallocate. */
1470 return false;
1473 case TARGET_MEM_REF:
1474 if (TREE_CODE (TMR_BASE (x)) != ADDR_EXPR)
1475 return true;
1476 x = TREE_OPERAND (TMR_BASE (x), 0);
1477 if (TREE_CODE (x) == PARM_DECL)
1478 return false;
1479 gcc_assert (TREE_CODE (x) == VAR_DECL);
1480 /* FALLTHRU */
1482 case PARM_DECL:
1483 case RESULT_DECL:
1484 case VAR_DECL:
1485 if (DECL_BY_REFERENCE (x))
1487 /* ??? This value is a pointer, but aggregate_value_p has been
1488 jigged to return true which confuses needs_to_live_in_memory.
1489 This ought to be cleaned up generically.
1491 FIXME: Verify this still happens after the next mainline
1492 merge. Testcase ie g++.dg/tm/pr47554.C.
1494 return false;
1497 if (is_global_var (x))
1498 return !TREE_READONLY (x);
1499 if (/* FIXME: This condition should actually go below in the
1500 tm_log_add() call, however is_call_clobbered() depends on
1501 aliasing info which is not available during
1502 gimplification. Since requires_barrier() gets called
1503 during lower_sequence_tm/gimplification, leave the call
1504 to needs_to_live_in_memory until we eliminate
1505 lower_sequence_tm altogether. */
1506 needs_to_live_in_memory (x))
1507 return true;
1508 else
1510 /* For local memory that doesn't escape (aka thread private
1511 memory), we can either save the value at the beginning of
1512 the transaction and restore on restart, or call a tm
1513 function to dynamically save and restore on restart
1514 (ITM_L*). */
1515 if (stmt)
1516 tm_log_add (entry_block, orig, stmt);
1517 return false;
1520 default:
1521 return false;
1525 /* Mark the GIMPLE_ASSIGN statement as appropriate for being inside
1526 a transaction region. */
1528 static void
1529 examine_assign_tm (unsigned *state, gimple_stmt_iterator *gsi)
1531 gimple stmt = gsi_stmt (*gsi);
1533 if (requires_barrier (/*entry_block=*/NULL, gimple_assign_rhs1 (stmt), NULL))
1534 *state |= GTMA_HAVE_LOAD;
1535 if (requires_barrier (/*entry_block=*/NULL, gimple_assign_lhs (stmt), NULL))
1536 *state |= GTMA_HAVE_STORE;
1539 /* Mark a GIMPLE_CALL as appropriate for being inside a transaction. */
1541 static void
1542 examine_call_tm (unsigned *state, gimple_stmt_iterator *gsi)
1544 gimple stmt = gsi_stmt (*gsi);
1545 tree fn;
1547 if (is_tm_pure_call (stmt))
1548 return;
1550 /* Check if this call is a transaction abort. */
1551 fn = gimple_call_fndecl (stmt);
1552 if (is_tm_abort (fn))
1553 *state |= GTMA_HAVE_ABORT;
1555 /* Note that something may happen. */
1556 *state |= GTMA_HAVE_LOAD | GTMA_HAVE_STORE;
1559 /* Lower a GIMPLE_TRANSACTION statement. */
1561 static void
1562 lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi)
1564 gimple g, stmt = gsi_stmt (*gsi);
1565 unsigned int *outer_state = (unsigned int *) wi->info;
1566 unsigned int this_state = 0;
1567 struct walk_stmt_info this_wi;
1569 /* First, lower the body. The scanning that we do inside gives
1570 us some idea of what we're dealing with. */
1571 memset (&this_wi, 0, sizeof (this_wi));
1572 this_wi.info = (void *) &this_state;
1573 walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
1574 lower_sequence_tm, NULL, &this_wi);
1576 /* If there was absolutely nothing transaction related inside the
1577 transaction, we may elide it. Likewise if this is a nested
1578 transaction and does not contain an abort. */
1579 if (this_state == 0
1580 || (!(this_state & GTMA_HAVE_ABORT) && outer_state != NULL))
1582 if (outer_state)
1583 *outer_state |= this_state;
1585 gsi_insert_seq_before (gsi, gimple_transaction_body (stmt),
1586 GSI_SAME_STMT);
1587 gimple_transaction_set_body (stmt, NULL);
1589 gsi_remove (gsi, true);
1590 wi->removed_stmt = true;
1591 return;
1594 /* Wrap the body of the transaction in a try-finally node so that
1595 the commit call is always properly called. */
1596 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT), 0);
1597 if (flag_exceptions)
1599 tree ptr;
1600 gimple_seq n_seq, e_seq;
1602 n_seq = gimple_seq_alloc_with_stmt (g);
1603 e_seq = NULL;
1605 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_EH_POINTER),
1606 1, integer_zero_node);
1607 ptr = create_tmp_var (ptr_type_node, NULL);
1608 gimple_call_set_lhs (g, ptr);
1609 gimple_seq_add_stmt (&e_seq, g);
1611 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT_EH),
1612 1, ptr);
1613 gimple_seq_add_stmt (&e_seq, g);
1615 g = gimple_build_eh_else (n_seq, e_seq);
1618 g = gimple_build_try (gimple_transaction_body (stmt),
1619 gimple_seq_alloc_with_stmt (g), GIMPLE_TRY_FINALLY);
1620 gsi_insert_after (gsi, g, GSI_CONTINUE_LINKING);
1622 gimple_transaction_set_body (stmt, NULL);
1624 /* If the transaction calls abort or if this is an outer transaction,
1625 add an "over" label afterwards. */
1626 if ((this_state & (GTMA_HAVE_ABORT))
1627 || (gimple_transaction_subcode(stmt) & GTMA_IS_OUTER))
1629 tree label = create_artificial_label (UNKNOWN_LOCATION);
1630 gimple_transaction_set_label (stmt, label);
1631 gsi_insert_after (gsi, gimple_build_label (label), GSI_CONTINUE_LINKING);
1634 /* Record the set of operations found for use later. */
1635 this_state |= gimple_transaction_subcode (stmt) & GTMA_DECLARATION_MASK;
1636 gimple_transaction_set_subcode (stmt, this_state);
1639 /* Iterate through the statements in the sequence, lowering them all
1640 as appropriate for being in a transaction. */
1642 static tree
1643 lower_sequence_tm (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1644 struct walk_stmt_info *wi)
1646 unsigned int *state = (unsigned int *) wi->info;
1647 gimple stmt = gsi_stmt (*gsi);
1649 *handled_ops_p = true;
1650 switch (gimple_code (stmt))
1652 case GIMPLE_ASSIGN:
1653 /* Only memory reads/writes need to be instrumented. */
1654 if (gimple_assign_single_p (stmt))
1655 examine_assign_tm (state, gsi);
1656 break;
1658 case GIMPLE_CALL:
1659 examine_call_tm (state, gsi);
1660 break;
1662 case GIMPLE_ASM:
1663 *state |= GTMA_MAY_ENTER_IRREVOCABLE;
1664 break;
1666 case GIMPLE_TRANSACTION:
1667 lower_transaction (gsi, wi);
1668 break;
1670 default:
1671 *handled_ops_p = !gimple_has_substatements (stmt);
1672 break;
1675 return NULL_TREE;
1678 /* Iterate through the statements in the sequence, lowering them all
1679 as appropriate for being outside of a transaction. */
1681 static tree
1682 lower_sequence_no_tm (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1683 struct walk_stmt_info * wi)
1685 gimple stmt = gsi_stmt (*gsi);
1687 if (gimple_code (stmt) == GIMPLE_TRANSACTION)
1689 *handled_ops_p = true;
1690 lower_transaction (gsi, wi);
1692 else
1693 *handled_ops_p = !gimple_has_substatements (stmt);
1695 return NULL_TREE;
1698 /* Main entry point for flattening GIMPLE_TRANSACTION constructs. After
1699 this, GIMPLE_TRANSACTION nodes still exist, but the nested body has
1700 been moved out, and all the data required for constructing a proper
1701 CFG has been recorded. */
1703 static unsigned int
1704 execute_lower_tm (void)
1706 struct walk_stmt_info wi;
1707 gimple_seq body;
1709 /* Transactional clones aren't created until a later pass. */
1710 gcc_assert (!decl_is_tm_clone (current_function_decl));
1712 body = gimple_body (current_function_decl);
1713 memset (&wi, 0, sizeof (wi));
1714 walk_gimple_seq_mod (&body, lower_sequence_no_tm, NULL, &wi);
1715 gimple_set_body (current_function_decl, body);
1717 return 0;
1720 struct gimple_opt_pass pass_lower_tm =
1723 GIMPLE_PASS,
1724 "tmlower", /* name */
1725 gate_tm, /* gate */
1726 execute_lower_tm, /* execute */
1727 NULL, /* sub */
1728 NULL, /* next */
1729 0, /* static_pass_number */
1730 TV_TRANS_MEM, /* tv_id */
1731 PROP_gimple_lcf, /* properties_required */
1732 0, /* properties_provided */
1733 0, /* properties_destroyed */
1734 0, /* todo_flags_start */
1735 0, /* todo_flags_finish */
1739 /* Collect region information for each transaction. */
1741 struct tm_region
1743 /* Link to the next unnested transaction. */
1744 struct tm_region *next;
1746 /* Link to the next inner transaction. */
1747 struct tm_region *inner;
1749 /* Link to the next outer transaction. */
1750 struct tm_region *outer;
1752 /* The GIMPLE_TRANSACTION statement beginning this transaction. */
1753 gimple transaction_stmt;
1755 /* The entry block to this region. */
1756 basic_block entry_block;
1758 /* The set of all blocks that end the region; NULL if only EXIT_BLOCK.
1759 These blocks are still a part of the region (i.e., the border is
1760 inclusive). Note that this set is only complete for paths in the CFG
1761 starting at ENTRY_BLOCK, and that there is no exit block recorded for
1762 the edge to the "over" label. */
1763 bitmap exit_blocks;
1765 /* The set of all blocks that have an TM_IRREVOCABLE call. */
1766 bitmap irr_blocks;
1769 typedef struct tm_region *tm_region_p;
1770 DEF_VEC_P (tm_region_p);
1771 DEF_VEC_ALLOC_P (tm_region_p, heap);
1773 /* True if there are pending edge statements to be committed for the
1774 current function being scanned in the tmmark pass. */
1775 bool pending_edge_inserts_p;
1777 static struct tm_region *all_tm_regions;
1778 static bitmap_obstack tm_obstack;
1781 /* A subroutine of tm_region_init. Record the existance of the
1782 GIMPLE_TRANSACTION statement in a tree of tm_region elements. */
1784 static struct tm_region *
1785 tm_region_init_0 (struct tm_region *outer, basic_block bb, gimple stmt)
1787 struct tm_region *region;
1789 region = (struct tm_region *)
1790 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
1792 if (outer)
1794 region->next = outer->inner;
1795 outer->inner = region;
1797 else
1799 region->next = all_tm_regions;
1800 all_tm_regions = region;
1802 region->inner = NULL;
1803 region->outer = outer;
1805 region->transaction_stmt = stmt;
1807 /* There are either one or two edges out of the block containing
1808 the GIMPLE_TRANSACTION, one to the actual region and one to the
1809 "over" label if the region contains an abort. The former will
1810 always be the one marked FALLTHRU. */
1811 region->entry_block = FALLTHRU_EDGE (bb)->dest;
1813 region->exit_blocks = BITMAP_ALLOC (&tm_obstack);
1814 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
1816 return region;
1819 /* A subroutine of tm_region_init. Record all the exit and
1820 irrevocable blocks in BB into the region's exit_blocks and
1821 irr_blocks bitmaps. Returns the new region being scanned. */
1823 static struct tm_region *
1824 tm_region_init_1 (struct tm_region *region, basic_block bb)
1826 gimple_stmt_iterator gsi;
1827 gimple g;
1829 if (!region
1830 || (!region->irr_blocks && !region->exit_blocks))
1831 return region;
1833 /* Check to see if this is the end of a region by seeing if it
1834 contains a call to __builtin_tm_commit{,_eh}. Note that the
1835 outermost region for DECL_IS_TM_CLONE need not collect this. */
1836 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
1838 g = gsi_stmt (gsi);
1839 if (gimple_code (g) == GIMPLE_CALL)
1841 tree fn = gimple_call_fndecl (g);
1842 if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
1844 if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT
1845 || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH)
1846 && region->exit_blocks)
1848 bitmap_set_bit (region->exit_blocks, bb->index);
1849 region = region->outer;
1850 break;
1852 if (DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_IRREVOCABLE)
1853 bitmap_set_bit (region->irr_blocks, bb->index);
1857 return region;
1860 /* Collect all of the transaction regions within the current function
1861 and record them in ALL_TM_REGIONS. The REGION parameter may specify
1862 an "outermost" region for use by tm clones. */
1864 static void
1865 tm_region_init (struct tm_region *region)
1867 gimple g;
1868 edge_iterator ei;
1869 edge e;
1870 basic_block bb;
1871 VEC(basic_block, heap) *queue = NULL;
1872 bitmap visited_blocks = BITMAP_ALLOC (NULL);
1873 struct tm_region *old_region;
1874 VEC(tm_region_p, heap) *bb_regions = NULL;
1876 all_tm_regions = region;
1877 bb = single_succ (ENTRY_BLOCK_PTR);
1879 /* We could store this information in bb->aux, but we may get called
1880 through get_all_tm_blocks() from another pass that may be already
1881 using bb->aux. */
1882 VEC_safe_grow_cleared (tm_region_p, heap, bb_regions, last_basic_block);
1884 VEC_safe_push (basic_block, heap, queue, bb);
1885 VEC_replace (tm_region_p, bb_regions, bb->index, region);
1888 bb = VEC_pop (basic_block, queue);
1889 region = VEC_index (tm_region_p, bb_regions, bb->index);
1890 VEC_replace (tm_region_p, bb_regions, bb->index, NULL);
1892 /* Record exit and irrevocable blocks. */
1893 region = tm_region_init_1 (region, bb);
1895 /* Check for the last statement in the block beginning a new region. */
1896 g = last_stmt (bb);
1897 old_region = region;
1898 if (g && gimple_code (g) == GIMPLE_TRANSACTION)
1899 region = tm_region_init_0 (region, bb, g);
1901 /* Process subsequent blocks. */
1902 FOR_EACH_EDGE (e, ei, bb->succs)
1903 if (!bitmap_bit_p (visited_blocks, e->dest->index))
1905 bitmap_set_bit (visited_blocks, e->dest->index);
1906 VEC_safe_push (basic_block, heap, queue, e->dest);
1908 /* If the current block started a new region, make sure that only
1909 the entry block of the new region is associated with this region.
1910 Other successors are still part of the old region. */
1911 if (old_region != region && e->dest != region->entry_block)
1912 VEC_replace (tm_region_p, bb_regions, e->dest->index, old_region);
1913 else
1914 VEC_replace (tm_region_p, bb_regions, e->dest->index, region);
1917 while (!VEC_empty (basic_block, queue));
1918 VEC_free (basic_block, heap, queue);
1919 BITMAP_FREE (visited_blocks);
1920 VEC_free (tm_region_p, heap, bb_regions);
1923 /* The "gate" function for all transactional memory expansion and optimization
1924 passes. We collect region information for each top-level transaction, and
1925 if we don't find any, we skip all of the TM passes. Each region will have
1926 all of the exit blocks recorded, and the originating statement. */
1928 static bool
1929 gate_tm_init (void)
1931 if (!flag_tm)
1932 return false;
1934 calculate_dominance_info (CDI_DOMINATORS);
1935 bitmap_obstack_initialize (&tm_obstack);
1937 /* If the function is a TM_CLONE, then the entire function is the region. */
1938 if (decl_is_tm_clone (current_function_decl))
1940 struct tm_region *region = (struct tm_region *)
1941 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
1942 memset (region, 0, sizeof (*region));
1943 region->entry_block = single_succ (ENTRY_BLOCK_PTR);
1944 /* For a clone, the entire function is the region. But even if
1945 we don't need to record any exit blocks, we may need to
1946 record irrevocable blocks. */
1947 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
1949 tm_region_init (region);
1951 else
1953 tm_region_init (NULL);
1955 /* If we didn't find any regions, cleanup and skip the whole tree
1956 of tm-related optimizations. */
1957 if (all_tm_regions == NULL)
1959 bitmap_obstack_release (&tm_obstack);
1960 return false;
1964 return true;
1967 struct gimple_opt_pass pass_tm_init =
1970 GIMPLE_PASS,
1971 "*tminit", /* name */
1972 gate_tm_init, /* gate */
1973 NULL, /* execute */
1974 NULL, /* sub */
1975 NULL, /* next */
1976 0, /* static_pass_number */
1977 TV_TRANS_MEM, /* tv_id */
1978 PROP_ssa | PROP_cfg, /* properties_required */
1979 0, /* properties_provided */
1980 0, /* properties_destroyed */
1981 0, /* todo_flags_start */
1982 0, /* todo_flags_finish */
1986 /* Add FLAGS to the GIMPLE_TRANSACTION subcode for the transaction region
1987 represented by STATE. */
1989 static inline void
1990 transaction_subcode_ior (struct tm_region *region, unsigned flags)
1992 if (region && region->transaction_stmt)
1994 flags |= gimple_transaction_subcode (region->transaction_stmt);
1995 gimple_transaction_set_subcode (region->transaction_stmt, flags);
1999 /* Construct a memory load in a transactional context. Return the
2000 gimple statement performing the load, or NULL if there is no
2001 TM_LOAD builtin of the appropriate size to do the load.
2003 LOC is the location to use for the new statement(s). */
2005 static gimple
2006 build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2008 enum built_in_function code = END_BUILTINS;
2009 tree t, type = TREE_TYPE (rhs), decl;
2010 gimple gcall;
2012 if (type == float_type_node)
2013 code = BUILT_IN_TM_LOAD_FLOAT;
2014 else if (type == double_type_node)
2015 code = BUILT_IN_TM_LOAD_DOUBLE;
2016 else if (type == long_double_type_node)
2017 code = BUILT_IN_TM_LOAD_LDOUBLE;
2018 else if (TYPE_SIZE_UNIT (type) != NULL
2019 && host_integerp (TYPE_SIZE_UNIT (type), 1))
2021 switch (tree_low_cst (TYPE_SIZE_UNIT (type), 1))
2023 case 1:
2024 code = BUILT_IN_TM_LOAD_1;
2025 break;
2026 case 2:
2027 code = BUILT_IN_TM_LOAD_2;
2028 break;
2029 case 4:
2030 code = BUILT_IN_TM_LOAD_4;
2031 break;
2032 case 8:
2033 code = BUILT_IN_TM_LOAD_8;
2034 break;
2038 if (code == END_BUILTINS)
2040 decl = targetm.vectorize.builtin_tm_load (type);
2041 if (!decl)
2042 return NULL;
2044 else
2045 decl = builtin_decl_explicit (code);
2047 t = gimplify_addr (gsi, rhs);
2048 gcall = gimple_build_call (decl, 1, t);
2049 gimple_set_location (gcall, loc);
2051 t = TREE_TYPE (TREE_TYPE (decl));
2052 if (useless_type_conversion_p (type, t))
2054 gimple_call_set_lhs (gcall, lhs);
2055 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2057 else
2059 gimple g;
2060 tree temp;
2062 temp = make_rename_temp (t, NULL);
2063 gimple_call_set_lhs (gcall, temp);
2064 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2066 t = fold_build1 (VIEW_CONVERT_EXPR, type, temp);
2067 g = gimple_build_assign (lhs, t);
2068 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2071 return gcall;
2075 /* Similarly for storing TYPE in a transactional context. */
2077 static gimple
2078 build_tm_store (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2080 enum built_in_function code = END_BUILTINS;
2081 tree t, fn, type = TREE_TYPE (rhs), simple_type;
2082 gimple gcall;
2084 if (type == float_type_node)
2085 code = BUILT_IN_TM_STORE_FLOAT;
2086 else if (type == double_type_node)
2087 code = BUILT_IN_TM_STORE_DOUBLE;
2088 else if (type == long_double_type_node)
2089 code = BUILT_IN_TM_STORE_LDOUBLE;
2090 else if (TYPE_SIZE_UNIT (type) != NULL
2091 && host_integerp (TYPE_SIZE_UNIT (type), 1))
2093 switch (tree_low_cst (TYPE_SIZE_UNIT (type), 1))
2095 case 1:
2096 code = BUILT_IN_TM_STORE_1;
2097 break;
2098 case 2:
2099 code = BUILT_IN_TM_STORE_2;
2100 break;
2101 case 4:
2102 code = BUILT_IN_TM_STORE_4;
2103 break;
2104 case 8:
2105 code = BUILT_IN_TM_STORE_8;
2106 break;
2110 if (code == END_BUILTINS)
2112 fn = targetm.vectorize.builtin_tm_store (type);
2113 if (!fn)
2114 return NULL;
2116 else
2117 fn = builtin_decl_explicit (code);
2119 simple_type = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))));
2121 if (TREE_CODE (rhs) == CONSTRUCTOR)
2123 /* Handle the easy initialization to zero. */
2124 if (CONSTRUCTOR_ELTS (rhs) == 0)
2125 rhs = build_int_cst (simple_type, 0);
2126 else
2128 /* ...otherwise punt to the caller and probably use
2129 BUILT_IN_TM_MEMMOVE, because we can't wrap a
2130 VIEW_CONVERT_EXPR around a CONSTRUCTOR (below) and produce
2131 valid gimple. */
2132 return NULL;
2135 else if (!useless_type_conversion_p (simple_type, type))
2137 gimple g;
2138 tree temp;
2140 temp = make_rename_temp (simple_type, NULL);
2141 t = fold_build1 (VIEW_CONVERT_EXPR, simple_type, rhs);
2142 g = gimple_build_assign (temp, t);
2143 gimple_set_location (g, loc);
2144 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2146 rhs = temp;
2149 t = gimplify_addr (gsi, lhs);
2150 gcall = gimple_build_call (fn, 2, t, rhs);
2151 gimple_set_location (gcall, loc);
2152 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2154 return gcall;
2158 /* Expand an assignment statement into transactional builtins. */
2160 static void
2161 expand_assign_tm (struct tm_region *region, gimple_stmt_iterator *gsi)
2163 gimple stmt = gsi_stmt (*gsi);
2164 location_t loc = gimple_location (stmt);
2165 tree lhs = gimple_assign_lhs (stmt);
2166 tree rhs = gimple_assign_rhs1 (stmt);
2167 bool store_p = requires_barrier (region->entry_block, lhs, NULL);
2168 bool load_p = requires_barrier (region->entry_block, rhs, NULL);
2169 gimple gcall = NULL;
2171 if (!load_p && !store_p)
2173 /* Add thread private addresses to log if applicable. */
2174 requires_barrier (region->entry_block, lhs, stmt);
2175 gsi_next (gsi);
2176 return;
2179 gsi_remove (gsi, true);
2181 if (load_p && !store_p)
2183 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2184 gcall = build_tm_load (loc, lhs, rhs, gsi);
2186 else if (store_p && !load_p)
2188 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2189 gcall = build_tm_store (loc, lhs, rhs, gsi);
2191 if (!gcall)
2193 tree lhs_addr, rhs_addr, tmp;
2195 if (load_p)
2196 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2197 if (store_p)
2198 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2200 /* ??? Figure out if there's any possible overlap between the LHS
2201 and the RHS and if not, use MEMCPY. */
2203 if (load_p && is_gimple_reg (lhs))
2205 tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
2206 lhs_addr = build_fold_addr_expr (tmp);
2208 else
2210 tmp = NULL_TREE;
2211 lhs_addr = gimplify_addr (gsi, lhs);
2213 rhs_addr = gimplify_addr (gsi, rhs);
2214 gcall = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_MEMMOVE),
2215 3, lhs_addr, rhs_addr,
2216 TYPE_SIZE_UNIT (TREE_TYPE (lhs)));
2217 gimple_set_location (gcall, loc);
2218 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2220 if (tmp)
2222 gcall = gimple_build_assign (lhs, tmp);
2223 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2227 /* Now that we have the load/store in its instrumented form, add
2228 thread private addresses to the log if applicable. */
2229 if (!store_p)
2230 requires_barrier (region->entry_block, lhs, gcall);
2232 /* add_stmt_to_tm_region (region, gcall); */
2236 /* Expand a call statement as appropriate for a transaction. That is,
2237 either verify that the call does not affect the transaction, or
2238 redirect the call to a clone that handles transactions, or change
2239 the transaction state to IRREVOCABLE. Return true if the call is
2240 one of the builtins that end a transaction. */
2242 static bool
2243 expand_call_tm (struct tm_region *region,
2244 gimple_stmt_iterator *gsi)
2246 gimple stmt = gsi_stmt (*gsi);
2247 tree lhs = gimple_call_lhs (stmt);
2248 tree fn_decl;
2249 struct cgraph_node *node;
2250 bool retval = false;
2252 fn_decl = gimple_call_fndecl (stmt);
2254 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMCPY)
2255 || fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMMOVE))
2256 transaction_subcode_ior (region, GTMA_HAVE_STORE | GTMA_HAVE_LOAD);
2257 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMSET))
2258 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2260 if (is_tm_pure_call (stmt))
2261 return false;
2263 if (fn_decl)
2264 retval = is_tm_ending_fndecl (fn_decl);
2265 if (!retval)
2267 /* Assume all non-const/pure calls write to memory, except
2268 transaction ending builtins. */
2269 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2272 /* For indirect calls, we already generated a call into the runtime. */
2273 if (!fn_decl)
2275 tree fn = gimple_call_fn (stmt);
2277 /* We are guaranteed never to go irrevocable on a safe or pure
2278 call, and the pure call was handled above. */
2279 if (is_tm_safe (fn))
2280 return false;
2281 else
2282 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2284 return false;
2287 node = cgraph_get_node (fn_decl);
2288 /* All calls should have cgraph here. */
2289 gcc_assert (node);
2290 if (node->local.tm_may_enter_irr)
2291 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2293 if (is_tm_abort (fn_decl))
2295 transaction_subcode_ior (region, GTMA_HAVE_ABORT);
2296 return true;
2299 /* Instrument the store if needed.
2301 If the assignment happens inside the function call (return slot
2302 optimization), there is no instrumentation to be done, since
2303 the callee should have done the right thing. */
2304 if (lhs && requires_barrier (region->entry_block, lhs, stmt)
2305 && !gimple_call_return_slot_opt_p (stmt))
2307 tree tmp = make_rename_temp (TREE_TYPE (lhs), NULL);
2308 location_t loc = gimple_location (stmt);
2309 edge fallthru_edge = NULL;
2311 /* Remember if the call was going to throw. */
2312 if (stmt_can_throw_internal (stmt))
2314 edge_iterator ei;
2315 edge e;
2316 basic_block bb = gimple_bb (stmt);
2318 FOR_EACH_EDGE (e, ei, bb->succs)
2319 if (e->flags & EDGE_FALLTHRU)
2321 fallthru_edge = e;
2322 break;
2326 gimple_call_set_lhs (stmt, tmp);
2327 update_stmt (stmt);
2328 stmt = gimple_build_assign (lhs, tmp);
2329 gimple_set_location (stmt, loc);
2331 /* We cannot throw in the middle of a BB. If the call was going
2332 to throw, place the instrumentation on the fallthru edge, so
2333 the call remains the last statement in the block. */
2334 if (fallthru_edge)
2336 gimple_seq fallthru_seq = gimple_seq_alloc_with_stmt (stmt);
2337 gimple_stmt_iterator fallthru_gsi = gsi_start (fallthru_seq);
2338 expand_assign_tm (region, &fallthru_gsi);
2339 gsi_insert_seq_on_edge (fallthru_edge, fallthru_seq);
2340 pending_edge_inserts_p = true;
2342 else
2344 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
2345 expand_assign_tm (region, gsi);
2348 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2351 return retval;
2355 /* Expand all statements in BB as appropriate for being inside
2356 a transaction. */
2358 static void
2359 expand_block_tm (struct tm_region *region, basic_block bb)
2361 gimple_stmt_iterator gsi;
2363 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2365 gimple stmt = gsi_stmt (gsi);
2366 switch (gimple_code (stmt))
2368 case GIMPLE_ASSIGN:
2369 /* Only memory reads/writes need to be instrumented. */
2370 if (gimple_assign_single_p (stmt)
2371 && !gimple_clobber_p (stmt))
2373 expand_assign_tm (region, &gsi);
2374 continue;
2376 break;
2378 case GIMPLE_CALL:
2379 if (expand_call_tm (region, &gsi))
2380 return;
2381 break;
2383 case GIMPLE_ASM:
2384 gcc_unreachable ();
2386 default:
2387 break;
2389 if (!gsi_end_p (gsi))
2390 gsi_next (&gsi);
2394 /* Return the list of basic-blocks in REGION.
2396 STOP_AT_IRREVOCABLE_P is true if caller is uninterested in blocks
2397 following a TM_IRREVOCABLE call. */
2399 static VEC (basic_block, heap) *
2400 get_tm_region_blocks (basic_block entry_block,
2401 bitmap exit_blocks,
2402 bitmap irr_blocks,
2403 bitmap all_region_blocks,
2404 bool stop_at_irrevocable_p)
2406 VEC(basic_block, heap) *bbs = NULL;
2407 unsigned i;
2408 edge e;
2409 edge_iterator ei;
2410 bitmap visited_blocks = BITMAP_ALLOC (NULL);
2412 i = 0;
2413 VEC_safe_push (basic_block, heap, bbs, entry_block);
2414 bitmap_set_bit (visited_blocks, entry_block->index);
2418 basic_block bb = VEC_index (basic_block, bbs, i++);
2420 if (exit_blocks &&
2421 bitmap_bit_p (exit_blocks, bb->index))
2422 continue;
2424 if (stop_at_irrevocable_p
2425 && irr_blocks
2426 && bitmap_bit_p (irr_blocks, bb->index))
2427 continue;
2429 FOR_EACH_EDGE (e, ei, bb->succs)
2430 if (!bitmap_bit_p (visited_blocks, e->dest->index))
2432 bitmap_set_bit (visited_blocks, e->dest->index);
2433 VEC_safe_push (basic_block, heap, bbs, e->dest);
2436 while (i < VEC_length (basic_block, bbs));
2438 if (all_region_blocks)
2439 bitmap_ior_into (all_region_blocks, visited_blocks);
2441 BITMAP_FREE (visited_blocks);
2442 return bbs;
2445 /* Set the IN_TRANSACTION for all gimple statements that appear in a
2446 transaction. */
2448 void
2449 compute_transaction_bits (void)
2451 struct tm_region *region;
2452 VEC (basic_block, heap) *queue;
2453 unsigned int i;
2454 gimple_stmt_iterator gsi;
2455 basic_block bb;
2457 /* ?? Perhaps we need to abstract gate_tm_init further, because we
2458 certainly don't need it to calculate CDI_DOMINATOR info. */
2459 gate_tm_init ();
2461 for (region = all_tm_regions; region; region = region->next)
2463 queue = get_tm_region_blocks (region->entry_block,
2464 region->exit_blocks,
2465 region->irr_blocks,
2466 NULL,
2467 /*stop_at_irr_p=*/true);
2468 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2469 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2471 gimple stmt = gsi_stmt (gsi);
2472 gimple_set_in_transaction (stmt, true);
2474 VEC_free (basic_block, heap, queue);
2477 if (all_tm_regions)
2478 bitmap_obstack_release (&tm_obstack);
2481 /* Entry point to the MARK phase of TM expansion. Here we replace
2482 transactional memory statements with calls to builtins, and function
2483 calls with their transactional clones (if available). But we don't
2484 yet lower GIMPLE_TRANSACTION or add the transaction restart back-edges. */
2486 static unsigned int
2487 execute_tm_mark (void)
2489 struct tm_region *region;
2490 basic_block bb;
2491 VEC (basic_block, heap) *queue;
2492 size_t i;
2494 queue = VEC_alloc (basic_block, heap, 10);
2495 pending_edge_inserts_p = false;
2497 for (region = all_tm_regions; region ; region = region->next)
2499 tm_log_init ();
2500 /* If we have a transaction... */
2501 if (region->exit_blocks)
2503 unsigned int subcode
2504 = gimple_transaction_subcode (region->transaction_stmt);
2506 /* Collect a new SUBCODE set, now that optimizations are done... */
2507 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2508 subcode &= (GTMA_DECLARATION_MASK | GTMA_DOES_GO_IRREVOCABLE
2509 | GTMA_MAY_ENTER_IRREVOCABLE);
2510 else
2511 subcode &= GTMA_DECLARATION_MASK;
2512 gimple_transaction_set_subcode (region->transaction_stmt, subcode);
2515 queue = get_tm_region_blocks (region->entry_block,
2516 region->exit_blocks,
2517 region->irr_blocks,
2518 NULL,
2519 /*stop_at_irr_p=*/true);
2520 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2521 expand_block_tm (region, bb);
2522 VEC_free (basic_block, heap, queue);
2524 tm_log_emit ();
2527 if (pending_edge_inserts_p)
2528 gsi_commit_edge_inserts ();
2529 return 0;
2532 struct gimple_opt_pass pass_tm_mark =
2535 GIMPLE_PASS,
2536 "tmmark", /* name */
2537 NULL, /* gate */
2538 execute_tm_mark, /* execute */
2539 NULL, /* sub */
2540 NULL, /* next */
2541 0, /* static_pass_number */
2542 TV_TRANS_MEM, /* tv_id */
2543 PROP_ssa | PROP_cfg, /* properties_required */
2544 0, /* properties_provided */
2545 0, /* properties_destroyed */
2546 0, /* todo_flags_start */
2547 TODO_update_ssa
2548 | TODO_verify_ssa, /* todo_flags_finish */
2552 /* Create an abnormal call edge from BB to the first block of the region
2553 represented by STATE. Also record the edge in the TM_RESTART map. */
2555 static inline void
2556 make_tm_edge (gimple stmt, basic_block bb, struct tm_region *region)
2558 void **slot;
2559 struct tm_restart_node *n, dummy;
2561 if (cfun->gimple_df->tm_restart == NULL)
2562 cfun->gimple_df->tm_restart = htab_create_ggc (31, struct_ptr_hash,
2563 struct_ptr_eq, ggc_free);
2565 dummy.stmt = stmt;
2566 dummy.label_or_list = gimple_block_label (region->entry_block);
2567 slot = htab_find_slot (cfun->gimple_df->tm_restart, &dummy, INSERT);
2568 n = (struct tm_restart_node *) *slot;
2569 if (n == NULL)
2571 n = ggc_alloc_tm_restart_node ();
2572 *n = dummy;
2574 else
2576 tree old = n->label_or_list;
2577 if (TREE_CODE (old) == LABEL_DECL)
2578 old = tree_cons (NULL, old, NULL);
2579 n->label_or_list = tree_cons (NULL, dummy.label_or_list, old);
2582 make_edge (bb, region->entry_block, EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
2586 /* Split block BB as necessary for every builtin function we added, and
2587 wire up the abnormal back edges implied by the transaction restart. */
2589 static void
2590 expand_block_edges (struct tm_region *region, basic_block bb)
2592 gimple_stmt_iterator gsi;
2594 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2596 gimple stmt = gsi_stmt (gsi);
2598 /* ??? TM_COMMIT (and any other tm builtin function) in a nested
2599 transaction has an abnormal edge back to the outer-most transaction
2600 (there are no nested retries), while a TM_ABORT also has an abnormal
2601 backedge to the inner-most transaction. We haven't actually saved
2602 the inner-most transaction here. We should be able to get to it
2603 via the region_nr saved on STMT, and read the transaction_stmt from
2604 that, and find the first region block from there. */
2605 /* ??? Shouldn't we split for any non-pure, non-irrevocable function? */
2606 if (gimple_code (stmt) == GIMPLE_CALL
2607 && (gimple_call_flags (stmt) & ECF_TM_BUILTIN) != 0)
2609 if (gsi_one_before_end_p (gsi))
2610 make_tm_edge (stmt, bb, region);
2611 else
2613 edge e = split_block (bb, stmt);
2614 make_tm_edge (stmt, bb, region);
2615 bb = e->dest;
2616 gsi = gsi_start_bb (bb);
2619 /* Delete any tail-call annotation that may have been added.
2620 The tail-call pass may have mis-identified the commit as being
2621 a candidate because we had not yet added this restart edge. */
2622 gimple_call_set_tail (stmt, false);
2625 gsi_next (&gsi);
2629 /* Expand the GIMPLE_TRANSACTION statement into the STM library call. */
2631 static void
2632 expand_transaction (struct tm_region *region)
2634 tree status, tm_start;
2635 basic_block atomic_bb, slice_bb;
2636 gimple_stmt_iterator gsi;
2637 tree t1, t2;
2638 gimple g;
2639 int flags, subcode;
2641 tm_start = builtin_decl_explicit (BUILT_IN_TM_START);
2642 status = make_rename_temp (TREE_TYPE (TREE_TYPE (tm_start)), "tm_state");
2644 /* ??? There are plenty of bits here we're not computing. */
2645 subcode = gimple_transaction_subcode (region->transaction_stmt);
2646 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2647 flags = PR_DOESGOIRREVOCABLE | PR_UNINSTRUMENTEDCODE;
2648 else
2649 flags = PR_INSTRUMENTEDCODE;
2650 if ((subcode & GTMA_MAY_ENTER_IRREVOCABLE) == 0)
2651 flags |= PR_HASNOIRREVOCABLE;
2652 /* If the transaction does not have an abort in lexical scope and is not
2653 marked as an outer transaction, then it will never abort. */
2654 if ((subcode & GTMA_HAVE_ABORT) == 0
2655 && (subcode & GTMA_IS_OUTER) == 0)
2656 flags |= PR_HASNOABORT;
2657 if ((subcode & GTMA_HAVE_STORE) == 0)
2658 flags |= PR_READONLY;
2659 t2 = build_int_cst (TREE_TYPE (status), flags);
2660 g = gimple_build_call (tm_start, 1, t2);
2661 gimple_call_set_lhs (g, status);
2662 gimple_set_location (g, gimple_location (region->transaction_stmt));
2664 atomic_bb = gimple_bb (region->transaction_stmt);
2666 if (!VEC_empty (tree, tm_log_save_addresses))
2667 tm_log_emit_saves (region->entry_block, atomic_bb);
2669 gsi = gsi_last_bb (atomic_bb);
2670 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2671 gsi_remove (&gsi, true);
2673 if (!VEC_empty (tree, tm_log_save_addresses))
2674 region->entry_block =
2675 tm_log_emit_save_or_restores (region->entry_block,
2676 A_RESTORELIVEVARIABLES,
2677 status,
2678 tm_log_emit_restores,
2679 atomic_bb,
2680 FALLTHRU_EDGE (atomic_bb),
2681 &slice_bb);
2682 else
2683 slice_bb = atomic_bb;
2685 /* If we have an ABORT statement, create a test following the start
2686 call to perform the abort. */
2687 if (gimple_transaction_label (region->transaction_stmt))
2689 edge e;
2690 basic_block test_bb;
2692 test_bb = create_empty_bb (slice_bb);
2693 if (current_loops && slice_bb->loop_father)
2694 add_bb_to_loop (test_bb, slice_bb->loop_father);
2695 if (VEC_empty (tree, tm_log_save_addresses))
2696 region->entry_block = test_bb;
2697 gsi = gsi_last_bb (test_bb);
2699 t1 = make_rename_temp (TREE_TYPE (status), NULL);
2700 t2 = build_int_cst (TREE_TYPE (status), A_ABORTTRANSACTION);
2701 g = gimple_build_assign_with_ops (BIT_AND_EXPR, t1, status, t2);
2702 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
2704 t2 = build_int_cst (TREE_TYPE (status), 0);
2705 g = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
2706 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
2708 e = FALLTHRU_EDGE (slice_bb);
2709 redirect_edge_pred (e, test_bb);
2710 e->flags = EDGE_FALSE_VALUE;
2711 e->probability = PROB_ALWAYS - PROB_VERY_UNLIKELY;
2713 e = BRANCH_EDGE (atomic_bb);
2714 redirect_edge_pred (e, test_bb);
2715 e->flags = EDGE_TRUE_VALUE;
2716 e->probability = PROB_VERY_UNLIKELY;
2718 e = make_edge (slice_bb, test_bb, EDGE_FALLTHRU);
2721 /* If we've no abort, but we do have PHIs at the beginning of the atomic
2722 region, that means we've a loop at the beginning of the atomic region
2723 that shares the first block. This can cause problems with the abnormal
2724 edges we're about to add for the transaction restart. Solve this by
2725 adding a new empty block to receive the abnormal edges. */
2726 else if (phi_nodes (region->entry_block))
2728 edge e;
2729 basic_block empty_bb;
2731 region->entry_block = empty_bb = create_empty_bb (atomic_bb);
2732 if (current_loops && atomic_bb->loop_father)
2733 add_bb_to_loop (empty_bb, atomic_bb->loop_father);
2735 e = FALLTHRU_EDGE (atomic_bb);
2736 redirect_edge_pred (e, empty_bb);
2738 e = make_edge (atomic_bb, empty_bb, EDGE_FALLTHRU);
2741 /* The GIMPLE_TRANSACTION statement no longer exists. */
2742 region->transaction_stmt = NULL;
2745 static void expand_regions (struct tm_region *);
2747 /* Helper function for expand_regions. Expand REGION and recurse to
2748 the inner region. */
2750 static void
2751 expand_regions_1 (struct tm_region *region)
2753 if (region->exit_blocks)
2755 unsigned int i;
2756 basic_block bb;
2757 VEC (basic_block, heap) *queue;
2759 /* Collect the set of blocks in this region. Do this before
2760 splitting edges, so that we don't have to play with the
2761 dominator tree in the middle. */
2762 queue = get_tm_region_blocks (region->entry_block,
2763 region->exit_blocks,
2764 region->irr_blocks,
2765 NULL,
2766 /*stop_at_irr_p=*/false);
2767 expand_transaction (region);
2768 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2769 expand_block_edges (region, bb);
2770 VEC_free (basic_block, heap, queue);
2772 if (region->inner)
2773 expand_regions (region->inner);
2776 /* Expand regions starting at REGION. */
2778 static void
2779 expand_regions (struct tm_region *region)
2781 while (region)
2783 expand_regions_1 (region);
2784 region = region->next;
2788 /* Entry point to the final expansion of transactional nodes. */
2790 static unsigned int
2791 execute_tm_edges (void)
2793 expand_regions (all_tm_regions);
2794 tm_log_delete ();
2796 /* We've got to release the dominance info now, to indicate that it
2797 must be rebuilt completely. Otherwise we'll crash trying to update
2798 the SSA web in the TODO section following this pass. */
2799 free_dominance_info (CDI_DOMINATORS);
2800 bitmap_obstack_release (&tm_obstack);
2801 all_tm_regions = NULL;
2803 return 0;
2806 struct gimple_opt_pass pass_tm_edges =
2809 GIMPLE_PASS,
2810 "tmedge", /* name */
2811 NULL, /* gate */
2812 execute_tm_edges, /* execute */
2813 NULL, /* sub */
2814 NULL, /* next */
2815 0, /* static_pass_number */
2816 TV_TRANS_MEM, /* tv_id */
2817 PROP_ssa | PROP_cfg, /* properties_required */
2818 0, /* properties_provided */
2819 0, /* properties_destroyed */
2820 0, /* todo_flags_start */
2821 TODO_update_ssa
2822 | TODO_verify_ssa, /* todo_flags_finish */
2826 /* A unique TM memory operation. */
2827 typedef struct tm_memop
2829 /* Unique ID that all memory operations to the same location have. */
2830 unsigned int value_id;
2831 /* Address of load/store. */
2832 tree addr;
2833 } *tm_memop_t;
2835 /* Sets for solving data flow equations in the memory optimization pass. */
2836 struct tm_memopt_bitmaps
2838 /* Stores available to this BB upon entry. Basically, stores that
2839 dominate this BB. */
2840 bitmap store_avail_in;
2841 /* Stores available at the end of this BB. */
2842 bitmap store_avail_out;
2843 bitmap store_antic_in;
2844 bitmap store_antic_out;
2845 /* Reads available to this BB upon entry. Basically, reads that
2846 dominate this BB. */
2847 bitmap read_avail_in;
2848 /* Reads available at the end of this BB. */
2849 bitmap read_avail_out;
2850 /* Reads performed in this BB. */
2851 bitmap read_local;
2852 /* Writes performed in this BB. */
2853 bitmap store_local;
2855 /* Temporary storage for pass. */
2856 /* Is the current BB in the worklist? */
2857 bool avail_in_worklist_p;
2858 /* Have we visited this BB? */
2859 bool visited_p;
2862 static bitmap_obstack tm_memopt_obstack;
2864 /* Unique counter for TM loads and stores. Loads and stores of the
2865 same address get the same ID. */
2866 static unsigned int tm_memopt_value_id;
2867 static htab_t tm_memopt_value_numbers;
2869 #define STORE_AVAIL_IN(BB) \
2870 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in
2871 #define STORE_AVAIL_OUT(BB) \
2872 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_out
2873 #define STORE_ANTIC_IN(BB) \
2874 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_in
2875 #define STORE_ANTIC_OUT(BB) \
2876 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_out
2877 #define READ_AVAIL_IN(BB) \
2878 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_in
2879 #define READ_AVAIL_OUT(BB) \
2880 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_out
2881 #define READ_LOCAL(BB) \
2882 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_local
2883 #define STORE_LOCAL(BB) \
2884 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_local
2885 #define AVAIL_IN_WORKLIST_P(BB) \
2886 ((struct tm_memopt_bitmaps *) ((BB)->aux))->avail_in_worklist_p
2887 #define BB_VISITED_P(BB) \
2888 ((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p
2890 /* Htab support. Return a hash value for a `tm_memop'. */
2891 static hashval_t
2892 tm_memop_hash (const void *p)
2894 const struct tm_memop *mem = (const struct tm_memop *) p;
2895 tree addr = mem->addr;
2896 /* We drill down to the SSA_NAME/DECL for the hash, but equality is
2897 actually done with operand_equal_p (see tm_memop_eq). */
2898 if (TREE_CODE (addr) == ADDR_EXPR)
2899 addr = TREE_OPERAND (addr, 0);
2900 return iterative_hash_expr (addr, 0);
2903 /* Htab support. Return true if two tm_memop's are the same. */
2904 static int
2905 tm_memop_eq (const void *p1, const void *p2)
2907 const struct tm_memop *mem1 = (const struct tm_memop *) p1;
2908 const struct tm_memop *mem2 = (const struct tm_memop *) p2;
2910 return operand_equal_p (mem1->addr, mem2->addr, 0);
2913 /* Given a TM load/store in STMT, return the value number for the address
2914 it accesses. */
2916 static unsigned int
2917 tm_memopt_value_number (gimple stmt, enum insert_option op)
2919 struct tm_memop tmpmem, *mem;
2920 void **slot;
2922 gcc_assert (is_tm_load (stmt) || is_tm_store (stmt));
2923 tmpmem.addr = gimple_call_arg (stmt, 0);
2924 slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op);
2925 if (*slot)
2926 mem = (struct tm_memop *) *slot;
2927 else if (op == INSERT)
2929 mem = XNEW (struct tm_memop);
2930 *slot = mem;
2931 mem->value_id = tm_memopt_value_id++;
2932 mem->addr = tmpmem.addr;
2934 else
2935 gcc_unreachable ();
2936 return mem->value_id;
2939 /* Accumulate TM memory operations in BB into STORE_LOCAL and READ_LOCAL. */
2941 static void
2942 tm_memopt_accumulate_memops (basic_block bb)
2944 gimple_stmt_iterator gsi;
2946 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2948 gimple stmt = gsi_stmt (gsi);
2949 bitmap bits;
2950 unsigned int loc;
2952 if (is_tm_store (stmt))
2953 bits = STORE_LOCAL (bb);
2954 else if (is_tm_load (stmt))
2955 bits = READ_LOCAL (bb);
2956 else
2957 continue;
2959 loc = tm_memopt_value_number (stmt, INSERT);
2960 bitmap_set_bit (bits, loc);
2961 if (dump_file)
2963 fprintf (dump_file, "TM memopt (%s): value num=%d, BB=%d, addr=",
2964 is_tm_load (stmt) ? "LOAD" : "STORE", loc,
2965 gimple_bb (stmt)->index);
2966 print_generic_expr (dump_file, gimple_call_arg (stmt, 0), 0);
2967 fprintf (dump_file, "\n");
2972 /* Prettily dump one of the memopt sets. BITS is the bitmap to dump. */
2974 static void
2975 dump_tm_memopt_set (const char *set_name, bitmap bits)
2977 unsigned i;
2978 bitmap_iterator bi;
2979 const char *comma = "";
2981 fprintf (dump_file, "TM memopt: %s: [", set_name);
2982 EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
2984 htab_iterator hi;
2985 struct tm_memop *mem;
2987 /* Yeah, yeah, yeah. Whatever. This is just for debugging. */
2988 FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
2989 if (mem->value_id == i)
2990 break;
2991 gcc_assert (mem->value_id == i);
2992 fprintf (dump_file, "%s", comma);
2993 comma = ", ";
2994 print_generic_expr (dump_file, mem->addr, 0);
2996 fprintf (dump_file, "]\n");
2999 /* Prettily dump all of the memopt sets in BLOCKS. */
3001 static void
3002 dump_tm_memopt_sets (VEC (basic_block, heap) *blocks)
3004 size_t i;
3005 basic_block bb;
3007 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3009 fprintf (dump_file, "------------BB %d---------\n", bb->index);
3010 dump_tm_memopt_set ("STORE_LOCAL", STORE_LOCAL (bb));
3011 dump_tm_memopt_set ("READ_LOCAL", READ_LOCAL (bb));
3012 dump_tm_memopt_set ("STORE_AVAIL_IN", STORE_AVAIL_IN (bb));
3013 dump_tm_memopt_set ("STORE_AVAIL_OUT", STORE_AVAIL_OUT (bb));
3014 dump_tm_memopt_set ("READ_AVAIL_IN", READ_AVAIL_IN (bb));
3015 dump_tm_memopt_set ("READ_AVAIL_OUT", READ_AVAIL_OUT (bb));
3019 /* Compute {STORE,READ}_AVAIL_IN for the basic block BB. */
3021 static void
3022 tm_memopt_compute_avin (basic_block bb)
3024 edge e;
3025 unsigned ix;
3027 /* Seed with the AVOUT of any predecessor. */
3028 for (ix = 0; ix < EDGE_COUNT (bb->preds); ix++)
3030 e = EDGE_PRED (bb, ix);
3031 /* Make sure we have already visited this BB, and is thus
3032 initialized.
3034 If e->src->aux is NULL, this predecessor is actually on an
3035 enclosing transaction. We only care about the current
3036 transaction, so ignore it. */
3037 if (e->src->aux && BB_VISITED_P (e->src))
3039 bitmap_copy (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3040 bitmap_copy (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3041 break;
3045 for (; ix < EDGE_COUNT (bb->preds); ix++)
3047 e = EDGE_PRED (bb, ix);
3048 if (e->src->aux && BB_VISITED_P (e->src))
3050 bitmap_and_into (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3051 bitmap_and_into (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3055 BB_VISITED_P (bb) = true;
3058 /* Compute the STORE_ANTIC_IN for the basic block BB. */
3060 static void
3061 tm_memopt_compute_antin (basic_block bb)
3063 edge e;
3064 unsigned ix;
3066 /* Seed with the ANTIC_OUT of any successor. */
3067 for (ix = 0; ix < EDGE_COUNT (bb->succs); ix++)
3069 e = EDGE_SUCC (bb, ix);
3070 /* Make sure we have already visited this BB, and is thus
3071 initialized. */
3072 if (BB_VISITED_P (e->dest))
3074 bitmap_copy (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3075 break;
3079 for (; ix < EDGE_COUNT (bb->succs); ix++)
3081 e = EDGE_SUCC (bb, ix);
3082 if (BB_VISITED_P (e->dest))
3083 bitmap_and_into (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3086 BB_VISITED_P (bb) = true;
3089 /* Compute the AVAIL sets for every basic block in BLOCKS.
3091 We compute {STORE,READ}_AVAIL_{OUT,IN} as follows:
3093 AVAIL_OUT[bb] = union (AVAIL_IN[bb], LOCAL[bb])
3094 AVAIL_IN[bb] = intersect (AVAIL_OUT[predecessors])
3096 This is basically what we do in lcm's compute_available(), but here
3097 we calculate two sets of sets (one for STOREs and one for READs),
3098 and we work on a region instead of the entire CFG.
3100 REGION is the TM region.
3101 BLOCKS are the basic blocks in the region. */
3103 static void
3104 tm_memopt_compute_available (struct tm_region *region,
3105 VEC (basic_block, heap) *blocks)
3107 edge e;
3108 basic_block *worklist, *qin, *qout, *qend, bb;
3109 unsigned int qlen, i;
3110 edge_iterator ei;
3111 bool changed;
3113 /* Allocate a worklist array/queue. Entries are only added to the
3114 list if they were not already on the list. So the size is
3115 bounded by the number of basic blocks in the region. */
3116 qlen = VEC_length (basic_block, blocks) - 1;
3117 qin = qout = worklist =
3118 XNEWVEC (basic_block, qlen);
3120 /* Put every block in the region on the worklist. */
3121 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3123 /* Seed AVAIL_OUT with the LOCAL set. */
3124 bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_LOCAL (bb));
3125 bitmap_ior_into (READ_AVAIL_OUT (bb), READ_LOCAL (bb));
3127 AVAIL_IN_WORKLIST_P (bb) = true;
3128 /* No need to insert the entry block, since it has an AVIN of
3129 null, and an AVOUT that has already been seeded in. */
3130 if (bb != region->entry_block)
3131 *qin++ = bb;
3134 /* The entry block has been initialized with the local sets. */
3135 BB_VISITED_P (region->entry_block) = true;
3137 qin = worklist;
3138 qend = &worklist[qlen];
3140 /* Iterate until the worklist is empty. */
3141 while (qlen)
3143 /* Take the first entry off the worklist. */
3144 bb = *qout++;
3145 qlen--;
3147 if (qout >= qend)
3148 qout = worklist;
3150 /* This block can be added to the worklist again if necessary. */
3151 AVAIL_IN_WORKLIST_P (bb) = false;
3152 tm_memopt_compute_avin (bb);
3154 /* Note: We do not add the LOCAL sets here because we already
3155 seeded the AVAIL_OUT sets with them. */
3156 changed = bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_AVAIL_IN (bb));
3157 changed |= bitmap_ior_into (READ_AVAIL_OUT (bb), READ_AVAIL_IN (bb));
3158 if (changed
3159 && (region->exit_blocks == NULL
3160 || !bitmap_bit_p (region->exit_blocks, bb->index)))
3161 /* If the out state of this block changed, then we need to add
3162 its successors to the worklist if they are not already in. */
3163 FOR_EACH_EDGE (e, ei, bb->succs)
3164 if (!AVAIL_IN_WORKLIST_P (e->dest) && e->dest != EXIT_BLOCK_PTR)
3166 *qin++ = e->dest;
3167 AVAIL_IN_WORKLIST_P (e->dest) = true;
3168 qlen++;
3170 if (qin >= qend)
3171 qin = worklist;
3175 free (worklist);
3177 if (dump_file)
3178 dump_tm_memopt_sets (blocks);
3181 /* Compute ANTIC sets for every basic block in BLOCKS.
3183 We compute STORE_ANTIC_OUT as follows:
3185 STORE_ANTIC_OUT[bb] = union(STORE_ANTIC_IN[bb], STORE_LOCAL[bb])
3186 STORE_ANTIC_IN[bb] = intersect(STORE_ANTIC_OUT[successors])
3188 REGION is the TM region.
3189 BLOCKS are the basic blocks in the region. */
3191 static void
3192 tm_memopt_compute_antic (struct tm_region *region,
3193 VEC (basic_block, heap) *blocks)
3195 edge e;
3196 basic_block *worklist, *qin, *qout, *qend, bb;
3197 unsigned int qlen;
3198 int i;
3199 edge_iterator ei;
3201 /* Allocate a worklist array/queue. Entries are only added to the
3202 list if they were not already on the list. So the size is
3203 bounded by the number of basic blocks in the region. */
3204 qin = qout = worklist =
3205 XNEWVEC (basic_block, VEC_length (basic_block, blocks));
3207 for (qlen = 0, i = VEC_length (basic_block, blocks) - 1; i >= 0; --i)
3209 bb = VEC_index (basic_block, blocks, i);
3211 /* Seed ANTIC_OUT with the LOCAL set. */
3212 bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_LOCAL (bb));
3214 /* Put every block in the region on the worklist. */
3215 AVAIL_IN_WORKLIST_P (bb) = true;
3216 /* No need to insert exit blocks, since their ANTIC_IN is NULL,
3217 and their ANTIC_OUT has already been seeded in. */
3218 if (region->exit_blocks
3219 && !bitmap_bit_p (region->exit_blocks, bb->index))
3221 qlen++;
3222 *qin++ = bb;
3226 /* The exit blocks have been initialized with the local sets. */
3227 if (region->exit_blocks)
3229 unsigned int i;
3230 bitmap_iterator bi;
3231 EXECUTE_IF_SET_IN_BITMAP (region->exit_blocks, 0, i, bi)
3232 BB_VISITED_P (BASIC_BLOCK (i)) = true;
3235 qin = worklist;
3236 qend = &worklist[qlen];
3238 /* Iterate until the worklist is empty. */
3239 while (qlen)
3241 /* Take the first entry off the worklist. */
3242 bb = *qout++;
3243 qlen--;
3245 if (qout >= qend)
3246 qout = worklist;
3248 /* This block can be added to the worklist again if necessary. */
3249 AVAIL_IN_WORKLIST_P (bb) = false;
3250 tm_memopt_compute_antin (bb);
3252 /* Note: We do not add the LOCAL sets here because we already
3253 seeded the ANTIC_OUT sets with them. */
3254 if (bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_ANTIC_IN (bb))
3255 && bb != region->entry_block)
3256 /* If the out state of this block changed, then we need to add
3257 its predecessors to the worklist if they are not already in. */
3258 FOR_EACH_EDGE (e, ei, bb->preds)
3259 if (!AVAIL_IN_WORKLIST_P (e->src))
3261 *qin++ = e->src;
3262 AVAIL_IN_WORKLIST_P (e->src) = true;
3263 qlen++;
3265 if (qin >= qend)
3266 qin = worklist;
3270 free (worklist);
3272 if (dump_file)
3273 dump_tm_memopt_sets (blocks);
3276 /* Offsets of load variants from TM_LOAD. For example,
3277 BUILT_IN_TM_LOAD_RAR* is an offset of 1 from BUILT_IN_TM_LOAD*.
3278 See gtm-builtins.def. */
3279 #define TRANSFORM_RAR 1
3280 #define TRANSFORM_RAW 2
3281 #define TRANSFORM_RFW 3
3282 /* Offsets of store variants from TM_STORE. */
3283 #define TRANSFORM_WAR 1
3284 #define TRANSFORM_WAW 2
3286 /* Inform about a load/store optimization. */
3288 static void
3289 dump_tm_memopt_transform (gimple stmt)
3291 if (dump_file)
3293 fprintf (dump_file, "TM memopt: transforming: ");
3294 print_gimple_stmt (dump_file, stmt, 0, 0);
3295 fprintf (dump_file, "\n");
3299 /* Perform a read/write optimization. Replaces the TM builtin in STMT
3300 by a builtin that is OFFSET entries down in the builtins table in
3301 gtm-builtins.def. */
3303 static void
3304 tm_memopt_transform_stmt (unsigned int offset,
3305 gimple stmt,
3306 gimple_stmt_iterator *gsi)
3308 tree fn = gimple_call_fn (stmt);
3309 gcc_assert (TREE_CODE (fn) == ADDR_EXPR);
3310 TREE_OPERAND (fn, 0)
3311 = builtin_decl_explicit ((enum built_in_function)
3312 (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0))
3313 + offset));
3314 gimple_call_set_fn (stmt, fn);
3315 gsi_replace (gsi, stmt, true);
3316 dump_tm_memopt_transform (stmt);
3319 /* Perform the actual TM memory optimization transformations in the
3320 basic blocks in BLOCKS. */
3322 static void
3323 tm_memopt_transform_blocks (VEC (basic_block, heap) *blocks)
3325 size_t i;
3326 basic_block bb;
3327 gimple_stmt_iterator gsi;
3329 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3331 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3333 gimple stmt = gsi_stmt (gsi);
3334 bitmap read_avail = READ_AVAIL_IN (bb);
3335 bitmap store_avail = STORE_AVAIL_IN (bb);
3336 bitmap store_antic = STORE_ANTIC_OUT (bb);
3337 unsigned int loc;
3339 if (is_tm_simple_load (stmt))
3341 loc = tm_memopt_value_number (stmt, NO_INSERT);
3342 if (store_avail && bitmap_bit_p (store_avail, loc))
3343 tm_memopt_transform_stmt (TRANSFORM_RAW, stmt, &gsi);
3344 else if (store_antic && bitmap_bit_p (store_antic, loc))
3346 tm_memopt_transform_stmt (TRANSFORM_RFW, stmt, &gsi);
3347 bitmap_set_bit (store_avail, loc);
3349 else if (read_avail && bitmap_bit_p (read_avail, loc))
3350 tm_memopt_transform_stmt (TRANSFORM_RAR, stmt, &gsi);
3351 else
3352 bitmap_set_bit (read_avail, loc);
3354 else if (is_tm_simple_store (stmt))
3356 loc = tm_memopt_value_number (stmt, NO_INSERT);
3357 if (store_avail && bitmap_bit_p (store_avail, loc))
3358 tm_memopt_transform_stmt (TRANSFORM_WAW, stmt, &gsi);
3359 else
3361 if (read_avail && bitmap_bit_p (read_avail, loc))
3362 tm_memopt_transform_stmt (TRANSFORM_WAR, stmt, &gsi);
3363 bitmap_set_bit (store_avail, loc);
3370 /* Return a new set of bitmaps for a BB. */
3372 static struct tm_memopt_bitmaps *
3373 tm_memopt_init_sets (void)
3375 struct tm_memopt_bitmaps *b
3376 = XOBNEW (&tm_memopt_obstack.obstack, struct tm_memopt_bitmaps);
3377 b->store_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3378 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3379 b->store_antic_in = BITMAP_ALLOC (&tm_memopt_obstack);
3380 b->store_antic_out = BITMAP_ALLOC (&tm_memopt_obstack);
3381 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3382 b->read_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3383 b->read_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3384 b->read_local = BITMAP_ALLOC (&tm_memopt_obstack);
3385 b->store_local = BITMAP_ALLOC (&tm_memopt_obstack);
3386 return b;
3389 /* Free sets computed for each BB. */
3391 static void
3392 tm_memopt_free_sets (VEC (basic_block, heap) *blocks)
3394 size_t i;
3395 basic_block bb;
3397 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3398 bb->aux = NULL;
3401 /* Clear the visited bit for every basic block in BLOCKS. */
3403 static void
3404 tm_memopt_clear_visited (VEC (basic_block, heap) *blocks)
3406 size_t i;
3407 basic_block bb;
3409 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3410 BB_VISITED_P (bb) = false;
3413 /* Replace TM load/stores with hints for the runtime. We handle
3414 things like read-after-write, write-after-read, read-after-read,
3415 read-for-write, etc. */
3417 static unsigned int
3418 execute_tm_memopt (void)
3420 struct tm_region *region;
3421 VEC (basic_block, heap) *bbs;
3423 tm_memopt_value_id = 0;
3424 tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free);
3426 for (region = all_tm_regions; region; region = region->next)
3428 /* All the TM stores/loads in the current region. */
3429 size_t i;
3430 basic_block bb;
3432 bitmap_obstack_initialize (&tm_memopt_obstack);
3434 /* Save all BBs for the current region. */
3435 bbs = get_tm_region_blocks (region->entry_block,
3436 region->exit_blocks,
3437 region->irr_blocks,
3438 NULL,
3439 false);
3441 /* Collect all the memory operations. */
3442 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i)
3444 bb->aux = tm_memopt_init_sets ();
3445 tm_memopt_accumulate_memops (bb);
3448 /* Solve data flow equations and transform each block accordingly. */
3449 tm_memopt_clear_visited (bbs);
3450 tm_memopt_compute_available (region, bbs);
3451 tm_memopt_clear_visited (bbs);
3452 tm_memopt_compute_antic (region, bbs);
3453 tm_memopt_transform_blocks (bbs);
3455 tm_memopt_free_sets (bbs);
3456 VEC_free (basic_block, heap, bbs);
3457 bitmap_obstack_release (&tm_memopt_obstack);
3458 htab_empty (tm_memopt_value_numbers);
3461 htab_delete (tm_memopt_value_numbers);
3462 return 0;
3465 static bool
3466 gate_tm_memopt (void)
3468 return flag_tm && optimize > 0;
3471 struct gimple_opt_pass pass_tm_memopt =
3474 GIMPLE_PASS,
3475 "tmmemopt", /* name */
3476 gate_tm_memopt, /* gate */
3477 execute_tm_memopt, /* execute */
3478 NULL, /* sub */
3479 NULL, /* next */
3480 0, /* static_pass_number */
3481 TV_TRANS_MEM, /* tv_id */
3482 PROP_ssa | PROP_cfg, /* properties_required */
3483 0, /* properties_provided */
3484 0, /* properties_destroyed */
3485 0, /* todo_flags_start */
3486 0, /* todo_flags_finish */
3491 /* Interprocedual analysis for the creation of transactional clones.
3492 The aim of this pass is to find which functions are referenced in
3493 a non-irrevocable transaction context, and for those over which
3494 we have control (or user directive), create a version of the
3495 function which uses only the transactional interface to reference
3496 protected memories. This analysis proceeds in several steps:
3498 (1) Collect the set of all possible transactional clones:
3500 (a) For all local public functions marked tm_callable, push
3501 it onto the tm_callee queue.
3503 (b) For all local functions, scan for calls in transaction blocks.
3504 Push the caller and callee onto the tm_caller and tm_callee
3505 queues. Count the number of callers for each callee.
3507 (c) For each local function on the callee list, assume we will
3508 create a transactional clone. Push *all* calls onto the
3509 callee queues; count the number of clone callers separately
3510 to the number of original callers.
3512 (2) Propagate irrevocable status up the dominator tree:
3514 (a) Any external function on the callee list that is not marked
3515 tm_callable is irrevocable. Push all callers of such onto
3516 a worklist.
3518 (b) For each function on the worklist, mark each block that
3519 contains an irrevocable call. Use the AND operator to
3520 propagate that mark up the dominator tree.
3522 (c) If we reach the entry block for a possible transactional
3523 clone, then the transactional clone is irrevocable, and
3524 we should not create the clone after all. Push all
3525 callers onto the worklist.
3527 (d) Place tm_irrevocable calls at the beginning of the relevant
3528 blocks. Special case here is the entry block for the entire
3529 transaction region; there we mark it GTMA_DOES_GO_IRREVOCABLE for
3530 the library to begin the region in serial mode. Decrement
3531 the call count for all callees in the irrevocable region.
3533 (3) Create the transactional clones:
3535 Any tm_callee that still has a non-zero call count is cloned.
3538 /* This structure is stored in the AUX field of each cgraph_node. */
3539 struct tm_ipa_cg_data
3541 /* The clone of the function that got created. */
3542 struct cgraph_node *clone;
3544 /* The tm regions in the normal function. */
3545 struct tm_region *all_tm_regions;
3547 /* The blocks of the normal/clone functions that contain irrevocable
3548 calls, or blocks that are post-dominated by irrevocable calls. */
3549 bitmap irrevocable_blocks_normal;
3550 bitmap irrevocable_blocks_clone;
3552 /* The blocks of the normal function that are involved in transactions. */
3553 bitmap transaction_blocks_normal;
3555 /* The number of callers to the transactional clone of this function
3556 from normal and transactional clones respectively. */
3557 unsigned tm_callers_normal;
3558 unsigned tm_callers_clone;
3560 /* True if all calls to this function's transactional clone
3561 are irrevocable. Also automatically true if the function
3562 has no transactional clone. */
3563 bool is_irrevocable;
3565 /* Flags indicating the presence of this function in various queues. */
3566 bool in_callee_queue;
3567 bool in_worklist;
3569 /* Flags indicating the kind of scan desired while in the worklist. */
3570 bool want_irr_scan_normal;
3573 typedef struct cgraph_node *cgraph_node_p;
3575 DEF_VEC_P (cgraph_node_p);
3576 DEF_VEC_ALLOC_P (cgraph_node_p, heap);
3578 typedef VEC (cgraph_node_p, heap) *cgraph_node_queue;
3580 /* Return the ipa data associated with NODE, allocating zeroed memory
3581 if necessary. TRAVERSE_ALIASES is true if we must traverse aliases
3582 and set *NODE accordingly. */
3584 static struct tm_ipa_cg_data *
3585 get_cg_data (struct cgraph_node **node, bool traverse_aliases)
3587 struct tm_ipa_cg_data *d;
3589 if (traverse_aliases && (*node)->alias)
3590 *node = cgraph_get_node ((*node)->thunk.alias);
3592 d = (struct tm_ipa_cg_data *) (*node)->symbol.aux;
3594 if (d == NULL)
3596 d = (struct tm_ipa_cg_data *)
3597 obstack_alloc (&tm_obstack.obstack, sizeof (*d));
3598 (*node)->symbol.aux = (void *) d;
3599 memset (d, 0, sizeof (*d));
3602 return d;
3605 /* Add NODE to the end of QUEUE, unless IN_QUEUE_P indicates that
3606 it is already present. */
3608 static void
3609 maybe_push_queue (struct cgraph_node *node,
3610 cgraph_node_queue *queue_p, bool *in_queue_p)
3612 if (!*in_queue_p)
3614 *in_queue_p = true;
3615 VEC_safe_push (cgraph_node_p, heap, *queue_p, node);
3619 /* A subroutine of ipa_tm_scan_calls_transaction and ipa_tm_scan_calls_clone.
3620 Queue all callees within block BB. */
3622 static void
3623 ipa_tm_scan_calls_block (cgraph_node_queue *callees_p,
3624 basic_block bb, bool for_clone)
3626 gimple_stmt_iterator gsi;
3628 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3630 gimple stmt = gsi_stmt (gsi);
3631 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
3633 tree fndecl = gimple_call_fndecl (stmt);
3634 if (fndecl)
3636 struct tm_ipa_cg_data *d;
3637 unsigned *pcallers;
3638 struct cgraph_node *node;
3640 if (is_tm_ending_fndecl (fndecl))
3641 continue;
3642 if (find_tm_replacement_function (fndecl))
3643 continue;
3645 node = cgraph_get_node (fndecl);
3646 gcc_assert (node != NULL);
3647 d = get_cg_data (&node, true);
3649 pcallers = (for_clone ? &d->tm_callers_clone
3650 : &d->tm_callers_normal);
3651 *pcallers += 1;
3653 maybe_push_queue (node, callees_p, &d->in_callee_queue);
3659 /* Scan all calls in NODE that are within a transaction region,
3660 and push the resulting nodes into the callee queue. */
3662 static void
3663 ipa_tm_scan_calls_transaction (struct tm_ipa_cg_data *d,
3664 cgraph_node_queue *callees_p)
3666 struct tm_region *r;
3668 d->transaction_blocks_normal = BITMAP_ALLOC (&tm_obstack);
3669 d->all_tm_regions = all_tm_regions;
3671 for (r = all_tm_regions; r; r = r->next)
3673 VEC (basic_block, heap) *bbs;
3674 basic_block bb;
3675 unsigned i;
3677 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks, NULL,
3678 d->transaction_blocks_normal, false);
3680 FOR_EACH_VEC_ELT (basic_block, bbs, i, bb)
3681 ipa_tm_scan_calls_block (callees_p, bb, false);
3683 VEC_free (basic_block, heap, bbs);
3687 /* Scan all calls in NODE as if this is the transactional clone,
3688 and push the destinations into the callee queue. */
3690 static void
3691 ipa_tm_scan_calls_clone (struct cgraph_node *node,
3692 cgraph_node_queue *callees_p)
3694 struct function *fn = DECL_STRUCT_FUNCTION (node->symbol.decl);
3695 basic_block bb;
3697 FOR_EACH_BB_FN (bb, fn)
3698 ipa_tm_scan_calls_block (callees_p, bb, true);
3701 /* The function NODE has been detected to be irrevocable. Push all
3702 of its callers onto WORKLIST for the purpose of re-scanning them. */
3704 static void
3705 ipa_tm_note_irrevocable (struct cgraph_node *node,
3706 cgraph_node_queue *worklist_p)
3708 struct tm_ipa_cg_data *d = get_cg_data (&node, true);
3709 struct cgraph_edge *e;
3711 d->is_irrevocable = true;
3713 for (e = node->callers; e ; e = e->next_caller)
3715 basic_block bb;
3716 struct cgraph_node *caller;
3718 /* Don't examine recursive calls. */
3719 if (e->caller == node)
3720 continue;
3721 /* Even if we think we can go irrevocable, believe the user
3722 above all. */
3723 if (is_tm_safe_or_pure (e->caller->symbol.decl))
3724 continue;
3726 caller = e->caller;
3727 d = get_cg_data (&caller, true);
3729 /* Check if the callee is in a transactional region. If so,
3730 schedule the function for normal re-scan as well. */
3731 bb = gimple_bb (e->call_stmt);
3732 gcc_assert (bb != NULL);
3733 if (d->transaction_blocks_normal
3734 && bitmap_bit_p (d->transaction_blocks_normal, bb->index))
3735 d->want_irr_scan_normal = true;
3737 maybe_push_queue (caller, worklist_p, &d->in_worklist);
3741 /* A subroutine of ipa_tm_scan_irr_blocks; return true iff any statement
3742 within the block is irrevocable. */
3744 static bool
3745 ipa_tm_scan_irr_block (basic_block bb)
3747 gimple_stmt_iterator gsi;
3748 tree fn;
3750 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3752 gimple stmt = gsi_stmt (gsi);
3753 switch (gimple_code (stmt))
3755 case GIMPLE_CALL:
3756 if (is_tm_pure_call (stmt))
3757 break;
3759 fn = gimple_call_fn (stmt);
3761 /* Functions with the attribute are by definition irrevocable. */
3762 if (is_tm_irrevocable (fn))
3763 return true;
3765 /* For direct function calls, go ahead and check for replacement
3766 functions, or transitive irrevocable functions. For indirect
3767 functions, we'll ask the runtime. */
3768 if (TREE_CODE (fn) == ADDR_EXPR)
3770 struct tm_ipa_cg_data *d;
3771 struct cgraph_node *node;
3773 fn = TREE_OPERAND (fn, 0);
3774 if (is_tm_ending_fndecl (fn))
3775 break;
3776 if (find_tm_replacement_function (fn))
3777 break;
3779 node = cgraph_get_node(fn);
3780 d = get_cg_data (&node, true);
3782 /* Return true if irrevocable, but above all, believe
3783 the user. */
3784 if (d->is_irrevocable
3785 && !is_tm_safe_or_pure (fn))
3786 return true;
3788 break;
3790 case GIMPLE_ASM:
3791 /* ??? The Approved Method of indicating that an inline
3792 assembly statement is not relevant to the transaction
3793 is to wrap it in a __tm_waiver block. This is not
3794 yet implemented, so we can't check for it. */
3795 if (is_tm_safe (current_function_decl))
3797 tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
3798 SET_EXPR_LOCATION (t, gimple_location (stmt));
3799 TREE_BLOCK (t) = gimple_block (stmt);
3800 error ("%Kasm not allowed in %<transaction_safe%> function", t);
3802 return true;
3804 default:
3805 break;
3809 return false;
3812 /* For each of the blocks seeded witin PQUEUE, walk the CFG looking
3813 for new irrevocable blocks, marking them in NEW_IRR. Don't bother
3814 scanning past OLD_IRR or EXIT_BLOCKS. */
3816 static bool
3817 ipa_tm_scan_irr_blocks (VEC (basic_block, heap) **pqueue, bitmap new_irr,
3818 bitmap old_irr, bitmap exit_blocks)
3820 bool any_new_irr = false;
3821 edge e;
3822 edge_iterator ei;
3823 bitmap visited_blocks = BITMAP_ALLOC (NULL);
3827 basic_block bb = VEC_pop (basic_block, *pqueue);
3829 /* Don't re-scan blocks we know already are irrevocable. */
3830 if (old_irr && bitmap_bit_p (old_irr, bb->index))
3831 continue;
3833 if (ipa_tm_scan_irr_block (bb))
3835 bitmap_set_bit (new_irr, bb->index);
3836 any_new_irr = true;
3838 else if (exit_blocks == NULL || !bitmap_bit_p (exit_blocks, bb->index))
3840 FOR_EACH_EDGE (e, ei, bb->succs)
3841 if (!bitmap_bit_p (visited_blocks, e->dest->index))
3843 bitmap_set_bit (visited_blocks, e->dest->index);
3844 VEC_safe_push (basic_block, heap, *pqueue, e->dest);
3848 while (!VEC_empty (basic_block, *pqueue));
3850 BITMAP_FREE (visited_blocks);
3852 return any_new_irr;
3855 /* Propagate the irrevocable property both up and down the dominator tree.
3856 BB is the current block being scanned; EXIT_BLOCKS are the edges of the
3857 TM regions; OLD_IRR are the results of a previous scan of the dominator
3858 tree which has been fully propagated; NEW_IRR is the set of new blocks
3859 which are gaining the irrevocable property during the current scan. */
3861 static void
3862 ipa_tm_propagate_irr (basic_block entry_block, bitmap new_irr,
3863 bitmap old_irr, bitmap exit_blocks)
3865 VEC (basic_block, heap) *bbs;
3866 bitmap all_region_blocks;
3868 /* If this block is in the old set, no need to rescan. */
3869 if (old_irr && bitmap_bit_p (old_irr, entry_block->index))
3870 return;
3872 all_region_blocks = BITMAP_ALLOC (&tm_obstack);
3873 bbs = get_tm_region_blocks (entry_block, exit_blocks, NULL,
3874 all_region_blocks, false);
3877 basic_block bb = VEC_pop (basic_block, bbs);
3878 bool this_irr = bitmap_bit_p (new_irr, bb->index);
3879 bool all_son_irr = false;
3880 edge_iterator ei;
3881 edge e;
3883 /* Propagate up. If my children are, I am too, but we must have
3884 at least one child that is. */
3885 if (!this_irr)
3887 FOR_EACH_EDGE (e, ei, bb->succs)
3889 if (!bitmap_bit_p (new_irr, e->dest->index))
3891 all_son_irr = false;
3892 break;
3894 else
3895 all_son_irr = true;
3897 if (all_son_irr)
3899 /* Add block to new_irr if it hasn't already been processed. */
3900 if (!old_irr || !bitmap_bit_p (old_irr, bb->index))
3902 bitmap_set_bit (new_irr, bb->index);
3903 this_irr = true;
3908 /* Propagate down to everyone we immediately dominate. */
3909 if (this_irr)
3911 basic_block son;
3912 for (son = first_dom_son (CDI_DOMINATORS, bb);
3913 son;
3914 son = next_dom_son (CDI_DOMINATORS, son))
3916 /* Make sure block is actually in a TM region, and it
3917 isn't already in old_irr. */
3918 if ((!old_irr || !bitmap_bit_p (old_irr, son->index))
3919 && bitmap_bit_p (all_region_blocks, son->index))
3920 bitmap_set_bit (new_irr, son->index);
3924 while (!VEC_empty (basic_block, bbs));
3926 BITMAP_FREE (all_region_blocks);
3927 VEC_free (basic_block, heap, bbs);
3930 static void
3931 ipa_tm_decrement_clone_counts (basic_block bb, bool for_clone)
3933 gimple_stmt_iterator gsi;
3935 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3937 gimple stmt = gsi_stmt (gsi);
3938 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
3940 tree fndecl = gimple_call_fndecl (stmt);
3941 if (fndecl)
3943 struct tm_ipa_cg_data *d;
3944 unsigned *pcallers;
3945 struct cgraph_node *tnode;
3947 if (is_tm_ending_fndecl (fndecl))
3948 continue;
3949 if (find_tm_replacement_function (fndecl))
3950 continue;
3952 tnode = cgraph_get_node (fndecl);
3953 d = get_cg_data (&tnode, true);
3955 pcallers = (for_clone ? &d->tm_callers_clone
3956 : &d->tm_callers_normal);
3958 gcc_assert (*pcallers > 0);
3959 *pcallers -= 1;
3965 /* (Re-)Scan the transaction blocks in NODE for calls to irrevocable functions,
3966 as well as other irrevocable actions such as inline assembly. Mark all
3967 such blocks as irrevocable and decrement the number of calls to
3968 transactional clones. Return true if, for the transactional clone, the
3969 entire function is irrevocable. */
3971 static bool
3972 ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
3974 struct tm_ipa_cg_data *d;
3975 bitmap new_irr, old_irr;
3976 VEC (basic_block, heap) *queue;
3977 bool ret = false;
3979 /* Builtin operators (operator new, and such). */
3980 if (DECL_STRUCT_FUNCTION (node->symbol.decl) == NULL
3981 || DECL_STRUCT_FUNCTION (node->symbol.decl)->cfg == NULL)
3982 return false;
3984 current_function_decl = node->symbol.decl;
3985 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
3986 calculate_dominance_info (CDI_DOMINATORS);
3988 d = get_cg_data (&node, true);
3989 queue = VEC_alloc (basic_block, heap, 10);
3990 new_irr = BITMAP_ALLOC (&tm_obstack);
3992 /* Scan each tm region, propagating irrevocable status through the tree. */
3993 if (for_clone)
3995 old_irr = d->irrevocable_blocks_clone;
3996 VEC_quick_push (basic_block, queue, single_succ (ENTRY_BLOCK_PTR));
3997 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr, NULL))
3999 ipa_tm_propagate_irr (single_succ (ENTRY_BLOCK_PTR), new_irr,
4000 old_irr, NULL);
4001 ret = bitmap_bit_p (new_irr, single_succ (ENTRY_BLOCK_PTR)->index);
4004 else
4006 struct tm_region *region;
4008 old_irr = d->irrevocable_blocks_normal;
4009 for (region = d->all_tm_regions; region; region = region->next)
4011 VEC_quick_push (basic_block, queue, region->entry_block);
4012 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr,
4013 region->exit_blocks))
4014 ipa_tm_propagate_irr (region->entry_block, new_irr, old_irr,
4015 region->exit_blocks);
4019 /* If we found any new irrevocable blocks, reduce the call count for
4020 transactional clones within the irrevocable blocks. Save the new
4021 set of irrevocable blocks for next time. */
4022 if (!bitmap_empty_p (new_irr))
4024 bitmap_iterator bmi;
4025 unsigned i;
4027 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
4028 ipa_tm_decrement_clone_counts (BASIC_BLOCK (i), for_clone);
4030 if (old_irr)
4032 bitmap_ior_into (old_irr, new_irr);
4033 BITMAP_FREE (new_irr);
4035 else if (for_clone)
4036 d->irrevocable_blocks_clone = new_irr;
4037 else
4038 d->irrevocable_blocks_normal = new_irr;
4040 if (dump_file && new_irr)
4042 const char *dname;
4043 bitmap_iterator bmi;
4044 unsigned i;
4046 dname = lang_hooks.decl_printable_name (current_function_decl, 2);
4047 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
4048 fprintf (dump_file, "%s: bb %d goes irrevocable\n", dname, i);
4051 else
4052 BITMAP_FREE (new_irr);
4054 VEC_free (basic_block, heap, queue);
4055 pop_cfun ();
4056 current_function_decl = NULL;
4058 return ret;
4061 /* Return true if, for the transactional clone of NODE, any call
4062 may enter irrevocable mode. */
4064 static bool
4065 ipa_tm_mayenterirr_function (struct cgraph_node *node)
4067 struct tm_ipa_cg_data *d;
4068 tree decl;
4069 unsigned flags;
4071 d = get_cg_data (&node, true);
4072 decl = node->symbol.decl;
4073 flags = flags_from_decl_or_type (decl);
4075 /* Handle some TM builtins. Ordinarily these aren't actually generated
4076 at this point, but handling these functions when written in by the
4077 user makes it easier to build unit tests. */
4078 if (flags & ECF_TM_BUILTIN)
4079 return false;
4081 /* Filter out all functions that are marked. */
4082 if (flags & ECF_TM_PURE)
4083 return false;
4084 if (is_tm_safe (decl))
4085 return false;
4086 if (is_tm_irrevocable (decl))
4087 return true;
4088 if (is_tm_callable (decl))
4089 return true;
4090 if (find_tm_replacement_function (decl))
4091 return true;
4093 /* If we aren't seeing the final version of the function we don't
4094 know what it will contain at runtime. */
4095 if (cgraph_function_body_availability (node) < AVAIL_AVAILABLE)
4096 return true;
4098 /* If the function must go irrevocable, then of course true. */
4099 if (d->is_irrevocable)
4100 return true;
4102 /* If there are any blocks marked irrevocable, then the function
4103 as a whole may enter irrevocable. */
4104 if (d->irrevocable_blocks_clone)
4105 return true;
4107 /* We may have previously marked this function as tm_may_enter_irr;
4108 see pass_diagnose_tm_blocks. */
4109 if (node->local.tm_may_enter_irr)
4110 return true;
4112 /* Recurse on the main body for aliases. In general, this will
4113 result in one of the bits above being set so that we will not
4114 have to recurse next time. */
4115 if (node->alias)
4116 return ipa_tm_mayenterirr_function (cgraph_get_node (node->thunk.alias));
4118 /* What remains is unmarked local functions without items that force
4119 the function to go irrevocable. */
4120 return false;
4123 /* Diagnose calls from transaction_safe functions to unmarked
4124 functions that are determined to not be safe. */
4126 static void
4127 ipa_tm_diagnose_tm_safe (struct cgraph_node *node)
4129 struct cgraph_edge *e;
4131 for (e = node->callees; e ; e = e->next_callee)
4132 if (!is_tm_callable (e->callee->symbol.decl)
4133 && e->callee->local.tm_may_enter_irr)
4134 error_at (gimple_location (e->call_stmt),
4135 "unsafe function call %qD within "
4136 "%<transaction_safe%> function", e->callee->symbol.decl);
4139 /* Diagnose call from atomic transactions to unmarked functions
4140 that are determined to not be safe. */
4142 static void
4143 ipa_tm_diagnose_transaction (struct cgraph_node *node,
4144 struct tm_region *all_tm_regions)
4146 struct tm_region *r;
4148 for (r = all_tm_regions; r ; r = r->next)
4149 if (gimple_transaction_subcode (r->transaction_stmt) & GTMA_IS_RELAXED)
4151 /* Atomic transactions can be nested inside relaxed. */
4152 if (r->inner)
4153 ipa_tm_diagnose_transaction (node, r->inner);
4155 else
4157 VEC (basic_block, heap) *bbs;
4158 gimple_stmt_iterator gsi;
4159 basic_block bb;
4160 size_t i;
4162 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks,
4163 r->irr_blocks, NULL, false);
4165 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i)
4166 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4168 gimple stmt = gsi_stmt (gsi);
4169 tree fndecl;
4171 if (gimple_code (stmt) == GIMPLE_ASM)
4173 error_at (gimple_location (stmt),
4174 "asm not allowed in atomic transaction");
4175 continue;
4178 if (!is_gimple_call (stmt))
4179 continue;
4180 fndecl = gimple_call_fndecl (stmt);
4182 /* Indirect function calls have been diagnosed already. */
4183 if (!fndecl)
4184 continue;
4186 /* Stop at the end of the transaction. */
4187 if (is_tm_ending_fndecl (fndecl))
4189 if (bitmap_bit_p (r->exit_blocks, bb->index))
4190 break;
4191 continue;
4194 /* Marked functions have been diagnosed already. */
4195 if (is_tm_pure_call (stmt))
4196 continue;
4197 if (is_tm_callable (fndecl))
4198 continue;
4200 if (cgraph_local_info (fndecl)->tm_may_enter_irr)
4201 error_at (gimple_location (stmt),
4202 "unsafe function call %qD within "
4203 "atomic transaction", fndecl);
4206 VEC_free (basic_block, heap, bbs);
4210 /* Return a transactional mangled name for the DECL_ASSEMBLER_NAME in
4211 OLD_DECL. The returned value is a freshly malloced pointer that
4212 should be freed by the caller. */
4214 static tree
4215 tm_mangle (tree old_asm_id)
4217 const char *old_asm_name;
4218 char *tm_name;
4219 void *alloc = NULL;
4220 struct demangle_component *dc;
4221 tree new_asm_id;
4223 /* Determine if the symbol is already a valid C++ mangled name. Do this
4224 even for C, which might be interfacing with C++ code via appropriately
4225 ugly identifiers. */
4226 /* ??? We could probably do just as well checking for "_Z" and be done. */
4227 old_asm_name = IDENTIFIER_POINTER (old_asm_id);
4228 dc = cplus_demangle_v3_components (old_asm_name, DMGL_NO_OPTS, &alloc);
4230 if (dc == NULL)
4232 char length[8];
4234 do_unencoded:
4235 sprintf (length, "%u", IDENTIFIER_LENGTH (old_asm_id));
4236 tm_name = concat ("_ZGTt", length, old_asm_name, NULL);
4238 else
4240 old_asm_name += 2; /* Skip _Z */
4242 switch (dc->type)
4244 case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
4245 case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
4246 /* Don't play silly games, you! */
4247 goto do_unencoded;
4249 case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
4250 /* I'd really like to know if we can ever be passed one of
4251 these from the C++ front end. The Logical Thing would
4252 seem that hidden-alias should be outer-most, so that we
4253 get hidden-alias of a transaction-clone and not vice-versa. */
4254 old_asm_name += 2;
4255 break;
4257 default:
4258 break;
4261 tm_name = concat ("_ZGTt", old_asm_name, NULL);
4263 free (alloc);
4265 new_asm_id = get_identifier (tm_name);
4266 free (tm_name);
4268 return new_asm_id;
4271 static inline void
4272 ipa_tm_mark_force_output_node (struct cgraph_node *node)
4274 cgraph_mark_force_output_node (node);
4275 /* ??? function_and_variable_visibility will reset
4276 the needed bit, without actually checking. */
4277 node->analyzed = 1;
4280 /* Callback data for ipa_tm_create_version_alias. */
4281 struct create_version_alias_info
4283 struct cgraph_node *old_node;
4284 tree new_decl;
4287 /* A subroutine of ipa_tm_create_version, called via
4288 cgraph_for_node_and_aliases. Create new tm clones for each of
4289 the existing aliases. */
4290 static bool
4291 ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
4293 struct create_version_alias_info *info
4294 = (struct create_version_alias_info *)data;
4295 tree old_decl, new_decl, tm_name;
4296 struct cgraph_node *new_node;
4298 if (!node->same_body_alias)
4299 return false;
4301 old_decl = node->symbol.decl;
4302 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4303 new_decl = build_decl (DECL_SOURCE_LOCATION (old_decl),
4304 TREE_CODE (old_decl), tm_name,
4305 TREE_TYPE (old_decl));
4307 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4308 SET_DECL_RTL (new_decl, NULL);
4310 /* Based loosely on C++'s make_alias_for(). */
4311 TREE_PUBLIC (new_decl) = TREE_PUBLIC (old_decl);
4312 DECL_CONTEXT (new_decl) = DECL_CONTEXT (old_decl);
4313 DECL_LANG_SPECIFIC (new_decl) = DECL_LANG_SPECIFIC (old_decl);
4314 TREE_READONLY (new_decl) = TREE_READONLY (old_decl);
4315 DECL_EXTERNAL (new_decl) = 0;
4316 DECL_ARTIFICIAL (new_decl) = 1;
4317 TREE_ADDRESSABLE (new_decl) = 1;
4318 TREE_USED (new_decl) = 1;
4319 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4321 /* Perform the same remapping to the comdat group. */
4322 if (DECL_ONE_ONLY (new_decl))
4323 DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
4325 new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
4326 new_node->tm_clone = true;
4327 new_node->symbol.externally_visible = info->old_node->symbol.externally_visible;
4328 /* ?? Do not traverse aliases here. */
4329 get_cg_data (&node, false)->clone = new_node;
4331 record_tm_clone_pair (old_decl, new_decl);
4333 if (info->old_node->symbol.force_output)
4334 ipa_tm_mark_force_output_node (new_node);
4335 return false;
4338 /* Create a copy of the function (possibly declaration only) of OLD_NODE,
4339 appropriate for the transactional clone. */
4341 static void
4342 ipa_tm_create_version (struct cgraph_node *old_node)
4344 tree new_decl, old_decl, tm_name;
4345 struct cgraph_node *new_node;
4347 old_decl = old_node->symbol.decl;
4348 new_decl = copy_node (old_decl);
4350 /* DECL_ASSEMBLER_NAME needs to be set before we call
4351 cgraph_copy_node_for_versioning below, because cgraph_node will
4352 fill the assembler_name_hash. */
4353 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4354 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4355 SET_DECL_RTL (new_decl, NULL);
4356 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4358 /* Perform the same remapping to the comdat group. */
4359 if (DECL_ONE_ONLY (new_decl))
4360 DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
4362 new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL);
4363 new_node->symbol.externally_visible = old_node->symbol.externally_visible;
4364 new_node->lowered = true;
4365 new_node->tm_clone = 1;
4366 get_cg_data (&old_node, true)->clone = new_node;
4368 if (cgraph_function_body_availability (old_node) >= AVAIL_OVERWRITABLE)
4370 /* Remap extern inline to static inline. */
4371 /* ??? Is it worth trying to use make_decl_one_only? */
4372 if (DECL_DECLARED_INLINE_P (new_decl) && DECL_EXTERNAL (new_decl))
4374 DECL_EXTERNAL (new_decl) = 0;
4375 TREE_PUBLIC (new_decl) = 0;
4376 DECL_WEAK (new_decl) = 0;
4379 tree_function_versioning (old_decl, new_decl, NULL, false, NULL, false,
4380 NULL, NULL);
4383 record_tm_clone_pair (old_decl, new_decl);
4385 cgraph_call_function_insertion_hooks (new_node);
4386 if (old_node->symbol.force_output)
4387 ipa_tm_mark_force_output_node (new_node);
4389 /* Do the same thing, but for any aliases of the original node. */
4391 struct create_version_alias_info data;
4392 data.old_node = old_node;
4393 data.new_decl = new_decl;
4394 cgraph_for_node_and_aliases (old_node, ipa_tm_create_version_alias,
4395 &data, true);
4399 /* Construct a call to TM_IRREVOCABLE and insert it at the beginning of BB. */
4401 static void
4402 ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region,
4403 basic_block bb)
4405 gimple_stmt_iterator gsi;
4406 gimple g;
4408 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4410 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE),
4411 1, build_int_cst (NULL_TREE, MODE_SERIALIRREVOCABLE));
4413 split_block_after_labels (bb);
4414 gsi = gsi_after_labels (bb);
4415 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
4417 cgraph_create_edge (node,
4418 cgraph_get_create_node
4419 (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE)),
4420 g, 0,
4421 compute_call_stmt_bb_frequency (node->symbol.decl,
4422 gimple_bb (g)));
4425 /* Construct a call to TM_GETTMCLONE and insert it before GSI. */
4427 static bool
4428 ipa_tm_insert_gettmclone_call (struct cgraph_node *node,
4429 struct tm_region *region,
4430 gimple_stmt_iterator *gsi, gimple stmt)
4432 tree gettm_fn, ret, old_fn, callfn;
4433 gimple g, g2;
4434 bool safe;
4436 old_fn = gimple_call_fn (stmt);
4438 if (TREE_CODE (old_fn) == ADDR_EXPR)
4440 tree fndecl = TREE_OPERAND (old_fn, 0);
4441 tree clone = get_tm_clone_pair (fndecl);
4443 /* By transforming the call into a TM_GETTMCLONE, we are
4444 technically taking the address of the original function and
4445 its clone. Explain this so inlining will know this function
4446 is needed. */
4447 cgraph_mark_address_taken_node (cgraph_get_node (fndecl));
4448 if (clone)
4449 cgraph_mark_address_taken_node (cgraph_get_node (clone));
4452 safe = is_tm_safe (TREE_TYPE (old_fn));
4453 gettm_fn = builtin_decl_explicit (safe ? BUILT_IN_TM_GETTMCLONE_SAFE
4454 : BUILT_IN_TM_GETTMCLONE_IRR);
4455 ret = create_tmp_var (ptr_type_node, NULL);
4456 add_referenced_var (ret);
4458 if (!safe)
4459 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4461 /* Discard OBJ_TYPE_REF, since we weren't able to fold it. */
4462 if (TREE_CODE (old_fn) == OBJ_TYPE_REF)
4463 old_fn = OBJ_TYPE_REF_EXPR (old_fn);
4465 g = gimple_build_call (gettm_fn, 1, old_fn);
4466 ret = make_ssa_name (ret, g);
4467 gimple_call_set_lhs (g, ret);
4469 gsi_insert_before (gsi, g, GSI_SAME_STMT);
4471 cgraph_create_edge (node, cgraph_get_create_node (gettm_fn), g, 0,
4472 compute_call_stmt_bb_frequency (node->symbol.decl,
4473 gimple_bb(g)));
4475 /* Cast return value from tm_gettmclone* into appropriate function
4476 pointer. */
4477 callfn = create_tmp_var (TREE_TYPE (old_fn), NULL);
4478 add_referenced_var (callfn);
4479 g2 = gimple_build_assign (callfn,
4480 fold_build1 (NOP_EXPR, TREE_TYPE (callfn), ret));
4481 callfn = make_ssa_name (callfn, g2);
4482 gimple_assign_set_lhs (g2, callfn);
4483 gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4485 /* ??? This is a hack to preserve the NOTHROW bit on the call,
4486 which we would have derived from the decl. Failure to save
4487 this bit means we might have to split the basic block. */
4488 if (gimple_call_nothrow_p (stmt))
4489 gimple_call_set_nothrow (stmt, true);
4491 gimple_call_set_fn (stmt, callfn);
4493 /* Discarding OBJ_TYPE_REF above may produce incompatible LHS and RHS
4494 for a call statement. Fix it. */
4496 tree lhs = gimple_call_lhs (stmt);
4497 tree rettype = TREE_TYPE (gimple_call_fntype (stmt));
4498 if (lhs
4499 && !useless_type_conversion_p (TREE_TYPE (lhs), rettype))
4501 tree temp;
4503 temp = make_rename_temp (rettype, 0);
4504 gimple_call_set_lhs (stmt, temp);
4506 g2 = gimple_build_assign (lhs,
4507 fold_build1 (VIEW_CONVERT_EXPR,
4508 TREE_TYPE (lhs), temp));
4509 gsi_insert_after (gsi, g2, GSI_SAME_STMT);
4513 update_stmt (stmt);
4515 return true;
4518 /* Helper function for ipa_tm_transform_calls*. Given a call
4519 statement in GSI which resides inside transaction REGION, redirect
4520 the call to either its wrapper function, or its clone. */
4522 static void
4523 ipa_tm_transform_calls_redirect (struct cgraph_node *node,
4524 struct tm_region *region,
4525 gimple_stmt_iterator *gsi,
4526 bool *need_ssa_rename_p)
4528 gimple stmt = gsi_stmt (*gsi);
4529 struct cgraph_node *new_node;
4530 struct cgraph_edge *e = cgraph_edge (node, stmt);
4531 tree fndecl = gimple_call_fndecl (stmt);
4533 /* For indirect calls, pass the address through the runtime. */
4534 if (fndecl == NULL)
4536 *need_ssa_rename_p |=
4537 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
4538 return;
4541 /* Handle some TM builtins. Ordinarily these aren't actually generated
4542 at this point, but handling these functions when written in by the
4543 user makes it easier to build unit tests. */
4544 if (flags_from_decl_or_type (fndecl) & ECF_TM_BUILTIN)
4545 return;
4547 /* Fixup recursive calls inside clones. */
4548 /* ??? Why did cgraph_copy_node_for_versioning update the call edges
4549 for recursion but not update the call statements themselves? */
4550 if (e->caller == e->callee && decl_is_tm_clone (current_function_decl))
4552 gimple_call_set_fndecl (stmt, current_function_decl);
4553 return;
4556 /* If there is a replacement, use it. */
4557 fndecl = find_tm_replacement_function (fndecl);
4558 if (fndecl)
4560 new_node = cgraph_get_create_node (fndecl);
4562 /* ??? Mark all transaction_wrap functions tm_may_enter_irr.
4564 We can't do this earlier in record_tm_replacement because
4565 cgraph_remove_unreachable_nodes is called before we inject
4566 references to the node. Further, we can't do this in some
4567 nice central place in ipa_tm_execute because we don't have
4568 the exact list of wrapper functions that would be used.
4569 Marking more wrappers than necessary results in the creation
4570 of unnecessary cgraph_nodes, which can cause some of the
4571 other IPA passes to crash.
4573 We do need to mark these nodes so that we get the proper
4574 result in expand_call_tm. */
4575 /* ??? This seems broken. How is it that we're marking the
4576 CALLEE as may_enter_irr? Surely we should be marking the
4577 CALLER. Also note that find_tm_replacement_function also
4578 contains mappings into the TM runtime, e.g. memcpy. These
4579 we know won't go irrevocable. */
4580 new_node->local.tm_may_enter_irr = 1;
4582 else
4584 struct tm_ipa_cg_data *d;
4585 struct cgraph_node *tnode = e->callee;
4587 d = get_cg_data (&tnode, true);
4588 new_node = d->clone;
4590 /* As we've already skipped pure calls and appropriate builtins,
4591 and we've already marked irrevocable blocks, if we can't come
4592 up with a static replacement, then ask the runtime. */
4593 if (new_node == NULL)
4595 *need_ssa_rename_p |=
4596 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
4597 return;
4600 fndecl = new_node->symbol.decl;
4603 cgraph_redirect_edge_callee (e, new_node);
4604 gimple_call_set_fndecl (stmt, fndecl);
4607 /* Helper function for ipa_tm_transform_calls. For a given BB,
4608 install calls to tm_irrevocable when IRR_BLOCKS are reached,
4609 redirect other calls to the generated transactional clone. */
4611 static bool
4612 ipa_tm_transform_calls_1 (struct cgraph_node *node, struct tm_region *region,
4613 basic_block bb, bitmap irr_blocks)
4615 gimple_stmt_iterator gsi;
4616 bool need_ssa_rename = false;
4618 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
4620 ipa_tm_insert_irr_call (node, region, bb);
4621 return true;
4624 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4626 gimple stmt = gsi_stmt (gsi);
4628 if (!is_gimple_call (stmt))
4629 continue;
4630 if (is_tm_pure_call (stmt))
4631 continue;
4633 /* Redirect edges to the appropriate replacement or clone. */
4634 ipa_tm_transform_calls_redirect (node, region, &gsi, &need_ssa_rename);
4637 return need_ssa_rename;
4640 /* Walk the CFG for REGION, beginning at BB. Install calls to
4641 tm_irrevocable when IRR_BLOCKS are reached, redirect other calls to
4642 the generated transactional clone. */
4644 static bool
4645 ipa_tm_transform_calls (struct cgraph_node *node, struct tm_region *region,
4646 basic_block bb, bitmap irr_blocks)
4648 bool need_ssa_rename = false;
4649 edge e;
4650 edge_iterator ei;
4651 VEC(basic_block, heap) *queue = NULL;
4652 bitmap visited_blocks = BITMAP_ALLOC (NULL);
4654 VEC_safe_push (basic_block, heap, queue, bb);
4657 bb = VEC_pop (basic_block, queue);
4659 need_ssa_rename |=
4660 ipa_tm_transform_calls_1 (node, region, bb, irr_blocks);
4662 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
4663 continue;
4665 if (region && bitmap_bit_p (region->exit_blocks, bb->index))
4666 continue;
4668 FOR_EACH_EDGE (e, ei, bb->succs)
4669 if (!bitmap_bit_p (visited_blocks, e->dest->index))
4671 bitmap_set_bit (visited_blocks, e->dest->index);
4672 VEC_safe_push (basic_block, heap, queue, e->dest);
4675 while (!VEC_empty (basic_block, queue));
4677 VEC_free (basic_block, heap, queue);
4678 BITMAP_FREE (visited_blocks);
4680 return need_ssa_rename;
4683 /* Transform the calls within the TM regions within NODE. */
4685 static void
4686 ipa_tm_transform_transaction (struct cgraph_node *node)
4688 struct tm_ipa_cg_data *d;
4689 struct tm_region *region;
4690 bool need_ssa_rename = false;
4692 d = get_cg_data (&node, true);
4694 current_function_decl = node->symbol.decl;
4695 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
4696 calculate_dominance_info (CDI_DOMINATORS);
4698 for (region = d->all_tm_regions; region; region = region->next)
4700 /* If we're sure to go irrevocable, don't transform anything. */
4701 if (d->irrevocable_blocks_normal
4702 && bitmap_bit_p (d->irrevocable_blocks_normal,
4703 region->entry_block->index))
4705 transaction_subcode_ior (region, GTMA_DOES_GO_IRREVOCABLE);
4706 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4707 continue;
4710 need_ssa_rename |=
4711 ipa_tm_transform_calls (node, region, region->entry_block,
4712 d->irrevocable_blocks_normal);
4715 if (need_ssa_rename)
4716 update_ssa (TODO_update_ssa_only_virtuals);
4718 pop_cfun ();
4719 current_function_decl = NULL;
4722 /* Transform the calls within the transactional clone of NODE. */
4724 static void
4725 ipa_tm_transform_clone (struct cgraph_node *node)
4727 struct tm_ipa_cg_data *d;
4728 bool need_ssa_rename;
4730 d = get_cg_data (&node, true);
4732 /* If this function makes no calls and has no irrevocable blocks,
4733 then there's nothing to do. */
4734 /* ??? Remove non-aborting top-level transactions. */
4735 if (!node->callees && !node->indirect_calls && !d->irrevocable_blocks_clone)
4736 return;
4738 current_function_decl = d->clone->symbol.decl;
4739 push_cfun (DECL_STRUCT_FUNCTION (current_function_decl));
4740 calculate_dominance_info (CDI_DOMINATORS);
4742 need_ssa_rename =
4743 ipa_tm_transform_calls (d->clone, NULL, single_succ (ENTRY_BLOCK_PTR),
4744 d->irrevocable_blocks_clone);
4746 if (need_ssa_rename)
4747 update_ssa (TODO_update_ssa_only_virtuals);
4749 pop_cfun ();
4750 current_function_decl = NULL;
4753 /* Main entry point for the transactional memory IPA pass. */
4755 static unsigned int
4756 ipa_tm_execute (void)
4758 cgraph_node_queue tm_callees = NULL;
4759 /* List of functions that will go irrevocable. */
4760 cgraph_node_queue irr_worklist = NULL;
4762 struct cgraph_node *node;
4763 struct tm_ipa_cg_data *d;
4764 enum availability a;
4765 unsigned int i;
4767 #ifdef ENABLE_CHECKING
4768 verify_cgraph ();
4769 #endif
4771 bitmap_obstack_initialize (&tm_obstack);
4773 /* For all local functions marked tm_callable, queue them. */
4774 FOR_EACH_DEFINED_FUNCTION (node)
4775 if (is_tm_callable (node->symbol.decl)
4776 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4778 d = get_cg_data (&node, true);
4779 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
4782 /* For all local reachable functions... */
4783 FOR_EACH_DEFINED_FUNCTION (node)
4784 if (node->lowered
4785 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4787 /* ... marked tm_pure, record that fact for the runtime by
4788 indicating that the pure function is its own tm_callable.
4789 No need to do this if the function's address can't be taken. */
4790 if (is_tm_pure (node->symbol.decl))
4792 if (!node->local.local)
4793 record_tm_clone_pair (node->symbol.decl, node->symbol.decl);
4794 continue;
4797 current_function_decl = node->symbol.decl;
4798 push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
4799 calculate_dominance_info (CDI_DOMINATORS);
4801 tm_region_init (NULL);
4802 if (all_tm_regions)
4804 d = get_cg_data (&node, true);
4806 /* Scan for calls that are in each transaction. */
4807 ipa_tm_scan_calls_transaction (d, &tm_callees);
4809 /* Put it in the worklist so we can scan the function
4810 later (ipa_tm_scan_irr_function) and mark the
4811 irrevocable blocks. */
4812 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4813 d->want_irr_scan_normal = true;
4816 pop_cfun ();
4817 current_function_decl = NULL;
4820 /* For every local function on the callee list, scan as if we will be
4821 creating a transactional clone, queueing all new functions we find
4822 along the way. */
4823 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4825 node = VEC_index (cgraph_node_p, tm_callees, i);
4826 a = cgraph_function_body_availability (node);
4827 d = get_cg_data (&node, true);
4829 /* Put it in the worklist so we can scan the function later
4830 (ipa_tm_scan_irr_function) and mark the irrevocable
4831 blocks. */
4832 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4834 /* Some callees cannot be arbitrarily cloned. These will always be
4835 irrevocable. Mark these now, so that we need not scan them. */
4836 if (is_tm_irrevocable (node->symbol.decl))
4837 ipa_tm_note_irrevocable (node, &irr_worklist);
4838 else if (a <= AVAIL_NOT_AVAILABLE
4839 && !is_tm_safe_or_pure (node->symbol.decl))
4840 ipa_tm_note_irrevocable (node, &irr_worklist);
4841 else if (a >= AVAIL_OVERWRITABLE)
4843 if (!tree_versionable_function_p (node->symbol.decl))
4844 ipa_tm_note_irrevocable (node, &irr_worklist);
4845 else if (!d->is_irrevocable)
4847 /* If this is an alias, make sure its base is queued as well.
4848 we need not scan the callees now, as the base will do. */
4849 if (node->alias)
4851 node = cgraph_get_node (node->thunk.alias);
4852 d = get_cg_data (&node, true);
4853 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
4854 continue;
4857 /* Add all nodes called by this function into
4858 tm_callees as well. */
4859 ipa_tm_scan_calls_clone (node, &tm_callees);
4864 /* Iterate scans until no more work to be done. Prefer not to use
4865 VEC_pop because the worklist tends to follow a breadth-first
4866 search of the callgraph, which should allow convergance with a
4867 minimum number of scans. But we also don't want the worklist
4868 array to grow without bound, so we shift the array up periodically. */
4869 for (i = 0; i < VEC_length (cgraph_node_p, irr_worklist); ++i)
4871 if (i > 256 && i == VEC_length (cgraph_node_p, irr_worklist) / 8)
4873 VEC_block_remove (cgraph_node_p, irr_worklist, 0, i);
4874 i = 0;
4877 node = VEC_index (cgraph_node_p, irr_worklist, i);
4878 d = get_cg_data (&node, true);
4879 d->in_worklist = false;
4881 if (d->want_irr_scan_normal)
4883 d->want_irr_scan_normal = false;
4884 ipa_tm_scan_irr_function (node, false);
4886 if (d->in_callee_queue && ipa_tm_scan_irr_function (node, true))
4887 ipa_tm_note_irrevocable (node, &irr_worklist);
4890 /* For every function on the callee list, collect the tm_may_enter_irr
4891 bit on the node. */
4892 VEC_truncate (cgraph_node_p, irr_worklist, 0);
4893 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4895 node = VEC_index (cgraph_node_p, tm_callees, i);
4896 if (ipa_tm_mayenterirr_function (node))
4898 d = get_cg_data (&node, true);
4899 gcc_assert (d->in_worklist == false);
4900 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4904 /* Propagate the tm_may_enter_irr bit to callers until stable. */
4905 for (i = 0; i < VEC_length (cgraph_node_p, irr_worklist); ++i)
4907 struct cgraph_node *caller;
4908 struct cgraph_edge *e;
4909 struct ipa_ref *ref;
4910 unsigned j;
4912 if (i > 256 && i == VEC_length (cgraph_node_p, irr_worklist) / 8)
4914 VEC_block_remove (cgraph_node_p, irr_worklist, 0, i);
4915 i = 0;
4918 node = VEC_index (cgraph_node_p, irr_worklist, i);
4919 d = get_cg_data (&node, true);
4920 d->in_worklist = false;
4921 node->local.tm_may_enter_irr = true;
4923 /* Propagate back to normal callers. */
4924 for (e = node->callers; e ; e = e->next_caller)
4926 caller = e->caller;
4927 if (!is_tm_safe_or_pure (caller->symbol.decl)
4928 && !caller->local.tm_may_enter_irr)
4930 d = get_cg_data (&caller, true);
4931 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
4935 /* Propagate back to referring aliases as well. */
4936 for (j = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, j, ref); j++)
4938 caller = cgraph (ref->referring);
4939 if (ref->use == IPA_REF_ALIAS
4940 && !caller->local.tm_may_enter_irr)
4942 /* ?? Do not traverse aliases here. */
4943 d = get_cg_data (&caller, false);
4944 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
4949 /* Now validate all tm_safe functions, and all atomic regions in
4950 other functions. */
4951 FOR_EACH_DEFINED_FUNCTION (node)
4952 if (node->lowered
4953 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4955 d = get_cg_data (&node, true);
4956 if (is_tm_safe (node->symbol.decl))
4957 ipa_tm_diagnose_tm_safe (node);
4958 else if (d->all_tm_regions)
4959 ipa_tm_diagnose_transaction (node, d->all_tm_regions);
4962 /* Create clones. Do those that are not irrevocable and have a
4963 positive call count. Do those publicly visible functions that
4964 the user directed us to clone. */
4965 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4967 bool doit = false;
4969 node = VEC_index (cgraph_node_p, tm_callees, i);
4970 if (node->same_body_alias)
4971 continue;
4973 a = cgraph_function_body_availability (node);
4974 d = get_cg_data (&node, true);
4976 if (a <= AVAIL_NOT_AVAILABLE)
4977 doit = is_tm_callable (node->symbol.decl);
4978 else if (a <= AVAIL_AVAILABLE && is_tm_callable (node->symbol.decl))
4979 doit = true;
4980 else if (!d->is_irrevocable
4981 && d->tm_callers_normal + d->tm_callers_clone > 0)
4982 doit = true;
4984 if (doit)
4985 ipa_tm_create_version (node);
4988 /* Redirect calls to the new clones, and insert irrevocable marks. */
4989 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4991 node = VEC_index (cgraph_node_p, tm_callees, i);
4992 if (node->analyzed)
4994 d = get_cg_data (&node, true);
4995 if (d->clone)
4996 ipa_tm_transform_clone (node);
4999 FOR_EACH_DEFINED_FUNCTION (node)
5000 if (node->lowered
5001 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
5003 d = get_cg_data (&node, true);
5004 if (d->all_tm_regions)
5005 ipa_tm_transform_transaction (node);
5008 /* Free and clear all data structures. */
5009 VEC_free (cgraph_node_p, heap, tm_callees);
5010 VEC_free (cgraph_node_p, heap, irr_worklist);
5011 bitmap_obstack_release (&tm_obstack);
5013 FOR_EACH_FUNCTION (node)
5014 node->symbol.aux = NULL;
5016 #ifdef ENABLE_CHECKING
5017 verify_cgraph ();
5018 #endif
5020 return 0;
5023 struct simple_ipa_opt_pass pass_ipa_tm =
5026 SIMPLE_IPA_PASS,
5027 "tmipa", /* name */
5028 gate_tm, /* gate */
5029 ipa_tm_execute, /* execute */
5030 NULL, /* sub */
5031 NULL, /* next */
5032 0, /* static_pass_number */
5033 TV_TRANS_MEM, /* tv_id */
5034 PROP_ssa | PROP_cfg, /* properties_required */
5035 0, /* properties_provided */
5036 0, /* properties_destroyed */
5037 0, /* todo_flags_start */
5038 0, /* todo_flags_finish */
5042 #include "gt-trans-mem.h"