On Wed, Oct 31, 2012 at 11:34:10AM -0700, Wei Mi wrote:
+static tree
+get_init_decl (void)
+{
+ tree typ;
+ static tree decl;
+
+ if (decl != NULL)
+ return decl;
+ typ = build_function_type_list (void_type_node, NULL_TREE);
+ decl = build_func_decl (typ, "__tsan_init");
+ return decl;
+}
The above can crash the compiler btw, as that static tree decl
(in many other functions) is not GTY(()) marked (must be file scope for
that), thus ggc_collect might free it. Also, please use type
instead of typ for variable names.
> + /* Instrumentation for assignment of a function result
> + must be inserted after the call. Instrumentation for
> + reads of function arguments must be inserted before the call.
> + That's because the call can contain synchronization. */
> + if (is_gimple_call (stmt) && is_write)
> + gsi_insert_seq_after (&gsi, gs, GSI_NEW_STMT);
Inserting stmts after a call may or may not work. E.g. if the call
can throw, it must be the last stmt in a basic block, so then the
stmts need to be inserted on a successor edge. Similarly noreturn
call must be last (but in that case it shouldn't have lhs).
> + gcode = gimple_code (stmt);
> + if (gcode == GIMPLE_CALL)
is_gimple_call (stmt)
> + {
> + if (gimple_call_fndecl (stmt) != get_init_decl ())
> + func_calls++;
> + }
> + else if (gcode == GIMPLE_ASSIGN)
is_gimple_assign (stmt)
> + {
> + /* Handle assignment lhs as store. */
> + lhs = gimple_assign_lhs (stmt);
> + instrument_expr (gsi, lhs, 1);
To find what a store or load is, you can just use the new
gimple_store_p (stmt) and gimple_assign_load_p (stmt)
predicates, or at least just do gimple_assign_single_p (stmt)
to guard instrument_expr calls on both lhs and rhs1.
No need to scan all operands, only single rhs assignments
can be loads. And as David said, use true/false instead of 1/0.
Jakub