for gcc/ChangeLog from Alexandre Oliva * tree-ssa.c (find_released_ssa_name): Handle NULL wi. (insert_debug_temp_for_var_def): Handle degenerate PHI nodes. Fix handling of released SSA names. (insert_debug_temps_for_defs): Handle PHI nodes. Index: gcc/tree-ssa.c =================================================================== --- gcc/tree-ssa.c.orig 2009-11-08 05:09:36.000000000 -0200 +++ gcc/tree-ssa.c 2009-11-08 05:34:12.000000000 -0200 @@ -279,7 +279,7 @@ find_released_ssa_name (tree *tp, int *w { struct walk_stmt_info *wi = (struct walk_stmt_info *) data_; - if (wi->is_lhs) + if (wi && wi->is_lhs) return NULL_TREE; if (TREE_CODE (*tp) == SSA_NAME) @@ -346,11 +346,30 @@ insert_debug_temp_for_var_def (gimple_st /* If we didn't get an insertion point, and the stmt has already been removed, we won't be able to insert the debug bind stmt, so we'll have to drop debug information. */ - if (is_gimple_assign (def_stmt)) + if (gimple_code (def_stmt) == GIMPLE_PHI || is_gimple_assign (def_stmt)) { bool no_value = false; - if (!dom_info_available_p (CDI_DOMINATORS)) + if (gimple_code (def_stmt) == GIMPLE_PHI) + { + struct walk_stmt_info wi; + size_t i; + + memset (&wi, 0, sizeof (wi)); + + for (i = 0; i < gimple_phi_num_args (def_stmt); i++) + { + tree *argp = gimple_phi_arg_def_ptr (def_stmt, i); + + if (!*argp + || walk_tree (argp, find_released_ssa_name, NULL, NULL)) + { + no_value = true; + break; + } + } + } + else if (!dom_info_available_p (CDI_DOMINATORS)) { struct walk_stmt_info wi; @@ -383,13 +402,22 @@ insert_debug_temp_for_var_def (gimple_st dead SSA NAMEs. SSA verification shall catch any errors. */ if ((!gsi && !gimple_bb (def_stmt)) - || !walk_gimple_op (def_stmt, find_released_ssa_name, - &wi)) + || walk_gimple_op (def_stmt, find_released_ssa_name, &wi)) no_value = true; } if (!no_value) - value = gimple_assign_rhs_to_tree (def_stmt); + { + if (gimple_code (def_stmt) == GIMPLE_PHI) + /* ??? We could handle at least some non-generate PHI + nodes by inserting debug temps on every edge. It's + not clear how much this would improve debug info. */ + value = degenerate_phi_result (def_stmt); + else if (is_gimple_assign (def_stmt)) + value = gimple_assign_rhs_to_tree (def_stmt); + else + gcc_unreachable (); + } } if (value) @@ -409,6 +437,7 @@ insert_debug_temp_for_var_def (gimple_st at the expense of duplication of expressions. */ if (CONSTANT_CLASS_P (value) + || gimple_code (def_stmt) == GIMPLE_PHI || (usecount == 1 && (!gimple_assign_single_p (def_stmt) || is_gimple_min_invariant (value))) @@ -479,6 +508,13 @@ insert_debug_temps_for_defs (gimple_stmt stmt = gsi_stmt (*gsi); + if (gimple_code (stmt) == GIMPLE_PHI) + { + tree var = gimple_phi_result (stmt); + insert_debug_temp_for_var_def (gsi, var); + return; + } + FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_DEF) { tree var = DEF_FROM_PTR (def_p);