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