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