Remove TODO_dump_func completely
[official-gcc.git] / gcc / trans-mem.c
blobc1c68be977c194367d457bfba3eafb93084371d9
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 (gimple_transaction_body (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 = gimple_seq_alloc ();
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;
1708 /* Transactional clones aren't created until a later pass. */
1709 gcc_assert (!decl_is_tm_clone (current_function_decl));
1711 memset (&wi, 0, sizeof (wi));
1712 walk_gimple_seq (gimple_body (current_function_decl),
1713 lower_sequence_no_tm, NULL, &wi);
1715 return 0;
1718 struct gimple_opt_pass pass_lower_tm =
1721 GIMPLE_PASS,
1722 "tmlower", /* name */
1723 gate_tm, /* gate */
1724 execute_lower_tm, /* execute */
1725 NULL, /* sub */
1726 NULL, /* next */
1727 0, /* static_pass_number */
1728 TV_TRANS_MEM, /* tv_id */
1729 PROP_gimple_lcf, /* properties_required */
1730 0, /* properties_provided */
1731 0, /* properties_destroyed */
1732 0, /* todo_flags_start */
1733 0, /* todo_flags_finish */
1737 /* Collect region information for each transaction. */
1739 struct tm_region
1741 /* Link to the next unnested transaction. */
1742 struct tm_region *next;
1744 /* Link to the next inner transaction. */
1745 struct tm_region *inner;
1747 /* Link to the next outer transaction. */
1748 struct tm_region *outer;
1750 /* The GIMPLE_TRANSACTION statement beginning this transaction. */
1751 gimple transaction_stmt;
1753 /* The entry block to this region. */
1754 basic_block entry_block;
1756 /* The set of all blocks that end the region; NULL if only EXIT_BLOCK.
1757 These blocks are still a part of the region (i.e., the border is
1758 inclusive). Note that this set is only complete for paths in the CFG
1759 starting at ENTRY_BLOCK, and that there is no exit block recorded for
1760 the edge to the "over" label. */
1761 bitmap exit_blocks;
1763 /* The set of all blocks that have an TM_IRREVOCABLE call. */
1764 bitmap irr_blocks;
1767 typedef struct tm_region *tm_region_p;
1768 DEF_VEC_P (tm_region_p);
1769 DEF_VEC_ALLOC_P (tm_region_p, heap);
1771 /* True if there are pending edge statements to be committed for the
1772 current function being scanned in the tmmark pass. */
1773 bool pending_edge_inserts_p;
1775 static struct tm_region *all_tm_regions;
1776 static bitmap_obstack tm_obstack;
1779 /* A subroutine of tm_region_init. Record the existance of the
1780 GIMPLE_TRANSACTION statement in a tree of tm_region elements. */
1782 static struct tm_region *
1783 tm_region_init_0 (struct tm_region *outer, basic_block bb, gimple stmt)
1785 struct tm_region *region;
1787 region = (struct tm_region *)
1788 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
1790 if (outer)
1792 region->next = outer->inner;
1793 outer->inner = region;
1795 else
1797 region->next = all_tm_regions;
1798 all_tm_regions = region;
1800 region->inner = NULL;
1801 region->outer = outer;
1803 region->transaction_stmt = stmt;
1805 /* There are either one or two edges out of the block containing
1806 the GIMPLE_TRANSACTION, one to the actual region and one to the
1807 "over" label if the region contains an abort. The former will
1808 always be the one marked FALLTHRU. */
1809 region->entry_block = FALLTHRU_EDGE (bb)->dest;
1811 region->exit_blocks = BITMAP_ALLOC (&tm_obstack);
1812 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
1814 return region;
1817 /* A subroutine of tm_region_init. Record all the exit and
1818 irrevocable blocks in BB into the region's exit_blocks and
1819 irr_blocks bitmaps. Returns the new region being scanned. */
1821 static struct tm_region *
1822 tm_region_init_1 (struct tm_region *region, basic_block bb)
1824 gimple_stmt_iterator gsi;
1825 gimple g;
1827 if (!region
1828 || (!region->irr_blocks && !region->exit_blocks))
1829 return region;
1831 /* Check to see if this is the end of a region by seeing if it
1832 contains a call to __builtin_tm_commit{,_eh}. Note that the
1833 outermost region for DECL_IS_TM_CLONE need not collect this. */
1834 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
1836 g = gsi_stmt (gsi);
1837 if (gimple_code (g) == GIMPLE_CALL)
1839 tree fn = gimple_call_fndecl (g);
1840 if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
1842 if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT
1843 || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH)
1844 && region->exit_blocks)
1846 bitmap_set_bit (region->exit_blocks, bb->index);
1847 region = region->outer;
1848 break;
1850 if (DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_IRREVOCABLE)
1851 bitmap_set_bit (region->irr_blocks, bb->index);
1855 return region;
1858 /* Collect all of the transaction regions within the current function
1859 and record them in ALL_TM_REGIONS. The REGION parameter may specify
1860 an "outermost" region for use by tm clones. */
1862 static void
1863 tm_region_init (struct tm_region *region)
1865 gimple g;
1866 edge_iterator ei;
1867 edge e;
1868 basic_block bb;
1869 VEC(basic_block, heap) *queue = NULL;
1870 bitmap visited_blocks = BITMAP_ALLOC (NULL);
1871 struct tm_region *old_region;
1872 VEC(tm_region_p, heap) *bb_regions = NULL;
1874 all_tm_regions = region;
1875 bb = single_succ (ENTRY_BLOCK_PTR);
1877 /* We could store this information in bb->aux, but we may get called
1878 through get_all_tm_blocks() from another pass that may be already
1879 using bb->aux. */
1880 VEC_safe_grow_cleared (tm_region_p, heap, bb_regions, last_basic_block);
1882 VEC_safe_push (basic_block, heap, queue, bb);
1883 VEC_replace (tm_region_p, bb_regions, bb->index, region);
1886 bb = VEC_pop (basic_block, queue);
1887 region = VEC_index (tm_region_p, bb_regions, bb->index);
1888 VEC_replace (tm_region_p, bb_regions, bb->index, NULL);
1890 /* Record exit and irrevocable blocks. */
1891 region = tm_region_init_1 (region, bb);
1893 /* Check for the last statement in the block beginning a new region. */
1894 g = last_stmt (bb);
1895 old_region = region;
1896 if (g && gimple_code (g) == GIMPLE_TRANSACTION)
1897 region = tm_region_init_0 (region, bb, g);
1899 /* Process subsequent blocks. */
1900 FOR_EACH_EDGE (e, ei, bb->succs)
1901 if (!bitmap_bit_p (visited_blocks, e->dest->index))
1903 bitmap_set_bit (visited_blocks, e->dest->index);
1904 VEC_safe_push (basic_block, heap, queue, e->dest);
1906 /* If the current block started a new region, make sure that only
1907 the entry block of the new region is associated with this region.
1908 Other successors are still part of the old region. */
1909 if (old_region != region && e->dest != region->entry_block)
1910 VEC_replace (tm_region_p, bb_regions, e->dest->index, old_region);
1911 else
1912 VEC_replace (tm_region_p, bb_regions, e->dest->index, region);
1915 while (!VEC_empty (basic_block, queue));
1916 VEC_free (basic_block, heap, queue);
1917 BITMAP_FREE (visited_blocks);
1918 VEC_free (tm_region_p, heap, bb_regions);
1921 /* The "gate" function for all transactional memory expansion and optimization
1922 passes. We collect region information for each top-level transaction, and
1923 if we don't find any, we skip all of the TM passes. Each region will have
1924 all of the exit blocks recorded, and the originating statement. */
1926 static bool
1927 gate_tm_init (void)
1929 if (!flag_tm)
1930 return false;
1932 calculate_dominance_info (CDI_DOMINATORS);
1933 bitmap_obstack_initialize (&tm_obstack);
1935 /* If the function is a TM_CLONE, then the entire function is the region. */
1936 if (decl_is_tm_clone (current_function_decl))
1938 struct tm_region *region = (struct tm_region *)
1939 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
1940 memset (region, 0, sizeof (*region));
1941 region->entry_block = single_succ (ENTRY_BLOCK_PTR);
1942 /* For a clone, the entire function is the region. But even if
1943 we don't need to record any exit blocks, we may need to
1944 record irrevocable blocks. */
1945 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
1947 tm_region_init (region);
1949 else
1951 tm_region_init (NULL);
1953 /* If we didn't find any regions, cleanup and skip the whole tree
1954 of tm-related optimizations. */
1955 if (all_tm_regions == NULL)
1957 bitmap_obstack_release (&tm_obstack);
1958 return false;
1962 return true;
1965 struct gimple_opt_pass pass_tm_init =
1968 GIMPLE_PASS,
1969 "*tminit", /* name */
1970 gate_tm_init, /* gate */
1971 NULL, /* execute */
1972 NULL, /* sub */
1973 NULL, /* next */
1974 0, /* static_pass_number */
1975 TV_TRANS_MEM, /* tv_id */
1976 PROP_ssa | PROP_cfg, /* properties_required */
1977 0, /* properties_provided */
1978 0, /* properties_destroyed */
1979 0, /* todo_flags_start */
1980 0, /* todo_flags_finish */
1984 /* Add FLAGS to the GIMPLE_TRANSACTION subcode for the transaction region
1985 represented by STATE. */
1987 static inline void
1988 transaction_subcode_ior (struct tm_region *region, unsigned flags)
1990 if (region && region->transaction_stmt)
1992 flags |= gimple_transaction_subcode (region->transaction_stmt);
1993 gimple_transaction_set_subcode (region->transaction_stmt, flags);
1997 /* Construct a memory load in a transactional context. Return the
1998 gimple statement performing the load, or NULL if there is no
1999 TM_LOAD builtin of the appropriate size to do the load.
2001 LOC is the location to use for the new statement(s). */
2003 static gimple
2004 build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2006 enum built_in_function code = END_BUILTINS;
2007 tree t, type = TREE_TYPE (rhs), decl;
2008 gimple gcall;
2010 if (type == float_type_node)
2011 code = BUILT_IN_TM_LOAD_FLOAT;
2012 else if (type == double_type_node)
2013 code = BUILT_IN_TM_LOAD_DOUBLE;
2014 else if (type == long_double_type_node)
2015 code = BUILT_IN_TM_LOAD_LDOUBLE;
2016 else if (TYPE_SIZE_UNIT (type) != NULL
2017 && host_integerp (TYPE_SIZE_UNIT (type), 1))
2019 switch (tree_low_cst (TYPE_SIZE_UNIT (type), 1))
2021 case 1:
2022 code = BUILT_IN_TM_LOAD_1;
2023 break;
2024 case 2:
2025 code = BUILT_IN_TM_LOAD_2;
2026 break;
2027 case 4:
2028 code = BUILT_IN_TM_LOAD_4;
2029 break;
2030 case 8:
2031 code = BUILT_IN_TM_LOAD_8;
2032 break;
2036 if (code == END_BUILTINS)
2038 decl = targetm.vectorize.builtin_tm_load (type);
2039 if (!decl)
2040 return NULL;
2042 else
2043 decl = builtin_decl_explicit (code);
2045 t = gimplify_addr (gsi, rhs);
2046 gcall = gimple_build_call (decl, 1, t);
2047 gimple_set_location (gcall, loc);
2049 t = TREE_TYPE (TREE_TYPE (decl));
2050 if (useless_type_conversion_p (type, t))
2052 gimple_call_set_lhs (gcall, lhs);
2053 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2055 else
2057 gimple g;
2058 tree temp;
2060 temp = make_rename_temp (t, NULL);
2061 gimple_call_set_lhs (gcall, temp);
2062 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2064 t = fold_build1 (VIEW_CONVERT_EXPR, type, temp);
2065 g = gimple_build_assign (lhs, t);
2066 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2069 return gcall;
2073 /* Similarly for storing TYPE in a transactional context. */
2075 static gimple
2076 build_tm_store (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2078 enum built_in_function code = END_BUILTINS;
2079 tree t, fn, type = TREE_TYPE (rhs), simple_type;
2080 gimple gcall;
2082 if (type == float_type_node)
2083 code = BUILT_IN_TM_STORE_FLOAT;
2084 else if (type == double_type_node)
2085 code = BUILT_IN_TM_STORE_DOUBLE;
2086 else if (type == long_double_type_node)
2087 code = BUILT_IN_TM_STORE_LDOUBLE;
2088 else if (TYPE_SIZE_UNIT (type) != NULL
2089 && host_integerp (TYPE_SIZE_UNIT (type), 1))
2091 switch (tree_low_cst (TYPE_SIZE_UNIT (type), 1))
2093 case 1:
2094 code = BUILT_IN_TM_STORE_1;
2095 break;
2096 case 2:
2097 code = BUILT_IN_TM_STORE_2;
2098 break;
2099 case 4:
2100 code = BUILT_IN_TM_STORE_4;
2101 break;
2102 case 8:
2103 code = BUILT_IN_TM_STORE_8;
2104 break;
2108 if (code == END_BUILTINS)
2110 fn = targetm.vectorize.builtin_tm_store (type);
2111 if (!fn)
2112 return NULL;
2114 else
2115 fn = builtin_decl_explicit (code);
2117 simple_type = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))));
2119 if (TREE_CODE (rhs) == CONSTRUCTOR)
2121 /* Handle the easy initialization to zero. */
2122 if (CONSTRUCTOR_ELTS (rhs) == 0)
2123 rhs = build_int_cst (simple_type, 0);
2124 else
2126 /* ...otherwise punt to the caller and probably use
2127 BUILT_IN_TM_MEMMOVE, because we can't wrap a
2128 VIEW_CONVERT_EXPR around a CONSTRUCTOR (below) and produce
2129 valid gimple. */
2130 return NULL;
2133 else if (!useless_type_conversion_p (simple_type, type))
2135 gimple g;
2136 tree temp;
2138 temp = make_rename_temp (simple_type, NULL);
2139 t = fold_build1 (VIEW_CONVERT_EXPR, simple_type, rhs);
2140 g = gimple_build_assign (temp, t);
2141 gimple_set_location (g, loc);
2142 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2144 rhs = temp;
2147 t = gimplify_addr (gsi, lhs);
2148 gcall = gimple_build_call (fn, 2, t, rhs);
2149 gimple_set_location (gcall, loc);
2150 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2152 return gcall;
2156 /* Expand an assignment statement into transactional builtins. */
2158 static void
2159 expand_assign_tm (struct tm_region *region, gimple_stmt_iterator *gsi)
2161 gimple stmt = gsi_stmt (*gsi);
2162 location_t loc = gimple_location (stmt);
2163 tree lhs = gimple_assign_lhs (stmt);
2164 tree rhs = gimple_assign_rhs1 (stmt);
2165 bool store_p = requires_barrier (region->entry_block, lhs, NULL);
2166 bool load_p = requires_barrier (region->entry_block, rhs, NULL);
2167 gimple gcall = NULL;
2169 if (!load_p && !store_p)
2171 /* Add thread private addresses to log if applicable. */
2172 requires_barrier (region->entry_block, lhs, stmt);
2173 gsi_next (gsi);
2174 return;
2177 gsi_remove (gsi, true);
2179 if (load_p && !store_p)
2181 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2182 gcall = build_tm_load (loc, lhs, rhs, gsi);
2184 else if (store_p && !load_p)
2186 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2187 gcall = build_tm_store (loc, lhs, rhs, gsi);
2189 if (!gcall)
2191 tree lhs_addr, rhs_addr, tmp;
2193 if (load_p)
2194 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2195 if (store_p)
2196 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2198 /* ??? Figure out if there's any possible overlap between the LHS
2199 and the RHS and if not, use MEMCPY. */
2201 if (load_p && is_gimple_reg (lhs))
2203 tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
2204 lhs_addr = build_fold_addr_expr (tmp);
2206 else
2208 tmp = NULL_TREE;
2209 lhs_addr = gimplify_addr (gsi, lhs);
2211 rhs_addr = gimplify_addr (gsi, rhs);
2212 gcall = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_MEMMOVE),
2213 3, lhs_addr, rhs_addr,
2214 TYPE_SIZE_UNIT (TREE_TYPE (lhs)));
2215 gimple_set_location (gcall, loc);
2216 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2218 if (tmp)
2220 gcall = gimple_build_assign (lhs, tmp);
2221 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2225 /* Now that we have the load/store in its instrumented form, add
2226 thread private addresses to the log if applicable. */
2227 if (!store_p)
2228 requires_barrier (region->entry_block, lhs, gcall);
2230 /* add_stmt_to_tm_region (region, gcall); */
2234 /* Expand a call statement as appropriate for a transaction. That is,
2235 either verify that the call does not affect the transaction, or
2236 redirect the call to a clone that handles transactions, or change
2237 the transaction state to IRREVOCABLE. Return true if the call is
2238 one of the builtins that end a transaction. */
2240 static bool
2241 expand_call_tm (struct tm_region *region,
2242 gimple_stmt_iterator *gsi)
2244 gimple stmt = gsi_stmt (*gsi);
2245 tree lhs = gimple_call_lhs (stmt);
2246 tree fn_decl;
2247 struct cgraph_node *node;
2248 bool retval = false;
2250 fn_decl = gimple_call_fndecl (stmt);
2252 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMCPY)
2253 || fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMMOVE))
2254 transaction_subcode_ior (region, GTMA_HAVE_STORE | GTMA_HAVE_LOAD);
2255 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMSET))
2256 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2258 if (is_tm_pure_call (stmt))
2259 return false;
2261 if (fn_decl)
2262 retval = is_tm_ending_fndecl (fn_decl);
2263 if (!retval)
2265 /* Assume all non-const/pure calls write to memory, except
2266 transaction ending builtins. */
2267 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2270 /* For indirect calls, we already generated a call into the runtime. */
2271 if (!fn_decl)
2273 tree fn = gimple_call_fn (stmt);
2275 /* We are guaranteed never to go irrevocable on a safe or pure
2276 call, and the pure call was handled above. */
2277 if (is_tm_safe (fn))
2278 return false;
2279 else
2280 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2282 return false;
2285 node = cgraph_get_node (fn_decl);
2286 /* All calls should have cgraph here. */
2287 gcc_assert (node);
2288 if (node->local.tm_may_enter_irr)
2289 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2291 if (is_tm_abort (fn_decl))
2293 transaction_subcode_ior (region, GTMA_HAVE_ABORT);
2294 return true;
2297 /* Instrument the store if needed.
2299 If the assignment happens inside the function call (return slot
2300 optimization), there is no instrumentation to be done, since
2301 the callee should have done the right thing. */
2302 if (lhs && requires_barrier (region->entry_block, lhs, stmt)
2303 && !gimple_call_return_slot_opt_p (stmt))
2305 tree tmp = make_rename_temp (TREE_TYPE (lhs), NULL);
2306 location_t loc = gimple_location (stmt);
2307 edge fallthru_edge = NULL;
2309 /* Remember if the call was going to throw. */
2310 if (stmt_can_throw_internal (stmt))
2312 edge_iterator ei;
2313 edge e;
2314 basic_block bb = gimple_bb (stmt);
2316 FOR_EACH_EDGE (e, ei, bb->succs)
2317 if (e->flags & EDGE_FALLTHRU)
2319 fallthru_edge = e;
2320 break;
2324 gimple_call_set_lhs (stmt, tmp);
2325 update_stmt (stmt);
2326 stmt = gimple_build_assign (lhs, tmp);
2327 gimple_set_location (stmt, loc);
2329 /* We cannot throw in the middle of a BB. If the call was going
2330 to throw, place the instrumentation on the fallthru edge, so
2331 the call remains the last statement in the block. */
2332 if (fallthru_edge)
2334 gimple_seq fallthru_seq = gimple_seq_alloc_with_stmt (stmt);
2335 gimple_stmt_iterator fallthru_gsi = gsi_start (fallthru_seq);
2336 expand_assign_tm (region, &fallthru_gsi);
2337 gsi_insert_seq_on_edge (fallthru_edge, fallthru_seq);
2338 pending_edge_inserts_p = true;
2340 else
2342 gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
2343 expand_assign_tm (region, gsi);
2346 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2349 return retval;
2353 /* Expand all statements in BB as appropriate for being inside
2354 a transaction. */
2356 static void
2357 expand_block_tm (struct tm_region *region, basic_block bb)
2359 gimple_stmt_iterator gsi;
2361 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2363 gimple stmt = gsi_stmt (gsi);
2364 switch (gimple_code (stmt))
2366 case GIMPLE_ASSIGN:
2367 /* Only memory reads/writes need to be instrumented. */
2368 if (gimple_assign_single_p (stmt)
2369 && !gimple_clobber_p (stmt))
2371 expand_assign_tm (region, &gsi);
2372 continue;
2374 break;
2376 case GIMPLE_CALL:
2377 if (expand_call_tm (region, &gsi))
2378 return;
2379 break;
2381 case GIMPLE_ASM:
2382 gcc_unreachable ();
2384 default:
2385 break;
2387 if (!gsi_end_p (gsi))
2388 gsi_next (&gsi);
2392 /* Return the list of basic-blocks in REGION.
2394 STOP_AT_IRREVOCABLE_P is true if caller is uninterested in blocks
2395 following a TM_IRREVOCABLE call. */
2397 static VEC (basic_block, heap) *
2398 get_tm_region_blocks (basic_block entry_block,
2399 bitmap exit_blocks,
2400 bitmap irr_blocks,
2401 bitmap all_region_blocks,
2402 bool stop_at_irrevocable_p)
2404 VEC(basic_block, heap) *bbs = NULL;
2405 unsigned i;
2406 edge e;
2407 edge_iterator ei;
2408 bitmap visited_blocks = BITMAP_ALLOC (NULL);
2410 i = 0;
2411 VEC_safe_push (basic_block, heap, bbs, entry_block);
2412 bitmap_set_bit (visited_blocks, entry_block->index);
2416 basic_block bb = VEC_index (basic_block, bbs, i++);
2418 if (exit_blocks &&
2419 bitmap_bit_p (exit_blocks, bb->index))
2420 continue;
2422 if (stop_at_irrevocable_p
2423 && irr_blocks
2424 && bitmap_bit_p (irr_blocks, bb->index))
2425 continue;
2427 FOR_EACH_EDGE (e, ei, bb->succs)
2428 if (!bitmap_bit_p (visited_blocks, e->dest->index))
2430 bitmap_set_bit (visited_blocks, e->dest->index);
2431 VEC_safe_push (basic_block, heap, bbs, e->dest);
2434 while (i < VEC_length (basic_block, bbs));
2436 if (all_region_blocks)
2437 bitmap_ior_into (all_region_blocks, visited_blocks);
2439 BITMAP_FREE (visited_blocks);
2440 return bbs;
2443 /* Set the IN_TRANSACTION for all gimple statements that appear in a
2444 transaction. */
2446 void
2447 compute_transaction_bits (void)
2449 struct tm_region *region;
2450 VEC (basic_block, heap) *queue;
2451 unsigned int i;
2452 gimple_stmt_iterator gsi;
2453 basic_block bb;
2455 /* ?? Perhaps we need to abstract gate_tm_init further, because we
2456 certainly don't need it to calculate CDI_DOMINATOR info. */
2457 gate_tm_init ();
2459 for (region = all_tm_regions; region; region = region->next)
2461 queue = get_tm_region_blocks (region->entry_block,
2462 region->exit_blocks,
2463 region->irr_blocks,
2464 NULL,
2465 /*stop_at_irr_p=*/true);
2466 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2467 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2469 gimple stmt = gsi_stmt (gsi);
2470 gimple_set_in_transaction (stmt, true);
2472 VEC_free (basic_block, heap, queue);
2475 if (all_tm_regions)
2476 bitmap_obstack_release (&tm_obstack);
2479 /* Entry point to the MARK phase of TM expansion. Here we replace
2480 transactional memory statements with calls to builtins, and function
2481 calls with their transactional clones (if available). But we don't
2482 yet lower GIMPLE_TRANSACTION or add the transaction restart back-edges. */
2484 static unsigned int
2485 execute_tm_mark (void)
2487 struct tm_region *region;
2488 basic_block bb;
2489 VEC (basic_block, heap) *queue;
2490 size_t i;
2492 queue = VEC_alloc (basic_block, heap, 10);
2493 pending_edge_inserts_p = false;
2495 for (region = all_tm_regions; region ; region = region->next)
2497 tm_log_init ();
2498 /* If we have a transaction... */
2499 if (region->exit_blocks)
2501 unsigned int subcode
2502 = gimple_transaction_subcode (region->transaction_stmt);
2504 /* Collect a new SUBCODE set, now that optimizations are done... */
2505 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2506 subcode &= (GTMA_DECLARATION_MASK | GTMA_DOES_GO_IRREVOCABLE
2507 | GTMA_MAY_ENTER_IRREVOCABLE);
2508 else
2509 subcode &= GTMA_DECLARATION_MASK;
2510 gimple_transaction_set_subcode (region->transaction_stmt, subcode);
2513 queue = get_tm_region_blocks (region->entry_block,
2514 region->exit_blocks,
2515 region->irr_blocks,
2516 NULL,
2517 /*stop_at_irr_p=*/true);
2518 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2519 expand_block_tm (region, bb);
2520 VEC_free (basic_block, heap, queue);
2522 tm_log_emit ();
2525 if (pending_edge_inserts_p)
2526 gsi_commit_edge_inserts ();
2527 return 0;
2530 struct gimple_opt_pass pass_tm_mark =
2533 GIMPLE_PASS,
2534 "tmmark", /* name */
2535 NULL, /* gate */
2536 execute_tm_mark, /* execute */
2537 NULL, /* sub */
2538 NULL, /* next */
2539 0, /* static_pass_number */
2540 TV_TRANS_MEM, /* tv_id */
2541 PROP_ssa | PROP_cfg, /* properties_required */
2542 0, /* properties_provided */
2543 0, /* properties_destroyed */
2544 0, /* todo_flags_start */
2545 TODO_update_ssa
2546 | TODO_verify_ssa, /* todo_flags_finish */
2550 /* Create an abnormal call edge from BB to the first block of the region
2551 represented by STATE. Also record the edge in the TM_RESTART map. */
2553 static inline void
2554 make_tm_edge (gimple stmt, basic_block bb, struct tm_region *region)
2556 void **slot;
2557 struct tm_restart_node *n, dummy;
2559 if (cfun->gimple_df->tm_restart == NULL)
2560 cfun->gimple_df->tm_restart = htab_create_ggc (31, struct_ptr_hash,
2561 struct_ptr_eq, ggc_free);
2563 dummy.stmt = stmt;
2564 dummy.label_or_list = gimple_block_label (region->entry_block);
2565 slot = htab_find_slot (cfun->gimple_df->tm_restart, &dummy, INSERT);
2566 n = (struct tm_restart_node *) *slot;
2567 if (n == NULL)
2569 n = ggc_alloc_tm_restart_node ();
2570 *n = dummy;
2572 else
2574 tree old = n->label_or_list;
2575 if (TREE_CODE (old) == LABEL_DECL)
2576 old = tree_cons (NULL, old, NULL);
2577 n->label_or_list = tree_cons (NULL, dummy.label_or_list, old);
2580 make_edge (bb, region->entry_block, EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
2584 /* Split block BB as necessary for every builtin function we added, and
2585 wire up the abnormal back edges implied by the transaction restart. */
2587 static void
2588 expand_block_edges (struct tm_region *region, basic_block bb)
2590 gimple_stmt_iterator gsi;
2592 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2594 gimple stmt = gsi_stmt (gsi);
2596 /* ??? TM_COMMIT (and any other tm builtin function) in a nested
2597 transaction has an abnormal edge back to the outer-most transaction
2598 (there are no nested retries), while a TM_ABORT also has an abnormal
2599 backedge to the inner-most transaction. We haven't actually saved
2600 the inner-most transaction here. We should be able to get to it
2601 via the region_nr saved on STMT, and read the transaction_stmt from
2602 that, and find the first region block from there. */
2603 /* ??? Shouldn't we split for any non-pure, non-irrevocable function? */
2604 if (gimple_code (stmt) == GIMPLE_CALL
2605 && (gimple_call_flags (stmt) & ECF_TM_BUILTIN) != 0)
2607 if (gsi_one_before_end_p (gsi))
2608 make_tm_edge (stmt, bb, region);
2609 else
2611 edge e = split_block (bb, stmt);
2612 make_tm_edge (stmt, bb, region);
2613 bb = e->dest;
2614 gsi = gsi_start_bb (bb);
2617 /* Delete any tail-call annotation that may have been added.
2618 The tail-call pass may have mis-identified the commit as being
2619 a candidate because we had not yet added this restart edge. */
2620 gimple_call_set_tail (stmt, false);
2623 gsi_next (&gsi);
2627 /* Expand the GIMPLE_TRANSACTION statement into the STM library call. */
2629 static void
2630 expand_transaction (struct tm_region *region)
2632 tree status, tm_start;
2633 basic_block atomic_bb, slice_bb;
2634 gimple_stmt_iterator gsi;
2635 tree t1, t2;
2636 gimple g;
2637 int flags, subcode;
2639 tm_start = builtin_decl_explicit (BUILT_IN_TM_START);
2640 status = make_rename_temp (TREE_TYPE (TREE_TYPE (tm_start)), "tm_state");
2642 /* ??? There are plenty of bits here we're not computing. */
2643 subcode = gimple_transaction_subcode (region->transaction_stmt);
2644 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2645 flags = PR_DOESGOIRREVOCABLE | PR_UNINSTRUMENTEDCODE;
2646 else
2647 flags = PR_INSTRUMENTEDCODE;
2648 if ((subcode & GTMA_MAY_ENTER_IRREVOCABLE) == 0)
2649 flags |= PR_HASNOIRREVOCABLE;
2650 /* If the transaction does not have an abort in lexical scope and is not
2651 marked as an outer transaction, then it will never abort. */
2652 if ((subcode & GTMA_HAVE_ABORT) == 0
2653 && (subcode & GTMA_IS_OUTER) == 0)
2654 flags |= PR_HASNOABORT;
2655 if ((subcode & GTMA_HAVE_STORE) == 0)
2656 flags |= PR_READONLY;
2657 t2 = build_int_cst (TREE_TYPE (status), flags);
2658 g = gimple_build_call (tm_start, 1, t2);
2659 gimple_call_set_lhs (g, status);
2660 gimple_set_location (g, gimple_location (region->transaction_stmt));
2662 atomic_bb = gimple_bb (region->transaction_stmt);
2664 if (!VEC_empty (tree, tm_log_save_addresses))
2665 tm_log_emit_saves (region->entry_block, atomic_bb);
2667 gsi = gsi_last_bb (atomic_bb);
2668 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2669 gsi_remove (&gsi, true);
2671 if (!VEC_empty (tree, tm_log_save_addresses))
2672 region->entry_block =
2673 tm_log_emit_save_or_restores (region->entry_block,
2674 A_RESTORELIVEVARIABLES,
2675 status,
2676 tm_log_emit_restores,
2677 atomic_bb,
2678 FALLTHRU_EDGE (atomic_bb),
2679 &slice_bb);
2680 else
2681 slice_bb = atomic_bb;
2683 /* If we have an ABORT statement, create a test following the start
2684 call to perform the abort. */
2685 if (gimple_transaction_label (region->transaction_stmt))
2687 edge e;
2688 basic_block test_bb;
2690 test_bb = create_empty_bb (slice_bb);
2691 if (current_loops && slice_bb->loop_father)
2692 add_bb_to_loop (test_bb, slice_bb->loop_father);
2693 if (VEC_empty (tree, tm_log_save_addresses))
2694 region->entry_block = test_bb;
2695 gsi = gsi_last_bb (test_bb);
2697 t1 = make_rename_temp (TREE_TYPE (status), NULL);
2698 t2 = build_int_cst (TREE_TYPE (status), A_ABORTTRANSACTION);
2699 g = gimple_build_assign_with_ops (BIT_AND_EXPR, t1, status, t2);
2700 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
2702 t2 = build_int_cst (TREE_TYPE (status), 0);
2703 g = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
2704 gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
2706 e = FALLTHRU_EDGE (slice_bb);
2707 redirect_edge_pred (e, test_bb);
2708 e->flags = EDGE_FALSE_VALUE;
2709 e->probability = PROB_ALWAYS - PROB_VERY_UNLIKELY;
2711 e = BRANCH_EDGE (atomic_bb);
2712 redirect_edge_pred (e, test_bb);
2713 e->flags = EDGE_TRUE_VALUE;
2714 e->probability = PROB_VERY_UNLIKELY;
2716 e = make_edge (slice_bb, test_bb, EDGE_FALLTHRU);
2719 /* If we've no abort, but we do have PHIs at the beginning of the atomic
2720 region, that means we've a loop at the beginning of the atomic region
2721 that shares the first block. This can cause problems with the abnormal
2722 edges we're about to add for the transaction restart. Solve this by
2723 adding a new empty block to receive the abnormal edges. */
2724 else if (phi_nodes (region->entry_block))
2726 edge e;
2727 basic_block empty_bb;
2729 region->entry_block = empty_bb = create_empty_bb (atomic_bb);
2730 if (current_loops && atomic_bb->loop_father)
2731 add_bb_to_loop (empty_bb, atomic_bb->loop_father);
2733 e = FALLTHRU_EDGE (atomic_bb);
2734 redirect_edge_pred (e, empty_bb);
2736 e = make_edge (atomic_bb, empty_bb, EDGE_FALLTHRU);
2739 /* The GIMPLE_TRANSACTION statement no longer exists. */
2740 region->transaction_stmt = NULL;
2743 static void expand_regions (struct tm_region *);
2745 /* Helper function for expand_regions. Expand REGION and recurse to
2746 the inner region. */
2748 static void
2749 expand_regions_1 (struct tm_region *region)
2751 if (region->exit_blocks)
2753 unsigned int i;
2754 basic_block bb;
2755 VEC (basic_block, heap) *queue;
2757 /* Collect the set of blocks in this region. Do this before
2758 splitting edges, so that we don't have to play with the
2759 dominator tree in the middle. */
2760 queue = get_tm_region_blocks (region->entry_block,
2761 region->exit_blocks,
2762 region->irr_blocks,
2763 NULL,
2764 /*stop_at_irr_p=*/false);
2765 expand_transaction (region);
2766 for (i = 0; VEC_iterate (basic_block, queue, i, bb); ++i)
2767 expand_block_edges (region, bb);
2768 VEC_free (basic_block, heap, queue);
2770 if (region->inner)
2771 expand_regions (region->inner);
2774 /* Expand regions starting at REGION. */
2776 static void
2777 expand_regions (struct tm_region *region)
2779 while (region)
2781 expand_regions_1 (region);
2782 region = region->next;
2786 /* Entry point to the final expansion of transactional nodes. */
2788 static unsigned int
2789 execute_tm_edges (void)
2791 expand_regions (all_tm_regions);
2792 tm_log_delete ();
2794 /* We've got to release the dominance info now, to indicate that it
2795 must be rebuilt completely. Otherwise we'll crash trying to update
2796 the SSA web in the TODO section following this pass. */
2797 free_dominance_info (CDI_DOMINATORS);
2798 bitmap_obstack_release (&tm_obstack);
2799 all_tm_regions = NULL;
2801 return 0;
2804 struct gimple_opt_pass pass_tm_edges =
2807 GIMPLE_PASS,
2808 "tmedge", /* name */
2809 NULL, /* gate */
2810 execute_tm_edges, /* execute */
2811 NULL, /* sub */
2812 NULL, /* next */
2813 0, /* static_pass_number */
2814 TV_TRANS_MEM, /* tv_id */
2815 PROP_ssa | PROP_cfg, /* properties_required */
2816 0, /* properties_provided */
2817 0, /* properties_destroyed */
2818 0, /* todo_flags_start */
2819 TODO_update_ssa
2820 | TODO_verify_ssa, /* todo_flags_finish */
2824 /* A unique TM memory operation. */
2825 typedef struct tm_memop
2827 /* Unique ID that all memory operations to the same location have. */
2828 unsigned int value_id;
2829 /* Address of load/store. */
2830 tree addr;
2831 } *tm_memop_t;
2833 /* Sets for solving data flow equations in the memory optimization pass. */
2834 struct tm_memopt_bitmaps
2836 /* Stores available to this BB upon entry. Basically, stores that
2837 dominate this BB. */
2838 bitmap store_avail_in;
2839 /* Stores available at the end of this BB. */
2840 bitmap store_avail_out;
2841 bitmap store_antic_in;
2842 bitmap store_antic_out;
2843 /* Reads available to this BB upon entry. Basically, reads that
2844 dominate this BB. */
2845 bitmap read_avail_in;
2846 /* Reads available at the end of this BB. */
2847 bitmap read_avail_out;
2848 /* Reads performed in this BB. */
2849 bitmap read_local;
2850 /* Writes performed in this BB. */
2851 bitmap store_local;
2853 /* Temporary storage for pass. */
2854 /* Is the current BB in the worklist? */
2855 bool avail_in_worklist_p;
2856 /* Have we visited this BB? */
2857 bool visited_p;
2860 static bitmap_obstack tm_memopt_obstack;
2862 /* Unique counter for TM loads and stores. Loads and stores of the
2863 same address get the same ID. */
2864 static unsigned int tm_memopt_value_id;
2865 static htab_t tm_memopt_value_numbers;
2867 #define STORE_AVAIL_IN(BB) \
2868 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in
2869 #define STORE_AVAIL_OUT(BB) \
2870 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_out
2871 #define STORE_ANTIC_IN(BB) \
2872 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_in
2873 #define STORE_ANTIC_OUT(BB) \
2874 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_out
2875 #define READ_AVAIL_IN(BB) \
2876 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_in
2877 #define READ_AVAIL_OUT(BB) \
2878 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_out
2879 #define READ_LOCAL(BB) \
2880 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_local
2881 #define STORE_LOCAL(BB) \
2882 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_local
2883 #define AVAIL_IN_WORKLIST_P(BB) \
2884 ((struct tm_memopt_bitmaps *) ((BB)->aux))->avail_in_worklist_p
2885 #define BB_VISITED_P(BB) \
2886 ((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p
2888 /* Htab support. Return a hash value for a `tm_memop'. */
2889 static hashval_t
2890 tm_memop_hash (const void *p)
2892 const struct tm_memop *mem = (const struct tm_memop *) p;
2893 tree addr = mem->addr;
2894 /* We drill down to the SSA_NAME/DECL for the hash, but equality is
2895 actually done with operand_equal_p (see tm_memop_eq). */
2896 if (TREE_CODE (addr) == ADDR_EXPR)
2897 addr = TREE_OPERAND (addr, 0);
2898 return iterative_hash_expr (addr, 0);
2901 /* Htab support. Return true if two tm_memop's are the same. */
2902 static int
2903 tm_memop_eq (const void *p1, const void *p2)
2905 const struct tm_memop *mem1 = (const struct tm_memop *) p1;
2906 const struct tm_memop *mem2 = (const struct tm_memop *) p2;
2908 return operand_equal_p (mem1->addr, mem2->addr, 0);
2911 /* Given a TM load/store in STMT, return the value number for the address
2912 it accesses. */
2914 static unsigned int
2915 tm_memopt_value_number (gimple stmt, enum insert_option op)
2917 struct tm_memop tmpmem, *mem;
2918 void **slot;
2920 gcc_assert (is_tm_load (stmt) || is_tm_store (stmt));
2921 tmpmem.addr = gimple_call_arg (stmt, 0);
2922 slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op);
2923 if (*slot)
2924 mem = (struct tm_memop *) *slot;
2925 else if (op == INSERT)
2927 mem = XNEW (struct tm_memop);
2928 *slot = mem;
2929 mem->value_id = tm_memopt_value_id++;
2930 mem->addr = tmpmem.addr;
2932 else
2933 gcc_unreachable ();
2934 return mem->value_id;
2937 /* Accumulate TM memory operations in BB into STORE_LOCAL and READ_LOCAL. */
2939 static void
2940 tm_memopt_accumulate_memops (basic_block bb)
2942 gimple_stmt_iterator gsi;
2944 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2946 gimple stmt = gsi_stmt (gsi);
2947 bitmap bits;
2948 unsigned int loc;
2950 if (is_tm_store (stmt))
2951 bits = STORE_LOCAL (bb);
2952 else if (is_tm_load (stmt))
2953 bits = READ_LOCAL (bb);
2954 else
2955 continue;
2957 loc = tm_memopt_value_number (stmt, INSERT);
2958 bitmap_set_bit (bits, loc);
2959 if (dump_file)
2961 fprintf (dump_file, "TM memopt (%s): value num=%d, BB=%d, addr=",
2962 is_tm_load (stmt) ? "LOAD" : "STORE", loc,
2963 gimple_bb (stmt)->index);
2964 print_generic_expr (dump_file, gimple_call_arg (stmt, 0), 0);
2965 fprintf (dump_file, "\n");
2970 /* Prettily dump one of the memopt sets. BITS is the bitmap to dump. */
2972 static void
2973 dump_tm_memopt_set (const char *set_name, bitmap bits)
2975 unsigned i;
2976 bitmap_iterator bi;
2977 const char *comma = "";
2979 fprintf (dump_file, "TM memopt: %s: [", set_name);
2980 EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
2982 htab_iterator hi;
2983 struct tm_memop *mem;
2985 /* Yeah, yeah, yeah. Whatever. This is just for debugging. */
2986 FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
2987 if (mem->value_id == i)
2988 break;
2989 gcc_assert (mem->value_id == i);
2990 fprintf (dump_file, "%s", comma);
2991 comma = ", ";
2992 print_generic_expr (dump_file, mem->addr, 0);
2994 fprintf (dump_file, "]\n");
2997 /* Prettily dump all of the memopt sets in BLOCKS. */
2999 static void
3000 dump_tm_memopt_sets (VEC (basic_block, heap) *blocks)
3002 size_t i;
3003 basic_block bb;
3005 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3007 fprintf (dump_file, "------------BB %d---------\n", bb->index);
3008 dump_tm_memopt_set ("STORE_LOCAL", STORE_LOCAL (bb));
3009 dump_tm_memopt_set ("READ_LOCAL", READ_LOCAL (bb));
3010 dump_tm_memopt_set ("STORE_AVAIL_IN", STORE_AVAIL_IN (bb));
3011 dump_tm_memopt_set ("STORE_AVAIL_OUT", STORE_AVAIL_OUT (bb));
3012 dump_tm_memopt_set ("READ_AVAIL_IN", READ_AVAIL_IN (bb));
3013 dump_tm_memopt_set ("READ_AVAIL_OUT", READ_AVAIL_OUT (bb));
3017 /* Compute {STORE,READ}_AVAIL_IN for the basic block BB. */
3019 static void
3020 tm_memopt_compute_avin (basic_block bb)
3022 edge e;
3023 unsigned ix;
3025 /* Seed with the AVOUT of any predecessor. */
3026 for (ix = 0; ix < EDGE_COUNT (bb->preds); ix++)
3028 e = EDGE_PRED (bb, ix);
3029 /* Make sure we have already visited this BB, and is thus
3030 initialized.
3032 If e->src->aux is NULL, this predecessor is actually on an
3033 enclosing transaction. We only care about the current
3034 transaction, so ignore it. */
3035 if (e->src->aux && BB_VISITED_P (e->src))
3037 bitmap_copy (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3038 bitmap_copy (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3039 break;
3043 for (; ix < EDGE_COUNT (bb->preds); ix++)
3045 e = EDGE_PRED (bb, ix);
3046 if (e->src->aux && BB_VISITED_P (e->src))
3048 bitmap_and_into (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3049 bitmap_and_into (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3053 BB_VISITED_P (bb) = true;
3056 /* Compute the STORE_ANTIC_IN for the basic block BB. */
3058 static void
3059 tm_memopt_compute_antin (basic_block bb)
3061 edge e;
3062 unsigned ix;
3064 /* Seed with the ANTIC_OUT of any successor. */
3065 for (ix = 0; ix < EDGE_COUNT (bb->succs); ix++)
3067 e = EDGE_SUCC (bb, ix);
3068 /* Make sure we have already visited this BB, and is thus
3069 initialized. */
3070 if (BB_VISITED_P (e->dest))
3072 bitmap_copy (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3073 break;
3077 for (; ix < EDGE_COUNT (bb->succs); ix++)
3079 e = EDGE_SUCC (bb, ix);
3080 if (BB_VISITED_P (e->dest))
3081 bitmap_and_into (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3084 BB_VISITED_P (bb) = true;
3087 /* Compute the AVAIL sets for every basic block in BLOCKS.
3089 We compute {STORE,READ}_AVAIL_{OUT,IN} as follows:
3091 AVAIL_OUT[bb] = union (AVAIL_IN[bb], LOCAL[bb])
3092 AVAIL_IN[bb] = intersect (AVAIL_OUT[predecessors])
3094 This is basically what we do in lcm's compute_available(), but here
3095 we calculate two sets of sets (one for STOREs and one for READs),
3096 and we work on a region instead of the entire CFG.
3098 REGION is the TM region.
3099 BLOCKS are the basic blocks in the region. */
3101 static void
3102 tm_memopt_compute_available (struct tm_region *region,
3103 VEC (basic_block, heap) *blocks)
3105 edge e;
3106 basic_block *worklist, *qin, *qout, *qend, bb;
3107 unsigned int qlen, i;
3108 edge_iterator ei;
3109 bool changed;
3111 /* Allocate a worklist array/queue. Entries are only added to the
3112 list if they were not already on the list. So the size is
3113 bounded by the number of basic blocks in the region. */
3114 qlen = VEC_length (basic_block, blocks) - 1;
3115 qin = qout = worklist =
3116 XNEWVEC (basic_block, qlen);
3118 /* Put every block in the region on the worklist. */
3119 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3121 /* Seed AVAIL_OUT with the LOCAL set. */
3122 bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_LOCAL (bb));
3123 bitmap_ior_into (READ_AVAIL_OUT (bb), READ_LOCAL (bb));
3125 AVAIL_IN_WORKLIST_P (bb) = true;
3126 /* No need to insert the entry block, since it has an AVIN of
3127 null, and an AVOUT that has already been seeded in. */
3128 if (bb != region->entry_block)
3129 *qin++ = bb;
3132 /* The entry block has been initialized with the local sets. */
3133 BB_VISITED_P (region->entry_block) = true;
3135 qin = worklist;
3136 qend = &worklist[qlen];
3138 /* Iterate until the worklist is empty. */
3139 while (qlen)
3141 /* Take the first entry off the worklist. */
3142 bb = *qout++;
3143 qlen--;
3145 if (qout >= qend)
3146 qout = worklist;
3148 /* This block can be added to the worklist again if necessary. */
3149 AVAIL_IN_WORKLIST_P (bb) = false;
3150 tm_memopt_compute_avin (bb);
3152 /* Note: We do not add the LOCAL sets here because we already
3153 seeded the AVAIL_OUT sets with them. */
3154 changed = bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_AVAIL_IN (bb));
3155 changed |= bitmap_ior_into (READ_AVAIL_OUT (bb), READ_AVAIL_IN (bb));
3156 if (changed
3157 && (region->exit_blocks == NULL
3158 || !bitmap_bit_p (region->exit_blocks, bb->index)))
3159 /* If the out state of this block changed, then we need to add
3160 its successors to the worklist if they are not already in. */
3161 FOR_EACH_EDGE (e, ei, bb->succs)
3162 if (!AVAIL_IN_WORKLIST_P (e->dest) && e->dest != EXIT_BLOCK_PTR)
3164 *qin++ = e->dest;
3165 AVAIL_IN_WORKLIST_P (e->dest) = true;
3166 qlen++;
3168 if (qin >= qend)
3169 qin = worklist;
3173 free (worklist);
3175 if (dump_file)
3176 dump_tm_memopt_sets (blocks);
3179 /* Compute ANTIC sets for every basic block in BLOCKS.
3181 We compute STORE_ANTIC_OUT as follows:
3183 STORE_ANTIC_OUT[bb] = union(STORE_ANTIC_IN[bb], STORE_LOCAL[bb])
3184 STORE_ANTIC_IN[bb] = intersect(STORE_ANTIC_OUT[successors])
3186 REGION is the TM region.
3187 BLOCKS are the basic blocks in the region. */
3189 static void
3190 tm_memopt_compute_antic (struct tm_region *region,
3191 VEC (basic_block, heap) *blocks)
3193 edge e;
3194 basic_block *worklist, *qin, *qout, *qend, bb;
3195 unsigned int qlen;
3196 int i;
3197 edge_iterator ei;
3199 /* Allocate a worklist array/queue. Entries are only added to the
3200 list if they were not already on the list. So the size is
3201 bounded by the number of basic blocks in the region. */
3202 qin = qout = worklist =
3203 XNEWVEC (basic_block, VEC_length (basic_block, blocks));
3205 for (qlen = 0, i = VEC_length (basic_block, blocks) - 1; i >= 0; --i)
3207 bb = VEC_index (basic_block, blocks, i);
3209 /* Seed ANTIC_OUT with the LOCAL set. */
3210 bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_LOCAL (bb));
3212 /* Put every block in the region on the worklist. */
3213 AVAIL_IN_WORKLIST_P (bb) = true;
3214 /* No need to insert exit blocks, since their ANTIC_IN is NULL,
3215 and their ANTIC_OUT has already been seeded in. */
3216 if (region->exit_blocks
3217 && !bitmap_bit_p (region->exit_blocks, bb->index))
3219 qlen++;
3220 *qin++ = bb;
3224 /* The exit blocks have been initialized with the local sets. */
3225 if (region->exit_blocks)
3227 unsigned int i;
3228 bitmap_iterator bi;
3229 EXECUTE_IF_SET_IN_BITMAP (region->exit_blocks, 0, i, bi)
3230 BB_VISITED_P (BASIC_BLOCK (i)) = true;
3233 qin = worklist;
3234 qend = &worklist[qlen];
3236 /* Iterate until the worklist is empty. */
3237 while (qlen)
3239 /* Take the first entry off the worklist. */
3240 bb = *qout++;
3241 qlen--;
3243 if (qout >= qend)
3244 qout = worklist;
3246 /* This block can be added to the worklist again if necessary. */
3247 AVAIL_IN_WORKLIST_P (bb) = false;
3248 tm_memopt_compute_antin (bb);
3250 /* Note: We do not add the LOCAL sets here because we already
3251 seeded the ANTIC_OUT sets with them. */
3252 if (bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_ANTIC_IN (bb))
3253 && bb != region->entry_block)
3254 /* If the out state of this block changed, then we need to add
3255 its predecessors to the worklist if they are not already in. */
3256 FOR_EACH_EDGE (e, ei, bb->preds)
3257 if (!AVAIL_IN_WORKLIST_P (e->src))
3259 *qin++ = e->src;
3260 AVAIL_IN_WORKLIST_P (e->src) = true;
3261 qlen++;
3263 if (qin >= qend)
3264 qin = worklist;
3268 free (worklist);
3270 if (dump_file)
3271 dump_tm_memopt_sets (blocks);
3274 /* Offsets of load variants from TM_LOAD. For example,
3275 BUILT_IN_TM_LOAD_RAR* is an offset of 1 from BUILT_IN_TM_LOAD*.
3276 See gtm-builtins.def. */
3277 #define TRANSFORM_RAR 1
3278 #define TRANSFORM_RAW 2
3279 #define TRANSFORM_RFW 3
3280 /* Offsets of store variants from TM_STORE. */
3281 #define TRANSFORM_WAR 1
3282 #define TRANSFORM_WAW 2
3284 /* Inform about a load/store optimization. */
3286 static void
3287 dump_tm_memopt_transform (gimple stmt)
3289 if (dump_file)
3291 fprintf (dump_file, "TM memopt: transforming: ");
3292 print_gimple_stmt (dump_file, stmt, 0, 0);
3293 fprintf (dump_file, "\n");
3297 /* Perform a read/write optimization. Replaces the TM builtin in STMT
3298 by a builtin that is OFFSET entries down in the builtins table in
3299 gtm-builtins.def. */
3301 static void
3302 tm_memopt_transform_stmt (unsigned int offset,
3303 gimple stmt,
3304 gimple_stmt_iterator *gsi)
3306 tree fn = gimple_call_fn (stmt);
3307 gcc_assert (TREE_CODE (fn) == ADDR_EXPR);
3308 TREE_OPERAND (fn, 0)
3309 = builtin_decl_explicit ((enum built_in_function)
3310 (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0))
3311 + offset));
3312 gimple_call_set_fn (stmt, fn);
3313 gsi_replace (gsi, stmt, true);
3314 dump_tm_memopt_transform (stmt);
3317 /* Perform the actual TM memory optimization transformations in the
3318 basic blocks in BLOCKS. */
3320 static void
3321 tm_memopt_transform_blocks (VEC (basic_block, heap) *blocks)
3323 size_t i;
3324 basic_block bb;
3325 gimple_stmt_iterator gsi;
3327 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3329 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3331 gimple stmt = gsi_stmt (gsi);
3332 bitmap read_avail = READ_AVAIL_IN (bb);
3333 bitmap store_avail = STORE_AVAIL_IN (bb);
3334 bitmap store_antic = STORE_ANTIC_OUT (bb);
3335 unsigned int loc;
3337 if (is_tm_simple_load (stmt))
3339 loc = tm_memopt_value_number (stmt, NO_INSERT);
3340 if (store_avail && bitmap_bit_p (store_avail, loc))
3341 tm_memopt_transform_stmt (TRANSFORM_RAW, stmt, &gsi);
3342 else if (store_antic && bitmap_bit_p (store_antic, loc))
3344 tm_memopt_transform_stmt (TRANSFORM_RFW, stmt, &gsi);
3345 bitmap_set_bit (store_avail, loc);
3347 else if (read_avail && bitmap_bit_p (read_avail, loc))
3348 tm_memopt_transform_stmt (TRANSFORM_RAR, stmt, &gsi);
3349 else
3350 bitmap_set_bit (read_avail, loc);
3352 else if (is_tm_simple_store (stmt))
3354 loc = tm_memopt_value_number (stmt, NO_INSERT);
3355 if (store_avail && bitmap_bit_p (store_avail, loc))
3356 tm_memopt_transform_stmt (TRANSFORM_WAW, stmt, &gsi);
3357 else
3359 if (read_avail && bitmap_bit_p (read_avail, loc))
3360 tm_memopt_transform_stmt (TRANSFORM_WAR, stmt, &gsi);
3361 bitmap_set_bit (store_avail, loc);
3368 /* Return a new set of bitmaps for a BB. */
3370 static struct tm_memopt_bitmaps *
3371 tm_memopt_init_sets (void)
3373 struct tm_memopt_bitmaps *b
3374 = XOBNEW (&tm_memopt_obstack.obstack, struct tm_memopt_bitmaps);
3375 b->store_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3376 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3377 b->store_antic_in = BITMAP_ALLOC (&tm_memopt_obstack);
3378 b->store_antic_out = BITMAP_ALLOC (&tm_memopt_obstack);
3379 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3380 b->read_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3381 b->read_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3382 b->read_local = BITMAP_ALLOC (&tm_memopt_obstack);
3383 b->store_local = BITMAP_ALLOC (&tm_memopt_obstack);
3384 return b;
3387 /* Free sets computed for each BB. */
3389 static void
3390 tm_memopt_free_sets (VEC (basic_block, heap) *blocks)
3392 size_t i;
3393 basic_block bb;
3395 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3396 bb->aux = NULL;
3399 /* Clear the visited bit for every basic block in BLOCKS. */
3401 static void
3402 tm_memopt_clear_visited (VEC (basic_block, heap) *blocks)
3404 size_t i;
3405 basic_block bb;
3407 for (i = 0; VEC_iterate (basic_block, blocks, i, bb); ++i)
3408 BB_VISITED_P (bb) = false;
3411 /* Replace TM load/stores with hints for the runtime. We handle
3412 things like read-after-write, write-after-read, read-after-read,
3413 read-for-write, etc. */
3415 static unsigned int
3416 execute_tm_memopt (void)
3418 struct tm_region *region;
3419 VEC (basic_block, heap) *bbs;
3421 tm_memopt_value_id = 0;
3422 tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free);
3424 for (region = all_tm_regions; region; region = region->next)
3426 /* All the TM stores/loads in the current region. */
3427 size_t i;
3428 basic_block bb;
3430 bitmap_obstack_initialize (&tm_memopt_obstack);
3432 /* Save all BBs for the current region. */
3433 bbs = get_tm_region_blocks (region->entry_block,
3434 region->exit_blocks,
3435 region->irr_blocks,
3436 NULL,
3437 false);
3439 /* Collect all the memory operations. */
3440 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i)
3442 bb->aux = tm_memopt_init_sets ();
3443 tm_memopt_accumulate_memops (bb);
3446 /* Solve data flow equations and transform each block accordingly. */
3447 tm_memopt_clear_visited (bbs);
3448 tm_memopt_compute_available (region, bbs);
3449 tm_memopt_clear_visited (bbs);
3450 tm_memopt_compute_antic (region, bbs);
3451 tm_memopt_transform_blocks (bbs);
3453 tm_memopt_free_sets (bbs);
3454 VEC_free (basic_block, heap, bbs);
3455 bitmap_obstack_release (&tm_memopt_obstack);
3456 htab_empty (tm_memopt_value_numbers);
3459 htab_delete (tm_memopt_value_numbers);
3460 return 0;
3463 static bool
3464 gate_tm_memopt (void)
3466 return flag_tm && optimize > 0;
3469 struct gimple_opt_pass pass_tm_memopt =
3472 GIMPLE_PASS,
3473 "tmmemopt", /* name */
3474 gate_tm_memopt, /* gate */
3475 execute_tm_memopt, /* execute */
3476 NULL, /* sub */
3477 NULL, /* next */
3478 0, /* static_pass_number */
3479 TV_TRANS_MEM, /* tv_id */
3480 PROP_ssa | PROP_cfg, /* properties_required */
3481 0, /* properties_provided */
3482 0, /* properties_destroyed */
3483 0, /* todo_flags_start */
3484 0, /* todo_flags_finish */
3489 /* Interprocedual analysis for the creation of transactional clones.
3490 The aim of this pass is to find which functions are referenced in
3491 a non-irrevocable transaction context, and for those over which
3492 we have control (or user directive), create a version of the
3493 function which uses only the transactional interface to reference
3494 protected memories. This analysis proceeds in several steps:
3496 (1) Collect the set of all possible transactional clones:
3498 (a) For all local public functions marked tm_callable, push
3499 it onto the tm_callee queue.
3501 (b) For all local functions, scan for calls in transaction blocks.
3502 Push the caller and callee onto the tm_caller and tm_callee
3503 queues. Count the number of callers for each callee.
3505 (c) For each local function on the callee list, assume we will
3506 create a transactional clone. Push *all* calls onto the
3507 callee queues; count the number of clone callers separately
3508 to the number of original callers.
3510 (2) Propagate irrevocable status up the dominator tree:
3512 (a) Any external function on the callee list that is not marked
3513 tm_callable is irrevocable. Push all callers of such onto
3514 a worklist.
3516 (b) For each function on the worklist, mark each block that
3517 contains an irrevocable call. Use the AND operator to
3518 propagate that mark up the dominator tree.
3520 (c) If we reach the entry block for a possible transactional
3521 clone, then the transactional clone is irrevocable, and
3522 we should not create the clone after all. Push all
3523 callers onto the worklist.
3525 (d) Place tm_irrevocable calls at the beginning of the relevant
3526 blocks. Special case here is the entry block for the entire
3527 transaction region; there we mark it GTMA_DOES_GO_IRREVOCABLE for
3528 the library to begin the region in serial mode. Decrement
3529 the call count for all callees in the irrevocable region.
3531 (3) Create the transactional clones:
3533 Any tm_callee that still has a non-zero call count is cloned.
3536 /* This structure is stored in the AUX field of each cgraph_node. */
3537 struct tm_ipa_cg_data
3539 /* The clone of the function that got created. */
3540 struct cgraph_node *clone;
3542 /* The tm regions in the normal function. */
3543 struct tm_region *all_tm_regions;
3545 /* The blocks of the normal/clone functions that contain irrevocable
3546 calls, or blocks that are post-dominated by irrevocable calls. */
3547 bitmap irrevocable_blocks_normal;
3548 bitmap irrevocable_blocks_clone;
3550 /* The blocks of the normal function that are involved in transactions. */
3551 bitmap transaction_blocks_normal;
3553 /* The number of callers to the transactional clone of this function
3554 from normal and transactional clones respectively. */
3555 unsigned tm_callers_normal;
3556 unsigned tm_callers_clone;
3558 /* True if all calls to this function's transactional clone
3559 are irrevocable. Also automatically true if the function
3560 has no transactional clone. */
3561 bool is_irrevocable;
3563 /* Flags indicating the presence of this function in various queues. */
3564 bool in_callee_queue;
3565 bool in_worklist;
3567 /* Flags indicating the kind of scan desired while in the worklist. */
3568 bool want_irr_scan_normal;
3571 typedef struct cgraph_node *cgraph_node_p;
3573 DEF_VEC_P (cgraph_node_p);
3574 DEF_VEC_ALLOC_P (cgraph_node_p, heap);
3576 typedef VEC (cgraph_node_p, heap) *cgraph_node_queue;
3578 /* Return the ipa data associated with NODE, allocating zeroed memory
3579 if necessary. TRAVERSE_ALIASES is true if we must traverse aliases
3580 and set *NODE accordingly. */
3582 static struct tm_ipa_cg_data *
3583 get_cg_data (struct cgraph_node **node, bool traverse_aliases)
3585 struct tm_ipa_cg_data *d;
3587 if (traverse_aliases && (*node)->alias)
3588 *node = cgraph_get_node ((*node)->thunk.alias);
3590 d = (struct tm_ipa_cg_data *) (*node)->aux;
3592 if (d == NULL)
3594 d = (struct tm_ipa_cg_data *)
3595 obstack_alloc (&tm_obstack.obstack, sizeof (*d));
3596 (*node)->aux = (void *) d;
3597 memset (d, 0, sizeof (*d));
3600 return d;
3603 /* Add NODE to the end of QUEUE, unless IN_QUEUE_P indicates that
3604 it is already present. */
3606 static void
3607 maybe_push_queue (struct cgraph_node *node,
3608 cgraph_node_queue *queue_p, bool *in_queue_p)
3610 if (!*in_queue_p)
3612 *in_queue_p = true;
3613 VEC_safe_push (cgraph_node_p, heap, *queue_p, node);
3617 /* A subroutine of ipa_tm_scan_calls_transaction and ipa_tm_scan_calls_clone.
3618 Queue all callees within block BB. */
3620 static void
3621 ipa_tm_scan_calls_block (cgraph_node_queue *callees_p,
3622 basic_block bb, bool for_clone)
3624 gimple_stmt_iterator gsi;
3626 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3628 gimple stmt = gsi_stmt (gsi);
3629 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
3631 tree fndecl = gimple_call_fndecl (stmt);
3632 if (fndecl)
3634 struct tm_ipa_cg_data *d;
3635 unsigned *pcallers;
3636 struct cgraph_node *node;
3638 if (is_tm_ending_fndecl (fndecl))
3639 continue;
3640 if (find_tm_replacement_function (fndecl))
3641 continue;
3643 node = cgraph_get_node (fndecl);
3644 gcc_assert (node != NULL);
3645 d = get_cg_data (&node, true);
3647 pcallers = (for_clone ? &d->tm_callers_clone
3648 : &d->tm_callers_normal);
3649 *pcallers += 1;
3651 maybe_push_queue (node, callees_p, &d->in_callee_queue);
3657 /* Scan all calls in NODE that are within a transaction region,
3658 and push the resulting nodes into the callee queue. */
3660 static void
3661 ipa_tm_scan_calls_transaction (struct tm_ipa_cg_data *d,
3662 cgraph_node_queue *callees_p)
3664 struct tm_region *r;
3666 d->transaction_blocks_normal = BITMAP_ALLOC (&tm_obstack);
3667 d->all_tm_regions = all_tm_regions;
3669 for (r = all_tm_regions; r; r = r->next)
3671 VEC (basic_block, heap) *bbs;
3672 basic_block bb;
3673 unsigned i;
3675 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks, NULL,
3676 d->transaction_blocks_normal, false);
3678 FOR_EACH_VEC_ELT (basic_block, bbs, i, bb)
3679 ipa_tm_scan_calls_block (callees_p, bb, false);
3681 VEC_free (basic_block, heap, bbs);
3685 /* Scan all calls in NODE as if this is the transactional clone,
3686 and push the destinations into the callee queue. */
3688 static void
3689 ipa_tm_scan_calls_clone (struct cgraph_node *node,
3690 cgraph_node_queue *callees_p)
3692 struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
3693 basic_block bb;
3695 FOR_EACH_BB_FN (bb, fn)
3696 ipa_tm_scan_calls_block (callees_p, bb, true);
3699 /* The function NODE has been detected to be irrevocable. Push all
3700 of its callers onto WORKLIST for the purpose of re-scanning them. */
3702 static void
3703 ipa_tm_note_irrevocable (struct cgraph_node *node,
3704 cgraph_node_queue *worklist_p)
3706 struct tm_ipa_cg_data *d = get_cg_data (&node, true);
3707 struct cgraph_edge *e;
3709 d->is_irrevocable = true;
3711 for (e = node->callers; e ; e = e->next_caller)
3713 basic_block bb;
3714 struct cgraph_node *caller;
3716 /* Don't examine recursive calls. */
3717 if (e->caller == node)
3718 continue;
3719 /* Even if we think we can go irrevocable, believe the user
3720 above all. */
3721 if (is_tm_safe_or_pure (e->caller->decl))
3722 continue;
3724 caller = e->caller;
3725 d = get_cg_data (&caller, true);
3727 /* Check if the callee is in a transactional region. If so,
3728 schedule the function for normal re-scan as well. */
3729 bb = gimple_bb (e->call_stmt);
3730 gcc_assert (bb != NULL);
3731 if (d->transaction_blocks_normal
3732 && bitmap_bit_p (d->transaction_blocks_normal, bb->index))
3733 d->want_irr_scan_normal = true;
3735 maybe_push_queue (caller, worklist_p, &d->in_worklist);
3739 /* A subroutine of ipa_tm_scan_irr_blocks; return true iff any statement
3740 within the block is irrevocable. */
3742 static bool
3743 ipa_tm_scan_irr_block (basic_block bb)
3745 gimple_stmt_iterator gsi;
3746 tree fn;
3748 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3750 gimple stmt = gsi_stmt (gsi);
3751 switch (gimple_code (stmt))
3753 case GIMPLE_CALL:
3754 if (is_tm_pure_call (stmt))
3755 break;
3757 fn = gimple_call_fn (stmt);
3759 /* Functions with the attribute are by definition irrevocable. */
3760 if (is_tm_irrevocable (fn))
3761 return true;
3763 /* For direct function calls, go ahead and check for replacement
3764 functions, or transitive irrevocable functions. For indirect
3765 functions, we'll ask the runtime. */
3766 if (TREE_CODE (fn) == ADDR_EXPR)
3768 struct tm_ipa_cg_data *d;
3769 struct cgraph_node *node;
3771 fn = TREE_OPERAND (fn, 0);
3772 if (is_tm_ending_fndecl (fn))
3773 break;
3774 if (find_tm_replacement_function (fn))
3775 break;
3777 node = cgraph_get_node(fn);
3778 d = get_cg_data (&node, true);
3780 /* Return true if irrevocable, but above all, believe
3781 the user. */
3782 if (d->is_irrevocable
3783 && !is_tm_safe_or_pure (fn))
3784 return true;
3786 break;
3788 case GIMPLE_ASM:
3789 /* ??? The Approved Method of indicating that an inline
3790 assembly statement is not relevant to the transaction
3791 is to wrap it in a __tm_waiver block. This is not
3792 yet implemented, so we can't check for it. */
3793 if (is_tm_safe (current_function_decl))
3795 tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
3796 SET_EXPR_LOCATION (t, gimple_location (stmt));
3797 TREE_BLOCK (t) = gimple_block (stmt);
3798 error ("%Kasm not allowed in %<transaction_safe%> function", t);
3800 return true;
3802 default:
3803 break;
3807 return false;
3810 /* For each of the blocks seeded witin PQUEUE, walk the CFG looking
3811 for new irrevocable blocks, marking them in NEW_IRR. Don't bother
3812 scanning past OLD_IRR or EXIT_BLOCKS. */
3814 static bool
3815 ipa_tm_scan_irr_blocks (VEC (basic_block, heap) **pqueue, bitmap new_irr,
3816 bitmap old_irr, bitmap exit_blocks)
3818 bool any_new_irr = false;
3819 edge e;
3820 edge_iterator ei;
3821 bitmap visited_blocks = BITMAP_ALLOC (NULL);
3825 basic_block bb = VEC_pop (basic_block, *pqueue);
3827 /* Don't re-scan blocks we know already are irrevocable. */
3828 if (old_irr && bitmap_bit_p (old_irr, bb->index))
3829 continue;
3831 if (ipa_tm_scan_irr_block (bb))
3833 bitmap_set_bit (new_irr, bb->index);
3834 any_new_irr = true;
3836 else if (exit_blocks == NULL || !bitmap_bit_p (exit_blocks, bb->index))
3838 FOR_EACH_EDGE (e, ei, bb->succs)
3839 if (!bitmap_bit_p (visited_blocks, e->dest->index))
3841 bitmap_set_bit (visited_blocks, e->dest->index);
3842 VEC_safe_push (basic_block, heap, *pqueue, e->dest);
3846 while (!VEC_empty (basic_block, *pqueue));
3848 BITMAP_FREE (visited_blocks);
3850 return any_new_irr;
3853 /* Propagate the irrevocable property both up and down the dominator tree.
3854 BB is the current block being scanned; EXIT_BLOCKS are the edges of the
3855 TM regions; OLD_IRR are the results of a previous scan of the dominator
3856 tree which has been fully propagated; NEW_IRR is the set of new blocks
3857 which are gaining the irrevocable property during the current scan. */
3859 static void
3860 ipa_tm_propagate_irr (basic_block entry_block, bitmap new_irr,
3861 bitmap old_irr, bitmap exit_blocks)
3863 VEC (basic_block, heap) *bbs;
3864 bitmap all_region_blocks;
3866 /* If this block is in the old set, no need to rescan. */
3867 if (old_irr && bitmap_bit_p (old_irr, entry_block->index))
3868 return;
3870 all_region_blocks = BITMAP_ALLOC (&tm_obstack);
3871 bbs = get_tm_region_blocks (entry_block, exit_blocks, NULL,
3872 all_region_blocks, false);
3875 basic_block bb = VEC_pop (basic_block, bbs);
3876 bool this_irr = bitmap_bit_p (new_irr, bb->index);
3877 bool all_son_irr = false;
3878 edge_iterator ei;
3879 edge e;
3881 /* Propagate up. If my children are, I am too, but we must have
3882 at least one child that is. */
3883 if (!this_irr)
3885 FOR_EACH_EDGE (e, ei, bb->succs)
3887 if (!bitmap_bit_p (new_irr, e->dest->index))
3889 all_son_irr = false;
3890 break;
3892 else
3893 all_son_irr = true;
3895 if (all_son_irr)
3897 /* Add block to new_irr if it hasn't already been processed. */
3898 if (!old_irr || !bitmap_bit_p (old_irr, bb->index))
3900 bitmap_set_bit (new_irr, bb->index);
3901 this_irr = true;
3906 /* Propagate down to everyone we immediately dominate. */
3907 if (this_irr)
3909 basic_block son;
3910 for (son = first_dom_son (CDI_DOMINATORS, bb);
3911 son;
3912 son = next_dom_son (CDI_DOMINATORS, son))
3914 /* Make sure block is actually in a TM region, and it
3915 isn't already in old_irr. */
3916 if ((!old_irr || !bitmap_bit_p (old_irr, son->index))
3917 && bitmap_bit_p (all_region_blocks, son->index))
3918 bitmap_set_bit (new_irr, son->index);
3922 while (!VEC_empty (basic_block, bbs));
3924 BITMAP_FREE (all_region_blocks);
3925 VEC_free (basic_block, heap, bbs);
3928 static void
3929 ipa_tm_decrement_clone_counts (basic_block bb, bool for_clone)
3931 gimple_stmt_iterator gsi;
3933 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3935 gimple stmt = gsi_stmt (gsi);
3936 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
3938 tree fndecl = gimple_call_fndecl (stmt);
3939 if (fndecl)
3941 struct tm_ipa_cg_data *d;
3942 unsigned *pcallers;
3943 struct cgraph_node *tnode;
3945 if (is_tm_ending_fndecl (fndecl))
3946 continue;
3947 if (find_tm_replacement_function (fndecl))
3948 continue;
3950 tnode = cgraph_get_node (fndecl);
3951 d = get_cg_data (&tnode, true);
3953 pcallers = (for_clone ? &d->tm_callers_clone
3954 : &d->tm_callers_normal);
3956 gcc_assert (*pcallers > 0);
3957 *pcallers -= 1;
3963 /* (Re-)Scan the transaction blocks in NODE for calls to irrevocable functions,
3964 as well as other irrevocable actions such as inline assembly. Mark all
3965 such blocks as irrevocable and decrement the number of calls to
3966 transactional clones. Return true if, for the transactional clone, the
3967 entire function is irrevocable. */
3969 static bool
3970 ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
3972 struct tm_ipa_cg_data *d;
3973 bitmap new_irr, old_irr;
3974 VEC (basic_block, heap) *queue;
3975 bool ret = false;
3977 /* Builtin operators (operator new, and such). */
3978 if (DECL_STRUCT_FUNCTION (node->decl) == NULL
3979 || DECL_STRUCT_FUNCTION (node->decl)->cfg == NULL)
3980 return false;
3982 current_function_decl = node->decl;
3983 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
3984 calculate_dominance_info (CDI_DOMINATORS);
3986 d = get_cg_data (&node, true);
3987 queue = VEC_alloc (basic_block, heap, 10);
3988 new_irr = BITMAP_ALLOC (&tm_obstack);
3990 /* Scan each tm region, propagating irrevocable status through the tree. */
3991 if (for_clone)
3993 old_irr = d->irrevocable_blocks_clone;
3994 VEC_quick_push (basic_block, queue, single_succ (ENTRY_BLOCK_PTR));
3995 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr, NULL))
3997 ipa_tm_propagate_irr (single_succ (ENTRY_BLOCK_PTR), new_irr,
3998 old_irr, NULL);
3999 ret = bitmap_bit_p (new_irr, single_succ (ENTRY_BLOCK_PTR)->index);
4002 else
4004 struct tm_region *region;
4006 old_irr = d->irrevocable_blocks_normal;
4007 for (region = d->all_tm_regions; region; region = region->next)
4009 VEC_quick_push (basic_block, queue, region->entry_block);
4010 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr,
4011 region->exit_blocks))
4012 ipa_tm_propagate_irr (region->entry_block, new_irr, old_irr,
4013 region->exit_blocks);
4017 /* If we found any new irrevocable blocks, reduce the call count for
4018 transactional clones within the irrevocable blocks. Save the new
4019 set of irrevocable blocks for next time. */
4020 if (!bitmap_empty_p (new_irr))
4022 bitmap_iterator bmi;
4023 unsigned i;
4025 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
4026 ipa_tm_decrement_clone_counts (BASIC_BLOCK (i), for_clone);
4028 if (old_irr)
4030 bitmap_ior_into (old_irr, new_irr);
4031 BITMAP_FREE (new_irr);
4033 else if (for_clone)
4034 d->irrevocable_blocks_clone = new_irr;
4035 else
4036 d->irrevocable_blocks_normal = new_irr;
4038 if (dump_file && new_irr)
4040 const char *dname;
4041 bitmap_iterator bmi;
4042 unsigned i;
4044 dname = lang_hooks.decl_printable_name (current_function_decl, 2);
4045 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
4046 fprintf (dump_file, "%s: bb %d goes irrevocable\n", dname, i);
4049 else
4050 BITMAP_FREE (new_irr);
4052 VEC_free (basic_block, heap, queue);
4053 pop_cfun ();
4054 current_function_decl = NULL;
4056 return ret;
4059 /* Return true if, for the transactional clone of NODE, any call
4060 may enter irrevocable mode. */
4062 static bool
4063 ipa_tm_mayenterirr_function (struct cgraph_node *node)
4065 struct tm_ipa_cg_data *d;
4066 tree decl;
4067 unsigned flags;
4069 d = get_cg_data (&node, true);
4070 decl = node->decl;
4071 flags = flags_from_decl_or_type (decl);
4073 /* Handle some TM builtins. Ordinarily these aren't actually generated
4074 at this point, but handling these functions when written in by the
4075 user makes it easier to build unit tests. */
4076 if (flags & ECF_TM_BUILTIN)
4077 return false;
4079 /* Filter out all functions that are marked. */
4080 if (flags & ECF_TM_PURE)
4081 return false;
4082 if (is_tm_safe (decl))
4083 return false;
4084 if (is_tm_irrevocable (decl))
4085 return true;
4086 if (is_tm_callable (decl))
4087 return true;
4088 if (find_tm_replacement_function (decl))
4089 return true;
4091 /* If we aren't seeing the final version of the function we don't
4092 know what it will contain at runtime. */
4093 if (cgraph_function_body_availability (node) < AVAIL_AVAILABLE)
4094 return true;
4096 /* If the function must go irrevocable, then of course true. */
4097 if (d->is_irrevocable)
4098 return true;
4100 /* If there are any blocks marked irrevocable, then the function
4101 as a whole may enter irrevocable. */
4102 if (d->irrevocable_blocks_clone)
4103 return true;
4105 /* We may have previously marked this function as tm_may_enter_irr;
4106 see pass_diagnose_tm_blocks. */
4107 if (node->local.tm_may_enter_irr)
4108 return true;
4110 /* Recurse on the main body for aliases. In general, this will
4111 result in one of the bits above being set so that we will not
4112 have to recurse next time. */
4113 if (node->alias)
4114 return ipa_tm_mayenterirr_function (cgraph_get_node (node->thunk.alias));
4116 /* What remains is unmarked local functions without items that force
4117 the function to go irrevocable. */
4118 return false;
4121 /* Diagnose calls from transaction_safe functions to unmarked
4122 functions that are determined to not be safe. */
4124 static void
4125 ipa_tm_diagnose_tm_safe (struct cgraph_node *node)
4127 struct cgraph_edge *e;
4129 for (e = node->callees; e ; e = e->next_callee)
4130 if (!is_tm_callable (e->callee->decl)
4131 && e->callee->local.tm_may_enter_irr)
4132 error_at (gimple_location (e->call_stmt),
4133 "unsafe function call %qD within "
4134 "%<transaction_safe%> function", e->callee->decl);
4137 /* Diagnose call from atomic transactions to unmarked functions
4138 that are determined to not be safe. */
4140 static void
4141 ipa_tm_diagnose_transaction (struct cgraph_node *node,
4142 struct tm_region *all_tm_regions)
4144 struct tm_region *r;
4146 for (r = all_tm_regions; r ; r = r->next)
4147 if (gimple_transaction_subcode (r->transaction_stmt) & GTMA_IS_RELAXED)
4149 /* Atomic transactions can be nested inside relaxed. */
4150 if (r->inner)
4151 ipa_tm_diagnose_transaction (node, r->inner);
4153 else
4155 VEC (basic_block, heap) *bbs;
4156 gimple_stmt_iterator gsi;
4157 basic_block bb;
4158 size_t i;
4160 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks,
4161 r->irr_blocks, NULL, false);
4163 for (i = 0; VEC_iterate (basic_block, bbs, i, bb); ++i)
4164 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4166 gimple stmt = gsi_stmt (gsi);
4167 tree fndecl;
4169 if (gimple_code (stmt) == GIMPLE_ASM)
4171 error_at (gimple_location (stmt),
4172 "asm not allowed in atomic transaction");
4173 continue;
4176 if (!is_gimple_call (stmt))
4177 continue;
4178 fndecl = gimple_call_fndecl (stmt);
4180 /* Indirect function calls have been diagnosed already. */
4181 if (!fndecl)
4182 continue;
4184 /* Stop at the end of the transaction. */
4185 if (is_tm_ending_fndecl (fndecl))
4187 if (bitmap_bit_p (r->exit_blocks, bb->index))
4188 break;
4189 continue;
4192 /* Marked functions have been diagnosed already. */
4193 if (is_tm_pure_call (stmt))
4194 continue;
4195 if (is_tm_callable (fndecl))
4196 continue;
4198 if (cgraph_local_info (fndecl)->tm_may_enter_irr)
4199 error_at (gimple_location (stmt),
4200 "unsafe function call %qD within "
4201 "atomic transaction", fndecl);
4204 VEC_free (basic_block, heap, bbs);
4208 /* Return a transactional mangled name for the DECL_ASSEMBLER_NAME in
4209 OLD_DECL. The returned value is a freshly malloced pointer that
4210 should be freed by the caller. */
4212 static tree
4213 tm_mangle (tree old_asm_id)
4215 const char *old_asm_name;
4216 char *tm_name;
4217 void *alloc = NULL;
4218 struct demangle_component *dc;
4219 tree new_asm_id;
4221 /* Determine if the symbol is already a valid C++ mangled name. Do this
4222 even for C, which might be interfacing with C++ code via appropriately
4223 ugly identifiers. */
4224 /* ??? We could probably do just as well checking for "_Z" and be done. */
4225 old_asm_name = IDENTIFIER_POINTER (old_asm_id);
4226 dc = cplus_demangle_v3_components (old_asm_name, DMGL_NO_OPTS, &alloc);
4228 if (dc == NULL)
4230 char length[8];
4232 do_unencoded:
4233 sprintf (length, "%u", IDENTIFIER_LENGTH (old_asm_id));
4234 tm_name = concat ("_ZGTt", length, old_asm_name, NULL);
4236 else
4238 old_asm_name += 2; /* Skip _Z */
4240 switch (dc->type)
4242 case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
4243 case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
4244 /* Don't play silly games, you! */
4245 goto do_unencoded;
4247 case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
4248 /* I'd really like to know if we can ever be passed one of
4249 these from the C++ front end. The Logical Thing would
4250 seem that hidden-alias should be outer-most, so that we
4251 get hidden-alias of a transaction-clone and not vice-versa. */
4252 old_asm_name += 2;
4253 break;
4255 default:
4256 break;
4259 tm_name = concat ("_ZGTt", old_asm_name, NULL);
4261 free (alloc);
4263 new_asm_id = get_identifier (tm_name);
4264 free (tm_name);
4266 return new_asm_id;
4269 static inline void
4270 ipa_tm_mark_needed_node (struct cgraph_node *node)
4272 cgraph_mark_needed_node (node);
4273 /* ??? function_and_variable_visibility will reset
4274 the needed bit, without actually checking. */
4275 node->analyzed = 1;
4278 /* Callback data for ipa_tm_create_version_alias. */
4279 struct create_version_alias_info
4281 struct cgraph_node *old_node;
4282 tree new_decl;
4285 /* A subroutine of ipa_tm_create_version, called via
4286 cgraph_for_node_and_aliases. Create new tm clones for each of
4287 the existing aliases. */
4288 static bool
4289 ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
4291 struct create_version_alias_info *info
4292 = (struct create_version_alias_info *)data;
4293 tree old_decl, new_decl, tm_name;
4294 struct cgraph_node *new_node;
4296 if (!node->same_body_alias)
4297 return false;
4299 old_decl = node->decl;
4300 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4301 new_decl = build_decl (DECL_SOURCE_LOCATION (old_decl),
4302 TREE_CODE (old_decl), tm_name,
4303 TREE_TYPE (old_decl));
4305 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4306 SET_DECL_RTL (new_decl, NULL);
4308 /* Based loosely on C++'s make_alias_for(). */
4309 TREE_PUBLIC (new_decl) = TREE_PUBLIC (old_decl);
4310 DECL_CONTEXT (new_decl) = DECL_CONTEXT (old_decl);
4311 DECL_LANG_SPECIFIC (new_decl) = DECL_LANG_SPECIFIC (old_decl);
4312 TREE_READONLY (new_decl) = TREE_READONLY (old_decl);
4313 DECL_EXTERNAL (new_decl) = 0;
4314 DECL_ARTIFICIAL (new_decl) = 1;
4315 TREE_ADDRESSABLE (new_decl) = 1;
4316 TREE_USED (new_decl) = 1;
4317 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4319 /* Perform the same remapping to the comdat group. */
4320 if (DECL_ONE_ONLY (new_decl))
4321 DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
4323 new_node = cgraph_same_body_alias (NULL, new_decl, info->new_decl);
4324 new_node->tm_clone = true;
4325 new_node->local.externally_visible = info->old_node->local.externally_visible;
4326 /* ?? Do not traverse aliases here. */
4327 get_cg_data (&node, false)->clone = new_node;
4329 record_tm_clone_pair (old_decl, new_decl);
4331 if (info->old_node->needed)
4332 ipa_tm_mark_needed_node (new_node);
4333 return false;
4336 /* Create a copy of the function (possibly declaration only) of OLD_NODE,
4337 appropriate for the transactional clone. */
4339 static void
4340 ipa_tm_create_version (struct cgraph_node *old_node)
4342 tree new_decl, old_decl, tm_name;
4343 struct cgraph_node *new_node;
4345 old_decl = old_node->decl;
4346 new_decl = copy_node (old_decl);
4348 /* DECL_ASSEMBLER_NAME needs to be set before we call
4349 cgraph_copy_node_for_versioning below, because cgraph_node will
4350 fill the assembler_name_hash. */
4351 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4352 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4353 SET_DECL_RTL (new_decl, NULL);
4354 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4356 /* Perform the same remapping to the comdat group. */
4357 if (DECL_ONE_ONLY (new_decl))
4358 DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
4360 new_node = cgraph_copy_node_for_versioning (old_node, new_decl, NULL, NULL);
4361 new_node->local.externally_visible = old_node->local.externally_visible;
4362 new_node->lowered = true;
4363 new_node->tm_clone = 1;
4364 get_cg_data (&old_node, true)->clone = new_node;
4366 if (cgraph_function_body_availability (old_node) >= AVAIL_OVERWRITABLE)
4368 /* Remap extern inline to static inline. */
4369 /* ??? Is it worth trying to use make_decl_one_only? */
4370 if (DECL_DECLARED_INLINE_P (new_decl) && DECL_EXTERNAL (new_decl))
4372 DECL_EXTERNAL (new_decl) = 0;
4373 TREE_PUBLIC (new_decl) = 0;
4374 DECL_WEAK (new_decl) = 0;
4377 tree_function_versioning (old_decl, new_decl, NULL, false, NULL, false,
4378 NULL, NULL);
4381 record_tm_clone_pair (old_decl, new_decl);
4383 cgraph_call_function_insertion_hooks (new_node);
4384 if (old_node->needed)
4385 ipa_tm_mark_needed_node (new_node);
4387 /* Do the same thing, but for any aliases of the original node. */
4389 struct create_version_alias_info data;
4390 data.old_node = old_node;
4391 data.new_decl = new_decl;
4392 cgraph_for_node_and_aliases (old_node, ipa_tm_create_version_alias,
4393 &data, true);
4397 /* Construct a call to TM_IRREVOCABLE and insert it at the beginning of BB. */
4399 static void
4400 ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region,
4401 basic_block bb)
4403 gimple_stmt_iterator gsi;
4404 gimple g;
4406 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4408 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE),
4409 1, build_int_cst (NULL_TREE, MODE_SERIALIRREVOCABLE));
4411 split_block_after_labels (bb);
4412 gsi = gsi_after_labels (bb);
4413 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
4415 cgraph_create_edge (node,
4416 cgraph_get_create_node
4417 (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE)),
4418 g, 0,
4419 compute_call_stmt_bb_frequency (node->decl,
4420 gimple_bb (g)));
4423 /* Construct a call to TM_GETTMCLONE and insert it before GSI. */
4425 static bool
4426 ipa_tm_insert_gettmclone_call (struct cgraph_node *node,
4427 struct tm_region *region,
4428 gimple_stmt_iterator *gsi, gimple stmt)
4430 tree gettm_fn, ret, old_fn, callfn;
4431 gimple g, g2;
4432 bool safe;
4434 old_fn = gimple_call_fn (stmt);
4436 if (TREE_CODE (old_fn) == ADDR_EXPR)
4438 tree fndecl = TREE_OPERAND (old_fn, 0);
4439 tree clone = get_tm_clone_pair (fndecl);
4441 /* By transforming the call into a TM_GETTMCLONE, we are
4442 technically taking the address of the original function and
4443 its clone. Explain this so inlining will know this function
4444 is needed. */
4445 cgraph_mark_address_taken_node (cgraph_get_node (fndecl));
4446 if (clone)
4447 cgraph_mark_address_taken_node (cgraph_get_node (clone));
4450 safe = is_tm_safe (TREE_TYPE (old_fn));
4451 gettm_fn = builtin_decl_explicit (safe ? BUILT_IN_TM_GETTMCLONE_SAFE
4452 : BUILT_IN_TM_GETTMCLONE_IRR);
4453 ret = create_tmp_var (ptr_type_node, NULL);
4454 add_referenced_var (ret);
4456 if (!safe)
4457 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4459 /* Discard OBJ_TYPE_REF, since we weren't able to fold it. */
4460 if (TREE_CODE (old_fn) == OBJ_TYPE_REF)
4461 old_fn = OBJ_TYPE_REF_EXPR (old_fn);
4463 g = gimple_build_call (gettm_fn, 1, old_fn);
4464 ret = make_ssa_name (ret, g);
4465 gimple_call_set_lhs (g, ret);
4467 gsi_insert_before (gsi, g, GSI_SAME_STMT);
4469 cgraph_create_edge (node, cgraph_get_create_node (gettm_fn), g, 0,
4470 compute_call_stmt_bb_frequency (node->decl,
4471 gimple_bb(g)));
4473 /* Cast return value from tm_gettmclone* into appropriate function
4474 pointer. */
4475 callfn = create_tmp_var (TREE_TYPE (old_fn), NULL);
4476 add_referenced_var (callfn);
4477 g2 = gimple_build_assign (callfn,
4478 fold_build1 (NOP_EXPR, TREE_TYPE (callfn), ret));
4479 callfn = make_ssa_name (callfn, g2);
4480 gimple_assign_set_lhs (g2, callfn);
4481 gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4483 /* ??? This is a hack to preserve the NOTHROW bit on the call,
4484 which we would have derived from the decl. Failure to save
4485 this bit means we might have to split the basic block. */
4486 if (gimple_call_nothrow_p (stmt))
4487 gimple_call_set_nothrow (stmt, true);
4489 gimple_call_set_fn (stmt, callfn);
4491 /* Discarding OBJ_TYPE_REF above may produce incompatible LHS and RHS
4492 for a call statement. Fix it. */
4494 tree lhs = gimple_call_lhs (stmt);
4495 tree rettype = TREE_TYPE (gimple_call_fntype (stmt));
4496 if (lhs
4497 && !useless_type_conversion_p (TREE_TYPE (lhs), rettype))
4499 tree temp;
4501 temp = make_rename_temp (rettype, 0);
4502 gimple_call_set_lhs (stmt, temp);
4504 g2 = gimple_build_assign (lhs,
4505 fold_build1 (VIEW_CONVERT_EXPR,
4506 TREE_TYPE (lhs), temp));
4507 gsi_insert_after (gsi, g2, GSI_SAME_STMT);
4511 update_stmt (stmt);
4513 return true;
4516 /* Helper function for ipa_tm_transform_calls*. Given a call
4517 statement in GSI which resides inside transaction REGION, redirect
4518 the call to either its wrapper function, or its clone. */
4520 static void
4521 ipa_tm_transform_calls_redirect (struct cgraph_node *node,
4522 struct tm_region *region,
4523 gimple_stmt_iterator *gsi,
4524 bool *need_ssa_rename_p)
4526 gimple stmt = gsi_stmt (*gsi);
4527 struct cgraph_node *new_node;
4528 struct cgraph_edge *e = cgraph_edge (node, stmt);
4529 tree fndecl = gimple_call_fndecl (stmt);
4531 /* For indirect calls, pass the address through the runtime. */
4532 if (fndecl == NULL)
4534 *need_ssa_rename_p |=
4535 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
4536 return;
4539 /* Handle some TM builtins. Ordinarily these aren't actually generated
4540 at this point, but handling these functions when written in by the
4541 user makes it easier to build unit tests. */
4542 if (flags_from_decl_or_type (fndecl) & ECF_TM_BUILTIN)
4543 return;
4545 /* Fixup recursive calls inside clones. */
4546 /* ??? Why did cgraph_copy_node_for_versioning update the call edges
4547 for recursion but not update the call statements themselves? */
4548 if (e->caller == e->callee && decl_is_tm_clone (current_function_decl))
4550 gimple_call_set_fndecl (stmt, current_function_decl);
4551 return;
4554 /* If there is a replacement, use it. */
4555 fndecl = find_tm_replacement_function (fndecl);
4556 if (fndecl)
4558 new_node = cgraph_get_create_node (fndecl);
4560 /* ??? Mark all transaction_wrap functions tm_may_enter_irr.
4562 We can't do this earlier in record_tm_replacement because
4563 cgraph_remove_unreachable_nodes is called before we inject
4564 references to the node. Further, we can't do this in some
4565 nice central place in ipa_tm_execute because we don't have
4566 the exact list of wrapper functions that would be used.
4567 Marking more wrappers than necessary results in the creation
4568 of unnecessary cgraph_nodes, which can cause some of the
4569 other IPA passes to crash.
4571 We do need to mark these nodes so that we get the proper
4572 result in expand_call_tm. */
4573 /* ??? This seems broken. How is it that we're marking the
4574 CALLEE as may_enter_irr? Surely we should be marking the
4575 CALLER. Also note that find_tm_replacement_function also
4576 contains mappings into the TM runtime, e.g. memcpy. These
4577 we know won't go irrevocable. */
4578 new_node->local.tm_may_enter_irr = 1;
4580 else
4582 struct tm_ipa_cg_data *d;
4583 struct cgraph_node *tnode = e->callee;
4585 d = get_cg_data (&tnode, true);
4586 new_node = d->clone;
4588 /* As we've already skipped pure calls and appropriate builtins,
4589 and we've already marked irrevocable blocks, if we can't come
4590 up with a static replacement, then ask the runtime. */
4591 if (new_node == NULL)
4593 *need_ssa_rename_p |=
4594 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
4595 return;
4598 fndecl = new_node->decl;
4601 cgraph_redirect_edge_callee (e, new_node);
4602 gimple_call_set_fndecl (stmt, fndecl);
4605 /* Helper function for ipa_tm_transform_calls. For a given BB,
4606 install calls to tm_irrevocable when IRR_BLOCKS are reached,
4607 redirect other calls to the generated transactional clone. */
4609 static bool
4610 ipa_tm_transform_calls_1 (struct cgraph_node *node, struct tm_region *region,
4611 basic_block bb, bitmap irr_blocks)
4613 gimple_stmt_iterator gsi;
4614 bool need_ssa_rename = false;
4616 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
4618 ipa_tm_insert_irr_call (node, region, bb);
4619 return true;
4622 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4624 gimple stmt = gsi_stmt (gsi);
4626 if (!is_gimple_call (stmt))
4627 continue;
4628 if (is_tm_pure_call (stmt))
4629 continue;
4631 /* Redirect edges to the appropriate replacement or clone. */
4632 ipa_tm_transform_calls_redirect (node, region, &gsi, &need_ssa_rename);
4635 return need_ssa_rename;
4638 /* Walk the CFG for REGION, beginning at BB. Install calls to
4639 tm_irrevocable when IRR_BLOCKS are reached, redirect other calls to
4640 the generated transactional clone. */
4642 static bool
4643 ipa_tm_transform_calls (struct cgraph_node *node, struct tm_region *region,
4644 basic_block bb, bitmap irr_blocks)
4646 bool need_ssa_rename = false;
4647 edge e;
4648 edge_iterator ei;
4649 VEC(basic_block, heap) *queue = NULL;
4650 bitmap visited_blocks = BITMAP_ALLOC (NULL);
4652 VEC_safe_push (basic_block, heap, queue, bb);
4655 bb = VEC_pop (basic_block, queue);
4657 need_ssa_rename |=
4658 ipa_tm_transform_calls_1 (node, region, bb, irr_blocks);
4660 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
4661 continue;
4663 if (region && bitmap_bit_p (region->exit_blocks, bb->index))
4664 continue;
4666 FOR_EACH_EDGE (e, ei, bb->succs)
4667 if (!bitmap_bit_p (visited_blocks, e->dest->index))
4669 bitmap_set_bit (visited_blocks, e->dest->index);
4670 VEC_safe_push (basic_block, heap, queue, e->dest);
4673 while (!VEC_empty (basic_block, queue));
4675 VEC_free (basic_block, heap, queue);
4676 BITMAP_FREE (visited_blocks);
4678 return need_ssa_rename;
4681 /* Transform the calls within the TM regions within NODE. */
4683 static void
4684 ipa_tm_transform_transaction (struct cgraph_node *node)
4686 struct tm_ipa_cg_data *d;
4687 struct tm_region *region;
4688 bool need_ssa_rename = false;
4690 d = get_cg_data (&node, true);
4692 current_function_decl = node->decl;
4693 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4694 calculate_dominance_info (CDI_DOMINATORS);
4696 for (region = d->all_tm_regions; region; region = region->next)
4698 /* If we're sure to go irrevocable, don't transform anything. */
4699 if (d->irrevocable_blocks_normal
4700 && bitmap_bit_p (d->irrevocable_blocks_normal,
4701 region->entry_block->index))
4703 transaction_subcode_ior (region, GTMA_DOES_GO_IRREVOCABLE);
4704 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
4705 continue;
4708 need_ssa_rename |=
4709 ipa_tm_transform_calls (node, region, region->entry_block,
4710 d->irrevocable_blocks_normal);
4713 if (need_ssa_rename)
4714 update_ssa (TODO_update_ssa_only_virtuals);
4716 pop_cfun ();
4717 current_function_decl = NULL;
4720 /* Transform the calls within the transactional clone of NODE. */
4722 static void
4723 ipa_tm_transform_clone (struct cgraph_node *node)
4725 struct tm_ipa_cg_data *d;
4726 bool need_ssa_rename;
4728 d = get_cg_data (&node, true);
4730 /* If this function makes no calls and has no irrevocable blocks,
4731 then there's nothing to do. */
4732 /* ??? Remove non-aborting top-level transactions. */
4733 if (!node->callees && !d->irrevocable_blocks_clone)
4734 return;
4736 current_function_decl = d->clone->decl;
4737 push_cfun (DECL_STRUCT_FUNCTION (current_function_decl));
4738 calculate_dominance_info (CDI_DOMINATORS);
4740 need_ssa_rename =
4741 ipa_tm_transform_calls (d->clone, NULL, single_succ (ENTRY_BLOCK_PTR),
4742 d->irrevocable_blocks_clone);
4744 if (need_ssa_rename)
4745 update_ssa (TODO_update_ssa_only_virtuals);
4747 pop_cfun ();
4748 current_function_decl = NULL;
4751 /* Main entry point for the transactional memory IPA pass. */
4753 static unsigned int
4754 ipa_tm_execute (void)
4756 cgraph_node_queue tm_callees = NULL;
4757 /* List of functions that will go irrevocable. */
4758 cgraph_node_queue irr_worklist = NULL;
4760 struct cgraph_node *node;
4761 struct tm_ipa_cg_data *d;
4762 enum availability a;
4763 unsigned int i;
4765 #ifdef ENABLE_CHECKING
4766 verify_cgraph ();
4767 #endif
4769 bitmap_obstack_initialize (&tm_obstack);
4771 /* For all local functions marked tm_callable, queue them. */
4772 for (node = cgraph_nodes; node; node = node->next)
4773 if (is_tm_callable (node->decl)
4774 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4776 d = get_cg_data (&node, true);
4777 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
4780 /* For all local reachable functions... */
4781 for (node = cgraph_nodes; node; node = node->next)
4782 if (node->reachable && node->lowered
4783 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4785 /* ... marked tm_pure, record that fact for the runtime by
4786 indicating that the pure function is its own tm_callable.
4787 No need to do this if the function's address can't be taken. */
4788 if (is_tm_pure (node->decl))
4790 if (!node->local.local)
4791 record_tm_clone_pair (node->decl, node->decl);
4792 continue;
4795 current_function_decl = node->decl;
4796 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4797 calculate_dominance_info (CDI_DOMINATORS);
4799 tm_region_init (NULL);
4800 if (all_tm_regions)
4802 d = get_cg_data (&node, true);
4804 /* Scan for calls that are in each transaction. */
4805 ipa_tm_scan_calls_transaction (d, &tm_callees);
4807 /* Put it in the worklist so we can scan the function
4808 later (ipa_tm_scan_irr_function) and mark the
4809 irrevocable blocks. */
4810 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4811 d->want_irr_scan_normal = true;
4814 pop_cfun ();
4815 current_function_decl = NULL;
4818 /* For every local function on the callee list, scan as if we will be
4819 creating a transactional clone, queueing all new functions we find
4820 along the way. */
4821 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4823 node = VEC_index (cgraph_node_p, tm_callees, i);
4824 a = cgraph_function_body_availability (node);
4825 d = get_cg_data (&node, true);
4827 /* Put it in the worklist so we can scan the function later
4828 (ipa_tm_scan_irr_function) and mark the irrevocable
4829 blocks. */
4830 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4832 /* Some callees cannot be arbitrarily cloned. These will always be
4833 irrevocable. Mark these now, so that we need not scan them. */
4834 if (is_tm_irrevocable (node->decl))
4835 ipa_tm_note_irrevocable (node, &irr_worklist);
4836 else if (a <= AVAIL_NOT_AVAILABLE
4837 && !is_tm_safe_or_pure (node->decl))
4838 ipa_tm_note_irrevocable (node, &irr_worklist);
4839 else if (a >= AVAIL_OVERWRITABLE)
4841 if (!tree_versionable_function_p (node->decl))
4842 ipa_tm_note_irrevocable (node, &irr_worklist);
4843 else if (!d->is_irrevocable)
4845 /* If this is an alias, make sure its base is queued as well.
4846 we need not scan the callees now, as the base will do. */
4847 if (node->alias)
4849 node = cgraph_get_node (node->thunk.alias);
4850 d = get_cg_data (&node, true);
4851 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
4852 continue;
4855 /* Add all nodes called by this function into
4856 tm_callees as well. */
4857 ipa_tm_scan_calls_clone (node, &tm_callees);
4862 /* Iterate scans until no more work to be done. Prefer not to use
4863 VEC_pop because the worklist tends to follow a breadth-first
4864 search of the callgraph, which should allow convergance with a
4865 minimum number of scans. But we also don't want the worklist
4866 array to grow without bound, so we shift the array up periodically. */
4867 for (i = 0; i < VEC_length (cgraph_node_p, irr_worklist); ++i)
4869 if (i > 256 && i == VEC_length (cgraph_node_p, irr_worklist) / 8)
4871 VEC_block_remove (cgraph_node_p, irr_worklist, 0, i);
4872 i = 0;
4875 node = VEC_index (cgraph_node_p, irr_worklist, i);
4876 d = get_cg_data (&node, true);
4877 d->in_worklist = false;
4879 if (d->want_irr_scan_normal)
4881 d->want_irr_scan_normal = false;
4882 ipa_tm_scan_irr_function (node, false);
4884 if (d->in_callee_queue && ipa_tm_scan_irr_function (node, true))
4885 ipa_tm_note_irrevocable (node, &irr_worklist);
4888 /* For every function on the callee list, collect the tm_may_enter_irr
4889 bit on the node. */
4890 VEC_truncate (cgraph_node_p, irr_worklist, 0);
4891 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4893 node = VEC_index (cgraph_node_p, tm_callees, i);
4894 if (ipa_tm_mayenterirr_function (node))
4896 d = get_cg_data (&node, true);
4897 gcc_assert (d->in_worklist == false);
4898 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4902 /* Propagate the tm_may_enter_irr bit to callers until stable. */
4903 for (i = 0; i < VEC_length (cgraph_node_p, irr_worklist); ++i)
4905 struct cgraph_node *caller;
4906 struct cgraph_edge *e;
4907 struct ipa_ref *ref;
4908 unsigned j;
4910 if (i > 256 && i == VEC_length (cgraph_node_p, irr_worklist) / 8)
4912 VEC_block_remove (cgraph_node_p, irr_worklist, 0, i);
4913 i = 0;
4916 node = VEC_index (cgraph_node_p, irr_worklist, i);
4917 d = get_cg_data (&node, true);
4918 d->in_worklist = false;
4919 node->local.tm_may_enter_irr = true;
4921 /* Propagate back to normal callers. */
4922 for (e = node->callers; e ; e = e->next_caller)
4924 caller = e->caller;
4925 if (!is_tm_safe_or_pure (caller->decl)
4926 && !caller->local.tm_may_enter_irr)
4928 d = get_cg_data (&caller, true);
4929 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
4933 /* Propagate back to referring aliases as well. */
4934 for (j = 0; ipa_ref_list_refering_iterate (&node->ref_list, j, ref); j++)
4936 caller = ref->refering.cgraph_node;
4937 if (ref->use == IPA_REF_ALIAS
4938 && !caller->local.tm_may_enter_irr)
4940 /* ?? Do not traverse aliases here. */
4941 d = get_cg_data (&caller, false);
4942 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
4947 /* Now validate all tm_safe functions, and all atomic regions in
4948 other functions. */
4949 for (node = cgraph_nodes; node; node = node->next)
4950 if (node->reachable && node->lowered
4951 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
4953 d = get_cg_data (&node, true);
4954 if (is_tm_safe (node->decl))
4955 ipa_tm_diagnose_tm_safe (node);
4956 else if (d->all_tm_regions)
4957 ipa_tm_diagnose_transaction (node, d->all_tm_regions);
4960 /* Create clones. Do those that are not irrevocable and have a
4961 positive call count. Do those publicly visible functions that
4962 the user directed us to clone. */
4963 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4965 bool doit = false;
4967 node = VEC_index (cgraph_node_p, tm_callees, i);
4968 if (node->same_body_alias)
4969 continue;
4971 a = cgraph_function_body_availability (node);
4972 d = get_cg_data (&node, true);
4974 if (a <= AVAIL_NOT_AVAILABLE)
4975 doit = is_tm_callable (node->decl);
4976 else if (a <= AVAIL_AVAILABLE && is_tm_callable (node->decl))
4977 doit = true;
4978 else if (!d->is_irrevocable
4979 && d->tm_callers_normal + d->tm_callers_clone > 0)
4980 doit = true;
4982 if (doit)
4983 ipa_tm_create_version (node);
4986 /* Redirect calls to the new clones, and insert irrevocable marks. */
4987 for (i = 0; i < VEC_length (cgraph_node_p, tm_callees); ++i)
4989 node = VEC_index (cgraph_node_p, tm_callees, i);
4990 if (node->analyzed)
4992 d = get_cg_data (&node, true);
4993 if (d->clone)
4994 ipa_tm_transform_clone (node);
4997 for (node = cgraph_nodes; node; node = node->next)
4998 if (node->reachable && node->lowered
4999 && cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
5001 d = get_cg_data (&node, true);
5002 if (d->all_tm_regions)
5003 ipa_tm_transform_transaction (node);
5006 /* Free and clear all data structures. */
5007 VEC_free (cgraph_node_p, heap, tm_callees);
5008 VEC_free (cgraph_node_p, heap, irr_worklist);
5009 bitmap_obstack_release (&tm_obstack);
5011 for (node = cgraph_nodes; node; node = node->next)
5012 node->aux = NULL;
5014 #ifdef ENABLE_CHECKING
5015 verify_cgraph ();
5016 #endif
5018 return 0;
5021 struct simple_ipa_opt_pass pass_ipa_tm =
5024 SIMPLE_IPA_PASS,
5025 "tmipa", /* name */
5026 gate_tm, /* gate */
5027 ipa_tm_execute, /* execute */
5028 NULL, /* sub */
5029 NULL, /* next */
5030 0, /* static_pass_number */
5031 TV_TRANS_MEM, /* tv_id */
5032 PROP_ssa | PROP_cfg, /* properties_required */
5033 0, /* properties_provided */
5034 0, /* properties_destroyed */
5035 0, /* todo_flags_start */
5036 0, /* todo_flags_finish */
5040 #include "gt-trans-mem.h"