void gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base) { tree tmp1; gimple stmt1, stmt2, stmt3; gimple stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); tree ref_ptr = tree_coverage_counter_addr (tag, base); ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, true, NULL_TREE, true, GSI_SAME_STMT); /* Insert code: __gcov_indirect_call_counters = get_relevant_counter_ptr (); __gcov_indirect_call_callee = (void *) indirect call argument; */ tmp1 = create_tmp_reg (ptr_void, "PROF"); stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr); find_referenced_vars_in (stmt1); stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value)); gimple_assign_set_lhs (stmt2, make_ssa_name (tmp1, stmt2)); find_referenced_vars_in (stmt2); stmt3 = gimple_build_assign (ic_void_ptr_var, gimple_assign_lhs (stmt2)); add_referenced_var (ic_void_ptr_var); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); }
void input_bb (struct lto_input_block *ib, enum LTO_tags tag, struct data_in *data_in, struct function *fn, int count_materialization_scale) { unsigned int index; basic_block bb; gimple_stmt_iterator bsi; /* This routine assumes that CFUN is set to FN, as it needs to call basic GIMPLE routines that use CFUN. */ gcc_assert (cfun == fn); index = streamer_read_uhwi (ib); bb = BASIC_BLOCK_FOR_FUNCTION (fn, index); bb->count = (streamer_read_hwi (ib) * count_materialization_scale + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE; bb->loop_depth = streamer_read_hwi (ib); bb->frequency = streamer_read_hwi (ib); bb->flags = streamer_read_hwi (ib); /* LTO_bb1 has statements. LTO_bb0 does not. */ if (tag == LTO_bb0) return; bsi = gsi_start_bb (bb); tag = streamer_read_record_start (ib); while (tag) { gimple stmt = input_gimple_stmt (ib, data_in, fn, tag); if (!is_gimple_debug (stmt)) find_referenced_vars_in (stmt); gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); /* After the statement, expect a 0 delimiter or the EH region that the previous statement belongs to. */ tag = streamer_read_record_start (ib); lto_tag_check_set (tag, 2, LTO_eh_region, LTO_null); if (tag == LTO_eh_region) { HOST_WIDE_INT region = streamer_read_hwi (ib); gcc_assert (region == (int) region); add_stmt_to_eh_lp (stmt, region); } tag = streamer_read_record_start (ib); } tag = streamer_read_record_start (ib); while (tag) { gimple phi = input_phi (ib, bb, data_in, fn); find_referenced_vars_in (phi); tag = streamer_read_record_start (ib); } }
void gimple_gen_edge_profiler (int edgeno, edge e) { tree ref, one; gimple stmt1, stmt2, stmt3; /* We share one temporary variable declaration per function. This gets re-set in tree_profiling. */ if (gcov_type_tmp_var == NULL_TREE) gcov_type_tmp_var = create_tmp_reg (gcov_type_node, "PROF_edge_counter"); if (PROFILE_GEN_EDGE_ATOMIC) ref = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno); else ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno); one = build_int_cst (gcov_type_node, 1); if (PROFILE_GEN_EDGE_ATOMIC) { /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */ stmt3 = gimple_build_call (builtin_decl_explicit ( GCOV_TYPE_ATOMIC_FETCH_ADD), 3, ref, one, build_int_cst (integer_type_node, MEMMODEL_RELAXED)); find_referenced_vars_in (stmt3); } else { stmt1 = gimple_build_assign (gcov_type_tmp_var, ref); gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1)); find_referenced_vars_in (stmt1); stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var, gimple_assign_lhs (stmt1), one); gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2)); stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2)); gsi_insert_on_edge (e, stmt1); gsi_insert_on_edge (e, stmt2); } gsi_insert_on_edge (e, stmt3); }
void gimple_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base) { gimple stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); tree ref_ptr = tree_coverage_counter_addr (tag, base); gimple call; tree val; ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr, true, NULL_TREE, true, GSI_SAME_STMT); val = prepare_instrumented_value (&gsi, value); call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val); find_referenced_vars_in (call); gsi_insert_before (&gsi, call, GSI_NEW_STMT); }
void gimple_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base) { gimple stmt = value->hvalue.stmt; gimple_stmt_iterator gsi = gsi_for_stmt (stmt); tree ref = tree_coverage_counter_ref (tag, base), ref_ptr; gimple call; tree val; tree start = build_int_cst_type (integer_type_node, value->hdata.intvl.int_start); tree steps = build_int_cst_type (unsigned_type_node, value->hdata.intvl.steps); ref_ptr = force_gimple_operand_gsi (&gsi, build_addr (ref, current_function_decl), true, NULL_TREE, true, GSI_SAME_STMT); val = prepare_instrumented_value (&gsi, value); call = gimple_build_call (tree_interval_profiler_fn, 4, ref_ptr, val, start, steps); find_referenced_vars_in (call); gsi_insert_before (&gsi, call, GSI_NEW_STMT); }
void gimple_gen_edge_profiler (int edgeno, edge e) { tree ref, one; gimple stmt1, stmt2, stmt3; /* We share one temporary variable declaration per function. This gets re-set in tree_profiling. */ if (gcov_type_tmp_var == NULL_TREE) gcov_type_tmp_var = create_tmp_reg (gcov_type_node, "PROF_edge_counter"); ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno); one = build_int_cst (gcov_type_node, 1); stmt1 = gimple_build_assign (gcov_type_tmp_var, ref); gimple_assign_set_lhs (stmt1, make_ssa_name (gcov_type_tmp_var, stmt1)); find_referenced_vars_in (stmt1); stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var, gimple_assign_lhs (stmt1), one); gimple_assign_set_lhs (stmt2, make_ssa_name (gcov_type_tmp_var, stmt2)); stmt3 = gimple_build_assign (unshare_expr (ref), gimple_assign_lhs (stmt2)); gsi_insert_on_edge (e, stmt1); gsi_insert_on_edge (e, stmt2); gsi_insert_on_edge (e, stmt3); }