static void adjust_simduid_builtins (hash_table<simduid_to_vf> *htab) { basic_block bb; FOR_EACH_BB_FN (bb, cfun) { gimple_stmt_iterator i; for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) { unsigned int vf = 1; enum internal_fn ifn; gimple stmt = gsi_stmt (i); tree t; if (!is_gimple_call (stmt) || !gimple_call_internal_p (stmt)) continue; ifn = gimple_call_internal_fn (stmt); switch (ifn) { case IFN_GOMP_SIMD_LANE: case IFN_GOMP_SIMD_VF: case IFN_GOMP_SIMD_LAST_LANE: break; default: continue; } tree arg = gimple_call_arg (stmt, 0); gcc_assert (arg != NULL_TREE); gcc_assert (TREE_CODE (arg) == SSA_NAME); simduid_to_vf *p = NULL, data; data.simduid = DECL_UID (SSA_NAME_VAR (arg)); if (htab) { p = htab->find (&data); if (p) vf = p->vf; } switch (ifn) { case IFN_GOMP_SIMD_VF: t = build_int_cst (unsigned_type_node, vf); break; case IFN_GOMP_SIMD_LANE: t = build_int_cst (unsigned_type_node, 0); break; case IFN_GOMP_SIMD_LAST_LANE: t = gimple_call_arg (stmt, 1); break; default: gcc_unreachable (); } update_call_from_tree (&i, t); } }
void propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val) { gimple stmt = gsi_stmt (*gsi); if (is_gimple_assign (stmt)) { tree expr = NULL_TREE; if (gimple_assign_single_p (stmt)) expr = gimple_assign_rhs1 (stmt); propagate_tree_value (&expr, val); gimple_assign_set_rhs_from_tree (gsi, expr); } else if (gimple_code (stmt) == GIMPLE_COND) { tree lhs = NULL_TREE; tree rhs = build_zero_cst (TREE_TYPE (val)); propagate_tree_value (&lhs, val); gimple_cond_set_code (stmt, NE_EXPR); gimple_cond_set_lhs (stmt, lhs); gimple_cond_set_rhs (stmt, rhs); } else if (is_gimple_call (stmt) && gimple_call_lhs (stmt) != NULL_TREE) { tree expr = NULL_TREE; bool res; propagate_tree_value (&expr, val); res = update_call_from_tree (gsi, expr); gcc_assert (res); } else if (gimple_code (stmt) == GIMPLE_SWITCH) propagate_tree_value (gimple_switch_index_ptr (stmt), val); else gcc_unreachable (); }
static void adjust_simduid_builtins (hash_table<simduid_to_vf> *htab) { basic_block bb; FOR_EACH_BB_FN (bb, cfun) { gimple_stmt_iterator i; for (i = gsi_start_bb (bb); !gsi_end_p (i); ) { unsigned int vf = 1; enum internal_fn ifn; gimple *stmt = gsi_stmt (i); tree t; if (!is_gimple_call (stmt) || !gimple_call_internal_p (stmt)) { gsi_next (&i); continue; } ifn = gimple_call_internal_fn (stmt); switch (ifn) { case IFN_GOMP_SIMD_LANE: case IFN_GOMP_SIMD_VF: case IFN_GOMP_SIMD_LAST_LANE: break; case IFN_GOMP_SIMD_ORDERED_START: case IFN_GOMP_SIMD_ORDERED_END: if (integer_onep (gimple_call_arg (stmt, 0))) { enum built_in_function bcode = (ifn == IFN_GOMP_SIMD_ORDERED_START ? BUILT_IN_GOMP_ORDERED_START : BUILT_IN_GOMP_ORDERED_END); gimple *g = gimple_build_call (builtin_decl_explicit (bcode), 0); tree vdef = gimple_vdef (stmt); gimple_set_vdef (g, vdef); SSA_NAME_DEF_STMT (vdef) = g; gimple_set_vuse (g, gimple_vuse (stmt)); gsi_replace (&i, g, true); continue; } gsi_remove (&i, true); unlink_stmt_vdef (stmt); continue; default: gsi_next (&i); continue; } tree arg = gimple_call_arg (stmt, 0); gcc_assert (arg != NULL_TREE); gcc_assert (TREE_CODE (arg) == SSA_NAME); simduid_to_vf *p = NULL, data; data.simduid = DECL_UID (SSA_NAME_VAR (arg)); /* Need to nullify loop safelen field since it's value is not valid after transformation. */ if (bb->loop_father && bb->loop_father->safelen > 0) bb->loop_father->safelen = 0; if (htab) { p = htab->find (&data); if (p) vf = p->vf; } switch (ifn) { case IFN_GOMP_SIMD_VF: t = build_int_cst (unsigned_type_node, vf); break; case IFN_GOMP_SIMD_LANE: t = build_int_cst (unsigned_type_node, 0); break; case IFN_GOMP_SIMD_LAST_LANE: t = gimple_call_arg (stmt, 1); break; default: gcc_unreachable (); } update_call_from_tree (&i, t); gsi_next (&i); } }