]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/trans-mem.c
2015-06-04 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / trans-mem.c
CommitLineData
4c0315d0 1/* Passes for transactional memory support.
d353bf18 2 Copyright (C) 2008-2015 Free Software Foundation, Inc.
4c0315d0 3
4 This file is part of GCC.
5
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.
10
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.
15
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/>. */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
d9dd21a8 23#include "hash-table.h"
94ea8568 24#include "hash-set.h"
b20a8bb4 25#include "vec.h"
b20a8bb4 26#include "input.h"
27#include "alias.h"
28#include "symtab.h"
29#include "options.h"
b20a8bb4 30#include "inchash.h"
31#include "tree.h"
32#include "fold-const.h"
33#include "predict.h"
94ea8568 34#include "tm.h"
35#include "hard-reg-set.h"
36#include "input.h"
37#include "function.h"
38#include "dominance.h"
39#include "cfg.h"
bc61cadb 40#include "basic-block.h"
41#include "tree-ssa-alias.h"
42#include "internal-fn.h"
43#include "tree-eh.h"
44#include "gimple-expr.h"
45#include "is-a.h"
e795d6e1 46#include "gimple.h"
9ed99284 47#include "calls.h"
9ed99284 48#include "rtl.h"
49#include "emit-rtl.h"
a8783bee 50#include "gimplify.h"
dcf1a1ec 51#include "gimple-iterator.h"
e795d6e1 52#include "gimplify-me.h"
dcf1a1ec 53#include "gimple-walk.h"
073c1fd5 54#include "gimple-ssa.h"
1140c305 55#include "hash-map.h"
56#include "plugin-api.h"
57#include "ipa-ref.h"
073c1fd5 58#include "cgraph.h"
59#include "tree-cfg.h"
9ed99284 60#include "stringpool.h"
073c1fd5 61#include "tree-ssanames.h"
62#include "tree-into-ssa.h"
4c0315d0 63#include "tree-pass.h"
64#include "tree-inline.h"
65#include "diagnostic-core.h"
66#include "demangle.h"
67#include "output.h"
68#include "trans-mem.h"
69#include "params.h"
70#include "target.h"
71#include "langhooks.h"
4c0315d0 72#include "gimple-pretty-print.h"
79f958cb 73#include "cfgloop.h"
424a4a92 74#include "tree-ssa-address.h"
4c0315d0 75
76
4c0315d0 77#define A_RUNINSTRUMENTEDCODE 0x0001
78#define A_RUNUNINSTRUMENTEDCODE 0x0002
79#define A_SAVELIVEVARIABLES 0x0004
80#define A_RESTORELIVEVARIABLES 0x0008
81#define A_ABORTTRANSACTION 0x0010
82
83#define AR_USERABORT 0x0001
84#define AR_USERRETRY 0x0002
85#define AR_TMCONFLICT 0x0004
86#define AR_EXCEPTIONBLOCKABORT 0x0008
87#define AR_OUTERABORT 0x0010
88
89#define MODE_SERIALIRREVOCABLE 0x0000
90
91
92/* The representation of a transaction changes several times during the
93 lowering process. In the beginning, in the front-end we have the
94 GENERIC tree TRANSACTION_EXPR. For example,
95
96 __transaction {
97 local++;
98 if (++global == 10)
99 __tm_abort;
100 }
101
102 During initial gimplification (gimplify.c) the TRANSACTION_EXPR node is
103 trivially replaced with a GIMPLE_TRANSACTION node.
104
105 During pass_lower_tm, we examine the body of transactions looking
106 for aborts. Transactions that do not contain an abort may be
107 merged into an outer transaction. We also add a TRY-FINALLY node
108 to arrange for the transaction to be committed on any exit.
109
110 [??? Think about how this arrangement affects throw-with-commit
111 and throw-with-abort operations. In this case we want the TRY to
112 handle gotos, but not to catch any exceptions because the transaction
113 will already be closed.]
114
115 GIMPLE_TRANSACTION [label=NULL] {
116 try {
117 local = local + 1;
118 t0 = global;
119 t1 = t0 + 1;
120 global = t1;
121 if (t1 == 10)
122 __builtin___tm_abort ();
123 } finally {
124 __builtin___tm_commit ();
125 }
126 }
127
128 During pass_lower_eh, we create EH regions for the transactions,
129 intermixed with the regular EH stuff. This gives us a nice persistent
130 mapping (all the way through rtl) from transactional memory operation
131 back to the transaction, which allows us to get the abnormal edges
132 correct to model transaction aborts and restarts:
133
134 GIMPLE_TRANSACTION [label=over]
135 local = local + 1;
136 t0 = global;
137 t1 = t0 + 1;
138 global = t1;
139 if (t1 == 10)
140 __builtin___tm_abort ();
141 __builtin___tm_commit ();
142 over:
143
144 This is the end of all_lowering_passes, and so is what is present
145 during the IPA passes, and through all of the optimization passes.
146
147 During pass_ipa_tm, we examine all GIMPLE_TRANSACTION blocks in all
148 functions and mark functions for cloning.
149
150 At the end of gimple optimization, before exiting SSA form,
151 pass_tm_edges replaces statements that perform transactional
152 memory operations with the appropriate TM builtins, and swap
153 out function calls with their transactional clones. At this
154 point we introduce the abnormal transaction restart edges and
155 complete lowering of the GIMPLE_TRANSACTION node.
156
157 x = __builtin___tm_start (MAY_ABORT);
158 eh_label:
159 if (x & abort_transaction)
160 goto over;
161 local = local + 1;
162 t0 = __builtin___tm_load (global);
163 t1 = t0 + 1;
164 __builtin___tm_store (&global, t1);
165 if (t1 == 10)
166 __builtin___tm_abort ();
167 __builtin___tm_commit ();
168 over:
169*/
170
0cd02a19 171static void *expand_regions (struct tm_region *,
172 void *(*callback)(struct tm_region *, void *),
00d83cc8 173 void *, bool);
0cd02a19 174
4c0315d0 175\f
176/* Return the attributes we want to examine for X, or NULL if it's not
177 something we examine. We look at function types, but allow pointers
178 to function types and function decls and peek through. */
179
180static tree
181get_attrs_for (const_tree x)
182{
547355ae 183 if (x == NULL_TREE)
184 return NULL_TREE;
185
4c0315d0 186 switch (TREE_CODE (x))
187 {
188 case FUNCTION_DECL:
189 return TYPE_ATTRIBUTES (TREE_TYPE (x));
190 break;
191
192 default:
193 if (TYPE_P (x))
547355ae 194 return NULL_TREE;
4c0315d0 195 x = TREE_TYPE (x);
196 if (TREE_CODE (x) != POINTER_TYPE)
547355ae 197 return NULL_TREE;
4c0315d0 198 /* FALLTHRU */
199
200 case POINTER_TYPE:
201 x = TREE_TYPE (x);
202 if (TREE_CODE (x) != FUNCTION_TYPE && TREE_CODE (x) != METHOD_TYPE)
547355ae 203 return NULL_TREE;
4c0315d0 204 /* FALLTHRU */
205
206 case FUNCTION_TYPE:
207 case METHOD_TYPE:
208 return TYPE_ATTRIBUTES (x);
209 }
210}
211
212/* Return true if X has been marked TM_PURE. */
213
214bool
215is_tm_pure (const_tree x)
216{
217 unsigned flags;
218
219 switch (TREE_CODE (x))
220 {
221 case FUNCTION_DECL:
222 case FUNCTION_TYPE:
223 case METHOD_TYPE:
224 break;
225
226 default:
227 if (TYPE_P (x))
228 return false;
229 x = TREE_TYPE (x);
230 if (TREE_CODE (x) != POINTER_TYPE)
231 return false;
232 /* FALLTHRU */
233
234 case POINTER_TYPE:
235 x = TREE_TYPE (x);
236 if (TREE_CODE (x) != FUNCTION_TYPE && TREE_CODE (x) != METHOD_TYPE)
237 return false;
238 break;
239 }
240
241 flags = flags_from_decl_or_type (x);
242 return (flags & ECF_TM_PURE) != 0;
243}
244
245/* Return true if X has been marked TM_IRREVOCABLE. */
246
247static bool
248is_tm_irrevocable (tree x)
249{
250 tree attrs = get_attrs_for (x);
251
252 if (attrs && lookup_attribute ("transaction_unsafe", attrs))
253 return true;
254
255 /* A call to the irrevocable builtin is by definition,
256 irrevocable. */
257 if (TREE_CODE (x) == ADDR_EXPR)
258 x = TREE_OPERAND (x, 0);
259 if (TREE_CODE (x) == FUNCTION_DECL
260 && DECL_BUILT_IN_CLASS (x) == BUILT_IN_NORMAL
261 && DECL_FUNCTION_CODE (x) == BUILT_IN_TM_IRREVOCABLE)
262 return true;
263
264 return false;
265}
266
267/* Return true if X has been marked TM_SAFE. */
268
269bool
270is_tm_safe (const_tree x)
271{
272 if (flag_tm)
273 {
274 tree attrs = get_attrs_for (x);
275 if (attrs)
276 {
277 if (lookup_attribute ("transaction_safe", attrs))
278 return true;
279 if (lookup_attribute ("transaction_may_cancel_outer", attrs))
280 return true;
281 }
282 }
283 return false;
284}
285
286/* Return true if CALL is const, or tm_pure. */
287
288static bool
289is_tm_pure_call (gimple call)
290{
291 tree fn = gimple_call_fn (call);
292
293 if (TREE_CODE (fn) == ADDR_EXPR)
294 {
295 fn = TREE_OPERAND (fn, 0);
296 gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
297 }
298 else
299 fn = TREE_TYPE (fn);
300
301 return is_tm_pure (fn);
302}
303
304/* Return true if X has been marked TM_CALLABLE. */
305
306static bool
307is_tm_callable (tree x)
308{
309 tree attrs = get_attrs_for (x);
310 if (attrs)
311 {
312 if (lookup_attribute ("transaction_callable", attrs))
313 return true;
314 if (lookup_attribute ("transaction_safe", attrs))
315 return true;
316 if (lookup_attribute ("transaction_may_cancel_outer", attrs))
317 return true;
318 }
319 return false;
320}
321
322/* Return true if X has been marked TRANSACTION_MAY_CANCEL_OUTER. */
323
324bool
325is_tm_may_cancel_outer (tree x)
326{
327 tree attrs = get_attrs_for (x);
328 if (attrs)
329 return lookup_attribute ("transaction_may_cancel_outer", attrs) != NULL;
330 return false;
331}
332
333/* Return true for built in functions that "end" a transaction. */
334
335bool
336is_tm_ending_fndecl (tree fndecl)
337{
338 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
339 switch (DECL_FUNCTION_CODE (fndecl))
340 {
341 case BUILT_IN_TM_COMMIT:
342 case BUILT_IN_TM_COMMIT_EH:
343 case BUILT_IN_TM_ABORT:
344 case BUILT_IN_TM_IRREVOCABLE:
345 return true;
346 default:
347 break;
348 }
349
350 return false;
351}
352
50a50143 353/* Return true if STMT is a built in function call that "ends" a
354 transaction. */
355
356bool
357is_tm_ending (gimple stmt)
358{
359 tree fndecl;
360
361 if (gimple_code (stmt) != GIMPLE_CALL)
362 return false;
363
364 fndecl = gimple_call_fndecl (stmt);
365 return (fndecl != NULL_TREE
366 && is_tm_ending_fndecl (fndecl));
367}
368
4c0315d0 369/* Return true if STMT is a TM load. */
370
371static bool
372is_tm_load (gimple stmt)
373{
374 tree fndecl;
375
376 if (gimple_code (stmt) != GIMPLE_CALL)
377 return false;
378
379 fndecl = gimple_call_fndecl (stmt);
380 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
381 && BUILTIN_TM_LOAD_P (DECL_FUNCTION_CODE (fndecl)));
382}
383
384/* Same as above, but for simple TM loads, that is, not the
385 after-write, after-read, etc optimized variants. */
386
387static bool
388is_tm_simple_load (gimple stmt)
389{
390 tree fndecl;
391
392 if (gimple_code (stmt) != GIMPLE_CALL)
393 return false;
394
395 fndecl = gimple_call_fndecl (stmt);
396 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
397 {
398 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
399 return (fcode == BUILT_IN_TM_LOAD_1
400 || fcode == BUILT_IN_TM_LOAD_2
401 || fcode == BUILT_IN_TM_LOAD_4
402 || fcode == BUILT_IN_TM_LOAD_8
403 || fcode == BUILT_IN_TM_LOAD_FLOAT
404 || fcode == BUILT_IN_TM_LOAD_DOUBLE
405 || fcode == BUILT_IN_TM_LOAD_LDOUBLE
406 || fcode == BUILT_IN_TM_LOAD_M64
407 || fcode == BUILT_IN_TM_LOAD_M128
408 || fcode == BUILT_IN_TM_LOAD_M256);
409 }
410 return false;
411}
412
413/* Return true if STMT is a TM store. */
414
415static bool
416is_tm_store (gimple stmt)
417{
418 tree fndecl;
419
420 if (gimple_code (stmt) != GIMPLE_CALL)
421 return false;
422
423 fndecl = gimple_call_fndecl (stmt);
424 return (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
425 && BUILTIN_TM_STORE_P (DECL_FUNCTION_CODE (fndecl)));
426}
427
428/* Same as above, but for simple TM stores, that is, not the
429 after-write, after-read, etc optimized variants. */
430
431static bool
432is_tm_simple_store (gimple stmt)
433{
434 tree fndecl;
435
436 if (gimple_code (stmt) != GIMPLE_CALL)
437 return false;
438
439 fndecl = gimple_call_fndecl (stmt);
440 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
441 {
442 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
443 return (fcode == BUILT_IN_TM_STORE_1
444 || fcode == BUILT_IN_TM_STORE_2
445 || fcode == BUILT_IN_TM_STORE_4
446 || fcode == BUILT_IN_TM_STORE_8
447 || fcode == BUILT_IN_TM_STORE_FLOAT
448 || fcode == BUILT_IN_TM_STORE_DOUBLE
449 || fcode == BUILT_IN_TM_STORE_LDOUBLE
450 || fcode == BUILT_IN_TM_STORE_M64
451 || fcode == BUILT_IN_TM_STORE_M128
452 || fcode == BUILT_IN_TM_STORE_M256);
453 }
454 return false;
455}
456
457/* Return true if FNDECL is BUILT_IN_TM_ABORT. */
458
459static bool
460is_tm_abort (tree fndecl)
461{
462 return (fndecl
463 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
464 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_TM_ABORT);
465}
466
467/* Build a GENERIC tree for a user abort. This is called by front ends
468 while transforming the __tm_abort statement. */
469
470tree
471build_tm_abort_call (location_t loc, bool is_outer)
472{
473 return build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TM_ABORT), 1,
474 build_int_cst (integer_type_node,
475 AR_USERABORT
476 | (is_outer ? AR_OUTERABORT : 0)));
477}
4c0315d0 478\f
479/* Map for aribtrary function replacement under TM, as created
480 by the tm_wrap attribute. */
481
d1023d12 482struct tm_wrapper_hasher : ggc_cache_hasher<tree_map *>
483{
484 static inline hashval_t hash (tree_map *m) { return m->hash; }
485 static inline bool
486 equal (tree_map *a, tree_map *b)
487 {
488 return a->base.from == b->base.from;
489 }
490
491 static void
492 handle_cache_entry (tree_map *&m)
493 {
494 extern void gt_ggc_mx (tree_map *&);
495 if (m == HTAB_EMPTY_ENTRY || m == HTAB_DELETED_ENTRY)
496 return;
497 else if (ggc_marked_p (m->base.from))
498 gt_ggc_mx (m);
499 else
500 m = static_cast<tree_map *> (HTAB_DELETED_ENTRY);
501 }
502};
503
504static GTY((cache)) hash_table<tm_wrapper_hasher> *tm_wrap_map;
4c0315d0 505
506void
507record_tm_replacement (tree from, tree to)
508{
509 struct tree_map **slot, *h;
510
511 /* Do not inline wrapper functions that will get replaced in the TM
512 pass.
513
514 Suppose you have foo() that will get replaced into tmfoo(). Make
515 sure the inliner doesn't try to outsmart us and inline foo()
516 before we get a chance to do the TM replacement. */
517 DECL_UNINLINABLE (from) = 1;
518
519 if (tm_wrap_map == NULL)
d1023d12 520 tm_wrap_map = hash_table<tm_wrapper_hasher>::create_ggc (32);
4c0315d0 521
25a27413 522 h = ggc_alloc<tree_map> ();
4c0315d0 523 h->hash = htab_hash_pointer (from);
524 h->base.from = from;
525 h->to = to;
526
d1023d12 527 slot = tm_wrap_map->find_slot_with_hash (h, h->hash, INSERT);
4c0315d0 528 *slot = h;
529}
530
531/* Return a TM-aware replacement function for DECL. */
532
533static tree
534find_tm_replacement_function (tree fndecl)
535{
536 if (tm_wrap_map)
537 {
538 struct tree_map *h, in;
539
540 in.base.from = fndecl;
541 in.hash = htab_hash_pointer (fndecl);
d1023d12 542 h = tm_wrap_map->find_with_hash (&in, in.hash);
4c0315d0 543 if (h)
544 return h->to;
545 }
546
547 /* ??? We may well want TM versions of most of the common <string.h>
548 functions. For now, we've already these two defined. */
549 /* Adjust expand_call_tm() attributes as necessary for the cases
550 handled here: */
551 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
552 switch (DECL_FUNCTION_CODE (fndecl))
553 {
554 case BUILT_IN_MEMCPY:
555 return builtin_decl_explicit (BUILT_IN_TM_MEMCPY);
556 case BUILT_IN_MEMMOVE:
557 return builtin_decl_explicit (BUILT_IN_TM_MEMMOVE);
558 case BUILT_IN_MEMSET:
559 return builtin_decl_explicit (BUILT_IN_TM_MEMSET);
560 default:
561 return NULL;
562 }
563
564 return NULL;
565}
566
567/* When appropriate, record TM replacement for memory allocation functions.
568
569 FROM is the FNDECL to wrap. */
570void
571tm_malloc_replacement (tree from)
572{
573 const char *str;
574 tree to;
575
576 if (TREE_CODE (from) != FUNCTION_DECL)
577 return;
578
579 /* If we have a previous replacement, the user must be explicitly
580 wrapping malloc/calloc/free. They better know what they're
581 doing... */
582 if (find_tm_replacement_function (from))
583 return;
584
585 str = IDENTIFIER_POINTER (DECL_NAME (from));
586
587 if (!strcmp (str, "malloc"))
588 to = builtin_decl_explicit (BUILT_IN_TM_MALLOC);
589 else if (!strcmp (str, "calloc"))
590 to = builtin_decl_explicit (BUILT_IN_TM_CALLOC);
591 else if (!strcmp (str, "free"))
592 to = builtin_decl_explicit (BUILT_IN_TM_FREE);
593 else
594 return;
595
596 TREE_NOTHROW (to) = 0;
597
598 record_tm_replacement (from, to);
599}
600\f
601/* Diagnostics for tm_safe functions/regions. Called by the front end
602 once we've lowered the function to high-gimple. */
603
604/* Subroutine of diagnose_tm_safe_errors, called through walk_gimple_seq.
605 Process exactly one statement. WI->INFO is set to non-null when in
606 the context of a tm_safe function, and null for a __transaction block. */
607
608#define DIAG_TM_OUTER 1
609#define DIAG_TM_SAFE 2
610#define DIAG_TM_RELAXED 4
611
612struct diagnose_tm
613{
614 unsigned int summary_flags : 8;
615 unsigned int block_flags : 8;
616 unsigned int func_flags : 8;
4c0315d0 617 unsigned int saw_volatile : 1;
618 gimple stmt;
619};
620
e153bd50 621/* Return true if T is a volatile variable of some kind. */
622
623static bool
624volatile_var_p (tree t)
625{
626 return (SSA_VAR_P (t)
627 && TREE_THIS_VOLATILE (TREE_TYPE (t)));
628}
629
4c0315d0 630/* Tree callback function for diagnose_tm pass. */
631
632static tree
633diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
634 void *data)
635{
636 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
637 struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
4c0315d0 638
e153bd50 639 if (volatile_var_p (*tp)
640 && d->block_flags & DIAG_TM_SAFE
4c0315d0 641 && !d->saw_volatile)
642 {
643 d->saw_volatile = 1;
644 error_at (gimple_location (d->stmt),
645 "invalid volatile use of %qD inside transaction",
646 *tp);
647 }
648
649 return NULL_TREE;
650}
651
0e80b01d 652static inline bool
653is_tm_safe_or_pure (const_tree x)
654{
655 return is_tm_safe (x) || is_tm_pure (x);
656}
657
4c0315d0 658static tree
659diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
660 struct walk_stmt_info *wi)
661{
662 gimple stmt = gsi_stmt (*gsi);
663 struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
664
665 /* Save stmt for use in leaf analysis. */
666 d->stmt = stmt;
667
668 switch (gimple_code (stmt))
669 {
670 case GIMPLE_CALL:
671 {
672 tree fn = gimple_call_fn (stmt);
673
674 if ((d->summary_flags & DIAG_TM_OUTER) == 0
675 && is_tm_may_cancel_outer (fn))
676 error_at (gimple_location (stmt),
677 "%<transaction_may_cancel_outer%> function call not within"
678 " outer transaction or %<transaction_may_cancel_outer%>");
679
680 if (d->summary_flags & DIAG_TM_SAFE)
681 {
682 bool is_safe, direct_call_p;
683 tree replacement;
684
685 if (TREE_CODE (fn) == ADDR_EXPR
686 && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
687 {
688 direct_call_p = true;
689 replacement = TREE_OPERAND (fn, 0);
690 replacement = find_tm_replacement_function (replacement);
691 if (replacement)
692 fn = replacement;
693 }
694 else
695 {
696 direct_call_p = false;
697 replacement = NULL_TREE;
698 }
699
700 if (is_tm_safe_or_pure (fn))
701 is_safe = true;
702 else if (is_tm_callable (fn) || is_tm_irrevocable (fn))
703 {
704 /* A function explicitly marked transaction_callable as
705 opposed to transaction_safe is being defined to be
706 unsafe as part of its ABI, regardless of its contents. */
707 is_safe = false;
708 }
709 else if (direct_call_p)
710 {
c579aed5 711 if (IS_TYPE_OR_DECL_P (fn)
712 && flags_from_decl_or_type (fn) & ECF_TM_BUILTIN)
4c0315d0 713 is_safe = true;
714 else if (replacement)
715 {
716 /* ??? At present we've been considering replacements
717 merely transaction_callable, and therefore might
718 enter irrevocable. The tm_wrap attribute has not
719 yet made it into the new language spec. */
720 is_safe = false;
721 }
722 else
723 {
724 /* ??? Diagnostics for unmarked direct calls moved into
725 the IPA pass. Section 3.2 of the spec details how
726 functions not marked should be considered "implicitly
727 safe" based on having examined the function body. */
728 is_safe = true;
729 }
730 }
731 else
732 {
733 /* An unmarked indirect call. Consider it unsafe even
734 though optimization may yet figure out how to inline. */
735 is_safe = false;
736 }
737
738 if (!is_safe)
739 {
740 if (TREE_CODE (fn) == ADDR_EXPR)
741 fn = TREE_OPERAND (fn, 0);
742 if (d->block_flags & DIAG_TM_SAFE)
2d3bf658 743 {
744 if (direct_call_p)
745 error_at (gimple_location (stmt),
746 "unsafe function call %qD within "
747 "atomic transaction", fn);
748 else
300eddba 749 {
750 if (!DECL_P (fn) || DECL_NAME (fn))
751 error_at (gimple_location (stmt),
752 "unsafe function call %qE within "
753 "atomic transaction", fn);
754 else
755 error_at (gimple_location (stmt),
756 "unsafe indirect function call within "
757 "atomic transaction");
758 }
2d3bf658 759 }
4c0315d0 760 else
2d3bf658 761 {
762 if (direct_call_p)
763 error_at (gimple_location (stmt),
764 "unsafe function call %qD within "
765 "%<transaction_safe%> function", fn);
766 else
300eddba 767 {
768 if (!DECL_P (fn) || DECL_NAME (fn))
769 error_at (gimple_location (stmt),
770 "unsafe function call %qE within "
771 "%<transaction_safe%> function", fn);
772 else
773 error_at (gimple_location (stmt),
774 "unsafe indirect function call within "
775 "%<transaction_safe%> function");
776 }
2d3bf658 777 }
4c0315d0 778 }
779 }
780 }
781 break;
782
783 case GIMPLE_ASM:
784 /* ??? We ought to come up with a way to add attributes to
785 asm statements, and then add "transaction_safe" to it.
786 Either that or get the language spec to resurrect __tm_waiver. */
787 if (d->block_flags & DIAG_TM_SAFE)
788 error_at (gimple_location (stmt),
789 "asm not allowed in atomic transaction");
790 else if (d->func_flags & DIAG_TM_SAFE)
791 error_at (gimple_location (stmt),
792 "asm not allowed in %<transaction_safe%> function");
4c0315d0 793 break;
794
795 case GIMPLE_TRANSACTION:
796 {
1a91d914 797 gtransaction *trans_stmt = as_a <gtransaction *> (stmt);
4c0315d0 798 unsigned char inner_flags = DIAG_TM_SAFE;
799
1a91d914 800 if (gimple_transaction_subcode (trans_stmt) & GTMA_IS_RELAXED)
4c0315d0 801 {
802 if (d->block_flags & DIAG_TM_SAFE)
803 error_at (gimple_location (stmt),
804 "relaxed transaction in atomic transaction");
805 else if (d->func_flags & DIAG_TM_SAFE)
806 error_at (gimple_location (stmt),
807 "relaxed transaction in %<transaction_safe%> function");
4c0315d0 808 inner_flags = DIAG_TM_RELAXED;
809 }
1a91d914 810 else if (gimple_transaction_subcode (trans_stmt) & GTMA_IS_OUTER)
4c0315d0 811 {
812 if (d->block_flags)
813 error_at (gimple_location (stmt),
814 "outer transaction in transaction");
815 else if (d->func_flags & DIAG_TM_OUTER)
816 error_at (gimple_location (stmt),
817 "outer transaction in "
818 "%<transaction_may_cancel_outer%> function");
819 else if (d->func_flags & DIAG_TM_SAFE)
820 error_at (gimple_location (stmt),
821 "outer transaction in %<transaction_safe%> function");
4c0315d0 822 inner_flags |= DIAG_TM_OUTER;
823 }
824
825 *handled_ops_p = true;
1a91d914 826 if (gimple_transaction_body (trans_stmt))
4c0315d0 827 {
828 struct walk_stmt_info wi_inner;
829 struct diagnose_tm d_inner;
830
831 memset (&d_inner, 0, sizeof (d_inner));
832 d_inner.func_flags = d->func_flags;
833 d_inner.block_flags = d->block_flags | inner_flags;
834 d_inner.summary_flags = d_inner.func_flags | d_inner.block_flags;
835
836 memset (&wi_inner, 0, sizeof (wi_inner));
837 wi_inner.info = &d_inner;
838
1a91d914 839 walk_gimple_seq (gimple_transaction_body (trans_stmt),
4c0315d0 840 diagnose_tm_1, diagnose_tm_1_op, &wi_inner);
4c0315d0 841 }
842 }
843 break;
844
845 default:
846 break;
847 }
848
849 return NULL_TREE;
850}
851
852static unsigned int
853diagnose_tm_blocks (void)
854{
855 struct walk_stmt_info wi;
856 struct diagnose_tm d;
857
858 memset (&d, 0, sizeof (d));
859 if (is_tm_may_cancel_outer (current_function_decl))
860 d.func_flags = DIAG_TM_OUTER | DIAG_TM_SAFE;
861 else if (is_tm_safe (current_function_decl))
862 d.func_flags = DIAG_TM_SAFE;
863 d.summary_flags = d.func_flags;
864
865 memset (&wi, 0, sizeof (wi));
866 wi.info = &d;
867
868 walk_gimple_seq (gimple_body (current_function_decl),
869 diagnose_tm_1, diagnose_tm_1_op, &wi);
870
4c0315d0 871 return 0;
872}
873
cbe8bda8 874namespace {
875
876const pass_data pass_data_diagnose_tm_blocks =
877{
878 GIMPLE_PASS, /* type */
879 "*diagnose_tm_blocks", /* name */
880 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 881 TV_TRANS_MEM, /* tv_id */
882 PROP_gimple_any, /* properties_required */
883 0, /* properties_provided */
884 0, /* properties_destroyed */
885 0, /* todo_flags_start */
886 0, /* todo_flags_finish */
4c0315d0 887};
cbe8bda8 888
889class pass_diagnose_tm_blocks : public gimple_opt_pass
890{
891public:
9af5ce0c 892 pass_diagnose_tm_blocks (gcc::context *ctxt)
893 : gimple_opt_pass (pass_data_diagnose_tm_blocks, ctxt)
cbe8bda8 894 {}
895
896 /* opt_pass methods: */
31315c24 897 virtual bool gate (function *) { return flag_tm; }
65b0537f 898 virtual unsigned int execute (function *) { return diagnose_tm_blocks (); }
cbe8bda8 899
900}; // class pass_diagnose_tm_blocks
901
902} // anon namespace
903
904gimple_opt_pass *
905make_pass_diagnose_tm_blocks (gcc::context *ctxt)
906{
907 return new pass_diagnose_tm_blocks (ctxt);
908}
4c0315d0 909\f
910/* Instead of instrumenting thread private memory, we save the
911 addresses in a log which we later use to save/restore the addresses
912 upon transaction start/restart.
913
914 The log is keyed by address, where each element contains individual
915 statements among different code paths that perform the store.
916
917 This log is later used to generate either plain save/restore of the
918 addresses upon transaction start/restart, or calls to the ITM_L*
919 logging functions.
920
921 So for something like:
922
923 struct large { int x[1000]; };
924 struct large lala = { 0 };
925 __transaction {
926 lala.x[i] = 123;
927 ...
928 }
929
930 We can either save/restore:
931
932 lala = { 0 };
933 trxn = _ITM_startTransaction ();
934 if (trxn & a_saveLiveVariables)
935 tmp_lala1 = lala.x[i];
936 else if (a & a_restoreLiveVariables)
937 lala.x[i] = tmp_lala1;
938
939 or use the logging functions:
940
941 lala = { 0 };
942 trxn = _ITM_startTransaction ();
943 _ITM_LU4 (&lala.x[i]);
944
945 Obviously, if we use _ITM_L* to log, we prefer to call _ITM_L* as
946 far up the dominator tree to shadow all of the writes to a given
947 location (thus reducing the total number of logging calls), but not
948 so high as to be called on a path that does not perform a
949 write. */
950
951/* One individual log entry. We may have multiple statements for the
952 same location if neither dominate each other (on different
953 execution paths). */
954typedef struct tm_log_entry
955{
956 /* Address to save. */
957 tree addr;
958 /* Entry block for the transaction this address occurs in. */
959 basic_block entry_block;
960 /* Dominating statements the store occurs in. */
1a91d914 961 vec<gimple> stmts;
4c0315d0 962 /* Initially, while we are building the log, we place a nonzero
963 value here to mean that this address *will* be saved with a
964 save/restore sequence. Later, when generating the save sequence
965 we place the SSA temp generated here. */
966 tree save_var;
967} *tm_log_entry_t;
968
4c0315d0 969
d9dd21a8 970/* Log entry hashtable helpers. */
4c0315d0 971
d9dd21a8 972struct log_entry_hasher
4c0315d0 973{
9969c043 974 typedef tm_log_entry *value_type;
975 typedef tm_log_entry *compare_type;
976 static inline hashval_t hash (const tm_log_entry *);
977 static inline bool equal (const tm_log_entry *, const tm_log_entry *);
978 static inline void remove (tm_log_entry *);
d9dd21a8 979};
4c0315d0 980
981/* Htab support. Return hash value for a `tm_log_entry'. */
d9dd21a8 982inline hashval_t
9969c043 983log_entry_hasher::hash (const tm_log_entry *log)
4c0315d0 984{
4c0315d0 985 return iterative_hash_expr (log->addr, 0);
986}
987
988/* Htab support. Return true if two log entries are the same. */
d9dd21a8 989inline bool
9969c043 990log_entry_hasher::equal (const tm_log_entry *log1, const tm_log_entry *log2)
4c0315d0 991{
4c0315d0 992 /* FIXME:
993
994 rth: I suggest that we get rid of the component refs etc.
995 I.e. resolve the reference to base + offset.
996
997 We may need to actually finish a merge with mainline for this,
998 since we'd like to be presented with Richi's MEM_REF_EXPRs more
999 often than not. But in the meantime your tm_log_entry could save
1000 the results of get_inner_reference.
1001
1002 See: g++.dg/tm/pr46653.C
1003 */
1004
1005 /* Special case plain equality because operand_equal_p() below will
1006 return FALSE if the addresses are equal but they have
1007 side-effects (e.g. a volatile address). */
1008 if (log1->addr == log2->addr)
1009 return true;
1010
1011 return operand_equal_p (log1->addr, log2->addr, 0);
1012}
1013
1014/* Htab support. Free one tm_log_entry. */
d9dd21a8 1015inline void
9969c043 1016log_entry_hasher::remove (tm_log_entry *lp)
4c0315d0 1017{
f1f41a6c 1018 lp->stmts.release ();
4c0315d0 1019 free (lp);
1020}
1021
d9dd21a8 1022
1023/* The actual log. */
c1f445d2 1024static hash_table<log_entry_hasher> *tm_log;
d9dd21a8 1025
1026/* Addresses to log with a save/restore sequence. These should be in
1027 dominator order. */
1028static vec<tree> tm_log_save_addresses;
1029
1030enum thread_memory_type
1031 {
1032 mem_non_local = 0,
1033 mem_thread_local,
1034 mem_transaction_local,
1035 mem_max
1036 };
1037
1038typedef struct tm_new_mem_map
1039{
1040 /* SSA_NAME being dereferenced. */
1041 tree val;
1042 enum thread_memory_type local_new_memory;
1043} tm_new_mem_map_t;
1044
1045/* Hashtable helpers. */
1046
1047struct tm_mem_map_hasher : typed_free_remove <tm_new_mem_map_t>
1048{
9969c043 1049 typedef tm_new_mem_map_t *value_type;
1050 typedef tm_new_mem_map_t *compare_type;
1051 static inline hashval_t hash (const tm_new_mem_map_t *);
1052 static inline bool equal (const tm_new_mem_map_t *, const tm_new_mem_map_t *);
d9dd21a8 1053};
1054
1055inline hashval_t
9969c043 1056tm_mem_map_hasher::hash (const tm_new_mem_map_t *v)
d9dd21a8 1057{
1058 return (intptr_t)v->val >> 4;
1059}
1060
1061inline bool
9969c043 1062tm_mem_map_hasher::equal (const tm_new_mem_map_t *v, const tm_new_mem_map_t *c)
d9dd21a8 1063{
1064 return v->val == c->val;
1065}
1066
1067/* Map for an SSA_NAME originally pointing to a non aliased new piece
1068 of memory (malloc, alloc, etc). */
c1f445d2 1069static hash_table<tm_mem_map_hasher> *tm_new_mem_hash;
d9dd21a8 1070
4c0315d0 1071/* Initialize logging data structures. */
1072static void
1073tm_log_init (void)
1074{
c1f445d2 1075 tm_log = new hash_table<log_entry_hasher> (10);
1076 tm_new_mem_hash = new hash_table<tm_mem_map_hasher> (5);
f1f41a6c 1077 tm_log_save_addresses.create (5);
4c0315d0 1078}
1079
1080/* Free logging data structures. */
1081static void
1082tm_log_delete (void)
1083{
c1f445d2 1084 delete tm_log;
1085 tm_log = NULL;
1086 delete tm_new_mem_hash;
1087 tm_new_mem_hash = NULL;
f1f41a6c 1088 tm_log_save_addresses.release ();
4c0315d0 1089}
1090
1091/* Return true if MEM is a transaction invariant memory for the TM
1092 region starting at REGION_ENTRY_BLOCK. */
1093static bool
1094transaction_invariant_address_p (const_tree mem, basic_block region_entry_block)
1095{
1096 if ((TREE_CODE (mem) == INDIRECT_REF || TREE_CODE (mem) == MEM_REF)
1097 && TREE_CODE (TREE_OPERAND (mem, 0)) == SSA_NAME)
1098 {
1099 basic_block def_bb;
1100
1101 def_bb = gimple_bb (SSA_NAME_DEF_STMT (TREE_OPERAND (mem, 0)));
1102 return def_bb != region_entry_block
1103 && dominated_by_p (CDI_DOMINATORS, region_entry_block, def_bb);
1104 }
1105
1106 mem = strip_invariant_refs (mem);
1107 return mem && (CONSTANT_CLASS_P (mem) || decl_address_invariant_p (mem));
1108}
1109
1110/* Given an address ADDR in STMT, find it in the memory log or add it,
1111 making sure to keep only the addresses highest in the dominator
1112 tree.
1113
1114 ENTRY_BLOCK is the entry_block for the transaction.
1115
1116 If we find the address in the log, make sure it's either the same
1117 address, or an equivalent one that dominates ADDR.
1118
1119 If we find the address, but neither ADDR dominates the found
1120 address, nor the found one dominates ADDR, we're on different
1121 execution paths. Add it.
1122
1123 If known, ENTRY_BLOCK is the entry block for the region, otherwise
1124 NULL. */
1125static void
1126tm_log_add (basic_block entry_block, tree addr, gimple stmt)
1127{
d9dd21a8 1128 tm_log_entry **slot;
4c0315d0 1129 struct tm_log_entry l, *lp;
1130
1131 l.addr = addr;
c1f445d2 1132 slot = tm_log->find_slot (&l, INSERT);
4c0315d0 1133 if (!*slot)
1134 {
1135 tree type = TREE_TYPE (addr);
1136
1137 lp = XNEW (struct tm_log_entry);
1138 lp->addr = addr;
1139 *slot = lp;
1140
1141 /* Small invariant addresses can be handled as save/restores. */
1142 if (entry_block
1143 && transaction_invariant_address_p (lp->addr, entry_block)
1144 && TYPE_SIZE_UNIT (type) != NULL
cd4547bf 1145 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
aa59f000 1146 && ((HOST_WIDE_INT) tree_to_uhwi (TYPE_SIZE_UNIT (type))
4c0315d0 1147 < PARAM_VALUE (PARAM_TM_MAX_AGGREGATE_SIZE))
1148 /* We must be able to copy this type normally. I.e., no
1149 special constructors and the like. */
1150 && !TREE_ADDRESSABLE (type))
1151 {
54a0a932 1152 lp->save_var = create_tmp_reg (TREE_TYPE (lp->addr), "tm_save");
f1f41a6c 1153 lp->stmts.create (0);
4c0315d0 1154 lp->entry_block = entry_block;
1155 /* Save addresses separately in dominator order so we don't
1156 get confused by overlapping addresses in the save/restore
1157 sequence. */
f1f41a6c 1158 tm_log_save_addresses.safe_push (lp->addr);
4c0315d0 1159 }
1160 else
1161 {
1162 /* Use the logging functions. */
f1f41a6c 1163 lp->stmts.create (5);
1164 lp->stmts.quick_push (stmt);
4c0315d0 1165 lp->save_var = NULL;
1166 }
1167 }
1168 else
1169 {
1170 size_t i;
1171 gimple oldstmt;
1172
d9dd21a8 1173 lp = *slot;
4c0315d0 1174
1175 /* If we're generating a save/restore sequence, we don't care
1176 about statements. */
1177 if (lp->save_var)
1178 return;
1179
f1f41a6c 1180 for (i = 0; lp->stmts.iterate (i, &oldstmt); ++i)
4c0315d0 1181 {
1182 if (stmt == oldstmt)
1183 return;
1184 /* We already have a store to the same address, higher up the
1185 dominator tree. Nothing to do. */
1186 if (dominated_by_p (CDI_DOMINATORS,
1187 gimple_bb (stmt), gimple_bb (oldstmt)))
1188 return;
1189 /* We should be processing blocks in dominator tree order. */
1190 gcc_assert (!dominated_by_p (CDI_DOMINATORS,
1191 gimple_bb (oldstmt), gimple_bb (stmt)));
1192 }
1193 /* Store is on a different code path. */
f1f41a6c 1194 lp->stmts.safe_push (stmt);
4c0315d0 1195 }
1196}
1197
1198/* Gimplify the address of a TARGET_MEM_REF. Return the SSA_NAME
1199 result, insert the new statements before GSI. */
1200
1201static tree
1202gimplify_addr (gimple_stmt_iterator *gsi, tree x)
1203{
1204 if (TREE_CODE (x) == TARGET_MEM_REF)
1205 x = tree_mem_ref_addr (build_pointer_type (TREE_TYPE (x)), x);
1206 else
1207 x = build_fold_addr_expr (x);
1208 return force_gimple_operand_gsi (gsi, x, true, NULL, true, GSI_SAME_STMT);
1209}
1210
1211/* Instrument one address with the logging functions.
1212 ADDR is the address to save.
1213 STMT is the statement before which to place it. */
1214static void
1215tm_log_emit_stmt (tree addr, gimple stmt)
1216{
1217 tree type = TREE_TYPE (addr);
1218 tree size = TYPE_SIZE_UNIT (type);
1219 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
1220 gimple log;
1221 enum built_in_function code = BUILT_IN_TM_LOG;
1222
1223 if (type == float_type_node)
1224 code = BUILT_IN_TM_LOG_FLOAT;
1225 else if (type == double_type_node)
1226 code = BUILT_IN_TM_LOG_DOUBLE;
1227 else if (type == long_double_type_node)
1228 code = BUILT_IN_TM_LOG_LDOUBLE;
cd4547bf 1229 else if (tree_fits_uhwi_p (size))
4c0315d0 1230 {
6a0712d4 1231 unsigned int n = tree_to_uhwi (size);
4c0315d0 1232 switch (n)
1233 {
1234 case 1:
1235 code = BUILT_IN_TM_LOG_1;
1236 break;
1237 case 2:
1238 code = BUILT_IN_TM_LOG_2;
1239 break;
1240 case 4:
1241 code = BUILT_IN_TM_LOG_4;
1242 break;
1243 case 8:
1244 code = BUILT_IN_TM_LOG_8;
1245 break;
1246 default:
1247 code = BUILT_IN_TM_LOG;
1248 if (TREE_CODE (type) == VECTOR_TYPE)
1249 {
1250 if (n == 8 && builtin_decl_explicit (BUILT_IN_TM_LOG_M64))
1251 code = BUILT_IN_TM_LOG_M64;
1252 else if (n == 16 && builtin_decl_explicit (BUILT_IN_TM_LOG_M128))
1253 code = BUILT_IN_TM_LOG_M128;
1254 else if (n == 32 && builtin_decl_explicit (BUILT_IN_TM_LOG_M256))
1255 code = BUILT_IN_TM_LOG_M256;
1256 }
1257 break;
1258 }
1259 }
1260
1261 addr = gimplify_addr (&gsi, addr);
1262 if (code == BUILT_IN_TM_LOG)
1263 log = gimple_build_call (builtin_decl_explicit (code), 2, addr, size);
1264 else
1265 log = gimple_build_call (builtin_decl_explicit (code), 1, addr);
1266 gsi_insert_before (&gsi, log, GSI_SAME_STMT);
1267}
1268
1269/* Go through the log and instrument address that must be instrumented
1270 with the logging functions. Leave the save/restore addresses for
1271 later. */
1272static void
1273tm_log_emit (void)
1274{
c1f445d2 1275 hash_table<log_entry_hasher>::iterator hi;
4c0315d0 1276 struct tm_log_entry *lp;
1277
c1f445d2 1278 FOR_EACH_HASH_TABLE_ELEMENT (*tm_log, lp, tm_log_entry_t, hi)
4c0315d0 1279 {
1280 size_t i;
1281 gimple stmt;
1282
1283 if (dump_file)
1284 {
1285 fprintf (dump_file, "TM thread private mem logging: ");
1286 print_generic_expr (dump_file, lp->addr, 0);
1287 fprintf (dump_file, "\n");
1288 }
1289
1290 if (lp->save_var)
1291 {
1292 if (dump_file)
1293 fprintf (dump_file, "DUMPING to variable\n");
1294 continue;
1295 }
1296 else
1297 {
1298 if (dump_file)
1299 fprintf (dump_file, "DUMPING with logging functions\n");
f1f41a6c 1300 for (i = 0; lp->stmts.iterate (i, &stmt); ++i)
4c0315d0 1301 tm_log_emit_stmt (lp->addr, stmt);
1302 }
1303 }
1304}
1305
1306/* Emit the save sequence for the corresponding addresses in the log.
1307 ENTRY_BLOCK is the entry block for the transaction.
1308 BB is the basic block to insert the code in. */
1309static void
1310tm_log_emit_saves (basic_block entry_block, basic_block bb)
1311{
1312 size_t i;
1313 gimple_stmt_iterator gsi = gsi_last_bb (bb);
1314 gimple stmt;
1315 struct tm_log_entry l, *lp;
1316
f1f41a6c 1317 for (i = 0; i < tm_log_save_addresses.length (); ++i)
4c0315d0 1318 {
f1f41a6c 1319 l.addr = tm_log_save_addresses[i];
c1f445d2 1320 lp = *(tm_log->find_slot (&l, NO_INSERT));
4c0315d0 1321 gcc_assert (lp->save_var != NULL);
1322
1323 /* We only care about variables in the current transaction. */
1324 if (lp->entry_block != entry_block)
1325 continue;
1326
1327 stmt = gimple_build_assign (lp->save_var, unshare_expr (lp->addr));
1328
1329 /* Make sure we can create an SSA_NAME for this type. For
1330 instance, aggregates aren't allowed, in which case the system
1331 will create a VOP for us and everything will just work. */
1332 if (is_gimple_reg_type (TREE_TYPE (lp->save_var)))
1333 {
1334 lp->save_var = make_ssa_name (lp->save_var, stmt);
1335 gimple_assign_set_lhs (stmt, lp->save_var);
1336 }
1337
1338 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1339 }
1340}
1341
1342/* Emit the restore sequence for the corresponding addresses in the log.
1343 ENTRY_BLOCK is the entry block for the transaction.
1344 BB is the basic block to insert the code in. */
1345static void
1346tm_log_emit_restores (basic_block entry_block, basic_block bb)
1347{
1348 int i;
1349 struct tm_log_entry l, *lp;
1350 gimple_stmt_iterator gsi;
1351 gimple stmt;
1352
f1f41a6c 1353 for (i = tm_log_save_addresses.length () - 1; i >= 0; i--)
4c0315d0 1354 {
f1f41a6c 1355 l.addr = tm_log_save_addresses[i];
c1f445d2 1356 lp = *(tm_log->find_slot (&l, NO_INSERT));
4c0315d0 1357 gcc_assert (lp->save_var != NULL);
1358
1359 /* We only care about variables in the current transaction. */
1360 if (lp->entry_block != entry_block)
1361 continue;
1362
1363 /* Restores are in LIFO order from the saves in case we have
1364 overlaps. */
1365 gsi = gsi_start_bb (bb);
1366
1367 stmt = gimple_build_assign (unshare_expr (lp->addr), lp->save_var);
1368 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
1369 }
1370}
1371
4c0315d0 1372\f
1373static tree lower_sequence_tm (gimple_stmt_iterator *, bool *,
1374 struct walk_stmt_info *);
1375static tree lower_sequence_no_tm (gimple_stmt_iterator *, bool *,
1376 struct walk_stmt_info *);
1377
1378/* Evaluate an address X being dereferenced and determine if it
1379 originally points to a non aliased new chunk of memory (malloc,
1380 alloca, etc).
1381
1382 Return MEM_THREAD_LOCAL if it points to a thread-local address.
1383 Return MEM_TRANSACTION_LOCAL if it points to a transaction-local address.
1384 Return MEM_NON_LOCAL otherwise.
1385
1386 ENTRY_BLOCK is the entry block to the transaction containing the
1387 dereference of X. */
1388static enum thread_memory_type
1389thread_private_new_memory (basic_block entry_block, tree x)
1390{
1391 gimple stmt = NULL;
1392 enum tree_code code;
d9dd21a8 1393 tm_new_mem_map_t **slot;
4c0315d0 1394 tm_new_mem_map_t elt, *elt_p;
1395 tree val = x;
1396 enum thread_memory_type retval = mem_transaction_local;
1397
1398 if (!entry_block
1399 || TREE_CODE (x) != SSA_NAME
1400 /* Possible uninitialized use, or a function argument. In
1401 either case, we don't care. */
1402 || SSA_NAME_IS_DEFAULT_DEF (x))
1403 return mem_non_local;
1404
1405 /* Look in cache first. */
1406 elt.val = x;
c1f445d2 1407 slot = tm_new_mem_hash->find_slot (&elt, INSERT);
d9dd21a8 1408 elt_p = *slot;
4c0315d0 1409 if (elt_p)
1410 return elt_p->local_new_memory;
1411
1412 /* Optimistically assume the memory is transaction local during
1413 processing. This catches recursion into this variable. */
1414 *slot = elt_p = XNEW (tm_new_mem_map_t);
1415 elt_p->val = val;
1416 elt_p->local_new_memory = mem_transaction_local;
1417
1418 /* Search DEF chain to find the original definition of this address. */
1419 do
1420 {
1421 if (ptr_deref_may_alias_global_p (x))
1422 {
1423 /* Address escapes. This is not thread-private. */
1424 retval = mem_non_local;
1425 goto new_memory_ret;
1426 }
1427
1428 stmt = SSA_NAME_DEF_STMT (x);
1429
1430 /* If the malloc call is outside the transaction, this is
1431 thread-local. */
1432 if (retval != mem_thread_local
1433 && !dominated_by_p (CDI_DOMINATORS, gimple_bb (stmt), entry_block))
1434 retval = mem_thread_local;
1435
1436 if (is_gimple_assign (stmt))
1437 {
1438 code = gimple_assign_rhs_code (stmt);
1439 /* x = foo ==> foo */
1440 if (code == SSA_NAME)
1441 x = gimple_assign_rhs1 (stmt);
1442 /* x = foo + n ==> foo */
1443 else if (code == POINTER_PLUS_EXPR)
1444 x = gimple_assign_rhs1 (stmt);
1445 /* x = (cast*) foo ==> foo */
d09ef31a 1446 else if (code == VIEW_CONVERT_EXPR || CONVERT_EXPR_CODE_P (code))
4c0315d0 1447 x = gimple_assign_rhs1 (stmt);
43ee99ea 1448 /* x = c ? op1 : op2 == > op1 or op2 just like a PHI */
1449 else if (code == COND_EXPR)
1450 {
1451 tree op1 = gimple_assign_rhs2 (stmt);
1452 tree op2 = gimple_assign_rhs3 (stmt);
1453 enum thread_memory_type mem;
1454 retval = thread_private_new_memory (entry_block, op1);
1455 if (retval == mem_non_local)
1456 goto new_memory_ret;
1457 mem = thread_private_new_memory (entry_block, op2);
1458 retval = MIN (retval, mem);
1459 goto new_memory_ret;
1460 }
4c0315d0 1461 else
1462 {
1463 retval = mem_non_local;
1464 goto new_memory_ret;
1465 }
1466 }
1467 else
1468 {
1469 if (gimple_code (stmt) == GIMPLE_PHI)
1470 {
1471 unsigned int i;
1472 enum thread_memory_type mem;
1473 tree phi_result = gimple_phi_result (stmt);
1474
1475 /* If any of the ancestors are non-local, we are sure to
1476 be non-local. Otherwise we can avoid doing anything
1477 and inherit what has already been generated. */
1478 retval = mem_max;
1479 for (i = 0; i < gimple_phi_num_args (stmt); ++i)
1480 {
1481 tree op = PHI_ARG_DEF (stmt, i);
1482
1483 /* Exclude self-assignment. */
1484 if (phi_result == op)
1485 continue;
1486
1487 mem = thread_private_new_memory (entry_block, op);
1488 if (mem == mem_non_local)
1489 {
1490 retval = mem;
1491 goto new_memory_ret;
1492 }
1493 retval = MIN (retval, mem);
1494 }
1495 goto new_memory_ret;
1496 }
1497 break;
1498 }
1499 }
1500 while (TREE_CODE (x) == SSA_NAME);
1501
1502 if (stmt && is_gimple_call (stmt) && gimple_call_flags (stmt) & ECF_MALLOC)
1503 /* Thread-local or transaction-local. */
1504 ;
1505 else
1506 retval = mem_non_local;
1507
1508 new_memory_ret:
1509 elt_p->local_new_memory = retval;
1510 return retval;
1511}
1512
1513/* Determine whether X has to be instrumented using a read
1514 or write barrier.
1515
1516 ENTRY_BLOCK is the entry block for the region where stmt resides
1517 in. NULL if unknown.
1518
1519 STMT is the statement in which X occurs in. It is used for thread
1520 private memory instrumentation. If no TPM instrumentation is
1521 desired, STMT should be null. */
1522static bool
1523requires_barrier (basic_block entry_block, tree x, gimple stmt)
1524{
1525 tree orig = x;
1526 while (handled_component_p (x))
1527 x = TREE_OPERAND (x, 0);
1528
1529 switch (TREE_CODE (x))
1530 {
1531 case INDIRECT_REF:
1532 case MEM_REF:
1533 {
1534 enum thread_memory_type ret;
1535
1536 ret = thread_private_new_memory (entry_block, TREE_OPERAND (x, 0));
1537 if (ret == mem_non_local)
1538 return true;
1539 if (stmt && ret == mem_thread_local)
1540 /* ?? Should we pass `orig', or the INDIRECT_REF X. ?? */
1541 tm_log_add (entry_block, orig, stmt);
1542
1543 /* Transaction-locals require nothing at all. For malloc, a
1544 transaction restart frees the memory and we reallocate.
1545 For alloca, the stack pointer gets reset by the retry and
1546 we reallocate. */
1547 return false;
1548 }
1549
1550 case TARGET_MEM_REF:
1551 if (TREE_CODE (TMR_BASE (x)) != ADDR_EXPR)
1552 return true;
1553 x = TREE_OPERAND (TMR_BASE (x), 0);
1554 if (TREE_CODE (x) == PARM_DECL)
1555 return false;
1556 gcc_assert (TREE_CODE (x) == VAR_DECL);
1557 /* FALLTHRU */
1558
1559 case PARM_DECL:
1560 case RESULT_DECL:
1561 case VAR_DECL:
1562 if (DECL_BY_REFERENCE (x))
1563 {
1564 /* ??? This value is a pointer, but aggregate_value_p has been
1565 jigged to return true which confuses needs_to_live_in_memory.
1566 This ought to be cleaned up generically.
1567
1568 FIXME: Verify this still happens after the next mainline
1569 merge. Testcase ie g++.dg/tm/pr47554.C.
1570 */
1571 return false;
1572 }
1573
1574 if (is_global_var (x))
e0f3ea3e 1575 return !TREE_READONLY (x);
4c0315d0 1576 if (/* FIXME: This condition should actually go below in the
1577 tm_log_add() call, however is_call_clobbered() depends on
1578 aliasing info which is not available during
1579 gimplification. Since requires_barrier() gets called
1580 during lower_sequence_tm/gimplification, leave the call
1581 to needs_to_live_in_memory until we eliminate
1582 lower_sequence_tm altogether. */
3c8b8a41 1583 needs_to_live_in_memory (x))
4c0315d0 1584 return true;
e0f3ea3e 1585 else
1586 {
1587 /* For local memory that doesn't escape (aka thread private
1588 memory), we can either save the value at the beginning of
1589 the transaction and restore on restart, or call a tm
1590 function to dynamically save and restore on restart
1591 (ITM_L*). */
1592 if (stmt)
1593 tm_log_add (entry_block, orig, stmt);
1594 return false;
1595 }
4c0315d0 1596
1597 default:
1598 return false;
1599 }
1600}
1601
1602/* Mark the GIMPLE_ASSIGN statement as appropriate for being inside
1603 a transaction region. */
1604
1605static void
1606examine_assign_tm (unsigned *state, gimple_stmt_iterator *gsi)
1607{
1608 gimple stmt = gsi_stmt (*gsi);
1609
1610 if (requires_barrier (/*entry_block=*/NULL, gimple_assign_rhs1 (stmt), NULL))
1611 *state |= GTMA_HAVE_LOAD;
1612 if (requires_barrier (/*entry_block=*/NULL, gimple_assign_lhs (stmt), NULL))
1613 *state |= GTMA_HAVE_STORE;
1614}
1615
1616/* Mark a GIMPLE_CALL as appropriate for being inside a transaction. */
1617
1618static void
1619examine_call_tm (unsigned *state, gimple_stmt_iterator *gsi)
1620{
1621 gimple stmt = gsi_stmt (*gsi);
1622 tree fn;
1623
1624 if (is_tm_pure_call (stmt))
1625 return;
1626
1627 /* Check if this call is a transaction abort. */
1628 fn = gimple_call_fndecl (stmt);
1629 if (is_tm_abort (fn))
1630 *state |= GTMA_HAVE_ABORT;
1631
1632 /* Note that something may happen. */
1633 *state |= GTMA_HAVE_LOAD | GTMA_HAVE_STORE;
1634}
1635
1636/* Lower a GIMPLE_TRANSACTION statement. */
1637
1638static void
1639lower_transaction (gimple_stmt_iterator *gsi, struct walk_stmt_info *wi)
1640{
1a91d914 1641 gimple g;
1642 gtransaction *stmt = as_a <gtransaction *> (gsi_stmt (*gsi));
4c0315d0 1643 unsigned int *outer_state = (unsigned int *) wi->info;
1644 unsigned int this_state = 0;
1645 struct walk_stmt_info this_wi;
1646
1647 /* First, lower the body. The scanning that we do inside gives
1648 us some idea of what we're dealing with. */
1649 memset (&this_wi, 0, sizeof (this_wi));
1650 this_wi.info = (void *) &this_state;
e3a19533 1651 walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
1652 lower_sequence_tm, NULL, &this_wi);
4c0315d0 1653
1654 /* If there was absolutely nothing transaction related inside the
1655 transaction, we may elide it. Likewise if this is a nested
1656 transaction and does not contain an abort. */
1657 if (this_state == 0
1658 || (!(this_state & GTMA_HAVE_ABORT) && outer_state != NULL))
1659 {
1660 if (outer_state)
1661 *outer_state |= this_state;
1662
1663 gsi_insert_seq_before (gsi, gimple_transaction_body (stmt),
1664 GSI_SAME_STMT);
1665 gimple_transaction_set_body (stmt, NULL);
1666
1667 gsi_remove (gsi, true);
1668 wi->removed_stmt = true;
1669 return;
1670 }
1671
1672 /* Wrap the body of the transaction in a try-finally node so that
1673 the commit call is always properly called. */
1674 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT), 0);
1675 if (flag_exceptions)
1676 {
1677 tree ptr;
1678 gimple_seq n_seq, e_seq;
1679
1680 n_seq = gimple_seq_alloc_with_stmt (g);
e3a19533 1681 e_seq = NULL;
4c0315d0 1682
1683 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_EH_POINTER),
1684 1, integer_zero_node);
f9e245b2 1685 ptr = create_tmp_var (ptr_type_node);
4c0315d0 1686 gimple_call_set_lhs (g, ptr);
1687 gimple_seq_add_stmt (&e_seq, g);
1688
1689 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_COMMIT_EH),
1690 1, ptr);
1691 gimple_seq_add_stmt (&e_seq, g);
1692
1693 g = gimple_build_eh_else (n_seq, e_seq);
1694 }
1695
1696 g = gimple_build_try (gimple_transaction_body (stmt),
1697 gimple_seq_alloc_with_stmt (g), GIMPLE_TRY_FINALLY);
1698 gsi_insert_after (gsi, g, GSI_CONTINUE_LINKING);
1699
1700 gimple_transaction_set_body (stmt, NULL);
1701
1702 /* If the transaction calls abort or if this is an outer transaction,
1703 add an "over" label afterwards. */
1704 if ((this_state & (GTMA_HAVE_ABORT))
9af5ce0c 1705 || (gimple_transaction_subcode (stmt) & GTMA_IS_OUTER))
4c0315d0 1706 {
1707 tree label = create_artificial_label (UNKNOWN_LOCATION);
1708 gimple_transaction_set_label (stmt, label);
1709 gsi_insert_after (gsi, gimple_build_label (label), GSI_CONTINUE_LINKING);
1710 }
1711
1712 /* Record the set of operations found for use later. */
1713 this_state |= gimple_transaction_subcode (stmt) & GTMA_DECLARATION_MASK;
1714 gimple_transaction_set_subcode (stmt, this_state);
1715}
1716
1717/* Iterate through the statements in the sequence, lowering them all
1718 as appropriate for being in a transaction. */
1719
1720static tree
1721lower_sequence_tm (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1722 struct walk_stmt_info *wi)
1723{
1724 unsigned int *state = (unsigned int *) wi->info;
1725 gimple stmt = gsi_stmt (*gsi);
1726
1727 *handled_ops_p = true;
1728 switch (gimple_code (stmt))
1729 {
1730 case GIMPLE_ASSIGN:
1731 /* Only memory reads/writes need to be instrumented. */
1732 if (gimple_assign_single_p (stmt))
1733 examine_assign_tm (state, gsi);
1734 break;
1735
1736 case GIMPLE_CALL:
1737 examine_call_tm (state, gsi);
1738 break;
1739
1740 case GIMPLE_ASM:
1741 *state |= GTMA_MAY_ENTER_IRREVOCABLE;
1742 break;
1743
1744 case GIMPLE_TRANSACTION:
1745 lower_transaction (gsi, wi);
1746 break;
1747
1748 default:
1749 *handled_ops_p = !gimple_has_substatements (stmt);
1750 break;
1751 }
1752
1753 return NULL_TREE;
1754}
1755
1756/* Iterate through the statements in the sequence, lowering them all
1757 as appropriate for being outside of a transaction. */
1758
1759static tree
1760lower_sequence_no_tm (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1761 struct walk_stmt_info * wi)
1762{
1763 gimple stmt = gsi_stmt (*gsi);
1764
1765 if (gimple_code (stmt) == GIMPLE_TRANSACTION)
1766 {
1767 *handled_ops_p = true;
1768 lower_transaction (gsi, wi);
1769 }
1770 else
1771 *handled_ops_p = !gimple_has_substatements (stmt);
1772
1773 return NULL_TREE;
1774}
1775
1776/* Main entry point for flattening GIMPLE_TRANSACTION constructs. After
1777 this, GIMPLE_TRANSACTION nodes still exist, but the nested body has
1778 been moved out, and all the data required for constructing a proper
1779 CFG has been recorded. */
1780
1781static unsigned int
1782execute_lower_tm (void)
1783{
1784 struct walk_stmt_info wi;
e3a19533 1785 gimple_seq body;
4c0315d0 1786
1787 /* Transactional clones aren't created until a later pass. */
1788 gcc_assert (!decl_is_tm_clone (current_function_decl));
1789
e3a19533 1790 body = gimple_body (current_function_decl);
4c0315d0 1791 memset (&wi, 0, sizeof (wi));
e3a19533 1792 walk_gimple_seq_mod (&body, lower_sequence_no_tm, NULL, &wi);
1793 gimple_set_body (current_function_decl, body);
4c0315d0 1794
1795 return 0;
1796}
1797
cbe8bda8 1798namespace {
1799
1800const pass_data pass_data_lower_tm =
1801{
1802 GIMPLE_PASS, /* type */
1803 "tmlower", /* name */
1804 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 1805 TV_TRANS_MEM, /* tv_id */
1806 PROP_gimple_lcf, /* properties_required */
1807 0, /* properties_provided */
1808 0, /* properties_destroyed */
1809 0, /* todo_flags_start */
1810 0, /* todo_flags_finish */
4c0315d0 1811};
cbe8bda8 1812
1813class pass_lower_tm : public gimple_opt_pass
1814{
1815public:
9af5ce0c 1816 pass_lower_tm (gcc::context *ctxt)
1817 : gimple_opt_pass (pass_data_lower_tm, ctxt)
cbe8bda8 1818 {}
1819
1820 /* opt_pass methods: */
31315c24 1821 virtual bool gate (function *) { return flag_tm; }
65b0537f 1822 virtual unsigned int execute (function *) { return execute_lower_tm (); }
cbe8bda8 1823
1824}; // class pass_lower_tm
1825
1826} // anon namespace
1827
1828gimple_opt_pass *
1829make_pass_lower_tm (gcc::context *ctxt)
1830{
1831 return new pass_lower_tm (ctxt);
1832}
4c0315d0 1833\f
1834/* Collect region information for each transaction. */
1835
1836struct tm_region
1837{
1a91d914 1838public:
1839
1840 /* The field "transaction_stmt" is initially a gtransaction *,
1841 but eventually gets lowered to a gcall *(to BUILT_IN_TM_START).
1842
1843 Helper method to get it as a gtransaction *, with code-checking
1844 in a checked-build. */
1845
1846 gtransaction *
1847 get_transaction_stmt () const
1848 {
1849 return as_a <gtransaction *> (transaction_stmt);
1850 }
1851
1852public:
1853
4c0315d0 1854 /* Link to the next unnested transaction. */
1855 struct tm_region *next;
1856
1857 /* Link to the next inner transaction. */
1858 struct tm_region *inner;
1859
1860 /* Link to the next outer transaction. */
1861 struct tm_region *outer;
1862
0cd02a19 1863 /* The GIMPLE_TRANSACTION statement beginning this transaction.
1864 After TM_MARK, this gets replaced by a call to
1a91d914 1865 BUILT_IN_TM_START.
1866 Hence this will be either a gtransaction *or a gcall *. */
4c0315d0 1867 gimple transaction_stmt;
1868
0cd02a19 1869 /* After TM_MARK expands the GIMPLE_TRANSACTION into a call to
1870 BUILT_IN_TM_START, this field is true if the transaction is an
1871 outer transaction. */
1872 bool original_transaction_was_outer;
1873
1874 /* Return value from BUILT_IN_TM_START. */
1875 tree tm_state;
1876
1877 /* The entry block to this region. This will always be the first
1878 block of the body of the transaction. */
4c0315d0 1879 basic_block entry_block;
1880
0cd02a19 1881 /* The first block after an expanded call to _ITM_beginTransaction. */
1882 basic_block restart_block;
1883
4c0315d0 1884 /* The set of all blocks that end the region; NULL if only EXIT_BLOCK.
1885 These blocks are still a part of the region (i.e., the border is
1886 inclusive). Note that this set is only complete for paths in the CFG
1887 starting at ENTRY_BLOCK, and that there is no exit block recorded for
1888 the edge to the "over" label. */
1889 bitmap exit_blocks;
1890
1891 /* The set of all blocks that have an TM_IRREVOCABLE call. */
1892 bitmap irr_blocks;
1893};
1894
5ab54790 1895typedef struct tm_region *tm_region_p;
5ab54790 1896
4c0315d0 1897/* True if there are pending edge statements to be committed for the
1898 current function being scanned in the tmmark pass. */
1899bool pending_edge_inserts_p;
1900
1901static struct tm_region *all_tm_regions;
1902static bitmap_obstack tm_obstack;
1903
1904
9d75589a 1905/* A subroutine of tm_region_init. Record the existence of the
4c0315d0 1906 GIMPLE_TRANSACTION statement in a tree of tm_region elements. */
1907
1908static struct tm_region *
1a91d914 1909tm_region_init_0 (struct tm_region *outer, basic_block bb,
1910 gtransaction *stmt)
4c0315d0 1911{
1912 struct tm_region *region;
1913
1914 region = (struct tm_region *)
1915 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
1916
1917 if (outer)
1918 {
1919 region->next = outer->inner;
1920 outer->inner = region;
1921 }
1922 else
1923 {
1924 region->next = all_tm_regions;
1925 all_tm_regions = region;
1926 }
1927 region->inner = NULL;
1928 region->outer = outer;
1929
1930 region->transaction_stmt = stmt;
0cd02a19 1931 region->original_transaction_was_outer = false;
1932 region->tm_state = NULL;
4c0315d0 1933
1934 /* There are either one or two edges out of the block containing
1935 the GIMPLE_TRANSACTION, one to the actual region and one to the
1936 "over" label if the region contains an abort. The former will
1937 always be the one marked FALLTHRU. */
1938 region->entry_block = FALLTHRU_EDGE (bb)->dest;
1939
1940 region->exit_blocks = BITMAP_ALLOC (&tm_obstack);
1941 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
1942
1943 return region;
1944}
1945
1946/* A subroutine of tm_region_init. Record all the exit and
1947 irrevocable blocks in BB into the region's exit_blocks and
1948 irr_blocks bitmaps. Returns the new region being scanned. */
1949
1950static struct tm_region *
1951tm_region_init_1 (struct tm_region *region, basic_block bb)
1952{
1953 gimple_stmt_iterator gsi;
1954 gimple g;
1955
1956 if (!region
1957 || (!region->irr_blocks && !region->exit_blocks))
1958 return region;
1959
1960 /* Check to see if this is the end of a region by seeing if it
1961 contains a call to __builtin_tm_commit{,_eh}. Note that the
1962 outermost region for DECL_IS_TM_CLONE need not collect this. */
1963 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
1964 {
1965 g = gsi_stmt (gsi);
1966 if (gimple_code (g) == GIMPLE_CALL)
1967 {
1968 tree fn = gimple_call_fndecl (g);
1969 if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
1970 {
1971 if ((DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT
1972 || DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_COMMIT_EH)
1973 && region->exit_blocks)
1974 {
1975 bitmap_set_bit (region->exit_blocks, bb->index);
1976 region = region->outer;
1977 break;
1978 }
1979 if (DECL_FUNCTION_CODE (fn) == BUILT_IN_TM_IRREVOCABLE)
1980 bitmap_set_bit (region->irr_blocks, bb->index);
1981 }
1982 }
1983 }
1984 return region;
1985}
1986
1987/* Collect all of the transaction regions within the current function
1988 and record them in ALL_TM_REGIONS. The REGION parameter may specify
1989 an "outermost" region for use by tm clones. */
1990
1991static void
1992tm_region_init (struct tm_region *region)
1993{
1994 gimple g;
1995 edge_iterator ei;
1996 edge e;
1997 basic_block bb;
c2078b80 1998 auto_vec<basic_block> queue;
4c0315d0 1999 bitmap visited_blocks = BITMAP_ALLOC (NULL);
2000 struct tm_region *old_region;
c2078b80 2001 auto_vec<tm_region_p> bb_regions;
4c0315d0 2002
2003 all_tm_regions = region;
34154e27 2004 bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4c0315d0 2005
de60f90c 2006 /* We could store this information in bb->aux, but we may get called
2007 through get_all_tm_blocks() from another pass that may be already
2008 using bb->aux. */
fe672ac0 2009 bb_regions.safe_grow_cleared (last_basic_block_for_fn (cfun));
de60f90c 2010
f1f41a6c 2011 queue.safe_push (bb);
2012 bb_regions[bb->index] = region;
4c0315d0 2013 do
2014 {
f1f41a6c 2015 bb = queue.pop ();
2016 region = bb_regions[bb->index];
2017 bb_regions[bb->index] = NULL;
4c0315d0 2018
2019 /* Record exit and irrevocable blocks. */
2020 region = tm_region_init_1 (region, bb);
2021
2022 /* Check for the last statement in the block beginning a new region. */
2023 g = last_stmt (bb);
2024 old_region = region;
1a91d914 2025 if (g)
2026 if (gtransaction *trans_stmt = dyn_cast <gtransaction *> (g))
2027 region = tm_region_init_0 (region, bb, trans_stmt);
4c0315d0 2028
2029 /* Process subsequent blocks. */
2030 FOR_EACH_EDGE (e, ei, bb->succs)
2031 if (!bitmap_bit_p (visited_blocks, e->dest->index))
2032 {
2033 bitmap_set_bit (visited_blocks, e->dest->index);
f1f41a6c 2034 queue.safe_push (e->dest);
4c0315d0 2035
2036 /* If the current block started a new region, make sure that only
2037 the entry block of the new region is associated with this region.
2038 Other successors are still part of the old region. */
2039 if (old_region != region && e->dest != region->entry_block)
f1f41a6c 2040 bb_regions[e->dest->index] = old_region;
4c0315d0 2041 else
f1f41a6c 2042 bb_regions[e->dest->index] = region;
4c0315d0 2043 }
2044 }
f1f41a6c 2045 while (!queue.is_empty ());
4c0315d0 2046 BITMAP_FREE (visited_blocks);
2047}
2048
2049/* The "gate" function for all transactional memory expansion and optimization
2050 passes. We collect region information for each top-level transaction, and
2051 if we don't find any, we skip all of the TM passes. Each region will have
2052 all of the exit blocks recorded, and the originating statement. */
2053
2054static bool
2055gate_tm_init (void)
2056{
2057 if (!flag_tm)
2058 return false;
2059
2060 calculate_dominance_info (CDI_DOMINATORS);
2061 bitmap_obstack_initialize (&tm_obstack);
2062
2063 /* If the function is a TM_CLONE, then the entire function is the region. */
2064 if (decl_is_tm_clone (current_function_decl))
2065 {
2066 struct tm_region *region = (struct tm_region *)
2067 obstack_alloc (&tm_obstack.obstack, sizeof (struct tm_region));
2068 memset (region, 0, sizeof (*region));
34154e27 2069 region->entry_block = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
4c0315d0 2070 /* For a clone, the entire function is the region. But even if
2071 we don't need to record any exit blocks, we may need to
2072 record irrevocable blocks. */
2073 region->irr_blocks = BITMAP_ALLOC (&tm_obstack);
2074
2075 tm_region_init (region);
2076 }
2077 else
2078 {
2079 tm_region_init (NULL);
2080
2081 /* If we didn't find any regions, cleanup and skip the whole tree
2082 of tm-related optimizations. */
2083 if (all_tm_regions == NULL)
2084 {
2085 bitmap_obstack_release (&tm_obstack);
2086 return false;
2087 }
2088 }
2089
2090 return true;
2091}
2092
cbe8bda8 2093namespace {
2094
2095const pass_data pass_data_tm_init =
2096{
2097 GIMPLE_PASS, /* type */
2098 "*tminit", /* name */
2099 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 2100 TV_TRANS_MEM, /* tv_id */
2101 ( PROP_ssa | PROP_cfg ), /* properties_required */
2102 0, /* properties_provided */
2103 0, /* properties_destroyed */
2104 0, /* todo_flags_start */
2105 0, /* todo_flags_finish */
4c0315d0 2106};
cbe8bda8 2107
2108class pass_tm_init : public gimple_opt_pass
2109{
2110public:
9af5ce0c 2111 pass_tm_init (gcc::context *ctxt)
2112 : gimple_opt_pass (pass_data_tm_init, ctxt)
cbe8bda8 2113 {}
2114
2115 /* opt_pass methods: */
31315c24 2116 virtual bool gate (function *) { return gate_tm_init (); }
cbe8bda8 2117
2118}; // class pass_tm_init
2119
2120} // anon namespace
2121
2122gimple_opt_pass *
2123make_pass_tm_init (gcc::context *ctxt)
2124{
2125 return new pass_tm_init (ctxt);
2126}
4c0315d0 2127\f
2128/* Add FLAGS to the GIMPLE_TRANSACTION subcode for the transaction region
2129 represented by STATE. */
2130
2131static inline void
2132transaction_subcode_ior (struct tm_region *region, unsigned flags)
2133{
2134 if (region && region->transaction_stmt)
2135 {
1a91d914 2136 gtransaction *transaction_stmt = region->get_transaction_stmt ();
2137 flags |= gimple_transaction_subcode (transaction_stmt);
2138 gimple_transaction_set_subcode (transaction_stmt, flags);
4c0315d0 2139 }
2140}
2141
2142/* Construct a memory load in a transactional context. Return the
2143 gimple statement performing the load, or NULL if there is no
2144 TM_LOAD builtin of the appropriate size to do the load.
2145
2146 LOC is the location to use for the new statement(s). */
2147
1a91d914 2148static gcall *
4c0315d0 2149build_tm_load (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2150{
2151 enum built_in_function code = END_BUILTINS;
2152 tree t, type = TREE_TYPE (rhs), decl;
1a91d914 2153 gcall *gcall;
4c0315d0 2154
2155 if (type == float_type_node)
2156 code = BUILT_IN_TM_LOAD_FLOAT;
2157 else if (type == double_type_node)
2158 code = BUILT_IN_TM_LOAD_DOUBLE;
2159 else if (type == long_double_type_node)
2160 code = BUILT_IN_TM_LOAD_LDOUBLE;
2161 else if (TYPE_SIZE_UNIT (type) != NULL
cd4547bf 2162 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
4c0315d0 2163 {
6a0712d4 2164 switch (tree_to_uhwi (TYPE_SIZE_UNIT (type)))
4c0315d0 2165 {
2166 case 1:
2167 code = BUILT_IN_TM_LOAD_1;
2168 break;
2169 case 2:
2170 code = BUILT_IN_TM_LOAD_2;
2171 break;
2172 case 4:
2173 code = BUILT_IN_TM_LOAD_4;
2174 break;
2175 case 8:
2176 code = BUILT_IN_TM_LOAD_8;
2177 break;
2178 }
2179 }
2180
2181 if (code == END_BUILTINS)
2182 {
2183 decl = targetm.vectorize.builtin_tm_load (type);
2184 if (!decl)
2185 return NULL;
2186 }
2187 else
2188 decl = builtin_decl_explicit (code);
2189
2190 t = gimplify_addr (gsi, rhs);
2191 gcall = gimple_build_call (decl, 1, t);
2192 gimple_set_location (gcall, loc);
2193
2194 t = TREE_TYPE (TREE_TYPE (decl));
2195 if (useless_type_conversion_p (type, t))
2196 {
2197 gimple_call_set_lhs (gcall, lhs);
2198 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2199 }
2200 else
2201 {
2202 gimple g;
2203 tree temp;
2204
f9e245b2 2205 temp = create_tmp_reg (t);
4c0315d0 2206 gimple_call_set_lhs (gcall, temp);
2207 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2208
2209 t = fold_build1 (VIEW_CONVERT_EXPR, type, temp);
2210 g = gimple_build_assign (lhs, t);
2211 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2212 }
2213
2214 return gcall;
2215}
2216
2217
2218/* Similarly for storing TYPE in a transactional context. */
2219
1a91d914 2220static gcall *
4c0315d0 2221build_tm_store (location_t loc, tree lhs, tree rhs, gimple_stmt_iterator *gsi)
2222{
2223 enum built_in_function code = END_BUILTINS;
2224 tree t, fn, type = TREE_TYPE (rhs), simple_type;
1a91d914 2225 gcall *gcall;
4c0315d0 2226
2227 if (type == float_type_node)
2228 code = BUILT_IN_TM_STORE_FLOAT;
2229 else if (type == double_type_node)
2230 code = BUILT_IN_TM_STORE_DOUBLE;
2231 else if (type == long_double_type_node)
2232 code = BUILT_IN_TM_STORE_LDOUBLE;
2233 else if (TYPE_SIZE_UNIT (type) != NULL
cd4547bf 2234 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
4c0315d0 2235 {
6a0712d4 2236 switch (tree_to_uhwi (TYPE_SIZE_UNIT (type)))
4c0315d0 2237 {
2238 case 1:
2239 code = BUILT_IN_TM_STORE_1;
2240 break;
2241 case 2:
2242 code = BUILT_IN_TM_STORE_2;
2243 break;
2244 case 4:
2245 code = BUILT_IN_TM_STORE_4;
2246 break;
2247 case 8:
2248 code = BUILT_IN_TM_STORE_8;
2249 break;
2250 }
2251 }
2252
2253 if (code == END_BUILTINS)
2254 {
2255 fn = targetm.vectorize.builtin_tm_store (type);
2256 if (!fn)
2257 return NULL;
2258 }
2259 else
2260 fn = builtin_decl_explicit (code);
2261
2262 simple_type = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))));
2263
2264 if (TREE_CODE (rhs) == CONSTRUCTOR)
2265 {
2266 /* Handle the easy initialization to zero. */
f1f41a6c 2267 if (!CONSTRUCTOR_ELTS (rhs))
4c0315d0 2268 rhs = build_int_cst (simple_type, 0);
2269 else
2270 {
2271 /* ...otherwise punt to the caller and probably use
2272 BUILT_IN_TM_MEMMOVE, because we can't wrap a
2273 VIEW_CONVERT_EXPR around a CONSTRUCTOR (below) and produce
2274 valid gimple. */
2275 return NULL;
2276 }
2277 }
2278 else if (!useless_type_conversion_p (simple_type, type))
2279 {
2280 gimple g;
2281 tree temp;
2282
f9e245b2 2283 temp = create_tmp_reg (simple_type);
4c0315d0 2284 t = fold_build1 (VIEW_CONVERT_EXPR, simple_type, rhs);
2285 g = gimple_build_assign (temp, t);
2286 gimple_set_location (g, loc);
2287 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2288
2289 rhs = temp;
2290 }
2291
2292 t = gimplify_addr (gsi, lhs);
2293 gcall = gimple_build_call (fn, 2, t, rhs);
2294 gimple_set_location (gcall, loc);
2295 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2296
2297 return gcall;
2298}
2299
2300
2301/* Expand an assignment statement into transactional builtins. */
2302
2303static void
2304expand_assign_tm (struct tm_region *region, gimple_stmt_iterator *gsi)
2305{
2306 gimple stmt = gsi_stmt (*gsi);
2307 location_t loc = gimple_location (stmt);
2308 tree lhs = gimple_assign_lhs (stmt);
2309 tree rhs = gimple_assign_rhs1 (stmt);
2310 bool store_p = requires_barrier (region->entry_block, lhs, NULL);
2311 bool load_p = requires_barrier (region->entry_block, rhs, NULL);
2312 gimple gcall = NULL;
2313
2314 if (!load_p && !store_p)
2315 {
2316 /* Add thread private addresses to log if applicable. */
2317 requires_barrier (region->entry_block, lhs, stmt);
2318 gsi_next (gsi);
2319 return;
2320 }
2321
0cd02a19 2322 // Remove original load/store statement.
4c0315d0 2323 gsi_remove (gsi, true);
2324
2325 if (load_p && !store_p)
2326 {
2327 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2328 gcall = build_tm_load (loc, lhs, rhs, gsi);
2329 }
2330 else if (store_p && !load_p)
2331 {
2332 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2333 gcall = build_tm_store (loc, lhs, rhs, gsi);
2334 }
2335 if (!gcall)
2336 {
ea580cf7 2337 tree lhs_addr, rhs_addr, tmp;
4c0315d0 2338
2339 if (load_p)
2340 transaction_subcode_ior (region, GTMA_HAVE_LOAD);
2341 if (store_p)
2342 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2343
2344 /* ??? Figure out if there's any possible overlap between the LHS
2345 and the RHS and if not, use MEMCPY. */
ea580cf7 2346
28098b5b 2347 if (load_p && is_gimple_reg (lhs))
ea580cf7 2348 {
f9e245b2 2349 tmp = create_tmp_var (TREE_TYPE (lhs));
ea580cf7 2350 lhs_addr = build_fold_addr_expr (tmp);
2351 }
2352 else
2353 {
2354 tmp = NULL_TREE;
2355 lhs_addr = gimplify_addr (gsi, lhs);
2356 }
4c0315d0 2357 rhs_addr = gimplify_addr (gsi, rhs);
2358 gcall = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_MEMMOVE),
2359 3, lhs_addr, rhs_addr,
2360 TYPE_SIZE_UNIT (TREE_TYPE (lhs)));
2361 gimple_set_location (gcall, loc);
2362 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
ea580cf7 2363
2364 if (tmp)
2365 {
2366 gcall = gimple_build_assign (lhs, tmp);
2367 gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
2368 }
4c0315d0 2369 }
2370
2371 /* Now that we have the load/store in its instrumented form, add
2372 thread private addresses to the log if applicable. */
2373 if (!store_p)
2374 requires_barrier (region->entry_block, lhs, gcall);
2375
0cd02a19 2376 // The calls to build_tm_{store,load} above inserted the instrumented
2377 // call into the stream.
2378 // gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
4c0315d0 2379}
2380
2381
2382/* Expand a call statement as appropriate for a transaction. That is,
2383 either verify that the call does not affect the transaction, or
2384 redirect the call to a clone that handles transactions, or change
2385 the transaction state to IRREVOCABLE. Return true if the call is
2386 one of the builtins that end a transaction. */
2387
2388static bool
2389expand_call_tm (struct tm_region *region,
2390 gimple_stmt_iterator *gsi)
2391{
1a91d914 2392 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
4c0315d0 2393 tree lhs = gimple_call_lhs (stmt);
2394 tree fn_decl;
2395 struct cgraph_node *node;
2396 bool retval = false;
2397
2398 fn_decl = gimple_call_fndecl (stmt);
2399
2400 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMCPY)
2401 || fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMMOVE))
2402 transaction_subcode_ior (region, GTMA_HAVE_STORE | GTMA_HAVE_LOAD);
2403 if (fn_decl == builtin_decl_explicit (BUILT_IN_TM_MEMSET))
2404 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2405
2406 if (is_tm_pure_call (stmt))
2407 return false;
2408
2409 if (fn_decl)
2410 retval = is_tm_ending_fndecl (fn_decl);
2411 if (!retval)
2412 {
2413 /* Assume all non-const/pure calls write to memory, except
2414 transaction ending builtins. */
2415 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2416 }
2417
2418 /* For indirect calls, we already generated a call into the runtime. */
2419 if (!fn_decl)
2420 {
2421 tree fn = gimple_call_fn (stmt);
2422
2423 /* We are guaranteed never to go irrevocable on a safe or pure
2424 call, and the pure call was handled above. */
2425 if (is_tm_safe (fn))
2426 return false;
2427 else
2428 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2429
2430 return false;
2431 }
2432
415d1b9a 2433 node = cgraph_node::get (fn_decl);
fce5ce8e 2434 /* All calls should have cgraph here. */
2435 if (!node)
2436 {
2437 /* We can have a nodeless call here if some pass after IPA-tm
2438 added uninstrumented calls. For example, loop distribution
2439 can transform certain loop constructs into __builtin_mem*
2440 calls. In this case, see if we have a suitable TM
2441 replacement and fill in the gaps. */
2442 gcc_assert (DECL_BUILT_IN_CLASS (fn_decl) == BUILT_IN_NORMAL);
2443 enum built_in_function code = DECL_FUNCTION_CODE (fn_decl);
2444 gcc_assert (code == BUILT_IN_MEMCPY
2445 || code == BUILT_IN_MEMMOVE
2446 || code == BUILT_IN_MEMSET);
2447
2448 tree repl = find_tm_replacement_function (fn_decl);
2449 if (repl)
2450 {
2451 gimple_call_set_fndecl (stmt, repl);
2452 update_stmt (stmt);
415d1b9a 2453 node = cgraph_node::create (repl);
fce5ce8e 2454 node->local.tm_may_enter_irr = false;
2455 return expand_call_tm (region, gsi);
2456 }
2457 gcc_unreachable ();
2458 }
4c0315d0 2459 if (node->local.tm_may_enter_irr)
2460 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
2461
2462 if (is_tm_abort (fn_decl))
2463 {
2464 transaction_subcode_ior (region, GTMA_HAVE_ABORT);
2465 return true;
2466 }
2467
2468 /* Instrument the store if needed.
2469
2470 If the assignment happens inside the function call (return slot
2471 optimization), there is no instrumentation to be done, since
2472 the callee should have done the right thing. */
2473 if (lhs && requires_barrier (region->entry_block, lhs, stmt)
2474 && !gimple_call_return_slot_opt_p (stmt))
2475 {
f9e245b2 2476 tree tmp = create_tmp_reg (TREE_TYPE (lhs));
4c0315d0 2477 location_t loc = gimple_location (stmt);
2478 edge fallthru_edge = NULL;
1a91d914 2479 gassign *assign_stmt;
4c0315d0 2480
2481 /* Remember if the call was going to throw. */
2482 if (stmt_can_throw_internal (stmt))
2483 {
2484 edge_iterator ei;
2485 edge e;
2486 basic_block bb = gimple_bb (stmt);
2487
2488 FOR_EACH_EDGE (e, ei, bb->succs)
2489 if (e->flags & EDGE_FALLTHRU)
2490 {
2491 fallthru_edge = e;
2492 break;
2493 }
2494 }
2495
2496 gimple_call_set_lhs (stmt, tmp);
2497 update_stmt (stmt);
1a91d914 2498 assign_stmt = gimple_build_assign (lhs, tmp);
2499 gimple_set_location (assign_stmt, loc);
4c0315d0 2500
2501 /* We cannot throw in the middle of a BB. If the call was going
2502 to throw, place the instrumentation on the fallthru edge, so
2503 the call remains the last statement in the block. */
2504 if (fallthru_edge)
2505 {
1a91d914 2506 gimple_seq fallthru_seq = gimple_seq_alloc_with_stmt (assign_stmt);
4c0315d0 2507 gimple_stmt_iterator fallthru_gsi = gsi_start (fallthru_seq);
2508 expand_assign_tm (region, &fallthru_gsi);
2509 gsi_insert_seq_on_edge (fallthru_edge, fallthru_seq);
2510 pending_edge_inserts_p = true;
2511 }
2512 else
2513 {
1a91d914 2514 gsi_insert_after (gsi, assign_stmt, GSI_CONTINUE_LINKING);
4c0315d0 2515 expand_assign_tm (region, gsi);
2516 }
2517
2518 transaction_subcode_ior (region, GTMA_HAVE_STORE);
2519 }
2520
2521 return retval;
2522}
2523
2524
2525/* Expand all statements in BB as appropriate for being inside
2526 a transaction. */
2527
2528static void
2529expand_block_tm (struct tm_region *region, basic_block bb)
2530{
2531 gimple_stmt_iterator gsi;
2532
2533 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2534 {
2535 gimple stmt = gsi_stmt (gsi);
2536 switch (gimple_code (stmt))
2537 {
2538 case GIMPLE_ASSIGN:
2539 /* Only memory reads/writes need to be instrumented. */
73fd1e9a 2540 if (gimple_assign_single_p (stmt)
2541 && !gimple_clobber_p (stmt))
4c0315d0 2542 {
2543 expand_assign_tm (region, &gsi);
2544 continue;
2545 }
2546 break;
2547
2548 case GIMPLE_CALL:
2549 if (expand_call_tm (region, &gsi))
2550 return;
2551 break;
2552
2553 case GIMPLE_ASM:
2554 gcc_unreachable ();
2555
2556 default:
2557 break;
2558 }
2559 if (!gsi_end_p (gsi))
2560 gsi_next (&gsi);
2561 }
2562}
2563
2564/* Return the list of basic-blocks in REGION.
2565
2566 STOP_AT_IRREVOCABLE_P is true if caller is uninterested in blocks
79f4a793 2567 following a TM_IRREVOCABLE call.
2568
2569 INCLUDE_UNINSTRUMENTED_P is TRUE if we should include the
2570 uninstrumented code path blocks in the list of basic blocks
2571 returned, false otherwise. */
4c0315d0 2572
f1f41a6c 2573static vec<basic_block>
4c0315d0 2574get_tm_region_blocks (basic_block entry_block,
2575 bitmap exit_blocks,
2576 bitmap irr_blocks,
2577 bitmap all_region_blocks,
79f4a793 2578 bool stop_at_irrevocable_p,
2579 bool include_uninstrumented_p = true)
4c0315d0 2580{
1e094109 2581 vec<basic_block> bbs = vNULL;
4c0315d0 2582 unsigned i;
2583 edge e;
2584 edge_iterator ei;
2585 bitmap visited_blocks = BITMAP_ALLOC (NULL);
2586
2587 i = 0;
f1f41a6c 2588 bbs.safe_push (entry_block);
4c0315d0 2589 bitmap_set_bit (visited_blocks, entry_block->index);
2590
2591 do
2592 {
f1f41a6c 2593 basic_block bb = bbs[i++];
4c0315d0 2594
2595 if (exit_blocks &&
2596 bitmap_bit_p (exit_blocks, bb->index))
2597 continue;
2598
2599 if (stop_at_irrevocable_p
2600 && irr_blocks
2601 && bitmap_bit_p (irr_blocks, bb->index))
2602 continue;
2603
2604 FOR_EACH_EDGE (e, ei, bb->succs)
79f4a793 2605 if ((include_uninstrumented_p
2606 || !(e->flags & EDGE_TM_UNINSTRUMENTED))
2607 && !bitmap_bit_p (visited_blocks, e->dest->index))
4c0315d0 2608 {
2609 bitmap_set_bit (visited_blocks, e->dest->index);
f1f41a6c 2610 bbs.safe_push (e->dest);
4c0315d0 2611 }
2612 }
f1f41a6c 2613 while (i < bbs.length ());
4c0315d0 2614
2615 if (all_region_blocks)
2616 bitmap_ior_into (all_region_blocks, visited_blocks);
2617
2618 BITMAP_FREE (visited_blocks);
2619 return bbs;
2620}
2621
79f4a793 2622// Callback data for collect_bb2reg.
2623struct bb2reg_stuff
2624{
2625 vec<tm_region_p> *bb2reg;
2626 bool include_uninstrumented_p;
2627};
2628
0cd02a19 2629// Callback for expand_regions, collect innermost region data for each bb.
2630static void *
2631collect_bb2reg (struct tm_region *region, void *data)
2632{
79f4a793 2633 struct bb2reg_stuff *stuff = (struct bb2reg_stuff *)data;
2634 vec<tm_region_p> *bb2reg = stuff->bb2reg;
f1f41a6c 2635 vec<basic_block> queue;
0cd02a19 2636 unsigned int i;
2637 basic_block bb;
2638
2639 queue = get_tm_region_blocks (region->entry_block,
2640 region->exit_blocks,
2641 region->irr_blocks,
2642 NULL,
79f4a793 2643 /*stop_at_irr_p=*/true,
2644 stuff->include_uninstrumented_p);
0cd02a19 2645
2646 // We expect expand_region to perform a post-order traversal of the region
2647 // tree. Therefore the last region seen for any bb is the innermost.
f1f41a6c 2648 FOR_EACH_VEC_ELT (queue, i, bb)
2649 (*bb2reg)[bb->index] = region;
0cd02a19 2650
f1f41a6c 2651 queue.release ();
0cd02a19 2652 return NULL;
2653}
2654
2655// Returns a vector, indexed by BB->INDEX, of the innermost tm_region to
2656// which a basic block belongs. Note that we only consider the instrumented
79f4a793 2657// code paths for the region; the uninstrumented code paths are ignored if
2658// INCLUDE_UNINSTRUMENTED_P is false.
0cd02a19 2659//
2660// ??? This data is very similar to the bb_regions array that is collected
2661// during tm_region_init. Or, rather, this data is similar to what could
2662// be used within tm_region_init. The actual computation in tm_region_init
2663// begins and ends with bb_regions entirely full of NULL pointers, due to
2664// the way in which pointers are swapped in and out of the array.
2665//
2666// ??? Our callers expect that blocks are not shared between transactions.
2667// When the optimizers get too smart, and blocks are shared, then during
2668// the tm_mark phase we'll add log entries to only one of the two transactions,
2669// and in the tm_edge phase we'll add edges to the CFG that create invalid
2670// cycles. The symptom being SSA defs that do not dominate their uses.
2671// Note that the optimizers were locally correct with their transformation,
2672// as we have no info within the program that suggests that the blocks cannot
2673// be shared.
2674//
2675// ??? There is currently a hack inside tree-ssa-pre.c to work around the
2676// only known instance of this block sharing.
2677
f1f41a6c 2678static vec<tm_region_p>
79f4a793 2679get_bb_regions_instrumented (bool traverse_clones,
2680 bool include_uninstrumented_p)
0cd02a19 2681{
fe672ac0 2682 unsigned n = last_basic_block_for_fn (cfun);
79f4a793 2683 struct bb2reg_stuff stuff;
f1f41a6c 2684 vec<tm_region_p> ret;
0cd02a19 2685
f1f41a6c 2686 ret.create (n);
2687 ret.safe_grow_cleared (n);
79f4a793 2688 stuff.bb2reg = &ret;
2689 stuff.include_uninstrumented_p = include_uninstrumented_p;
2690 expand_regions (all_tm_regions, collect_bb2reg, &stuff, traverse_clones);
0cd02a19 2691
2692 return ret;
2693}
2694
de60f90c 2695/* Set the IN_TRANSACTION for all gimple statements that appear in a
2696 transaction. */
2697
2698void
2699compute_transaction_bits (void)
2700{
2701 struct tm_region *region;
f1f41a6c 2702 vec<basic_block> queue;
de60f90c 2703 unsigned int i;
de60f90c 2704 basic_block bb;
2705
2706 /* ?? Perhaps we need to abstract gate_tm_init further, because we
2707 certainly don't need it to calculate CDI_DOMINATOR info. */
2708 gate_tm_init ();
2709
fc00614f 2710 FOR_EACH_BB_FN (bb, cfun)
6ad451f8 2711 bb->flags &= ~BB_IN_TRANSACTION;
2712
de60f90c 2713 for (region = all_tm_regions; region; region = region->next)
2714 {
2715 queue = get_tm_region_blocks (region->entry_block,
2716 region->exit_blocks,
2717 region->irr_blocks,
2718 NULL,
2719 /*stop_at_irr_p=*/true);
f1f41a6c 2720 for (i = 0; queue.iterate (i, &bb); ++i)
6ad451f8 2721 bb->flags |= BB_IN_TRANSACTION;
f1f41a6c 2722 queue.release ();
de60f90c 2723 }
2724
2725 if (all_tm_regions)
2726 bitmap_obstack_release (&tm_obstack);
2727}
2728
0cd02a19 2729/* Replace the GIMPLE_TRANSACTION in this region with the corresponding
2730 call to BUILT_IN_TM_START. */
2731
2732static void *
2733expand_transaction (struct tm_region *region, void *data ATTRIBUTE_UNUSED)
2734{
2735 tree tm_start = builtin_decl_explicit (BUILT_IN_TM_START);
2736 basic_block transaction_bb = gimple_bb (region->transaction_stmt);
2737 tree tm_state = region->tm_state;
2738 tree tm_state_type = TREE_TYPE (tm_state);
2739 edge abort_edge = NULL;
2740 edge inst_edge = NULL;
2741 edge uninst_edge = NULL;
2742 edge fallthru_edge = NULL;
2743
2744 // Identify the various successors of the transaction start.
2745 {
2746 edge_iterator i;
2747 edge e;
2748 FOR_EACH_EDGE (e, i, transaction_bb->succs)
2749 {
2750 if (e->flags & EDGE_TM_ABORT)
2751 abort_edge = e;
2752 else if (e->flags & EDGE_TM_UNINSTRUMENTED)
2753 uninst_edge = e;
2754 else
2755 inst_edge = e;
2756 if (e->flags & EDGE_FALLTHRU)
2757 fallthru_edge = e;
2758 }
2759 }
2760
2761 /* ??? There are plenty of bits here we're not computing. */
2762 {
1a91d914 2763 int subcode = gimple_transaction_subcode (region->get_transaction_stmt ());
0cd02a19 2764 int flags = 0;
2765 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2766 flags |= PR_DOESGOIRREVOCABLE;
2767 if ((subcode & GTMA_MAY_ENTER_IRREVOCABLE) == 0)
2768 flags |= PR_HASNOIRREVOCABLE;
2769 /* If the transaction does not have an abort in lexical scope and is not
2770 marked as an outer transaction, then it will never abort. */
2771 if ((subcode & GTMA_HAVE_ABORT) == 0 && (subcode & GTMA_IS_OUTER) == 0)
2772 flags |= PR_HASNOABORT;
2773 if ((subcode & GTMA_HAVE_STORE) == 0)
2774 flags |= PR_READONLY;
1910089e 2775 if (inst_edge && !(subcode & GTMA_HAS_NO_INSTRUMENTATION))
0cd02a19 2776 flags |= PR_INSTRUMENTEDCODE;
2777 if (uninst_edge)
2778 flags |= PR_UNINSTRUMENTEDCODE;
2779 if (subcode & GTMA_IS_OUTER)
2780 region->original_transaction_was_outer = true;
2781 tree t = build_int_cst (tm_state_type, flags);
1a91d914 2782 gcall *call = gimple_build_call (tm_start, 1, t);
0cd02a19 2783 gimple_call_set_lhs (call, tm_state);
2784 gimple_set_location (call, gimple_location (region->transaction_stmt));
2785
2786 // Replace the GIMPLE_TRANSACTION with the call to BUILT_IN_TM_START.
2787 gimple_stmt_iterator gsi = gsi_last_bb (transaction_bb);
2788 gcc_assert (gsi_stmt (gsi) == region->transaction_stmt);
2789 gsi_insert_before (&gsi, call, GSI_SAME_STMT);
2790 gsi_remove (&gsi, true);
2791 region->transaction_stmt = call;
2792 }
2793
2794 // Generate log saves.
f1f41a6c 2795 if (!tm_log_save_addresses.is_empty ())
0cd02a19 2796 tm_log_emit_saves (region->entry_block, transaction_bb);
2797
2798 // In the beginning, we've no tests to perform on transaction restart.
2799 // Note that after this point, transaction_bb becomes the "most recent
2800 // block containing tests for the transaction".
2801 region->restart_block = region->entry_block;
2802
2803 // Generate log restores.
f1f41a6c 2804 if (!tm_log_save_addresses.is_empty ())
0cd02a19 2805 {
2806 basic_block test_bb = create_empty_bb (transaction_bb);
2807 basic_block code_bb = create_empty_bb (test_bb);
2808 basic_block join_bb = create_empty_bb (code_bb);
b3083327 2809 add_bb_to_loop (test_bb, transaction_bb->loop_father);
2810 add_bb_to_loop (code_bb, transaction_bb->loop_father);
2811 add_bb_to_loop (join_bb, transaction_bb->loop_father);
0cd02a19 2812 if (region->restart_block == region->entry_block)
2813 region->restart_block = test_bb;
2814
f9e245b2 2815 tree t1 = create_tmp_reg (tm_state_type);
0cd02a19 2816 tree t2 = build_int_cst (tm_state_type, A_RESTORELIVEVARIABLES);
e9cf809e 2817 gimple stmt = gimple_build_assign (t1, BIT_AND_EXPR, tm_state, t2);
0cd02a19 2818 gimple_stmt_iterator gsi = gsi_last_bb (test_bb);
2819 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2820
2821 t2 = build_int_cst (tm_state_type, 0);
2822 stmt = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
2823 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2824
2825 tm_log_emit_restores (region->entry_block, code_bb);
2826
2827 edge ei = make_edge (transaction_bb, test_bb, EDGE_FALLTHRU);
2828 edge et = make_edge (test_bb, code_bb, EDGE_TRUE_VALUE);
2829 edge ef = make_edge (test_bb, join_bb, EDGE_FALSE_VALUE);
2830 redirect_edge_pred (fallthru_edge, join_bb);
2831
2832 join_bb->frequency = test_bb->frequency = transaction_bb->frequency;
2833 join_bb->count = test_bb->count = transaction_bb->count;
2834
2835 ei->probability = PROB_ALWAYS;
2836 et->probability = PROB_LIKELY;
2837 ef->probability = PROB_UNLIKELY;
9af5ce0c 2838 et->count = apply_probability (test_bb->count, et->probability);
2839 ef->count = apply_probability (test_bb->count, ef->probability);
0cd02a19 2840
2841 code_bb->count = et->count;
2842 code_bb->frequency = EDGE_FREQUENCY (et);
2843
2844 transaction_bb = join_bb;
2845 }
2846
2847 // If we have an ABORT edge, create a test to perform the abort.
2848 if (abort_edge)
2849 {
2850 basic_block test_bb = create_empty_bb (transaction_bb);
b3083327 2851 add_bb_to_loop (test_bb, transaction_bb->loop_father);
0cd02a19 2852 if (region->restart_block == region->entry_block)
2853 region->restart_block = test_bb;
2854
f9e245b2 2855 tree t1 = create_tmp_reg (tm_state_type);
0cd02a19 2856 tree t2 = build_int_cst (tm_state_type, A_ABORTTRANSACTION);
e9cf809e 2857 gimple stmt = gimple_build_assign (t1, BIT_AND_EXPR, tm_state, t2);
0cd02a19 2858 gimple_stmt_iterator gsi = gsi_last_bb (test_bb);
2859 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2860
2861 t2 = build_int_cst (tm_state_type, 0);
2862 stmt = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
2863 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2864
2865 edge ei = make_edge (transaction_bb, test_bb, EDGE_FALLTHRU);
2866 test_bb->frequency = transaction_bb->frequency;
2867 test_bb->count = transaction_bb->count;
2868 ei->probability = PROB_ALWAYS;
2869
2870 // Not abort edge. If both are live, chose one at random as we'll
2871 // we'll be fixing that up below.
2872 redirect_edge_pred (fallthru_edge, test_bb);
2873 fallthru_edge->flags = EDGE_FALSE_VALUE;
2874 fallthru_edge->probability = PROB_VERY_LIKELY;
2875 fallthru_edge->count
9af5ce0c 2876 = apply_probability (test_bb->count, fallthru_edge->probability);
0cd02a19 2877
2878 // Abort/over edge.
2879 redirect_edge_pred (abort_edge, test_bb);
2880 abort_edge->flags = EDGE_TRUE_VALUE;
2881 abort_edge->probability = PROB_VERY_UNLIKELY;
2882 abort_edge->count
9af5ce0c 2883 = apply_probability (test_bb->count, abort_edge->probability);
0cd02a19 2884
2885 transaction_bb = test_bb;
2886 }
2887
2888 // If we have both instrumented and uninstrumented code paths, select one.
2889 if (inst_edge && uninst_edge)
2890 {
2891 basic_block test_bb = create_empty_bb (transaction_bb);
b3083327 2892 add_bb_to_loop (test_bb, transaction_bb->loop_father);
0cd02a19 2893 if (region->restart_block == region->entry_block)
2894 region->restart_block = test_bb;
2895
f9e245b2 2896 tree t1 = create_tmp_reg (tm_state_type);
0cd02a19 2897 tree t2 = build_int_cst (tm_state_type, A_RUNUNINSTRUMENTEDCODE);
2898
e9cf809e 2899 gimple stmt = gimple_build_assign (t1, BIT_AND_EXPR, tm_state, t2);
0cd02a19 2900 gimple_stmt_iterator gsi = gsi_last_bb (test_bb);
2901 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2902
2903 t2 = build_int_cst (tm_state_type, 0);
2904 stmt = gimple_build_cond (NE_EXPR, t1, t2, NULL, NULL);
2905 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2906
2907 // Create the edge into test_bb first, as we want to copy values
2908 // out of the fallthru edge.
2909 edge e = make_edge (transaction_bb, test_bb, fallthru_edge->flags);
2910 e->probability = fallthru_edge->probability;
2911 test_bb->count = e->count = fallthru_edge->count;
2912 test_bb->frequency = EDGE_FREQUENCY (e);
2913
2914 // Now update the edges to the inst/uninist implementations.
2915 // For now assume that the paths are equally likely. When using HTM,
2916 // we'll try the uninst path first and fallback to inst path if htm
2917 // buffers are exceeded. Without HTM we start with the inst path and
2918 // use the uninst path when falling back to serial mode.
2919 redirect_edge_pred (inst_edge, test_bb);
2920 inst_edge->flags = EDGE_FALSE_VALUE;
2921 inst_edge->probability = REG_BR_PROB_BASE / 2;
2922 inst_edge->count
9af5ce0c 2923 = apply_probability (test_bb->count, inst_edge->probability);
0cd02a19 2924
2925 redirect_edge_pred (uninst_edge, test_bb);
2926 uninst_edge->flags = EDGE_TRUE_VALUE;
2927 uninst_edge->probability = REG_BR_PROB_BASE / 2;
2928 uninst_edge->count
9af5ce0c 2929 = apply_probability (test_bb->count, uninst_edge->probability);
0cd02a19 2930 }
2931
2932 // If we have no previous special cases, and we have PHIs at the beginning
2933 // of the atomic region, this means we have a loop at the beginning of the
2934 // atomic region that shares the first block. This can cause problems with
2935 // the transaction restart abnormal edges to be added in the tm_edges pass.
2936 // Solve this by adding a new empty block to receive the abnormal edges.
2937 if (region->restart_block == region->entry_block
2938 && phi_nodes (region->entry_block))
2939 {
2940 basic_block empty_bb = create_empty_bb (transaction_bb);
2941 region->restart_block = empty_bb;
b3083327 2942 add_bb_to_loop (empty_bb, transaction_bb->loop_father);
0cd02a19 2943
2944 redirect_edge_pred (fallthru_edge, empty_bb);
2945 make_edge (transaction_bb, empty_bb, EDGE_FALLTHRU);
2946 }
2947
2948 return NULL;
2949}
2950
2951/* Generate the temporary to be used for the return value of
2952 BUILT_IN_TM_START. */
2953
2954static void *
2955generate_tm_state (struct tm_region *region, void *data ATTRIBUTE_UNUSED)
2956{
2957 tree tm_start = builtin_decl_explicit (BUILT_IN_TM_START);
2958 region->tm_state =
2959 create_tmp_reg (TREE_TYPE (TREE_TYPE (tm_start)), "tm_state");
2960
2961 // Reset the subcode, post optimizations. We'll fill this in
2962 // again as we process blocks.
2963 if (region->exit_blocks)
2964 {
1a91d914 2965 gtransaction *transaction_stmt = region->get_transaction_stmt ();
2966 unsigned int subcode = gimple_transaction_subcode (transaction_stmt);
0cd02a19 2967
2968 if (subcode & GTMA_DOES_GO_IRREVOCABLE)
2969 subcode &= (GTMA_DECLARATION_MASK | GTMA_DOES_GO_IRREVOCABLE
1910089e 2970 | GTMA_MAY_ENTER_IRREVOCABLE
2971 | GTMA_HAS_NO_INSTRUMENTATION);
0cd02a19 2972 else
2973 subcode &= GTMA_DECLARATION_MASK;
1a91d914 2974 gimple_transaction_set_subcode (transaction_stmt, subcode);
0cd02a19 2975 }
2976
2977 return NULL;
2978}
2979
2980// Propagate flags from inner transactions outwards.
2981static void
2982propagate_tm_flags_out (struct tm_region *region)
2983{
2984 if (region == NULL)
2985 return;
2986 propagate_tm_flags_out (region->inner);
2987
2988 if (region->outer && region->outer->transaction_stmt)
2989 {
1a91d914 2990 unsigned s
2991 = gimple_transaction_subcode (region->get_transaction_stmt ());
0cd02a19 2992 s &= (GTMA_HAVE_ABORT | GTMA_HAVE_LOAD | GTMA_HAVE_STORE
2993 | GTMA_MAY_ENTER_IRREVOCABLE);
1a91d914 2994 s |= gimple_transaction_subcode (region->outer->get_transaction_stmt ());
2995 gimple_transaction_set_subcode (region->outer->get_transaction_stmt (),
2996 s);
0cd02a19 2997 }
2998
2999 propagate_tm_flags_out (region->next);
3000}
3001
4c0315d0 3002/* Entry point to the MARK phase of TM expansion. Here we replace
3003 transactional memory statements with calls to builtins, and function
3004 calls with their transactional clones (if available). But we don't
3005 yet lower GIMPLE_TRANSACTION or add the transaction restart back-edges. */
3006
3007static unsigned int
3008execute_tm_mark (void)
3009{
4c0315d0 3010 pending_edge_inserts_p = false;
3011
00d83cc8 3012 expand_regions (all_tm_regions, generate_tm_state, NULL,
3013 /*traverse_clones=*/true);
4c0315d0 3014
0cd02a19 3015 tm_log_init ();
4c0315d0 3016
00d83cc8 3017 vec<tm_region_p> bb_regions
79f4a793 3018 = get_bb_regions_instrumented (/*traverse_clones=*/true,
3019 /*include_uninstrumented_p=*/false);
0cd02a19 3020 struct tm_region *r;
3021 unsigned i;
4c0315d0 3022
0cd02a19 3023 // Expand memory operations into calls into the runtime.
3024 // This collects log entries as well.
f1f41a6c 3025 FOR_EACH_VEC_ELT (bb_regions, i, r)
ded1a556 3026 {
3027 if (r != NULL)
3028 {
3029 if (r->transaction_stmt)
3030 {
1a91d914 3031 unsigned sub
3032 = gimple_transaction_subcode (r->get_transaction_stmt ());
ded1a556 3033
3034 /* If we're sure to go irrevocable, there won't be
3035 anything to expand, since the run-time will go
3036 irrevocable right away. */
3037 if (sub & GTMA_DOES_GO_IRREVOCABLE
3038 && sub & GTMA_MAY_ENTER_IRREVOCABLE)
3039 continue;
3040 }
f5a6b05f 3041 expand_block_tm (r, BASIC_BLOCK_FOR_FN (cfun, i));
ded1a556 3042 }
3043 }
0cd02a19 3044
4aac6cf8 3045 bb_regions.release ();
3046
0cd02a19 3047 // Propagate flags from inner transactions outwards.
3048 propagate_tm_flags_out (all_tm_regions);
3049
3050 // Expand GIMPLE_TRANSACTIONs into calls into the runtime.
00d83cc8 3051 expand_regions (all_tm_regions, expand_transaction, NULL,
3052 /*traverse_clones=*/false);
0cd02a19 3053
3054 tm_log_emit ();
3055 tm_log_delete ();
4c0315d0 3056
3057 if (pending_edge_inserts_p)
3058 gsi_commit_edge_inserts ();
0cd02a19 3059 free_dominance_info (CDI_DOMINATORS);
4c0315d0 3060 return 0;
3061}
3062
cbe8bda8 3063namespace {
3064
3065const pass_data pass_data_tm_mark =
3066{
3067 GIMPLE_PASS, /* type */
3068 "tmmark", /* name */
3069 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 3070 TV_TRANS_MEM, /* tv_id */
3071 ( PROP_ssa | PROP_cfg ), /* properties_required */
3072 0, /* properties_provided */
3073 0, /* properties_destroyed */
3074 0, /* todo_flags_start */
8b88439e 3075 TODO_update_ssa, /* todo_flags_finish */
4c0315d0 3076};
cbe8bda8 3077
3078class pass_tm_mark : public gimple_opt_pass
3079{
3080public:
9af5ce0c 3081 pass_tm_mark (gcc::context *ctxt)
3082 : gimple_opt_pass (pass_data_tm_mark, ctxt)
cbe8bda8 3083 {}
3084
3085 /* opt_pass methods: */
65b0537f 3086 virtual unsigned int execute (function *) { return execute_tm_mark (); }
cbe8bda8 3087
3088}; // class pass_tm_mark
3089
3090} // anon namespace
3091
3092gimple_opt_pass *
3093make_pass_tm_mark (gcc::context *ctxt)
3094{
3095 return new pass_tm_mark (ctxt);
3096}
4c0315d0 3097\f
0cd02a19 3098
3099/* Create an abnormal edge from STMT at iter, splitting the block
3100 as necessary. Adjust *PNEXT as needed for the split block. */
4c0315d0 3101
3102static inline void
0cd02a19 3103split_bb_make_tm_edge (gimple stmt, basic_block dest_bb,
3104 gimple_stmt_iterator iter, gimple_stmt_iterator *pnext)
4c0315d0 3105{
0cd02a19 3106 basic_block bb = gimple_bb (stmt);
3107 if (!gsi_one_before_end_p (iter))
3108 {
3109 edge e = split_block (bb, stmt);
3110 *pnext = gsi_start_bb (e->dest);
3111 }
3112 make_edge (bb, dest_bb, EDGE_ABNORMAL);
4c0315d0 3113
0cd02a19 3114 // Record the need for the edge for the benefit of the rtl passes.
4c0315d0 3115 if (cfun->gimple_df->tm_restart == NULL)
b7aa58e4 3116 cfun->gimple_df->tm_restart
3117 = hash_table<tm_restart_hasher>::create_ggc (31);
4c0315d0 3118
0cd02a19 3119 struct tm_restart_node dummy;
4c0315d0 3120 dummy.stmt = stmt;
0cd02a19 3121 dummy.label_or_list = gimple_block_label (dest_bb);
3122
b7aa58e4 3123 tm_restart_node **slot = cfun->gimple_df->tm_restart->find_slot (&dummy,
3124 INSERT);
3125 struct tm_restart_node *n = *slot;
4c0315d0 3126 if (n == NULL)
3127 {
25a27413 3128 n = ggc_alloc<tm_restart_node> ();
4c0315d0 3129 *n = dummy;
3130 }
3131 else
3132 {
3133 tree old = n->label_or_list;
3134 if (TREE_CODE (old) == LABEL_DECL)
0cd02a19 3135 old = tree_cons (NULL, old, NULL);
4c0315d0 3136 n->label_or_list = tree_cons (NULL, dummy.label_or_list, old);
3137 }
4c0315d0 3138}
3139
4c0315d0 3140/* Split block BB as necessary for every builtin function we added, and
3141 wire up the abnormal back edges implied by the transaction restart. */
3142
3143static void
0cd02a19 3144expand_block_edges (struct tm_region *const region, basic_block bb)
4c0315d0 3145{
0cd02a19 3146 gimple_stmt_iterator gsi, next_gsi;
4c0315d0 3147
0cd02a19 3148 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi = next_gsi)
4c0315d0 3149 {
3150 gimple stmt = gsi_stmt (gsi);
1a91d914 3151 gcall *call_stmt;
4c0315d0 3152
0cd02a19 3153 next_gsi = gsi;
3154 gsi_next (&next_gsi);
3155
3156 // ??? Shouldn't we split for any non-pure, non-irrevocable function?
1a91d914 3157 call_stmt = dyn_cast <gcall *> (stmt);
3158 if ((!call_stmt)
3159 || (gimple_call_flags (call_stmt) & ECF_TM_BUILTIN) == 0)
0cd02a19 3160 continue;
3161
1a91d914 3162 if (DECL_FUNCTION_CODE (gimple_call_fndecl (call_stmt))
3163 == BUILT_IN_TM_ABORT)
4c0315d0 3164 {
0cd02a19 3165 // If we have a ``_transaction_cancel [[outer]]'', there is only
3166 // one abnormal edge: to the transaction marked OUTER.
3167 // All compiler-generated instances of BUILT_IN_TM_ABORT have a
3168 // constant argument, which we can examine here. Users invoking
3169 // TM_ABORT directly get what they deserve.
1a91d914 3170 tree arg = gimple_call_arg (call_stmt, 0);
0cd02a19 3171 if (TREE_CODE (arg) == INTEGER_CST
3172 && (TREE_INT_CST_LOW (arg) & AR_OUTERABORT) != 0
3173 && !decl_is_tm_clone (current_function_decl))
4c0315d0 3174 {
0cd02a19 3175 // Find the GTMA_IS_OUTER transaction.
3176 for (struct tm_region *o = region; o; o = o->outer)
3177 if (o->original_transaction_was_outer)
3178 {
1a91d914 3179 split_bb_make_tm_edge (call_stmt, o->restart_block,
0cd02a19 3180 gsi, &next_gsi);
3181 break;
3182 }
3183
3184 // Otherwise, the front-end should have semantically checked
3185 // outer aborts, but in either case the target region is not
3186 // within this function.
3187 continue;
4c0315d0 3188 }
3189
0cd02a19 3190 // Non-outer, TM aborts have an abnormal edge to the inner-most
3191 // transaction, the one being aborted;
1a91d914 3192 split_bb_make_tm_edge (call_stmt, region->restart_block, gsi,
3193 &next_gsi);
4c0315d0 3194 }
3195
0cd02a19 3196 // All TM builtins have an abnormal edge to the outer-most transaction.
3197 // We never restart inner transactions. For tm clones, we know a-priori
3198 // that the outer-most transaction is outside the function.
3199 if (decl_is_tm_clone (current_function_decl))
3200 continue;
4c0315d0 3201
0cd02a19 3202 if (cfun->gimple_df->tm_restart == NULL)
3203 cfun->gimple_df->tm_restart
b7aa58e4 3204 = hash_table<tm_restart_hasher>::create_ggc (31);
4c0315d0 3205
0cd02a19 3206 // All TM builtins have an abnormal edge to the outer-most transaction.
3207 // We never restart inner transactions.
3208 for (struct tm_region *o = region; o; o = o->outer)
3209 if (!o->outer)
3210 {
1a91d914 3211 split_bb_make_tm_edge (call_stmt, o->restart_block, gsi, &next_gsi);
0cd02a19 3212 break;
3213 }
4c0315d0 3214
0cd02a19 3215 // Delete any tail-call annotation that may have been added.
3216 // The tail-call pass may have mis-identified the commit as being
3217 // a candidate because we had not yet added this restart edge.
1a91d914 3218 gimple_call_set_tail (call_stmt, false);
4c0315d0 3219 }
3220}
3221
3222/* Entry point to the final expansion of transactional nodes. */
3223
cbe8bda8 3224namespace {
3225
3226const pass_data pass_data_tm_edges =
3227{
3228 GIMPLE_PASS, /* type */
3229 "tmedge", /* name */
3230 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 3231 TV_TRANS_MEM, /* tv_id */
3232 ( PROP_ssa | PROP_cfg ), /* properties_required */
3233 0, /* properties_provided */
3234 0, /* properties_destroyed */
3235 0, /* todo_flags_start */
8b88439e 3236 TODO_update_ssa, /* todo_flags_finish */
4c0315d0 3237};
cbe8bda8 3238
3239class pass_tm_edges : public gimple_opt_pass
3240{
3241public:
9af5ce0c 3242 pass_tm_edges (gcc::context *ctxt)
3243 : gimple_opt_pass (pass_data_tm_edges, ctxt)
cbe8bda8 3244 {}
3245
3246 /* opt_pass methods: */
65b0537f 3247 virtual unsigned int execute (function *);
cbe8bda8 3248
3249}; // class pass_tm_edges
3250
65b0537f 3251unsigned int
3252pass_tm_edges::execute (function *fun)
3253{
3254 vec<tm_region_p> bb_regions
3255 = get_bb_regions_instrumented (/*traverse_clones=*/false,
3256 /*include_uninstrumented_p=*/true);
3257 struct tm_region *r;
3258 unsigned i;
3259
3260 FOR_EACH_VEC_ELT (bb_regions, i, r)
3261 if (r != NULL)
3262 expand_block_edges (r, BASIC_BLOCK_FOR_FN (fun, i));
3263
3264 bb_regions.release ();
3265
3266 /* We've got to release the dominance info now, to indicate that it
3267 must be rebuilt completely. Otherwise we'll crash trying to update
3268 the SSA web in the TODO section following this pass. */
3269 free_dominance_info (CDI_DOMINATORS);
3270 bitmap_obstack_release (&tm_obstack);
3271 all_tm_regions = NULL;
3272
3273 return 0;
3274}
3275
cbe8bda8 3276} // anon namespace
3277
3278gimple_opt_pass *
3279make_pass_tm_edges (gcc::context *ctxt)
3280{
3281 return new pass_tm_edges (ctxt);
3282}
0cd02a19 3283\f
3284/* Helper function for expand_regions. Expand REGION and recurse to
3285 the inner region. Call CALLBACK on each region. CALLBACK returns
3286 NULL to continue the traversal, otherwise a non-null value which
00d83cc8 3287 this function will return as well. TRAVERSE_CLONES is true if we
3288 should traverse transactional clones. */
0cd02a19 3289
3290static void *
3291expand_regions_1 (struct tm_region *region,
3292 void *(*callback)(struct tm_region *, void *),
00d83cc8 3293 void *data,
3294 bool traverse_clones)
0cd02a19 3295{
3296 void *retval = NULL;
00d83cc8 3297 if (region->exit_blocks
3298 || (traverse_clones && decl_is_tm_clone (current_function_decl)))
0cd02a19 3299 {
3300 retval = callback (region, data);
3301 if (retval)
3302 return retval;
3303 }
3304 if (region->inner)
3305 {
00d83cc8 3306 retval = expand_regions (region->inner, callback, data, traverse_clones);
0cd02a19 3307 if (retval)
3308 return retval;
3309 }
3310 return retval;
3311}
3312
3313/* Traverse the regions enclosed and including REGION. Execute
3314 CALLBACK for each region, passing DATA. CALLBACK returns NULL to
3315 continue the traversal, otherwise a non-null value which this
00d83cc8 3316 function will return as well. TRAVERSE_CLONES is true if we should
3317 traverse transactional clones. */
0cd02a19 3318
3319static void *
3320expand_regions (struct tm_region *region,
3321 void *(*callback)(struct tm_region *, void *),
00d83cc8 3322 void *data,
3323 bool traverse_clones)
0cd02a19 3324{
3325 void *retval = NULL;
3326 while (region)
3327 {
00d83cc8 3328 retval = expand_regions_1 (region, callback, data, traverse_clones);
0cd02a19 3329 if (retval)
3330 return retval;
3331 region = region->next;
3332 }
3333 return retval;
3334}
3335
4c0315d0 3336\f
3337/* A unique TM memory operation. */
3338typedef struct tm_memop
3339{
3340 /* Unique ID that all memory operations to the same location have. */
3341 unsigned int value_id;
3342 /* Address of load/store. */
3343 tree addr;
3344} *tm_memop_t;
3345
d9dd21a8 3346/* TM memory operation hashtable helpers. */
3347
3348struct tm_memop_hasher : typed_free_remove <tm_memop>
3349{
9969c043 3350 typedef tm_memop *value_type;
3351 typedef tm_memop *compare_type;
3352 static inline hashval_t hash (const tm_memop *);
3353 static inline bool equal (const tm_memop *, const tm_memop *);
d9dd21a8 3354};
3355
3356/* Htab support. Return a hash value for a `tm_memop'. */
3357inline hashval_t
9969c043 3358tm_memop_hasher::hash (const tm_memop *mem)
d9dd21a8 3359{
3360 tree addr = mem->addr;
3361 /* We drill down to the SSA_NAME/DECL for the hash, but equality is
3362 actually done with operand_equal_p (see tm_memop_eq). */
3363 if (TREE_CODE (addr) == ADDR_EXPR)
3364 addr = TREE_OPERAND (addr, 0);
3365 return iterative_hash_expr (addr, 0);
3366}
3367
3368/* Htab support. Return true if two tm_memop's are the same. */
3369inline bool
9969c043 3370tm_memop_hasher::equal (const tm_memop *mem1, const tm_memop *mem2)
d9dd21a8 3371{
3372 return operand_equal_p (mem1->addr, mem2->addr, 0);
3373}
3374
4c0315d0 3375/* Sets for solving data flow equations in the memory optimization pass. */
3376struct tm_memopt_bitmaps
3377{
3378 /* Stores available to this BB upon entry. Basically, stores that
3379 dominate this BB. */
3380 bitmap store_avail_in;
3381 /* Stores available at the end of this BB. */
3382 bitmap store_avail_out;
3383 bitmap store_antic_in;
3384 bitmap store_antic_out;
3385 /* Reads available to this BB upon entry. Basically, reads that
3386 dominate this BB. */
3387 bitmap read_avail_in;
3388 /* Reads available at the end of this BB. */
3389 bitmap read_avail_out;
3390 /* Reads performed in this BB. */
3391 bitmap read_local;
3392 /* Writes performed in this BB. */
3393 bitmap store_local;
3394
3395 /* Temporary storage for pass. */
3396 /* Is the current BB in the worklist? */
3397 bool avail_in_worklist_p;
3398 /* Have we visited this BB? */
3399 bool visited_p;
3400};
3401
3402static bitmap_obstack tm_memopt_obstack;
3403
3404/* Unique counter for TM loads and stores. Loads and stores of the
3405 same address get the same ID. */
3406static unsigned int tm_memopt_value_id;
c1f445d2 3407static hash_table<tm_memop_hasher> *tm_memopt_value_numbers;
4c0315d0 3408
3409#define STORE_AVAIL_IN(BB) \
3410 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in
3411#define STORE_AVAIL_OUT(BB) \
3412 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_out
3413#define STORE_ANTIC_IN(BB) \
3414 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_in
3415#define STORE_ANTIC_OUT(BB) \
3416 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_antic_out
3417#define READ_AVAIL_IN(BB) \
3418 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_in
3419#define READ_AVAIL_OUT(BB) \
3420 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_avail_out
3421#define READ_LOCAL(BB) \
3422 ((struct tm_memopt_bitmaps *) ((BB)->aux))->read_local
3423#define STORE_LOCAL(BB) \
3424 ((struct tm_memopt_bitmaps *) ((BB)->aux))->store_local
3425#define AVAIL_IN_WORKLIST_P(BB) \
3426 ((struct tm_memopt_bitmaps *) ((BB)->aux))->avail_in_worklist_p
3427#define BB_VISITED_P(BB) \
3428 ((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p
3429
4c0315d0 3430/* Given a TM load/store in STMT, return the value number for the address
3431 it accesses. */
3432
3433static unsigned int
3434tm_memopt_value_number (gimple stmt, enum insert_option op)
3435{
3436 struct tm_memop tmpmem, *mem;
d9dd21a8 3437 tm_memop **slot;
4c0315d0 3438
3439 gcc_assert (is_tm_load (stmt) || is_tm_store (stmt));
3440 tmpmem.addr = gimple_call_arg (stmt, 0);
c1f445d2 3441 slot = tm_memopt_value_numbers->find_slot (&tmpmem, op);
4c0315d0 3442 if (*slot)
d9dd21a8 3443 mem = *slot;
4c0315d0 3444 else if (op == INSERT)
3445 {
3446 mem = XNEW (struct tm_memop);
3447 *slot = mem;
3448 mem->value_id = tm_memopt_value_id++;
3449 mem->addr = tmpmem.addr;
3450 }
3451 else
3452 gcc_unreachable ();
3453 return mem->value_id;
3454}
3455
3456/* Accumulate TM memory operations in BB into STORE_LOCAL and READ_LOCAL. */
3457
3458static void
3459tm_memopt_accumulate_memops (basic_block bb)
3460{
3461 gimple_stmt_iterator gsi;
3462
3463 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3464 {
3465 gimple stmt = gsi_stmt (gsi);
3466 bitmap bits;
3467 unsigned int loc;
3468
3469 if (is_tm_store (stmt))
3470 bits = STORE_LOCAL (bb);
3471 else if (is_tm_load (stmt))
3472 bits = READ_LOCAL (bb);
3473 else
3474 continue;
3475
3476 loc = tm_memopt_value_number (stmt, INSERT);
3477 bitmap_set_bit (bits, loc);
3478 if (dump_file)
3479 {
3480 fprintf (dump_file, "TM memopt (%s): value num=%d, BB=%d, addr=",
3481 is_tm_load (stmt) ? "LOAD" : "STORE", loc,
3482 gimple_bb (stmt)->index);
3483 print_generic_expr (dump_file, gimple_call_arg (stmt, 0), 0);
3484 fprintf (dump_file, "\n");
3485 }
3486 }
3487}
3488
3489/* Prettily dump one of the memopt sets. BITS is the bitmap to dump. */
3490
3491static void
3492dump_tm_memopt_set (const char *set_name, bitmap bits)
3493{
3494 unsigned i;
3495 bitmap_iterator bi;
3496 const char *comma = "";
3497
3498 fprintf (dump_file, "TM memopt: %s: [", set_name);
3499 EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
3500 {
c1f445d2 3501 hash_table<tm_memop_hasher>::iterator hi;
d9dd21a8 3502 struct tm_memop *mem = NULL;
4c0315d0 3503
3504 /* Yeah, yeah, yeah. Whatever. This is just for debugging. */
c1f445d2 3505 FOR_EACH_HASH_TABLE_ELEMENT (*tm_memopt_value_numbers, mem, tm_memop_t, hi)
4c0315d0 3506 if (mem->value_id == i)
3507 break;
3508 gcc_assert (mem->value_id == i);
3509 fprintf (dump_file, "%s", comma);
3510 comma = ", ";
3511 print_generic_expr (dump_file, mem->addr, 0);
3512 }
3513 fprintf (dump_file, "]\n");
3514}
3515
3516/* Prettily dump all of the memopt sets in BLOCKS. */
3517
3518static void
f1f41a6c 3519dump_tm_memopt_sets (vec<basic_block> blocks)
4c0315d0 3520{
3521 size_t i;
3522 basic_block bb;
3523
f1f41a6c 3524 for (i = 0; blocks.iterate (i, &bb); ++i)
4c0315d0 3525 {
3526 fprintf (dump_file, "------------BB %d---------\n", bb->index);
3527 dump_tm_memopt_set ("STORE_LOCAL", STORE_LOCAL (bb));
3528 dump_tm_memopt_set ("READ_LOCAL", READ_LOCAL (bb));
3529 dump_tm_memopt_set ("STORE_AVAIL_IN", STORE_AVAIL_IN (bb));
3530 dump_tm_memopt_set ("STORE_AVAIL_OUT", STORE_AVAIL_OUT (bb));
3531 dump_tm_memopt_set ("READ_AVAIL_IN", READ_AVAIL_IN (bb));
3532 dump_tm_memopt_set ("READ_AVAIL_OUT", READ_AVAIL_OUT (bb));
3533 }
3534}
3535
3536/* Compute {STORE,READ}_AVAIL_IN for the basic block BB. */
3537
3538static void
3539tm_memopt_compute_avin (basic_block bb)
3540{
3541 edge e;
3542 unsigned ix;
3543
3544 /* Seed with the AVOUT of any predecessor. */
3545 for (ix = 0; ix < EDGE_COUNT (bb->preds); ix++)
3546 {
3547 e = EDGE_PRED (bb, ix);
3548 /* Make sure we have already visited this BB, and is thus
3549 initialized.
3550
3551 If e->src->aux is NULL, this predecessor is actually on an
3552 enclosing transaction. We only care about the current
3553 transaction, so ignore it. */
3554 if (e->src->aux && BB_VISITED_P (e->src))
3555 {
3556 bitmap_copy (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3557 bitmap_copy (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3558 break;
3559 }
3560 }
3561
3562 for (; ix < EDGE_COUNT (bb->preds); ix++)
3563 {
3564 e = EDGE_PRED (bb, ix);
3565 if (e->src->aux && BB_VISITED_P (e->src))
3566 {
3567 bitmap_and_into (STORE_AVAIL_IN (bb), STORE_AVAIL_OUT (e->src));
3568 bitmap_and_into (READ_AVAIL_IN (bb), READ_AVAIL_OUT (e->src));
3569 }
3570 }
3571
3572 BB_VISITED_P (bb) = true;
3573}
3574
3575/* Compute the STORE_ANTIC_IN for the basic block BB. */
3576
3577static void
3578tm_memopt_compute_antin (basic_block bb)
3579{
3580 edge e;
3581 unsigned ix;
3582
3583 /* Seed with the ANTIC_OUT of any successor. */
3584 for (ix = 0; ix < EDGE_COUNT (bb->succs); ix++)
3585 {
3586 e = EDGE_SUCC (bb, ix);
3587 /* Make sure we have already visited this BB, and is thus
3588 initialized. */
3589 if (BB_VISITED_P (e->dest))
3590 {
3591 bitmap_copy (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3592 break;
3593 }
3594 }
3595
3596 for (; ix < EDGE_COUNT (bb->succs); ix++)
3597 {
3598 e = EDGE_SUCC (bb, ix);
3599 if (BB_VISITED_P (e->dest))
3600 bitmap_and_into (STORE_ANTIC_IN (bb), STORE_ANTIC_OUT (e->dest));
3601 }
3602
3603 BB_VISITED_P (bb) = true;
3604}
3605
3606/* Compute the AVAIL sets for every basic block in BLOCKS.
3607
3608 We compute {STORE,READ}_AVAIL_{OUT,IN} as follows:
3609
3610 AVAIL_OUT[bb] = union (AVAIL_IN[bb], LOCAL[bb])
3611 AVAIL_IN[bb] = intersect (AVAIL_OUT[predecessors])
3612
3613 This is basically what we do in lcm's compute_available(), but here
3614 we calculate two sets of sets (one for STOREs and one for READs),
3615 and we work on a region instead of the entire CFG.
3616
3617 REGION is the TM region.
3618 BLOCKS are the basic blocks in the region. */
3619
3620static void
3621tm_memopt_compute_available (struct tm_region *region,
f1f41a6c 3622 vec<basic_block> blocks)
4c0315d0 3623{
3624 edge e;
3625 basic_block *worklist, *qin, *qout, *qend, bb;
3626 unsigned int qlen, i;
3627 edge_iterator ei;
3628 bool changed;
3629
3630 /* Allocate a worklist array/queue. Entries are only added to the
3631 list if they were not already on the list. So the size is
3632 bounded by the number of basic blocks in the region. */
f1f41a6c 3633 qlen = blocks.length () - 1;
4c0315d0 3634 qin = qout = worklist =
3635 XNEWVEC (basic_block, qlen);
3636
3637 /* Put every block in the region on the worklist. */
f1f41a6c 3638 for (i = 0; blocks.iterate (i, &bb); ++i)
4c0315d0 3639 {
3640 /* Seed AVAIL_OUT with the LOCAL set. */
3641 bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_LOCAL (bb));
3642 bitmap_ior_into (READ_AVAIL_OUT (bb), READ_LOCAL (bb));
3643
3644 AVAIL_IN_WORKLIST_P (bb) = true;
3645 /* No need to insert the entry block, since it has an AVIN of
3646 null, and an AVOUT that has already been seeded in. */
3647 if (bb != region->entry_block)
3648 *qin++ = bb;
3649 }
3650
3651 /* The entry block has been initialized with the local sets. */
3652 BB_VISITED_P (region->entry_block) = true;
3653
3654 qin = worklist;
3655 qend = &worklist[qlen];
3656
3657 /* Iterate until the worklist is empty. */
3658 while (qlen)
3659 {
3660 /* Take the first entry off the worklist. */
3661 bb = *qout++;
3662 qlen--;
3663
3664 if (qout >= qend)
3665 qout = worklist;
3666
3667 /* This block can be added to the worklist again if necessary. */
3668 AVAIL_IN_WORKLIST_P (bb) = false;
3669 tm_memopt_compute_avin (bb);
3670
3671 /* Note: We do not add the LOCAL sets here because we already
3672 seeded the AVAIL_OUT sets with them. */
3673 changed = bitmap_ior_into (STORE_AVAIL_OUT (bb), STORE_AVAIL_IN (bb));
3674 changed |= bitmap_ior_into (READ_AVAIL_OUT (bb), READ_AVAIL_IN (bb));
3675 if (changed
3676 && (region->exit_blocks == NULL
3677 || !bitmap_bit_p (region->exit_blocks, bb->index)))
3678 /* If the out state of this block changed, then we need to add
3679 its successors to the worklist if they are not already in. */
3680 FOR_EACH_EDGE (e, ei, bb->succs)
34154e27 3681 if (!AVAIL_IN_WORKLIST_P (e->dest)
3682 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
4c0315d0 3683 {
3684 *qin++ = e->dest;
3685 AVAIL_IN_WORKLIST_P (e->dest) = true;
3686 qlen++;
3687
3688 if (qin >= qend)
3689 qin = worklist;
3690 }
3691 }
3692
3693 free (worklist);
3694
3695 if (dump_file)
3696 dump_tm_memopt_sets (blocks);
3697}
3698
3699/* Compute ANTIC sets for every basic block in BLOCKS.
3700
3701 We compute STORE_ANTIC_OUT as follows:
3702
3703 STORE_ANTIC_OUT[bb] = union(STORE_ANTIC_IN[bb], STORE_LOCAL[bb])
3704 STORE_ANTIC_IN[bb] = intersect(STORE_ANTIC_OUT[successors])
3705
3706 REGION is the TM region.
3707 BLOCKS are the basic blocks in the region. */
3708
3709static void
3710tm_memopt_compute_antic (struct tm_region *region,
f1f41a6c 3711 vec<basic_block> blocks)
4c0315d0 3712{
3713 edge e;
3714 basic_block *worklist, *qin, *qout, *qend, bb;
3715 unsigned int qlen;
3716 int i;
3717 edge_iterator ei;
3718
3719 /* Allocate a worklist array/queue. Entries are only added to the
3720 list if they were not already on the list. So the size is
3721 bounded by the number of basic blocks in the region. */
f1f41a6c 3722 qin = qout = worklist = XNEWVEC (basic_block, blocks.length ());
4c0315d0 3723
f1f41a6c 3724 for (qlen = 0, i = blocks.length () - 1; i >= 0; --i)
4c0315d0 3725 {
f1f41a6c 3726 bb = blocks[i];
4c0315d0 3727
3728 /* Seed ANTIC_OUT with the LOCAL set. */
3729 bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_LOCAL (bb));
3730
3731 /* Put every block in the region on the worklist. */
3732 AVAIL_IN_WORKLIST_P (bb) = true;
3733 /* No need to insert exit blocks, since their ANTIC_IN is NULL,
3734 and their ANTIC_OUT has already been seeded in. */
3735 if (region->exit_blocks
3736 && !bitmap_bit_p (region->exit_blocks, bb->index))
3737 {
3738 qlen++;
3739 *qin++ = bb;
3740 }
3741 }
3742
3743 /* The exit blocks have been initialized with the local sets. */
3744 if (region->exit_blocks)
3745 {
3746 unsigned int i;
3747 bitmap_iterator bi;
3748 EXECUTE_IF_SET_IN_BITMAP (region->exit_blocks, 0, i, bi)
f5a6b05f 3749 BB_VISITED_P (BASIC_BLOCK_FOR_FN (cfun, i)) = true;
4c0315d0 3750 }
3751
3752 qin = worklist;
3753 qend = &worklist[qlen];
3754
3755 /* Iterate until the worklist is empty. */
3756 while (qlen)
3757 {
3758 /* Take the first entry off the worklist. */
3759 bb = *qout++;
3760 qlen--;
3761
3762 if (qout >= qend)
3763 qout = worklist;
3764
3765 /* This block can be added to the worklist again if necessary. */
3766 AVAIL_IN_WORKLIST_P (bb) = false;
3767 tm_memopt_compute_antin (bb);
3768
3769 /* Note: We do not add the LOCAL sets here because we already
3770 seeded the ANTIC_OUT sets with them. */
3771 if (bitmap_ior_into (STORE_ANTIC_OUT (bb), STORE_ANTIC_IN (bb))
3772 && bb != region->entry_block)
3773 /* If the out state of this block changed, then we need to add
3774 its predecessors to the worklist if they are not already in. */
3775 FOR_EACH_EDGE (e, ei, bb->preds)
3776 if (!AVAIL_IN_WORKLIST_P (e->src))
3777 {
3778 *qin++ = e->src;
3779 AVAIL_IN_WORKLIST_P (e->src) = true;
3780 qlen++;
3781
3782 if (qin >= qend)
3783 qin = worklist;
3784 }
3785 }
3786
3787 free (worklist);
3788
3789 if (dump_file)
3790 dump_tm_memopt_sets (blocks);
3791}
3792
3793/* Offsets of load variants from TM_LOAD. For example,
3794 BUILT_IN_TM_LOAD_RAR* is an offset of 1 from BUILT_IN_TM_LOAD*.
3795 See gtm-builtins.def. */
3796#define TRANSFORM_RAR 1
3797#define TRANSFORM_RAW 2
3798#define TRANSFORM_RFW 3
3799/* Offsets of store variants from TM_STORE. */
3800#define TRANSFORM_WAR 1
3801#define TRANSFORM_WAW 2
3802
3803/* Inform about a load/store optimization. */
3804
3805static void
3806dump_tm_memopt_transform (gimple stmt)
3807{
3808 if (dump_file)
3809 {
3810 fprintf (dump_file, "TM memopt: transforming: ");
3811 print_gimple_stmt (dump_file, stmt, 0, 0);
3812 fprintf (dump_file, "\n");
3813 }
3814}
3815
3816/* Perform a read/write optimization. Replaces the TM builtin in STMT
3817 by a builtin that is OFFSET entries down in the builtins table in
3818 gtm-builtins.def. */
3819
3820static void
3821tm_memopt_transform_stmt (unsigned int offset,
1a91d914 3822 gcall *stmt,
4c0315d0 3823 gimple_stmt_iterator *gsi)
3824{
3825 tree fn = gimple_call_fn (stmt);
3826 gcc_assert (TREE_CODE (fn) == ADDR_EXPR);
3827 TREE_OPERAND (fn, 0)
3828 = builtin_decl_explicit ((enum built_in_function)
3829 (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0))
3830 + offset));
3831 gimple_call_set_fn (stmt, fn);
3832 gsi_replace (gsi, stmt, true);
3833 dump_tm_memopt_transform (stmt);
3834}
3835
3836/* Perform the actual TM memory optimization transformations in the
3837 basic blocks in BLOCKS. */
3838
3839static void
f1f41a6c 3840tm_memopt_transform_blocks (vec<basic_block> blocks)
4c0315d0 3841{
3842 size_t i;
3843 basic_block bb;
3844 gimple_stmt_iterator gsi;
3845
f1f41a6c 3846 for (i = 0; blocks.iterate (i, &bb); ++i)
4c0315d0 3847 {
3848 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3849 {
3850 gimple stmt = gsi_stmt (gsi);
3851 bitmap read_avail = READ_AVAIL_IN (bb);
3852 bitmap store_avail = STORE_AVAIL_IN (bb);
3853 bitmap store_antic = STORE_ANTIC_OUT (bb);
3854 unsigned int loc;
3855
3856 if (is_tm_simple_load (stmt))
3857 {
1a91d914 3858 gcall *call_stmt = as_a <gcall *> (stmt);
4c0315d0 3859 loc = tm_memopt_value_number (stmt, NO_INSERT);
3860 if (store_avail && bitmap_bit_p (store_avail, loc))
1a91d914 3861 tm_memopt_transform_stmt (TRANSFORM_RAW, call_stmt, &gsi);
4c0315d0 3862 else if (store_antic && bitmap_bit_p (store_antic, loc))
3863 {
1a91d914 3864 tm_memopt_transform_stmt (TRANSFORM_RFW, call_stmt, &gsi);
4c0315d0 3865 bitmap_set_bit (store_avail, loc);
3866 }
3867 else if (read_avail && bitmap_bit_p (read_avail, loc))
1a91d914 3868 tm_memopt_transform_stmt (TRANSFORM_RAR, call_stmt, &gsi);
4c0315d0 3869 else
3870 bitmap_set_bit (read_avail, loc);
3871 }
3872 else if (is_tm_simple_store (stmt))
3873 {
1a91d914 3874 gcall *call_stmt = as_a <gcall *> (stmt);
4c0315d0 3875 loc = tm_memopt_value_number (stmt, NO_INSERT);
3876 if (store_avail && bitmap_bit_p (store_avail, loc))
1a91d914 3877 tm_memopt_transform_stmt (TRANSFORM_WAW, call_stmt, &gsi);
4c0315d0 3878 else
3879 {
3880 if (read_avail && bitmap_bit_p (read_avail, loc))
1a91d914 3881 tm_memopt_transform_stmt (TRANSFORM_WAR, call_stmt, &gsi);
4c0315d0 3882 bitmap_set_bit (store_avail, loc);
3883 }
3884 }
3885 }
3886 }
3887}
3888
3889/* Return a new set of bitmaps for a BB. */
3890
3891static struct tm_memopt_bitmaps *
3892tm_memopt_init_sets (void)
3893{
3894 struct tm_memopt_bitmaps *b
3895 = XOBNEW (&tm_memopt_obstack.obstack, struct tm_memopt_bitmaps);
3896 b->store_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3897 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3898 b->store_antic_in = BITMAP_ALLOC (&tm_memopt_obstack);
3899 b->store_antic_out = BITMAP_ALLOC (&tm_memopt_obstack);
3900 b->store_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3901 b->read_avail_in = BITMAP_ALLOC (&tm_memopt_obstack);
3902 b->read_avail_out = BITMAP_ALLOC (&tm_memopt_obstack);
3903 b->read_local = BITMAP_ALLOC (&tm_memopt_obstack);
3904 b->store_local = BITMAP_ALLOC (&tm_memopt_obstack);
3905 return b;
3906}
3907
3908/* Free sets computed for each BB. */
3909
3910static void
f1f41a6c 3911tm_memopt_free_sets (vec<basic_block> blocks)
4c0315d0 3912{
3913 size_t i;
3914 basic_block bb;
3915
f1f41a6c 3916 for (i = 0; blocks.iterate (i, &bb); ++i)
4c0315d0 3917 bb->aux = NULL;
3918}
3919
3920/* Clear the visited bit for every basic block in BLOCKS. */
3921
3922static void
f1f41a6c 3923tm_memopt_clear_visited (vec<basic_block> blocks)
4c0315d0 3924{
3925 size_t i;
3926 basic_block bb;
3927
f1f41a6c 3928 for (i = 0; blocks.iterate (i, &bb); ++i)
4c0315d0 3929 BB_VISITED_P (bb) = false;
3930}
3931
3932/* Replace TM load/stores with hints for the runtime. We handle
3933 things like read-after-write, write-after-read, read-after-read,
3934 read-for-write, etc. */
3935
3936static unsigned int
3937execute_tm_memopt (void)
3938{
3939 struct tm_region *region;
f1f41a6c 3940 vec<basic_block> bbs;
4c0315d0 3941
3942 tm_memopt_value_id = 0;
c1f445d2 3943 tm_memopt_value_numbers = new hash_table<tm_memop_hasher> (10);
4c0315d0 3944
3945 for (region = all_tm_regions; region; region = region->next)
3946 {
3947 /* All the TM stores/loads in the current region. */
3948 size_t i;
3949 basic_block bb;
3950
3951 bitmap_obstack_initialize (&tm_memopt_obstack);
3952
3953 /* Save all BBs for the current region. */
3954 bbs = get_tm_region_blocks (region->entry_block,
3955 region->exit_blocks,
3956 region->irr_blocks,
3957 NULL,
3958 false);
3959
3960 /* Collect all the memory operations. */
f1f41a6c 3961 for (i = 0; bbs.iterate (i, &bb); ++i)
4c0315d0 3962 {
3963 bb->aux = tm_memopt_init_sets ();
3964 tm_memopt_accumulate_memops (bb);
3965 }
3966
3967 /* Solve data flow equations and transform each block accordingly. */
3968 tm_memopt_clear_visited (bbs);
3969 tm_memopt_compute_available (region, bbs);
3970 tm_memopt_clear_visited (bbs);
3971 tm_memopt_compute_antic (region, bbs);
3972 tm_memopt_transform_blocks (bbs);
3973
3974 tm_memopt_free_sets (bbs);
f1f41a6c 3975 bbs.release ();
4c0315d0 3976 bitmap_obstack_release (&tm_memopt_obstack);
c1f445d2 3977 tm_memopt_value_numbers->empty ();
4c0315d0 3978 }
3979
c1f445d2 3980 delete tm_memopt_value_numbers;
3981 tm_memopt_value_numbers = NULL;
4c0315d0 3982 return 0;
3983}
3984
cbe8bda8 3985namespace {
3986
3987const pass_data pass_data_tm_memopt =
3988{
3989 GIMPLE_PASS, /* type */
3990 "tmmemopt", /* name */
3991 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 3992 TV_TRANS_MEM, /* tv_id */
3993 ( PROP_ssa | PROP_cfg ), /* properties_required */
3994 0, /* properties_provided */
3995 0, /* properties_destroyed */
3996 0, /* todo_flags_start */
3997 0, /* todo_flags_finish */
4c0315d0 3998};
3999
cbe8bda8 4000class pass_tm_memopt : public gimple_opt_pass
4001{
4002public:
9af5ce0c 4003 pass_tm_memopt (gcc::context *ctxt)
4004 : gimple_opt_pass (pass_data_tm_memopt, ctxt)
cbe8bda8 4005 {}
4006
4007 /* opt_pass methods: */
31315c24 4008 virtual bool gate (function *) { return flag_tm && optimize > 0; }
65b0537f 4009 virtual unsigned int execute (function *) { return execute_tm_memopt (); }
cbe8bda8 4010
4011}; // class pass_tm_memopt
4012
4013} // anon namespace
4014
4015gimple_opt_pass *
4016make_pass_tm_memopt (gcc::context *ctxt)
4017{
4018 return new pass_tm_memopt (ctxt);
4019}
4020
4c0315d0 4021\f
4022/* Interprocedual analysis for the creation of transactional clones.
4023 The aim of this pass is to find which functions are referenced in
4024 a non-irrevocable transaction context, and for those over which
4025 we have control (or user directive), create a version of the
4026 function which uses only the transactional interface to reference
4027 protected memories. This analysis proceeds in several steps:
4028
4029 (1) Collect the set of all possible transactional clones:
4030
4031 (a) For all local public functions marked tm_callable, push
4032 it onto the tm_callee queue.
4033
4034 (b) For all local functions, scan for calls in transaction blocks.
4035 Push the caller and callee onto the tm_caller and tm_callee
4036 queues. Count the number of callers for each callee.
4037
4038 (c) For each local function on the callee list, assume we will
4039 create a transactional clone. Push *all* calls onto the
4040 callee queues; count the number of clone callers separately
4041 to the number of original callers.
4042
4043 (2) Propagate irrevocable status up the dominator tree:
4044
4045 (a) Any external function on the callee list that is not marked
4046 tm_callable is irrevocable. Push all callers of such onto
4047 a worklist.
4048
4049 (b) For each function on the worklist, mark each block that
4050 contains an irrevocable call. Use the AND operator to
4051 propagate that mark up the dominator tree.
4052
4053 (c) If we reach the entry block for a possible transactional
4054 clone, then the transactional clone is irrevocable, and
4055 we should not create the clone after all. Push all
4056 callers onto the worklist.
4057
4058 (d) Place tm_irrevocable calls at the beginning of the relevant
4059 blocks. Special case here is the entry block for the entire
4060 transaction region; there we mark it GTMA_DOES_GO_IRREVOCABLE for
4061 the library to begin the region in serial mode. Decrement
4062 the call count for all callees in the irrevocable region.
4063
4064 (3) Create the transactional clones:
4065
4066 Any tm_callee that still has a non-zero call count is cloned.
4067*/
4068
4069/* This structure is stored in the AUX field of each cgraph_node. */
4070struct tm_ipa_cg_data
4071{
4072 /* The clone of the function that got created. */
4073 struct cgraph_node *clone;
4074
4075 /* The tm regions in the normal function. */
4076 struct tm_region *all_tm_regions;
4077
4078 /* The blocks of the normal/clone functions that contain irrevocable
4079 calls, or blocks that are post-dominated by irrevocable calls. */
4080 bitmap irrevocable_blocks_normal;
4081 bitmap irrevocable_blocks_clone;
4082
4083 /* The blocks of the normal function that are involved in transactions. */
4084 bitmap transaction_blocks_normal;
4085
4086 /* The number of callers to the transactional clone of this function
4087 from normal and transactional clones respectively. */
4088 unsigned tm_callers_normal;
4089 unsigned tm_callers_clone;
4090
4091 /* True if all calls to this function's transactional clone
4092 are irrevocable. Also automatically true if the function
4093 has no transactional clone. */
4094 bool is_irrevocable;
4095
4096 /* Flags indicating the presence of this function in various queues. */
4097 bool in_callee_queue;
4098 bool in_worklist;
4099
4100 /* Flags indicating the kind of scan desired while in the worklist. */
4101 bool want_irr_scan_normal;
4102};
4103
415d1b9a 4104typedef vec<cgraph_node *> cgraph_node_queue;
4c0315d0 4105
4106/* Return the ipa data associated with NODE, allocating zeroed memory
3e426b86 4107 if necessary. TRAVERSE_ALIASES is true if we must traverse aliases
4108 and set *NODE accordingly. */
4c0315d0 4109
4110static struct tm_ipa_cg_data *
3e426b86 4111get_cg_data (struct cgraph_node **node, bool traverse_aliases)
4c0315d0 4112{
3e426b86 4113 struct tm_ipa_cg_data *d;
4114
02774f2d 4115 if (traverse_aliases && (*node)->alias)
415d1b9a 4116 *node = (*node)->get_alias_target ();
3e426b86 4117
02774f2d 4118 d = (struct tm_ipa_cg_data *) (*node)->aux;
4c0315d0 4119
4120 if (d == NULL)
4121 {
4122 d = (struct tm_ipa_cg_data *)
4123 obstack_alloc (&tm_obstack.obstack, sizeof (*d));
02774f2d 4124 (*node)->aux = (void *) d;
4c0315d0 4125 memset (d, 0, sizeof (*d));
4126 }
4127
4128 return d;
4129}
4130
4131/* Add NODE to the end of QUEUE, unless IN_QUEUE_P indicates that
4132 it is already present. */
4133
4134static void
4135maybe_push_queue (struct cgraph_node *node,
4136 cgraph_node_queue *queue_p, bool *in_queue_p)
4137{
4138 if (!*in_queue_p)
4139 {
4140 *in_queue_p = true;
f1f41a6c 4141 queue_p->safe_push (node);
4c0315d0 4142 }
4143}
4144
0cd02a19 4145/* Duplicate the basic blocks in QUEUE for use in the uninstrumented
4146 code path. QUEUE are the basic blocks inside the transaction
4147 represented in REGION.
4148
4149 Later in split_code_paths() we will add the conditional to choose
4150 between the two alternatives. */
4151
4152static void
4153ipa_uninstrument_transaction (struct tm_region *region,
f1f41a6c 4154 vec<basic_block> queue)
0cd02a19 4155{
4156 gimple transaction = region->transaction_stmt;
4157 basic_block transaction_bb = gimple_bb (transaction);
f1f41a6c 4158 int n = queue.length ();
0cd02a19 4159 basic_block *new_bbs = XNEWVEC (basic_block, n);
4160
d99f53b2 4161 copy_bbs (queue.address (), n, new_bbs, NULL, 0, NULL, NULL, transaction_bb,
4162 true);
0cd02a19 4163 edge e = make_edge (transaction_bb, new_bbs[0], EDGE_TM_UNINSTRUMENTED);
4164 add_phi_args_after_copy (new_bbs, n, e);
4165
4166 // Now we will have a GIMPLE_ATOMIC with 3 possible edges out of it.
4167 // a) EDGE_FALLTHRU into the transaction
4168 // b) EDGE_TM_ABORT out of the transaction
4169 // c) EDGE_TM_UNINSTRUMENTED into the uninstrumented blocks.
4170
4171 free (new_bbs);
4172}
4173
4c0315d0 4174/* A subroutine of ipa_tm_scan_calls_transaction and ipa_tm_scan_calls_clone.
4175 Queue all callees within block BB. */
4176
4177static void
4178ipa_tm_scan_calls_block (cgraph_node_queue *callees_p,
4179 basic_block bb, bool for_clone)
4180{
4181 gimple_stmt_iterator gsi;
4182
4183 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4184 {
4185 gimple stmt = gsi_stmt (gsi);
4186 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
4187 {
4188 tree fndecl = gimple_call_fndecl (stmt);
4189 if (fndecl)
4190 {
4191 struct tm_ipa_cg_data *d;
4192 unsigned *pcallers;
4193 struct cgraph_node *node;
4194
4195 if (is_tm_ending_fndecl (fndecl))
4196 continue;
4197 if (find_tm_replacement_function (fndecl))
4198 continue;
4199
415d1b9a 4200 node = cgraph_node::get (fndecl);
4c0315d0 4201 gcc_assert (node != NULL);
3e426b86 4202 d = get_cg_data (&node, true);
4c0315d0 4203
4204 pcallers = (for_clone ? &d->tm_callers_clone
4205 : &d->tm_callers_normal);
4206 *pcallers += 1;
4207
4208 maybe_push_queue (node, callees_p, &d->in_callee_queue);
4209 }
4210 }
4211 }
4212}
4213
4214/* Scan all calls in NODE that are within a transaction region,
4215 and push the resulting nodes into the callee queue. */
4216
4217static void
4218ipa_tm_scan_calls_transaction (struct tm_ipa_cg_data *d,
4219 cgraph_node_queue *callees_p)
4220{
4221 struct tm_region *r;
4222
4223 d->transaction_blocks_normal = BITMAP_ALLOC (&tm_obstack);
4224 d->all_tm_regions = all_tm_regions;
4225
4226 for (r = all_tm_regions; r; r = r->next)
4227 {
f1f41a6c 4228 vec<basic_block> bbs;
4c0315d0 4229 basic_block bb;
4230 unsigned i;
4231
4232 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks, NULL,
4233 d->transaction_blocks_normal, false);
4234
0cd02a19 4235 // Generate the uninstrumented code path for this transaction.
4236 ipa_uninstrument_transaction (r, bbs);
4237
f1f41a6c 4238 FOR_EACH_VEC_ELT (bbs, i, bb)
4c0315d0 4239 ipa_tm_scan_calls_block (callees_p, bb, false);
4240
f1f41a6c 4241 bbs.release ();
4c0315d0 4242 }
0cd02a19 4243
4244 // ??? copy_bbs should maintain cgraph edges for the blocks as it is
4245 // copying them, rather than forcing us to do this externally.
35ee1c66 4246 cgraph_edge::rebuild_edges ();
0cd02a19 4247
4248 // ??? In ipa_uninstrument_transaction we don't try to update dominators
4249 // because copy_bbs doesn't return a VEC like iterate_fix_dominators expects.
4250 // Instead, just release dominators here so update_ssa recomputes them.
4251 free_dominance_info (CDI_DOMINATORS);
4252
4253 // When building the uninstrumented code path, copy_bbs will have invoked
4254 // create_new_def_for starting an "ssa update context". There is only one
4255 // instance of this context, so resolve ssa updates before moving on to
4256 // the next function.
4257 update_ssa (TODO_update_ssa);
4c0315d0 4258}
4259
4260/* Scan all calls in NODE as if this is the transactional clone,
4261 and push the destinations into the callee queue. */
4262
4263static void
4264ipa_tm_scan_calls_clone (struct cgraph_node *node,
4265 cgraph_node_queue *callees_p)
4266{
02774f2d 4267 struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
4c0315d0 4268 basic_block bb;
4269
4270 FOR_EACH_BB_FN (bb, fn)
4271 ipa_tm_scan_calls_block (callees_p, bb, true);
4272}
4273
4274/* The function NODE has been detected to be irrevocable. Push all
4275 of its callers onto WORKLIST for the purpose of re-scanning them. */
4276
4277static void
4278ipa_tm_note_irrevocable (struct cgraph_node *node,
4279 cgraph_node_queue *worklist_p)
4280{
3e426b86 4281 struct tm_ipa_cg_data *d = get_cg_data (&node, true);
4c0315d0 4282 struct cgraph_edge *e;
4283
4284 d->is_irrevocable = true;
4285
4286 for (e = node->callers; e ; e = e->next_caller)
4287 {
4288 basic_block bb;
3e426b86 4289 struct cgraph_node *caller;
4c0315d0 4290
4291 /* Don't examine recursive calls. */
4292 if (e->caller == node)
4293 continue;
4294 /* Even if we think we can go irrevocable, believe the user
4295 above all. */
02774f2d 4296 if (is_tm_safe_or_pure (e->caller->decl))
4c0315d0 4297 continue;
4298
3e426b86 4299 caller = e->caller;
4300 d = get_cg_data (&caller, true);
4c0315d0 4301
4302 /* Check if the callee is in a transactional region. If so,
4303 schedule the function for normal re-scan as well. */
4304 bb = gimple_bb (e->call_stmt);
4305 gcc_assert (bb != NULL);
4306 if (d->transaction_blocks_normal
4307 && bitmap_bit_p (d->transaction_blocks_normal, bb->index))
4308 d->want_irr_scan_normal = true;
4309
3e426b86 4310 maybe_push_queue (caller, worklist_p, &d->in_worklist);
4c0315d0 4311 }
4312}
4313
4314/* A subroutine of ipa_tm_scan_irr_blocks; return true iff any statement
4315 within the block is irrevocable. */
4316
4317static bool
4318ipa_tm_scan_irr_block (basic_block bb)
4319{
4320 gimple_stmt_iterator gsi;
4321 tree fn;
4322
4323 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4324 {
4325 gimple stmt = gsi_stmt (gsi);
4326 switch (gimple_code (stmt))
4327 {
e153bd50 4328 case GIMPLE_ASSIGN:
4329 if (gimple_assign_single_p (stmt))
4330 {
4331 tree lhs = gimple_assign_lhs (stmt);
4332 tree rhs = gimple_assign_rhs1 (stmt);
4333 if (volatile_var_p (lhs) || volatile_var_p (rhs))
4334 return true;
4335 }
4336 break;
4337
4c0315d0 4338 case GIMPLE_CALL:
e153bd50 4339 {
4340 tree lhs = gimple_call_lhs (stmt);
4341 if (lhs && volatile_var_p (lhs))
4342 return true;
4c0315d0 4343
e153bd50 4344 if (is_tm_pure_call (stmt))
4345 break;
4c0315d0 4346
e153bd50 4347 fn = gimple_call_fn (stmt);
4c0315d0 4348
e153bd50 4349 /* Functions with the attribute are by definition irrevocable. */
4350 if (is_tm_irrevocable (fn))
4351 return true;
4c0315d0 4352
e153bd50 4353 /* For direct function calls, go ahead and check for replacement
4354 functions, or transitive irrevocable functions. For indirect
4355 functions, we'll ask the runtime. */
4356 if (TREE_CODE (fn) == ADDR_EXPR)
4357 {
4358 struct tm_ipa_cg_data *d;
4359 struct cgraph_node *node;
4c0315d0 4360
e153bd50 4361 fn = TREE_OPERAND (fn, 0);
4362 if (is_tm_ending_fndecl (fn))
4363 break;
4364 if (find_tm_replacement_function (fn))
4365 break;
40879ac6 4366
415d1b9a 4367 node = cgraph_node::get (fn);
e153bd50 4368 d = get_cg_data (&node, true);
4369
4370 /* Return true if irrevocable, but above all, believe
4371 the user. */
4372 if (d->is_irrevocable
4373 && !is_tm_safe_or_pure (fn))
4374 return true;
4375 }
4376 break;
4377 }
4c0315d0 4378
4379 case GIMPLE_ASM:
4380 /* ??? The Approved Method of indicating that an inline
4381 assembly statement is not relevant to the transaction
4382 is to wrap it in a __tm_waiver block. This is not
4383 yet implemented, so we can't check for it. */
43156aa3 4384 if (is_tm_safe (current_function_decl))
4385 {
4386 tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
4387 SET_EXPR_LOCATION (t, gimple_location (stmt));
43156aa3 4388 error ("%Kasm not allowed in %<transaction_safe%> function", t);
4389 }
4c0315d0 4390 return true;
4391
4392 default:
4393 break;
4394 }
4395 }
4396
4397 return false;
4398}
4399
4400/* For each of the blocks seeded witin PQUEUE, walk the CFG looking
4401 for new irrevocable blocks, marking them in NEW_IRR. Don't bother
4402 scanning past OLD_IRR or EXIT_BLOCKS. */
4403
4404static bool
f1f41a6c 4405ipa_tm_scan_irr_blocks (vec<basic_block> *pqueue, bitmap new_irr,
4c0315d0 4406 bitmap old_irr, bitmap exit_blocks)
4407{
4408 bool any_new_irr = false;
4409 edge e;
4410 edge_iterator ei;
4411 bitmap visited_blocks = BITMAP_ALLOC (NULL);
4412
4413 do
4414 {
f1f41a6c 4415 basic_block bb = pqueue->pop ();
4c0315d0 4416
4417 /* Don't re-scan blocks we know already are irrevocable. */
4418 if (old_irr && bitmap_bit_p (old_irr, bb->index))
4419 continue;
4420
4421 if (ipa_tm_scan_irr_block (bb))
4422 {
4423 bitmap_set_bit (new_irr, bb->index);
4424 any_new_irr = true;
4425 }
4426 else if (exit_blocks == NULL || !bitmap_bit_p (exit_blocks, bb->index))
4427 {
4428 FOR_EACH_EDGE (e, ei, bb->succs)
4429 if (!bitmap_bit_p (visited_blocks, e->dest->index))
4430 {
4431 bitmap_set_bit (visited_blocks, e->dest->index);
f1f41a6c 4432 pqueue->safe_push (e->dest);
4c0315d0 4433 }
4434 }
4435 }
f1f41a6c 4436 while (!pqueue->is_empty ());
4c0315d0 4437
4438 BITMAP_FREE (visited_blocks);
4439
4440 return any_new_irr;
4441}
4442
4443/* Propagate the irrevocable property both up and down the dominator tree.
4444 BB is the current block being scanned; EXIT_BLOCKS are the edges of the
4445 TM regions; OLD_IRR are the results of a previous scan of the dominator
4446 tree which has been fully propagated; NEW_IRR is the set of new blocks
4447 which are gaining the irrevocable property during the current scan. */
4448
4449static void
4450ipa_tm_propagate_irr (basic_block entry_block, bitmap new_irr,
4451 bitmap old_irr, bitmap exit_blocks)
4452{
f1f41a6c 4453 vec<basic_block> bbs;
4c0315d0 4454 bitmap all_region_blocks;
4455
4456 /* If this block is in the old set, no need to rescan. */
4457 if (old_irr && bitmap_bit_p (old_irr, entry_block->index))
4458 return;
4459
4460 all_region_blocks = BITMAP_ALLOC (&tm_obstack);
4461 bbs = get_tm_region_blocks (entry_block, exit_blocks, NULL,
4462 all_region_blocks, false);
4463 do
4464 {
f1f41a6c 4465 basic_block bb = bbs.pop ();
4c0315d0 4466 bool this_irr = bitmap_bit_p (new_irr, bb->index);
4467 bool all_son_irr = false;
4468 edge_iterator ei;
4469 edge e;
4470
4471 /* Propagate up. If my children are, I am too, but we must have
4472 at least one child that is. */
4473 if (!this_irr)
4474 {
4475 FOR_EACH_EDGE (e, ei, bb->succs)
4476 {
4477 if (!bitmap_bit_p (new_irr, e->dest->index))
4478 {
4479 all_son_irr = false;
4480 break;
4481 }
4482 else
4483 all_son_irr = true;
4484 }
4485 if (all_son_irr)
4486 {
4487 /* Add block to new_irr if it hasn't already been processed. */
4488 if (!old_irr || !bitmap_bit_p (old_irr, bb->index))
4489 {
4490 bitmap_set_bit (new_irr, bb->index);
4491 this_irr = true;
4492 }
4493 }
4494 }
4495
4496 /* Propagate down to everyone we immediately dominate. */
4497 if (this_irr)
4498 {
4499 basic_block son;
4500 for (son = first_dom_son (CDI_DOMINATORS, bb);
4501 son;
4502 son = next_dom_son (CDI_DOMINATORS, son))
4503 {
4504 /* Make sure block is actually in a TM region, and it
4505 isn't already in old_irr. */
4506 if ((!old_irr || !bitmap_bit_p (old_irr, son->index))
4507 && bitmap_bit_p (all_region_blocks, son->index))
4508 bitmap_set_bit (new_irr, son->index);
4509 }
4510 }
4511 }
f1f41a6c 4512 while (!bbs.is_empty ());
4c0315d0 4513
4514 BITMAP_FREE (all_region_blocks);
f1f41a6c 4515 bbs.release ();
4c0315d0 4516}
4517
4518static void
4519ipa_tm_decrement_clone_counts (basic_block bb, bool for_clone)
4520{
4521 gimple_stmt_iterator gsi;
4522
4523 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4524 {
4525 gimple stmt = gsi_stmt (gsi);
4526 if (is_gimple_call (stmt) && !is_tm_pure_call (stmt))
4527 {
4528 tree fndecl = gimple_call_fndecl (stmt);
4529 if (fndecl)
4530 {
4531 struct tm_ipa_cg_data *d;
4532 unsigned *pcallers;
3e426b86 4533 struct cgraph_node *tnode;
4c0315d0 4534
4535 if (is_tm_ending_fndecl (fndecl))
4536 continue;
4537 if (find_tm_replacement_function (fndecl))
4538 continue;
4539
415d1b9a 4540 tnode = cgraph_node::get (fndecl);
3e426b86 4541 d = get_cg_data (&tnode, true);
4542
4c0315d0 4543 pcallers = (for_clone ? &d->tm_callers_clone
4544 : &d->tm_callers_normal);
4545
4546 gcc_assert (*pcallers > 0);
4547 *pcallers -= 1;
4548 }
4549 }
4550 }
4551}
4552
4553/* (Re-)Scan the transaction blocks in NODE for calls to irrevocable functions,
4554 as well as other irrevocable actions such as inline assembly. Mark all
4555 such blocks as irrevocable and decrement the number of calls to
4556 transactional clones. Return true if, for the transactional clone, the
4557 entire function is irrevocable. */
4558
4559static bool
4560ipa_tm_scan_irr_function (struct cgraph_node *node, bool for_clone)
4561{
4562 struct tm_ipa_cg_data *d;
4563 bitmap new_irr, old_irr;
4c0315d0 4564 bool ret = false;
4565
40879ac6 4566 /* Builtin operators (operator new, and such). */
02774f2d 4567 if (DECL_STRUCT_FUNCTION (node->decl) == NULL
4568 || DECL_STRUCT_FUNCTION (node->decl)->cfg == NULL)
40879ac6 4569 return false;
4570
02774f2d 4571 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4c0315d0 4572 calculate_dominance_info (CDI_DOMINATORS);
4573
3e426b86 4574 d = get_cg_data (&node, true);
4997014d 4575 auto_vec<basic_block, 10> queue;
4c0315d0 4576 new_irr = BITMAP_ALLOC (&tm_obstack);
4577
4578 /* Scan each tm region, propagating irrevocable status through the tree. */
4579 if (for_clone)
4580 {
4581 old_irr = d->irrevocable_blocks_clone;
34154e27 4582 queue.quick_push (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
4c0315d0 4583 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr, NULL))
4584 {
34154e27 4585 ipa_tm_propagate_irr (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
4586 new_irr,
4c0315d0 4587 old_irr, NULL);
34154e27 4588 ret = bitmap_bit_p (new_irr,
4589 single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))->index);
4c0315d0 4590 }
4591 }
4592 else
4593 {
4594 struct tm_region *region;
4595
4596 old_irr = d->irrevocable_blocks_normal;
4597 for (region = d->all_tm_regions; region; region = region->next)
4598 {
f1f41a6c 4599 queue.quick_push (region->entry_block);
4c0315d0 4600 if (ipa_tm_scan_irr_blocks (&queue, new_irr, old_irr,
4601 region->exit_blocks))
4602 ipa_tm_propagate_irr (region->entry_block, new_irr, old_irr,
4603 region->exit_blocks);
4604 }
4605 }
4606
4607 /* If we found any new irrevocable blocks, reduce the call count for
4608 transactional clones within the irrevocable blocks. Save the new
4609 set of irrevocable blocks for next time. */
4610 if (!bitmap_empty_p (new_irr))
4611 {
4612 bitmap_iterator bmi;
4613 unsigned i;
4614
4615 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
f5a6b05f 4616 ipa_tm_decrement_clone_counts (BASIC_BLOCK_FOR_FN (cfun, i),
4617 for_clone);
4c0315d0 4618
4619 if (old_irr)
4620 {
4621 bitmap_ior_into (old_irr, new_irr);
4622 BITMAP_FREE (new_irr);
4623 }
4624 else if (for_clone)
4625 d->irrevocable_blocks_clone = new_irr;
4626 else
4627 d->irrevocable_blocks_normal = new_irr;
4628
4629 if (dump_file && new_irr)
4630 {
4631 const char *dname;
4632 bitmap_iterator bmi;
4633 unsigned i;
4634
4635 dname = lang_hooks.decl_printable_name (current_function_decl, 2);
4636 EXECUTE_IF_SET_IN_BITMAP (new_irr, 0, i, bmi)
4637 fprintf (dump_file, "%s: bb %d goes irrevocable\n", dname, i);
4638 }
4639 }
4640 else
4641 BITMAP_FREE (new_irr);
4642
4c0315d0 4643 pop_cfun ();
4c0315d0 4644
4645 return ret;
4646}
4647
4648/* Return true if, for the transactional clone of NODE, any call
4649 may enter irrevocable mode. */
4650
4651static bool
4652ipa_tm_mayenterirr_function (struct cgraph_node *node)
4653{
3e426b86 4654 struct tm_ipa_cg_data *d;
4655 tree decl;
4656 unsigned flags;
4657
4658 d = get_cg_data (&node, true);
02774f2d 4659 decl = node->decl;
3e426b86 4660 flags = flags_from_decl_or_type (decl);
4c0315d0 4661
4662 /* Handle some TM builtins. Ordinarily these aren't actually generated
4663 at this point, but handling these functions when written in by the
4664 user makes it easier to build unit tests. */
4665 if (flags & ECF_TM_BUILTIN)
4666 return false;
4667
4668 /* Filter out all functions that are marked. */
4669 if (flags & ECF_TM_PURE)
4670 return false;
4671 if (is_tm_safe (decl))
4672 return false;
4673 if (is_tm_irrevocable (decl))
4674 return true;
4675 if (is_tm_callable (decl))
4676 return true;
4677 if (find_tm_replacement_function (decl))
4678 return true;
4679
4680 /* If we aren't seeing the final version of the function we don't
4681 know what it will contain at runtime. */
415d1b9a 4682 if (node->get_availability () < AVAIL_AVAILABLE)
4c0315d0 4683 return true;
4684
4685 /* If the function must go irrevocable, then of course true. */
4686 if (d->is_irrevocable)
4687 return true;
4688
4689 /* If there are any blocks marked irrevocable, then the function
4690 as a whole may enter irrevocable. */
4691 if (d->irrevocable_blocks_clone)
4692 return true;
4693
4694 /* We may have previously marked this function as tm_may_enter_irr;
4695 see pass_diagnose_tm_blocks. */
4696 if (node->local.tm_may_enter_irr)
4697 return true;
4698
4699 /* Recurse on the main body for aliases. In general, this will
4700 result in one of the bits above being set so that we will not
4701 have to recurse next time. */
02774f2d 4702 if (node->alias)
415d1b9a 4703 return ipa_tm_mayenterirr_function (cgraph_node::get (node->thunk.alias));
4c0315d0 4704
4705 /* What remains is unmarked local functions without items that force
4706 the function to go irrevocable. */
4707 return false;
4708}
4709
4710/* Diagnose calls from transaction_safe functions to unmarked
4711 functions that are determined to not be safe. */
4712
4713static void
4714ipa_tm_diagnose_tm_safe (struct cgraph_node *node)
4715{
4716 struct cgraph_edge *e;
4717
4718 for (e = node->callees; e ; e = e->next_callee)
02774f2d 4719 if (!is_tm_callable (e->callee->decl)
4c0315d0 4720 && e->callee->local.tm_may_enter_irr)
4721 error_at (gimple_location (e->call_stmt),
4722 "unsafe function call %qD within "
02774f2d 4723 "%<transaction_safe%> function", e->callee->decl);
4c0315d0 4724}
4725
4726/* Diagnose call from atomic transactions to unmarked functions
4727 that are determined to not be safe. */
4728
4729static void
4730ipa_tm_diagnose_transaction (struct cgraph_node *node,
4731 struct tm_region *all_tm_regions)
4732{
4733 struct tm_region *r;
4734
4735 for (r = all_tm_regions; r ; r = r->next)
1a91d914 4736 if (gimple_transaction_subcode (r->get_transaction_stmt ())
4737 & GTMA_IS_RELAXED)
4c0315d0 4738 {
4739 /* Atomic transactions can be nested inside relaxed. */
4740 if (r->inner)
4741 ipa_tm_diagnose_transaction (node, r->inner);
4742 }
4743 else
4744 {
f1f41a6c 4745 vec<basic_block> bbs;
4c0315d0 4746 gimple_stmt_iterator gsi;
4747 basic_block bb;
4748 size_t i;
4749
4750 bbs = get_tm_region_blocks (r->entry_block, r->exit_blocks,
4751 r->irr_blocks, NULL, false);
4752
f1f41a6c 4753 for (i = 0; bbs.iterate (i, &bb); ++i)
4c0315d0 4754 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4755 {
4756 gimple stmt = gsi_stmt (gsi);
4757 tree fndecl;
4758
4759 if (gimple_code (stmt) == GIMPLE_ASM)
4760 {
4761 error_at (gimple_location (stmt),
4762 "asm not allowed in atomic transaction");
4763 continue;
4764 }
4765
4766 if (!is_gimple_call (stmt))
4767 continue;
4768 fndecl = gimple_call_fndecl (stmt);
4769
4770 /* Indirect function calls have been diagnosed already. */
4771 if (!fndecl)
4772 continue;
4773
4774 /* Stop at the end of the transaction. */
4775 if (is_tm_ending_fndecl (fndecl))
4776 {
4777 if (bitmap_bit_p (r->exit_blocks, bb->index))
4778 break;
4779 continue;
4780 }
4781
4782 /* Marked functions have been diagnosed already. */
4783 if (is_tm_pure_call (stmt))
4784 continue;
4785 if (is_tm_callable (fndecl))
4786 continue;
4787
35ee1c66 4788 if (cgraph_node::local_info (fndecl)->tm_may_enter_irr)
4c0315d0 4789 error_at (gimple_location (stmt),
4790 "unsafe function call %qD within "
4791 "atomic transaction", fndecl);
4792 }
4793
f1f41a6c 4794 bbs.release ();
4c0315d0 4795 }
4796}
4797
4798/* Return a transactional mangled name for the DECL_ASSEMBLER_NAME in
4799 OLD_DECL. The returned value is a freshly malloced pointer that
4800 should be freed by the caller. */
4801
4802static tree
4803tm_mangle (tree old_asm_id)
4804{
4805 const char *old_asm_name;
4806 char *tm_name;
4807 void *alloc = NULL;
4808 struct demangle_component *dc;
4809 tree new_asm_id;
4810
4811 /* Determine if the symbol is already a valid C++ mangled name. Do this
4812 even for C, which might be interfacing with C++ code via appropriately
4813 ugly identifiers. */
4814 /* ??? We could probably do just as well checking for "_Z" and be done. */
4815 old_asm_name = IDENTIFIER_POINTER (old_asm_id);
4816 dc = cplus_demangle_v3_components (old_asm_name, DMGL_NO_OPTS, &alloc);
4817
4818 if (dc == NULL)
4819 {
4820 char length[8];
4821
4822 do_unencoded:
4823 sprintf (length, "%u", IDENTIFIER_LENGTH (old_asm_id));
4824 tm_name = concat ("_ZGTt", length, old_asm_name, NULL);
4825 }
4826 else
4827 {
4828 old_asm_name += 2; /* Skip _Z */
4829
4830 switch (dc->type)
4831 {
4832 case DEMANGLE_COMPONENT_TRANSACTION_CLONE:
4833 case DEMANGLE_COMPONENT_NONTRANSACTION_CLONE:
4834 /* Don't play silly games, you! */
4835 goto do_unencoded;
4836
4837 case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
4838 /* I'd really like to know if we can ever be passed one of
4839 these from the C++ front end. The Logical Thing would
4840 seem that hidden-alias should be outer-most, so that we
4841 get hidden-alias of a transaction-clone and not vice-versa. */
4842 old_asm_name += 2;
4843 break;
4844
4845 default:
4846 break;
4847 }
4848
4849 tm_name = concat ("_ZGTt", old_asm_name, NULL);
4850 }
4851 free (alloc);
4852
4853 new_asm_id = get_identifier (tm_name);
4854 free (tm_name);
4855
4856 return new_asm_id;
4857}
4858
4859static inline void
8efa224a 4860ipa_tm_mark_force_output_node (struct cgraph_node *node)
4c0315d0 4861{
415d1b9a 4862 node->mark_force_output ();
02774f2d 4863 node->analyzed = true;
4c0315d0 4864}
4865
6a1c0403 4866static inline void
4867ipa_tm_mark_forced_by_abi_node (struct cgraph_node *node)
4868{
02774f2d 4869 node->forced_by_abi = true;
4870 node->analyzed = true;
6a1c0403 4871}
4872
4c0315d0 4873/* Callback data for ipa_tm_create_version_alias. */
4874struct create_version_alias_info
4875{
4876 struct cgraph_node *old_node;
4877 tree new_decl;
4878};
4879
caf29404 4880/* A subroutine of ipa_tm_create_version, called via
4c0315d0 4881 cgraph_for_node_and_aliases. Create new tm clones for each of
4882 the existing aliases. */
4883static bool
4884ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
4885{
4886 struct create_version_alias_info *info
4887 = (struct create_version_alias_info *)data;
4888 tree old_decl, new_decl, tm_name;
4889 struct cgraph_node *new_node;
4890
02774f2d 4891 if (!node->cpp_implicit_alias)
4c0315d0 4892 return false;
4893
02774f2d 4894 old_decl = node->decl;
4c0315d0 4895 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4896 new_decl = build_decl (DECL_SOURCE_LOCATION (old_decl),
4897 TREE_CODE (old_decl), tm_name,
4898 TREE_TYPE (old_decl));
4899
4900 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4901 SET_DECL_RTL (new_decl, NULL);
4902
4903 /* Based loosely on C++'s make_alias_for(). */
4904 TREE_PUBLIC (new_decl) = TREE_PUBLIC (old_decl);
f7c22b34 4905 DECL_CONTEXT (new_decl) = DECL_CONTEXT (old_decl);
4906 DECL_LANG_SPECIFIC (new_decl) = DECL_LANG_SPECIFIC (old_decl);
4c0315d0 4907 TREE_READONLY (new_decl) = TREE_READONLY (old_decl);
4908 DECL_EXTERNAL (new_decl) = 0;
4909 DECL_ARTIFICIAL (new_decl) = 1;
4910 TREE_ADDRESSABLE (new_decl) = 1;
4911 TREE_USED (new_decl) = 1;
4912 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4913
4914 /* Perform the same remapping to the comdat group. */
260d0713 4915 if (DECL_ONE_ONLY (new_decl))
97221fd7 4916 varpool_node::get (new_decl)->set_comdat_group
4917 (tm_mangle (decl_comdat_group_id (old_decl)));
4c0315d0 4918
415d1b9a 4919 new_node = cgraph_node::create_same_body_alias (new_decl, info->new_decl);
4c0315d0 4920 new_node->tm_clone = true;
02774f2d 4921 new_node->externally_visible = info->old_node->externally_visible;
6b722052 4922 new_node->no_reorder = info->old_node->no_reorder;
3e426b86 4923 /* ?? Do not traverse aliases here. */
4924 get_cg_data (&node, false)->clone = new_node;
4c0315d0 4925
4926 record_tm_clone_pair (old_decl, new_decl);
4927
02774f2d 4928 if (info->old_node->force_output
51ce5652 4929 || info->old_node->ref_list.first_referring ())
8efa224a 4930 ipa_tm_mark_force_output_node (new_node);
02774f2d 4931 if (info->old_node->forced_by_abi)
6a1c0403 4932 ipa_tm_mark_forced_by_abi_node (new_node);
4c0315d0 4933 return false;
4934}
4935
4936/* Create a copy of the function (possibly declaration only) of OLD_NODE,
4937 appropriate for the transactional clone. */
4938
4939static void
4940ipa_tm_create_version (struct cgraph_node *old_node)
4941{
4942 tree new_decl, old_decl, tm_name;
4943 struct cgraph_node *new_node;
4944
02774f2d 4945 old_decl = old_node->decl;
4c0315d0 4946 new_decl = copy_node (old_decl);
4947
4948 /* DECL_ASSEMBLER_NAME needs to be set before we call
4949 cgraph_copy_node_for_versioning below, because cgraph_node will
4950 fill the assembler_name_hash. */
4951 tm_name = tm_mangle (DECL_ASSEMBLER_NAME (old_decl));
4952 SET_DECL_ASSEMBLER_NAME (new_decl, tm_name);
4953 SET_DECL_RTL (new_decl, NULL);
4954 TREE_SYMBOL_REFERENCED (tm_name) = 1;
4955
4956 /* Perform the same remapping to the comdat group. */
260d0713 4957 if (DECL_ONE_ONLY (new_decl))
97221fd7 4958 varpool_node::get (new_decl)->set_comdat_group
4959 (tm_mangle (DECL_COMDAT_GROUP (old_decl)));
4c0315d0 4960
2cf4c3b3 4961 gcc_assert (!old_node->ipa_transforms_to_apply.exists ());
415d1b9a 4962 new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
281dea26 4963 new_node->local.local = false;
02774f2d 4964 new_node->externally_visible = old_node->externally_visible;
4c0315d0 4965 new_node->lowered = true;
4966 new_node->tm_clone = 1;
033ab5d3 4967 if (!old_node->implicit_section)
4968 new_node->set_section (old_node->get_section ());
3e426b86 4969 get_cg_data (&old_node, true)->clone = new_node;
4c0315d0 4970
415d1b9a 4971 if (old_node->get_availability () >= AVAIL_INTERPOSABLE)
4c0315d0 4972 {
4973 /* Remap extern inline to static inline. */
4974 /* ??? Is it worth trying to use make_decl_one_only? */
4975 if (DECL_DECLARED_INLINE_P (new_decl) && DECL_EXTERNAL (new_decl))
4976 {
4977 DECL_EXTERNAL (new_decl) = 0;
4978 TREE_PUBLIC (new_decl) = 0;
7a571443 4979 DECL_WEAK (new_decl) = 0;
4c0315d0 4980 }
4981
f1f41a6c 4982 tree_function_versioning (old_decl, new_decl,
4983 NULL, false, NULL,
4984 false, NULL, NULL);
4c0315d0 4985 }
4986
4987 record_tm_clone_pair (old_decl, new_decl);
4988
35ee1c66 4989 symtab->call_cgraph_insertion_hooks (new_node);
02774f2d 4990 if (old_node->force_output
51ce5652 4991 || old_node->ref_list.first_referring ())
8efa224a 4992 ipa_tm_mark_force_output_node (new_node);
02774f2d 4993 if (old_node->forced_by_abi)
6a1c0403 4994 ipa_tm_mark_forced_by_abi_node (new_node);
4c0315d0 4995
4996 /* Do the same thing, but for any aliases of the original node. */
4997 {
4998 struct create_version_alias_info data;
4999 data.old_node = old_node;
5000 data.new_decl = new_decl;
415d1b9a 5001 old_node->call_for_symbol_thunks_and_aliases (ipa_tm_create_version_alias,
5002 &data, true);
4c0315d0 5003 }
5004}
5005
5006/* Construct a call to TM_IRREVOCABLE and insert it at the beginning of BB. */
5007
5008static void
5009ipa_tm_insert_irr_call (struct cgraph_node *node, struct tm_region *region,
5010 basic_block bb)
5011{
5012 gimple_stmt_iterator gsi;
1a91d914 5013 gcall *g;
4c0315d0 5014
5015 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
5016
5017 g = gimple_build_call (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE),
5018 1, build_int_cst (NULL_TREE, MODE_SERIALIRREVOCABLE));
5019
5020 split_block_after_labels (bb);
5021 gsi = gsi_after_labels (bb);
5022 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
5023
415d1b9a 5024 node->create_edge (cgraph_node::get_create
5025 (builtin_decl_explicit (BUILT_IN_TM_IRREVOCABLE)),
5026 g, 0,
5027 compute_call_stmt_bb_frequency (node->decl,
5028 gimple_bb (g)));
4c0315d0 5029}
5030
5031/* Construct a call to TM_GETTMCLONE and insert it before GSI. */
5032
5033static bool
5034ipa_tm_insert_gettmclone_call (struct cgraph_node *node,
5035 struct tm_region *region,
1a91d914 5036 gimple_stmt_iterator *gsi, gcall *stmt)
4c0315d0 5037{
5038 tree gettm_fn, ret, old_fn, callfn;
1a91d914 5039 gcall *g;
5040 gassign *g2;
4c0315d0 5041 bool safe;
5042
5043 old_fn = gimple_call_fn (stmt);
5044
5045 if (TREE_CODE (old_fn) == ADDR_EXPR)
5046 {
5047 tree fndecl = TREE_OPERAND (old_fn, 0);
5048 tree clone = get_tm_clone_pair (fndecl);
5049
5050 /* By transforming the call into a TM_GETTMCLONE, we are
5051 technically taking the address of the original function and
5052 its clone. Explain this so inlining will know this function
5053 is needed. */
415d1b9a 5054 cgraph_node::get (fndecl)->mark_address_taken () ;
4c0315d0 5055 if (clone)
415d1b9a 5056 cgraph_node::get (clone)->mark_address_taken ();
4c0315d0 5057 }
5058
5059 safe = is_tm_safe (TREE_TYPE (old_fn));
5060 gettm_fn = builtin_decl_explicit (safe ? BUILT_IN_TM_GETTMCLONE_SAFE
5061 : BUILT_IN_TM_GETTMCLONE_IRR);
f9e245b2 5062 ret = create_tmp_var (ptr_type_node);
4c0315d0 5063
5064 if (!safe)
5065 transaction_subcode_ior (region, GTMA_MAY_ENTER_IRREVOCABLE);
5066
5067 /* Discard OBJ_TYPE_REF, since we weren't able to fold it. */
5068 if (TREE_CODE (old_fn) == OBJ_TYPE_REF)
5069 old_fn = OBJ_TYPE_REF_EXPR (old_fn);
5070
5071 g = gimple_build_call (gettm_fn, 1, old_fn);
5072 ret = make_ssa_name (ret, g);
5073 gimple_call_set_lhs (g, ret);
5074
5075 gsi_insert_before (gsi, g, GSI_SAME_STMT);
5076
415d1b9a 5077 node->create_edge (cgraph_node::get_create (gettm_fn), g, 0,
5078 compute_call_stmt_bb_frequency (node->decl,
5079 gimple_bb (g)));
4c0315d0 5080
5081 /* Cast return value from tm_gettmclone* into appropriate function
5082 pointer. */
f9e245b2 5083 callfn = create_tmp_var (TREE_TYPE (old_fn));
4c0315d0 5084 g2 = gimple_build_assign (callfn,
5085 fold_build1 (NOP_EXPR, TREE_TYPE (callfn), ret));
5086 callfn = make_ssa_name (callfn, g2);
5087 gimple_assign_set_lhs (g2, callfn);
5088 gsi_insert_before (gsi, g2, GSI_SAME_STMT);
5089
5090 /* ??? This is a hack to preserve the NOTHROW bit on the call,
5091 which we would have derived from the decl. Failure to save
5092 this bit means we might have to split the basic block. */
5093 if (gimple_call_nothrow_p (stmt))
5094 gimple_call_set_nothrow (stmt, true);
5095
5096 gimple_call_set_fn (stmt, callfn);
5097
5098 /* Discarding OBJ_TYPE_REF above may produce incompatible LHS and RHS
5099 for a call statement. Fix it. */
5100 {
5101 tree lhs = gimple_call_lhs (stmt);
5102 tree rettype = TREE_TYPE (gimple_call_fntype (stmt));
5103 if (lhs
5104 && !useless_type_conversion_p (TREE_TYPE (lhs), rettype))
5105 {
5106 tree temp;
5107
f9e245b2 5108 temp = create_tmp_reg (rettype);
4c0315d0 5109 gimple_call_set_lhs (stmt, temp);
5110
5111 g2 = gimple_build_assign (lhs,
5112 fold_build1 (VIEW_CONVERT_EXPR,
5113 TREE_TYPE (lhs), temp));
5114 gsi_insert_after (gsi, g2, GSI_SAME_STMT);
5115 }
5116 }
5117
5118 update_stmt (stmt);
d8b5abdb 5119 cgraph_edge *e = cgraph_node::get (current_function_decl)->get_edge (stmt);
5120 if (e && e->indirect_info)
5121 e->indirect_info->polymorphic = false;
4c0315d0 5122
5123 return true;
5124}
5125
5126/* Helper function for ipa_tm_transform_calls*. Given a call
5127 statement in GSI which resides inside transaction REGION, redirect
5128 the call to either its wrapper function, or its clone. */
5129
5130static void
5131ipa_tm_transform_calls_redirect (struct cgraph_node *node,
5132 struct tm_region *region,
5133 gimple_stmt_iterator *gsi,
5134 bool *need_ssa_rename_p)
5135{
1a91d914 5136 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
4c0315d0 5137 struct cgraph_node *new_node;
415d1b9a 5138 struct cgraph_edge *e = node->get_edge (stmt);
4c0315d0 5139 tree fndecl = gimple_call_fndecl (stmt);
5140
5141 /* For indirect calls, pass the address through the runtime. */
5142 if (fndecl == NULL)
5143 {
5144 *need_ssa_rename_p |=
5145 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
5146 return;
5147 }
5148
5149 /* Handle some TM builtins. Ordinarily these aren't actually generated
5150 at this point, but handling these functions when written in by the
5151 user makes it easier to build unit tests. */
5152 if (flags_from_decl_or_type (fndecl) & ECF_TM_BUILTIN)
5153 return;
5154
5155 /* Fixup recursive calls inside clones. */
5156 /* ??? Why did cgraph_copy_node_for_versioning update the call edges
5157 for recursion but not update the call statements themselves? */
5158 if (e->caller == e->callee && decl_is_tm_clone (current_function_decl))
5159 {
5160 gimple_call_set_fndecl (stmt, current_function_decl);
5161 return;
5162 }
5163
5164 /* If there is a replacement, use it. */
5165 fndecl = find_tm_replacement_function (fndecl);
5166 if (fndecl)
5167 {
415d1b9a 5168 new_node = cgraph_node::get_create (fndecl);
4c0315d0 5169
5170 /* ??? Mark all transaction_wrap functions tm_may_enter_irr.
5171
5172 We can't do this earlier in record_tm_replacement because
5173 cgraph_remove_unreachable_nodes is called before we inject
5174 references to the node. Further, we can't do this in some
5175 nice central place in ipa_tm_execute because we don't have
5176 the exact list of wrapper functions that would be used.
5177 Marking more wrappers than necessary results in the creation
5178 of unnecessary cgraph_nodes, which can cause some of the
5179 other IPA passes to crash.
5180
5181 We do need to mark these nodes so that we get the proper
5182 result in expand_call_tm. */
5183 /* ??? This seems broken. How is it that we're marking the
5184 CALLEE as may_enter_irr? Surely we should be marking the
5185 CALLER. Also note that find_tm_replacement_function also
5186 contains mappings into the TM runtime, e.g. memcpy. These
5187 we know won't go irrevocable. */
5188 new_node->local.tm_may_enter_irr = 1;
5189 }
5190 else
5191 {
3e426b86 5192 struct tm_ipa_cg_data *d;
5193 struct cgraph_node *tnode = e->callee;
5194
5195 d = get_cg_data (&tnode, true);
4c0315d0 5196 new_node = d->clone;
5197
5198 /* As we've already skipped pure calls and appropriate builtins,
5199 and we've already marked irrevocable blocks, if we can't come
5200 up with a static replacement, then ask the runtime. */
5201 if (new_node == NULL)
5202 {
5203 *need_ssa_rename_p |=
5204 ipa_tm_insert_gettmclone_call (node, region, gsi, stmt);
4c0315d0 5205 return;
5206 }
5207
02774f2d 5208 fndecl = new_node->decl;
4c0315d0 5209 }
5210
35ee1c66 5211 e->redirect_callee (new_node);
4c0315d0 5212 gimple_call_set_fndecl (stmt, fndecl);
5213}
5214
5215/* Helper function for ipa_tm_transform_calls. For a given BB,
5216 install calls to tm_irrevocable when IRR_BLOCKS are reached,
5217 redirect other calls to the generated transactional clone. */
5218
5219static bool
5220ipa_tm_transform_calls_1 (struct cgraph_node *node, struct tm_region *region,
5221 basic_block bb, bitmap irr_blocks)
5222{
5223 gimple_stmt_iterator gsi;
5224 bool need_ssa_rename = false;
5225
5226 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
5227 {
5228 ipa_tm_insert_irr_call (node, region, bb);
5229 return true;
5230 }
5231
5232 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
5233 {
5234 gimple stmt = gsi_stmt (gsi);
5235
5236 if (!is_gimple_call (stmt))
5237 continue;
5238 if (is_tm_pure_call (stmt))
5239 continue;
5240
5241 /* Redirect edges to the appropriate replacement or clone. */
5242 ipa_tm_transform_calls_redirect (node, region, &gsi, &need_ssa_rename);
5243 }
5244
5245 return need_ssa_rename;
5246}
5247
5248/* Walk the CFG for REGION, beginning at BB. Install calls to
5249 tm_irrevocable when IRR_BLOCKS are reached, redirect other calls to
5250 the generated transactional clone. */
5251
5252static bool
5253ipa_tm_transform_calls (struct cgraph_node *node, struct tm_region *region,
5254 basic_block bb, bitmap irr_blocks)
5255{
5256 bool need_ssa_rename = false;
5257 edge e;
5258 edge_iterator ei;
c2078b80 5259 auto_vec<basic_block> queue;
4c0315d0 5260 bitmap visited_blocks = BITMAP_ALLOC (NULL);
5261
f1f41a6c 5262 queue.safe_push (bb);
4c0315d0 5263 do
5264 {
f1f41a6c 5265 bb = queue.pop ();
4c0315d0 5266
5267 need_ssa_rename |=
5268 ipa_tm_transform_calls_1 (node, region, bb, irr_blocks);
5269
5270 if (irr_blocks && bitmap_bit_p (irr_blocks, bb->index))
5271 continue;
5272
5273 if (region && bitmap_bit_p (region->exit_blocks, bb->index))
5274 continue;
5275
5276 FOR_EACH_EDGE (e, ei, bb->succs)
5277 if (!bitmap_bit_p (visited_blocks, e->dest->index))
5278 {
5279 bitmap_set_bit (visited_blocks, e->dest->index);
f1f41a6c 5280 queue.safe_push (e->dest);
4c0315d0 5281 }
5282 }
f1f41a6c 5283 while (!queue.is_empty ());
4c0315d0 5284
4c0315d0 5285 BITMAP_FREE (visited_blocks);
5286
5287 return need_ssa_rename;
5288}
5289
5290/* Transform the calls within the TM regions within NODE. */
5291
5292static void
5293ipa_tm_transform_transaction (struct cgraph_node *node)
5294{
3e426b86 5295 struct tm_ipa_cg_data *d;
4c0315d0 5296 struct tm_region *region;
5297 bool need_ssa_rename = false;
5298
3e426b86 5299 d = get_cg_data (&node, true);
5300
02774f2d 5301 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4c0315d0 5302 calculate_dominance_info (CDI_DOMINATORS);
5303
5304 for (region = d->all_tm_regions; region; region = region->next)
5305 {
5306 /* If we're sure to go irrevocable, don't transform anything. */
5307 if (d->irrevocable_blocks_normal
5308 && bitmap_bit_p (d->irrevocable_blocks_normal,
5309 region->entry_block->index))
5310 {
1910089e 5311 transaction_subcode_ior (region, GTMA_DOES_GO_IRREVOCABLE
5312 | GTMA_MAY_ENTER_IRREVOCABLE
5313 | GTMA_HAS_NO_INSTRUMENTATION);
4c0315d0 5314 continue;
5315 }
5316
5317 need_ssa_rename |=
5318 ipa_tm_transform_calls (node, region, region->entry_block,
5319 d->irrevocable_blocks_normal);
5320 }
5321
5322 if (need_ssa_rename)
5323 update_ssa (TODO_update_ssa_only_virtuals);
5324
5325 pop_cfun ();
4c0315d0 5326}
5327
5328/* Transform the calls within the transactional clone of NODE. */
5329
5330static void
5331ipa_tm_transform_clone (struct cgraph_node *node)
5332{
3e426b86 5333 struct tm_ipa_cg_data *d;
4c0315d0 5334 bool need_ssa_rename;
5335
3e426b86 5336 d = get_cg_data (&node, true);
5337
4c0315d0 5338 /* If this function makes no calls and has no irrevocable blocks,
5339 then there's nothing to do. */
5340 /* ??? Remove non-aborting top-level transactions. */
2670559d 5341 if (!node->callees && !node->indirect_calls && !d->irrevocable_blocks_clone)
4c0315d0 5342 return;
5343
02774f2d 5344 push_cfun (DECL_STRUCT_FUNCTION (d->clone->decl));
4c0315d0 5345 calculate_dominance_info (CDI_DOMINATORS);
5346
5347 need_ssa_rename =
34154e27 5348 ipa_tm_transform_calls (d->clone, NULL,
5349 single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)),
4c0315d0 5350 d->irrevocable_blocks_clone);
5351
5352 if (need_ssa_rename)
5353 update_ssa (TODO_update_ssa_only_virtuals);
5354
5355 pop_cfun ();
4c0315d0 5356}
5357
5358/* Main entry point for the transactional memory IPA pass. */
5359
5360static unsigned int
5361ipa_tm_execute (void)
5362{
9af5ce0c 5363 cgraph_node_queue tm_callees = cgraph_node_queue ();
4c0315d0 5364 /* List of functions that will go irrevocable. */
9af5ce0c 5365 cgraph_node_queue irr_worklist = cgraph_node_queue ();
4c0315d0 5366
5367 struct cgraph_node *node;
5368 struct tm_ipa_cg_data *d;
5369 enum availability a;
5370 unsigned int i;
5371
5372#ifdef ENABLE_CHECKING
415d1b9a 5373 cgraph_node::verify_cgraph_nodes ();
4c0315d0 5374#endif
5375
5376 bitmap_obstack_initialize (&tm_obstack);
0cd02a19 5377 initialize_original_copy_tables ();
4c0315d0 5378
5379 /* For all local functions marked tm_callable, queue them. */
7c455d87 5380 FOR_EACH_DEFINED_FUNCTION (node)
02774f2d 5381 if (is_tm_callable (node->decl)
415d1b9a 5382 && node->get_availability () >= AVAIL_INTERPOSABLE)
4c0315d0 5383 {
3e426b86 5384 d = get_cg_data (&node, true);
4c0315d0 5385 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
5386 }
5387
5388 /* For all local reachable functions... */
7c455d87 5389 FOR_EACH_DEFINED_FUNCTION (node)
da751785 5390 if (node->lowered
415d1b9a 5391 && node->get_availability () >= AVAIL_INTERPOSABLE)
4c0315d0 5392 {
5393 /* ... marked tm_pure, record that fact for the runtime by
5394 indicating that the pure function is its own tm_callable.
5395 No need to do this if the function's address can't be taken. */
02774f2d 5396 if (is_tm_pure (node->decl))
4c0315d0 5397 {
5398 if (!node->local.local)
02774f2d 5399 record_tm_clone_pair (node->decl, node->decl);
4c0315d0 5400 continue;
5401 }
5402
02774f2d 5403 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4c0315d0 5404 calculate_dominance_info (CDI_DOMINATORS);
5405
5406 tm_region_init (NULL);
5407 if (all_tm_regions)
5408 {
3e426b86 5409 d = get_cg_data (&node, true);
4c0315d0 5410
0cd02a19 5411 /* Scan for calls that are in each transaction, and
5412 generate the uninstrumented code path. */
4c0315d0 5413 ipa_tm_scan_calls_transaction (d, &tm_callees);
5414
40879ac6 5415 /* Put it in the worklist so we can scan the function
5416 later (ipa_tm_scan_irr_function) and mark the
5417 irrevocable blocks. */
5418 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
5419 d->want_irr_scan_normal = true;
4c0315d0 5420 }
5421
5422 pop_cfun ();
4c0315d0 5423 }
5424
5425 /* For every local function on the callee list, scan as if we will be
5426 creating a transactional clone, queueing all new functions we find
5427 along the way. */
f1f41a6c 5428 for (i = 0; i < tm_callees.length (); ++i)
4c0315d0 5429 {
f1f41a6c 5430 node = tm_callees[i];
415d1b9a 5431 a = node->get_availability ();
3e426b86 5432 d = get_cg_data (&node, true);
4c0315d0 5433
40879ac6 5434 /* Put it in the worklist so we can scan the function later
5435 (ipa_tm_scan_irr_function) and mark the irrevocable
5436 blocks. */
5437 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
4c0315d0 5438
5439 /* Some callees cannot be arbitrarily cloned. These will always be
5440 irrevocable. Mark these now, so that we need not scan them. */
02774f2d 5441 if (is_tm_irrevocable (node->decl))
4c0315d0 5442 ipa_tm_note_irrevocable (node, &irr_worklist);
5443 else if (a <= AVAIL_NOT_AVAILABLE
02774f2d 5444 && !is_tm_safe_or_pure (node->decl))
4c0315d0 5445 ipa_tm_note_irrevocable (node, &irr_worklist);
415d1b9a 5446 else if (a >= AVAIL_INTERPOSABLE)
4c0315d0 5447 {
02774f2d 5448 if (!tree_versionable_function_p (node->decl))
4c0315d0 5449 ipa_tm_note_irrevocable (node, &irr_worklist);
5450 else if (!d->is_irrevocable)
5451 {
5452 /* If this is an alias, make sure its base is queued as well.
5453 we need not scan the callees now, as the base will do. */
02774f2d 5454 if (node->alias)
4c0315d0 5455 {
415d1b9a 5456 node = cgraph_node::get (node->thunk.alias);
3e426b86 5457 d = get_cg_data (&node, true);
4c0315d0 5458 maybe_push_queue (node, &tm_callees, &d->in_callee_queue);
5459 continue;
5460 }
5461
5462 /* Add all nodes called by this function into
5463 tm_callees as well. */
5464 ipa_tm_scan_calls_clone (node, &tm_callees);
5465 }
5466 }
5467 }
5468
5469 /* Iterate scans until no more work to be done. Prefer not to use
f1f41a6c 5470 vec::pop because the worklist tends to follow a breadth-first
4c0315d0 5471 search of the callgraph, which should allow convergance with a
5472 minimum number of scans. But we also don't want the worklist
5473 array to grow without bound, so we shift the array up periodically. */
f1f41a6c 5474 for (i = 0; i < irr_worklist.length (); ++i)
4c0315d0 5475 {
f1f41a6c 5476 if (i > 256 && i == irr_worklist.length () / 8)
4c0315d0 5477 {
f1f41a6c 5478 irr_worklist.block_remove (0, i);
4c0315d0 5479 i = 0;
5480 }
5481
f1f41a6c 5482 node = irr_worklist[i];
3e426b86 5483 d = get_cg_data (&node, true);
4c0315d0 5484 d->in_worklist = false;
5485
5486 if (d->want_irr_scan_normal)
5487 {
5488 d->want_irr_scan_normal = false;
5489 ipa_tm_scan_irr_function (node, false);
5490 }
5491 if (d->in_callee_queue && ipa_tm_scan_irr_function (node, true))
5492 ipa_tm_note_irrevocable (node, &irr_worklist);
5493 }
5494
5495 /* For every function on the callee list, collect the tm_may_enter_irr
5496 bit on the node. */
f1f41a6c 5497 irr_worklist.truncate (0);
5498 for (i = 0; i < tm_callees.length (); ++i)
4c0315d0 5499 {
f1f41a6c 5500 node = tm_callees[i];
4c0315d0 5501 if (ipa_tm_mayenterirr_function (node))
5502 {
3e426b86 5503 d = get_cg_data (&node, true);
4c0315d0 5504 gcc_assert (d->in_worklist == false);
5505 maybe_push_queue (node, &irr_worklist, &d->in_worklist);
5506 }
5507 }
5508
5509 /* Propagate the tm_may_enter_irr bit to callers until stable. */
f1f41a6c 5510 for (i = 0; i < irr_worklist.length (); ++i)
4c0315d0 5511 {
5512 struct cgraph_node *caller;
5513 struct cgraph_edge *e;
e4a2b488 5514 struct ipa_ref *ref;
4c0315d0 5515
f1f41a6c 5516 if (i > 256 && i == irr_worklist.length () / 8)
4c0315d0 5517 {
f1f41a6c 5518 irr_worklist.block_remove (0, i);
4c0315d0 5519 i = 0;
5520 }
5521
f1f41a6c 5522 node = irr_worklist[i];
3e426b86 5523 d = get_cg_data (&node, true);
4c0315d0 5524 d->in_worklist = false;
5525 node->local.tm_may_enter_irr = true;
5526
5527 /* Propagate back to normal callers. */
5528 for (e = node->callers; e ; e = e->next_caller)
5529 {
5530 caller = e->caller;
02774f2d 5531 if (!is_tm_safe_or_pure (caller->decl)
4c0315d0 5532 && !caller->local.tm_may_enter_irr)
5533 {
3e426b86 5534 d = get_cg_data (&caller, true);
4c0315d0 5535 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
5536 }
5537 }
5538
5539 /* Propagate back to referring aliases as well. */
e4a2b488 5540 FOR_EACH_ALIAS (node, ref)
4c0315d0 5541 {
415d1b9a 5542 caller = dyn_cast<cgraph_node *> (ref->referring);
e4a2b488 5543 if (!caller->local.tm_may_enter_irr)
4c0315d0 5544 {
3e426b86 5545 /* ?? Do not traverse aliases here. */
5546 d = get_cg_data (&caller, false);
4c0315d0 5547 maybe_push_queue (caller, &irr_worklist, &d->in_worklist);
5548 }
5549 }
5550 }
5551
5552 /* Now validate all tm_safe functions, and all atomic regions in
5553 other functions. */
7c455d87 5554 FOR_EACH_DEFINED_FUNCTION (node)
da751785 5555 if (node->lowered
415d1b9a 5556 && node->get_availability () >= AVAIL_INTERPOSABLE)
4c0315d0 5557 {
3e426b86 5558 d = get_cg_data (&node, true);
02774f2d 5559 if (is_tm_safe (node->decl))
4c0315d0 5560 ipa_tm_diagnose_tm_safe (node);
5561 else if (d->all_tm_regions)
5562 ipa_tm_diagnose_transaction (node, d->all_tm_regions);
5563 }
5564
5565 /* Create clones. Do those that are not irrevocable and have a
5566 positive call count. Do those publicly visible functions that
5567 the user directed us to clone. */
f1f41a6c 5568 for (i = 0; i < tm_callees.length (); ++i)
4c0315d0 5569 {
5570 bool doit = false;
5571
f1f41a6c 5572 node = tm_callees[i];
02774f2d 5573 if (node->cpp_implicit_alias)
4c0315d0 5574 continue;
5575
415d1b9a 5576 a = node->get_availability ();
3e426b86 5577 d = get_cg_data (&node, true);
4c0315d0 5578
5579 if (a <= AVAIL_NOT_AVAILABLE)
02774f2d 5580 doit = is_tm_callable (node->decl);
5581 else if (a <= AVAIL_AVAILABLE && is_tm_callable (node->decl))
4c0315d0 5582 doit = true;
5583 else if (!d->is_irrevocable
5584 && d->tm_callers_normal + d->tm_callers_clone > 0)
5585 doit = true;
5586
5587 if (doit)
5588 ipa_tm_create_version (node);
5589 }
5590
5591 /* Redirect calls to the new clones, and insert irrevocable marks. */
f1f41a6c 5592 for (i = 0; i < tm_callees.length (); ++i)
4c0315d0 5593 {
f1f41a6c 5594 node = tm_callees[i];
02774f2d 5595 if (node->analyzed)
4c0315d0 5596 {
3e426b86 5597 d = get_cg_data (&node, true);
4c0315d0 5598 if (d->clone)
5599 ipa_tm_transform_clone (node);
5600 }
5601 }
7c455d87 5602 FOR_EACH_DEFINED_FUNCTION (node)
da751785 5603 if (node->lowered
415d1b9a 5604 && node->get_availability () >= AVAIL_INTERPOSABLE)
4c0315d0 5605 {
3e426b86 5606 d = get_cg_data (&node, true);
4c0315d0 5607 if (d->all_tm_regions)
5608 ipa_tm_transform_transaction (node);
5609 }
5610
5611 /* Free and clear all data structures. */
f1f41a6c 5612 tm_callees.release ();
5613 irr_worklist.release ();
4c0315d0 5614 bitmap_obstack_release (&tm_obstack);
0cd02a19 5615 free_original_copy_tables ();
4c0315d0 5616
7c455d87 5617 FOR_EACH_FUNCTION (node)
02774f2d 5618 node->aux = NULL;
4c0315d0 5619
5620#ifdef ENABLE_CHECKING
415d1b9a 5621 cgraph_node::verify_cgraph_nodes ();
4c0315d0 5622#endif
5623
5624 return 0;
5625}
5626
cbe8bda8 5627namespace {
5628
5629const pass_data pass_data_ipa_tm =
5630{
5631 SIMPLE_IPA_PASS, /* type */
5632 "tmipa", /* name */
5633 OPTGROUP_NONE, /* optinfo_flags */
cbe8bda8 5634 TV_TRANS_MEM, /* tv_id */
5635 ( PROP_ssa | PROP_cfg ), /* properties_required */
5636 0, /* properties_provided */
5637 0, /* properties_destroyed */
5638 0, /* todo_flags_start */
5639 0, /* todo_flags_finish */
4c0315d0 5640};
5641
cbe8bda8 5642class pass_ipa_tm : public simple_ipa_opt_pass
5643{
5644public:
9af5ce0c 5645 pass_ipa_tm (gcc::context *ctxt)
5646 : simple_ipa_opt_pass (pass_data_ipa_tm, ctxt)
cbe8bda8 5647 {}
5648
5649 /* opt_pass methods: */
31315c24 5650 virtual bool gate (function *) { return flag_tm; }
65b0537f 5651 virtual unsigned int execute (function *) { return ipa_tm_execute (); }
cbe8bda8 5652
5653}; // class pass_ipa_tm
5654
5655} // anon namespace
5656
5657simple_ipa_opt_pass *
5658make_pass_ipa_tm (gcc::context *ctxt)
5659{
5660 return new pass_ipa_tm (ctxt);
5661}
5662
4c0315d0 5663#include "gt-trans-mem.h"