#include "tree-iterator.h"
#include "tree-ssa-propagate.h"
#include "tree-ssa-loop-ivopts.h"
+#include "tree-eh.h"
#include "tsan.h"
#include "asan.h"
#include "builtins.h"
return;
gimple_call_set_fndecl (stmt, decl);
update_stmt (stmt);
+ maybe_clean_eh_stmt (stmt);
if (tsan_atomic_table[i].action == fetch_op)
{
args[1] = gimple_call_arg (stmt, 1);
? MEMMODEL_SEQ_CST
: MEMMODEL_ACQUIRE);
update_gimple_call (gsi, decl, num + 1, args[0], args[1], args[2]);
+ maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
stmt = gsi_stmt (*gsi);
if (tsan_atomic_table[i].action == fetch_op_seq_cst)
{
return;
update_gimple_call (gsi, decl, 5, args[0], args[1], args[2],
args[4], args[5]);
+ maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
return;
case bool_cas:
case val_cas:
MEMMODEL_SEQ_CST),
build_int_cst (NULL_TREE,
MEMMODEL_SEQ_CST));
+ maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
if (tsan_atomic_table[i].action == val_cas && lhs)
{
tree cond;
build_int_cst (t, 0),
build_int_cst (NULL_TREE,
MEMMODEL_RELEASE));
+ maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
return;
case bool_clear:
case bool_test_and_set:
{
update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0),
build_int_cst (t, 0), last_arg);
+ maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
return;
}
t = build_int_cst (t, targetm.atomic_test_and_set_trueval);
update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0),
t, last_arg);
+ maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
stmt = gsi_stmt (*gsi);
lhs = gimple_call_lhs (stmt);
if (lhs == NULL_TREE)
Return true if func entry/exit should be instrumented. */
static bool
-instrument_memory_accesses (void)
+instrument_memory_accesses (bool *cfg_changed)
{
basic_block bb;
gimple_stmt_iterator gsi;
auto_vec<gimple *> tsan_func_exits;
FOR_EACH_BB_FN (bb, cfun)
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- if (gimple_call_internal_p (stmt, IFN_TSAN_FUNC_EXIT))
- {
- if (fentry_exit_instrument)
- replace_func_exit (stmt);
- else
- tsan_func_exits.safe_push (stmt);
- func_exit_seen = true;
- }
- else
- fentry_exit_instrument |= instrument_gimple (&gsi);
- }
+ {
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ if (gimple_call_internal_p (stmt, IFN_TSAN_FUNC_EXIT))
+ {
+ if (fentry_exit_instrument)
+ replace_func_exit (stmt);
+ else
+ tsan_func_exits.safe_push (stmt);
+ func_exit_seen = true;
+ }
+ else
+ fentry_exit_instrument |= instrument_gimple (&gsi);
+ }
+ if (gimple_purge_dead_eh_edges (bb))
+ *cfg_changed = true;
+ }
unsigned int i;
gimple *stmt;
FOR_EACH_VEC_ELT (tsan_func_exits, i, stmt)
tsan_pass (void)
{
initialize_sanitizer_builtins ();
- if (instrument_memory_accesses ())
+ bool cfg_changed = false;
+ if (instrument_memory_accesses (&cfg_changed))
instrument_func_entry ();
- return 0;
+ return cfg_changed ? TODO_cleanup_cfg : 0;
}
/* Inserts __tsan_init () into the list of CTORs. */