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

Reply via email to