gimple * walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct walk_stmt_info *wi) { gimple_stmt_iterator gsi; for (gsi = gsi_start (*pseq); !gsi_end_p (gsi); ) { tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi); if (ret) { /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist to hold it. */ gcc_assert (wi); wi->callback_result = ret; return wi->removed_stmt ? NULL : gsi_stmt (gsi); } if (!wi->removed_stmt) gsi_next (&gsi); } if (wi) wi->callback_result = NULL_TREE; return NULL; }
/* Redirect references. */ FOR_EACH_VEC_ELT (references_to_redirect, i, ref) { if (ref->use == IPA_REF_ADDR) { struct walk_stmt_info wi; memset (&wi, 0, sizeof (wi)); wi.info = (void *)node->function_version (); if (dyn_cast<varpool_node *> (ref->referring)) { hash_set<tree> visited_nodes; walk_tree (&DECL_INITIAL (ref->referring->decl), replace_function_decl, &wi, &visited_nodes); } else { gimple_stmt_iterator it = gsi_for_stmt (ref->stmt); if (ref->referring->decl != resolver_decl) walk_gimple_stmt (&it, NULL, replace_function_decl, &wi); } symtab_node *source = ref->referring; ref->remove_reference (); source->create_reference (inode, IPA_REF_ADDR); } else if (ref->use == IPA_REF_ALIAS) { symtab_node *source = ref->referring; ref->remove_reference (); source->create_reference (inode, IPA_REF_ALIAS); source->add_to_same_comdat_group (inode); } else gcc_unreachable (); }