From bc590dfb1f79493f63eafd5604d4c5d1ef2fb974 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Mon, 5 Dec 2011 11:05:24 +0000 Subject: [PATCH] tree-ssa.c (verify_ssa): Verify SSA names in the loop over all SSA names. 2011-12-05 Richard Guenther * tree-ssa.c (verify_ssa): Verify SSA names in the loop over all SSA names. Remove SSA operand checking, call verify_ssa_operands. * tree-ssa-operands.h (verify_ssa_operands): Declare. * tree-ssa-operands.c (verify_ssa_operands): New function. From-SVN: r182007 --- gcc/ChangeLog | 8 +++ gcc/tree-ssa-operands.c | 115 +++++++++++++++++++++++++++++++++++++++- gcc/tree-ssa-operands.h | 1 + gcc/tree-ssa.c | 89 +++---------------------------- 4 files changed, 130 insertions(+), 83 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8522c9986d6..5f36a0cac8d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-12-05 Richard Guenther + + * tree-ssa.c (verify_ssa): Verify SSA names in the loop + over all SSA names. Remove SSA operand checking, call + verify_ssa_operands. + * tree-ssa-operands.h (verify_ssa_operands): Declare. + * tree-ssa-operands.c (verify_ssa_operands): New function. + 2011-12-05 Ramana Radhakrishnan * config/arm/arm.c (vfp3_const_double_for_fract_bits): Define. diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 9012bfe26fe..3de34be7948 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -33,7 +33,8 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "timevar.h" #include "langhooks.h" -#include "ipa-reference.h" +#include "diagnostic-core.h" + /* This file contains the code required to manage the operands cache of the SSA optimizer. For every stmt, we maintain an operand cache in the stmt @@ -1081,6 +1082,118 @@ build_ssa_operands (gimple stmt) finalize_ssa_stmt_operands (stmt); } +/* Verifies SSA statement operands. */ + +DEBUG_FUNCTION bool +verify_ssa_operands (gimple stmt) +{ + use_operand_p use_p; + def_operand_p def_p; + ssa_op_iter iter; + unsigned i; + tree use, def; + bool volatile_p = gimple_has_volatile_ops (stmt); + + /* build_ssa_operands w/o finalizing them. */ + gimple_set_has_volatile_ops (stmt, false); + start_ssa_stmt_operands (); + parse_ssa_operands (stmt); + + /* Now verify the built operands are the same as present in STMT. */ + def = gimple_vdef (stmt); + if (def + && TREE_CODE (def) == SSA_NAME) + def = SSA_NAME_VAR (def); + if (build_vdef != def) + { + error ("virtual definition of statement not up-to-date"); + return true; + } + if (gimple_vdef (stmt) + && ((def_p = gimple_vdef_op (stmt)) == NULL_DEF_OPERAND_P + || DEF_FROM_PTR (def_p) != gimple_vdef (stmt))) + { + error ("virtual def operand missing for stmt"); + return true; + } + + use = gimple_vuse (stmt); + if (use + && TREE_CODE (use) == SSA_NAME) + use = SSA_NAME_VAR (use); + if (build_vuse != use) + { + error ("virtual use of statement not up-to-date"); + return true; + } + if (gimple_vuse (stmt) + && ((use_p = gimple_vuse_op (stmt)) == NULL_USE_OPERAND_P + || USE_FROM_PTR (use_p) != gimple_vuse (stmt))) + { + error ("virtual use operand missing for stmt"); + return true; + } + + FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) + { + FOR_EACH_VEC_ELT (tree, build_uses, i, use) + { + if (use_p->use == (tree *)use) + { + VEC_replace (tree, build_uses, i, NULL_TREE); + break; + } + } + if (i == VEC_length (tree, build_uses)) + { + error ("excess use operand for stmt"); + debug_generic_expr (USE_FROM_PTR (use_p)); + return true; + } + } + FOR_EACH_VEC_ELT (tree, build_uses, i, use) + if (use != NULL_TREE) + { + error ("use operand missing for stmt"); + debug_generic_expr (*(tree *)use); + return true; + } + + FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF) + { + FOR_EACH_VEC_ELT (tree, build_defs, i, def) + { + if (def_p == (tree *)def) + { + VEC_replace (tree, build_defs, i, NULL_TREE); + break; + } + } + if (i == VEC_length (tree, build_defs)) + { + error ("excess def operand for stmt"); + debug_generic_expr (DEF_FROM_PTR (def_p)); + return true; + } + } + FOR_EACH_VEC_ELT (tree, build_defs, i, def) + if (def != NULL_TREE) + { + error ("def operand missing for stmt"); + debug_generic_expr (*(tree *)def); + return true; + } + + if (gimple_has_volatile_ops (stmt) != volatile_p) + { + error ("stmt volatile flag not up-to-date"); + return true; + } + + cleanup_build_arrays (); + return false; +} + /* Releases the operands of STMT back to their freelists, and clears the stmt operand lists. */ diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h index 4c586f7fb27..ac195b575c3 100644 --- a/gcc/tree-ssa-operands.h +++ b/gcc/tree-ssa-operands.h @@ -105,6 +105,7 @@ extern void fini_ssa_operands (void); extern void update_stmt_operands (gimple); extern void free_stmt_operands (gimple); extern bool verify_imm_links (FILE *f, tree var); +extern bool verify_ssa_operands (gimple stmt); extern void dump_immediate_uses (FILE *file); extern void dump_immediate_uses_for (FILE *file, tree var); diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 8485af0a165..c28167e41aa 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -938,6 +938,8 @@ verify_ssa (bool check_modified_stmt) gimple stmt; TREE_VISITED (name) = 0; + verify_ssa_name (name, !is_gimple_reg (name)); + stmt = SSA_NAME_DEF_STMT (name); if (!gimple_nop_p (stmt)) { @@ -987,9 +989,6 @@ verify_ssa (bool check_modified_stmt) { gimple stmt = gsi_stmt (gsi); use_operand_p use_p; - bool has_err; - int count; - unsigned i; if (check_modified_stmt && gimple_modified_p (stmt)) { @@ -999,89 +998,15 @@ verify_ssa (bool check_modified_stmt) goto err; } - if (is_gimple_assign (stmt) - && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) + if (verify_ssa_operands (stmt)) { - tree lhs, base_address; - - lhs = gimple_assign_lhs (stmt); - base_address = get_base_address (lhs); - - if (base_address - && SSA_VAR_P (base_address) - && !gimple_vdef (stmt) - && optimize > 0) - { - error ("statement makes a memory store, but has no VDEFS"); - print_gimple_stmt (stderr, stmt, 0, TDF_VOPS); - goto err; - } - } - else if (gimple_debug_bind_p (stmt) - && !gimple_debug_bind_has_value_p (stmt)) - continue; - - /* Verify the single virtual operand and its constraints. */ - has_err = false; - if (gimple_vdef (stmt)) - { - if (gimple_vdef_op (stmt) == NULL_DEF_OPERAND_P) - { - error ("statement has VDEF operand not in defs list"); - has_err = true; - } - if (!gimple_vuse (stmt)) - { - error ("statement has VDEF but no VUSE operand"); - has_err = true; - } - else if (SSA_NAME_VAR (gimple_vdef (stmt)) - != SSA_NAME_VAR (gimple_vuse (stmt))) - { - error ("VDEF and VUSE do not use the same symbol"); - has_err = true; - } - has_err |= verify_ssa_name (gimple_vdef (stmt), true); - } - if (gimple_vuse (stmt)) - { - if (gimple_vuse_op (stmt) == NULL_USE_OPERAND_P) - { - error ("statement has VUSE operand not in uses list"); - has_err = true; - } - has_err |= verify_ssa_name (gimple_vuse (stmt), true); - } - if (has_err) - { - error ("in statement"); - print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS); + print_gimple_stmt (stderr, stmt, 0, TDF_VOPS); goto err; } - count = 0; - FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE|SSA_OP_DEF) - { - if (verify_ssa_name (op, false)) - { - error ("in statement"); - print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS); - goto err; - } - count++; - } - - for (i = 0; i < gimple_num_ops (stmt); i++) - { - op = gimple_op (stmt, i); - if (op && TREE_CODE (op) == SSA_NAME && --count < 0) - { - error ("number of operands and imm-links don%'t agree" - " in statement"); - print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS); - goto err; - } - } + if (gimple_debug_bind_p (stmt) + && !gimple_debug_bind_has_value_p (stmt)) + continue; FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE|SSA_OP_VUSE) {