On Sat, Nov 18, 2017 at 9:00 AM, Jeff Law <l...@redhat.com> wrote:
>
>
>
> This is just a straight cut-n-paste pulling the evrp_range_analyzer
> methods out of gimple-ssa-evrp.c into gimple-ssa-evrp-analyze.[ch].
>
> Bootstrapped and regression tested on x86_64.
>
>
> OK for the trunk?

Hum.   That makes things harder to follow - what's the advantage to
making two files of EVRP?

Richard.

> Jeff
>
>         * Makefile.in (OBJS): Add gimple-ssa-evrp-analyze.o.
>         * gimple-ssa-evrp-analyze.c: New file pulled from gimple-ssa-evrp.c.
>         * gimple-ssa-evrp-analyze.h: New file pulled from gimple-ssa-evrp.c.
>         * gimple-ssa-evrp.c: Remove bits moved into new files.  Include
>         gimple-ssa-evrp-analyze.h.
>
>
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index 5db78558c0c..38ab4e81026 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -1302,6 +1302,7 @@ OBJS = \
>         gimple-pretty-print.o \
>         gimple-ssa-backprop.o \
>         gimple-ssa-evrp.o \
> +       gimple-ssa-evrp-analyze.o \
>         gimple-ssa-isolate-paths.o \
>         gimple-ssa-nonnull-compare.o \
>         gimple-ssa-split-paths.o \
> diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
> new file mode 100644
> index 00000000000..4f33c644a74
> --- /dev/null
> +++ b/gcc/gimple-ssa-evrp-analyze.c
> @@ -0,0 +1,342 @@
> +/* Support routines for Value Range Propagation (VRP).
> +   Copyright (C) 2005-2017 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "backend.h"
> +#include "tree.h"
> +#include "gimple.h"
> +#include "tree-pass.h"
> +#include "ssa.h"
> +#include "gimple-pretty-print.h"
> +#include "cfganal.h"
> +#include "gimple-fold.h"
> +#include "tree-eh.h"
> +#include "gimple-iterator.h"
> +#include "tree-cfg.h"
> +#include "tree-ssa-loop-manip.h"
> +#include "tree-ssa-loop.h"
> +#include "cfgloop.h"
> +#include "tree-scalar-evolution.h"
> +.#include "tree-ssa-propagate.h"
> +#include "alloc-pool.h"
> +#include "domwalk.h"
> +#include "tree-cfgcleanup.h"
> +#include "vr-values.h"
> +#include "gimple-ssa-evrp-analyze.h"
> +
> +evrp_range_analyzer::evrp_range_analyzer () : stack (10)
> +{
> +  edge e;
> +  edge_iterator ei;
> +  basic_block bb;
> +  FOR_EACH_BB_FN (bb, cfun)
> +    {
> +      bb->flags &= ~BB_VISITED;
> +      FOR_EACH_EDGE (e, ei, bb->preds)
> +        e->flags |= EDGE_EXECUTABLE;
> +    }
> +}
> +
> +void
> +evrp_range_analyzer::enter (basic_block bb)
> +{
> +  stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL));
> +  record_ranges_from_incoming_edge (bb);
> +  record_ranges_from_phis (bb);
> +}
> +
> +/* Find new range for NAME such that (OP CODE LIMIT) is true.  */
> +value_range *
> +evrp_range_analyzer::try_find_new_range (tree name,
> +                                   tree op, tree_code code, tree limit)
> +{
> +  value_range vr = VR_INITIALIZER;
> +  value_range *old_vr = get_value_range (name);
> +
> +  /* Discover VR when condition is true.  */
> +  extract_range_for_var_from_comparison_expr (name, code, op,
> +                                             limit, &vr);
> +  /* If we found any usable VR, set the VR to ssa_name and create a
> +     PUSH old value in the stack with the old VR.  */
> +  if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
> +    {
> +      if (old_vr->type == vr.type
> +         && vrp_operand_equal_p (old_vr->min, vr.min)
> +         && vrp_operand_equal_p (old_vr->max, vr.max))
> +       return NULL;
> +      value_range *new_vr = vr_values.vrp_value_range_pool.allocate ();
> +      *new_vr = vr;
> +      return new_vr;
> +    }
> +  return NULL;
> +}
> +
> +void
> +evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
> +{
> +  edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
> +  if (pred_e)
> +    {
> +      gimple *stmt = last_stmt (pred_e->src);
> +      tree op0 = NULL_TREE;
> +
> +      if (stmt
> +         && gimple_code (stmt) == GIMPLE_COND
> +         && (op0 = gimple_cond_lhs (stmt))
> +         && TREE_CODE (op0) == SSA_NAME
> +         && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
> +             || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
> +       {
> +         if (dump_file && (dump_flags & TDF_DETAILS))
> +           {
> +             fprintf (dump_file, "Visiting controlling predicate ");
> +             print_gimple_stmt (dump_file, stmt, 0);
> +           }
> +         /* Entering a new scope.  Try to see if we can find a VR
> +            here.  */
> +         tree op1 = gimple_cond_rhs (stmt);
> +         if (TREE_OVERFLOW_P (op1))
> +           op1 = drop_tree_overflow (op1);
> +         tree_code code = gimple_cond_code (stmt);
> +
> +         auto_vec<assert_info, 8> asserts;
> +         register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
> +         if (TREE_CODE (op1) == SSA_NAME)
> +           register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);
> +
> +         auto_vec<std::pair<tree, value_range *>, 8> vrs;
> +         for (unsigned i = 0; i < asserts.length (); ++i)
> +           {
> +             value_range *vr = try_find_new_range (asserts[i].name,
> +                                                   asserts[i].expr,
> +                                                   asserts[i].comp_code,
> +                                                   asserts[i].val);
> +             if (vr)
> +               vrs.safe_push (std::make_pair (asserts[i].name, vr));
> +           }
> +         /* Push updated ranges only after finding all of them to avoid
> +            ordering issues that can lead to worse ranges.  */
> +         for (unsigned i = 0; i < vrs.length (); ++i)
> +           push_value_range (vrs[i].first, vrs[i].second);
> +       }
> +    }
> +}
> +
> +void
> +evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
> +{
> +  /* Visit PHI stmts and discover any new VRs possible.  */
> +  bool has_unvisited_preds = false;
> +  edge_iterator ei;
> +  edge e;
> +  FOR_EACH_EDGE (e, ei, bb->preds)
> +    if (e->flags & EDGE_EXECUTABLE
> +       && !(e->src->flags & BB_VISITED))
> +      {
> +       has_unvisited_preds = true;
> +       break;
> +      }
> +
> +  for (gphi_iterator gpi = gsi_start_phis (bb);
> +       !gsi_end_p (gpi); gsi_next (&gpi))
> +    {
> +      gphi *phi = gpi.phi ();
> +      tree lhs = PHI_RESULT (phi);
> +      if (virtual_operand_p (lhs))
> +       continue;
> +
> +      value_range vr_result = VR_INITIALIZER;
> +      bool interesting = stmt_interesting_for_vrp (phi);
> +      if (!has_unvisited_preds && interesting)
> +       extract_range_from_phi_node (phi, &vr_result);
> +      else
> +       {
> +         set_value_range_to_varying (&vr_result);
> +         /* When we have an unvisited executable predecessor we can't
> +            use PHI arg ranges which may be still UNDEFINED but have
> +            to use VARYING for them.  But we can still resort to
> +            SCEV for loop header PHIs.  */
> +         struct loop *l;
> +         if (interesting
> +             && (l = loop_containing_stmt (phi))
> +             && l->header == gimple_bb (phi))
> +         adjust_range_with_scev (&vr_result, l, phi, lhs);
> +       }
> +      update_value_range (lhs, &vr_result);
> +
> +      /* Set the SSA with the value range.  */
> +      if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
> +       {
> +         if ((vr_result.type == VR_RANGE
> +              || vr_result.type == VR_ANTI_RANGE)
> +             && (TREE_CODE (vr_result.min) == INTEGER_CST)
> +             && (TREE_CODE (vr_result.max) == INTEGER_CST))
> +           set_range_info (lhs, vr_result.type,
> +                           wi::to_wide (vr_result.min),
> +                           wi::to_wide (vr_result.max));
> +       }
> +      else if (POINTER_TYPE_P (TREE_TYPE (lhs))
> +              && ((vr_result.type == VR_RANGE
> +                   && range_includes_zero_p (vr_result.min,
> +                                             vr_result.max) == 0)
> +                  || (vr_result.type == VR_ANTI_RANGE
> +                      && range_includes_zero_p (vr_result.min,
> +                                                vr_result.max) == 1)))
> +       set_ptr_nonnull (lhs);
> +    }
> +}
> +
> +void
> +evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
> +{
> +  tree output = NULL_TREE;
> +
> +  if (dyn_cast <gcond *> (stmt))
> +    ;
> +  else if (stmt_interesting_for_vrp (stmt))
> +    {
> +      edge taken_edge;
> +      value_range vr = VR_INITIALIZER;
> +      extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
> +      if (output
> +         && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE))
> +       {
> +         update_value_range (output, &vr);
> +
> +         /* Set the SSA with the value range.  */
> +         if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
> +           {
> +             if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
> +                 && (TREE_CODE (vr.min) == INTEGER_CST)
> +                 && (TREE_CODE (vr.max) == INTEGER_CST))
> +               set_range_info (output, vr.type,
> +                               wi::to_wide (vr.min),
> +                               wi::to_wide (vr.max));
> +           }
> +         else if (POINTER_TYPE_P (TREE_TYPE (output))
> +                  && ((vr.type == VR_RANGE
> +                       && range_includes_zero_p (vr.min, vr.max) == 0)
> +                      || (vr.type == VR_ANTI_RANGE
> +                          && range_includes_zero_p (vr.min, vr.max) == 1)))
> +           set_ptr_nonnull (output);
> +       }
> +      else
> +       set_defs_to_varying (stmt);
> +    }
> +  else
> +    set_defs_to_varying (stmt);
> +
> +  /* See if we can derive a range for any of STMT's operands.  */
> +  tree op;
> +  ssa_op_iter i;
> +  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
> +    {
> +      tree value;
> +      enum tree_code comp_code;
> +
> +      /* If OP is used in such a way that we can infer a value
> +         range for it, and we don't find a previous assertion for
> +         it, create a new assertion location node for OP.  */
> +      if (infer_value_range (stmt, op, &comp_code, &value))
> +       {
> +         /* If we are able to infer a nonzero value range for OP,
> +            then walk backwards through the use-def chain to see if OP
> +            was set via a typecast.
> +            If so, then we can also infer a nonzero value range
> +            for the operand of the NOP_EXPR.  */
> +         if (comp_code == NE_EXPR && integer_zerop (value))
> +           {
> +             tree t = op;
> +             gimple *def_stmt = SSA_NAME_DEF_STMT (t);
> +             while (is_gimple_assign (def_stmt)
> +                    && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code 
> (def_stmt))
> +                    && TREE_CODE
> +                         (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
> +                    && POINTER_TYPE_P
> +                         (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
> +               {
> +                 t = gimple_assign_rhs1 (def_stmt);
> +                 def_stmt = SSA_NAME_DEF_STMT (t);
> +
> +                 /* Add VR when (T COMP_CODE value) condition is
> +                    true.  */
> +                 value_range *op_range
> +                   = try_find_new_range (t, t, comp_code, value);
> +                 if (op_range)
> +                   push_value_range (t, op_range);
> +               }
> +           }
> +         /* Add VR when (OP COMP_CODE value) condition is true.  */
> +         value_range *op_range = try_find_new_range (op, op,
> +                                                     comp_code, value);
> +         if (op_range)
> +           push_value_range (op, op_range);
> +       }
> +    }
> +}
> +
> +/* Restore/pop VRs valid only for BB when we leave BB.  */
> +
> +void
> +evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED)
> +{
> +  gcc_checking_assert (!stack.is_empty ());
> +  while (stack.last ().first != NULL_TREE)
> +    pop_value_range (stack.last ().first);
> +  stack.pop ();
> +}
> +
> +/* Push the Value Range of VAR to the stack and update it with new VR.  */
> +
> +void
> +evrp_range_analyzer::push_value_range (tree var, value_range *vr)
> +{
> +  if (dump_file && (dump_flags & TDF_DETAILS))
> +    {
> +      fprintf (dump_file, "pushing new range for ");
> +      print_generic_expr (dump_file, var);
> +      fprintf (dump_file, ": ");
> +      dump_value_range (dump_file, vr);
> +      fprintf (dump_file, "\n");
> +    }
> +  stack.safe_push (std::make_pair (var, get_value_range (var)));
> +  set_vr_value (var, vr);
> +}
> +
> +/* Pop the Value Range from the vrp_stack and update VAR with it.  */
> +
> +value_range *
> +evrp_range_analyzer::pop_value_range (tree var)
> +{
> +  value_range *vr = stack.last ().second;
> +  gcc_checking_assert (var == stack.last ().first);
> +  if (dump_file && (dump_flags & TDF_DETAILS))
> +    {
> +      fprintf (dump_file, "popping range for ");
> +      print_generic_expr (dump_file, var);
> +      fprintf (dump_file, ", restoring ");
> +      dump_value_range (dump_file, vr);
> +      fprintf (dump_file, "\n");
> +    }
> +  set_vr_value (var, vr);
> +  stack.pop ();
> +  return vr;
> +}
> diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h
> new file mode 100644
> index 00000000000..2e6c609c45b
> --- /dev/null
> +++ b/gcc/gimple-ssa-evrp-analyze.h
> @@ -0,0 +1,71 @@
> +/* Support routines for Value Range Propagation (VRP).
> +   Copyright (C) 2016-2017 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#ifndef GCC_GIMPLE_SSA_EVRP_ANALYZE_H
> +#define GCC_GIMPLE_SSA_EVRP_ANALYZE_H
> +
> +class evrp_range_analyzer
> +{
> + public:
> +  evrp_range_analyzer (void);
> +  ~evrp_range_analyzer (void) { stack.release (); }
> +
> +  void enter (basic_block);
> +  void leave (basic_block);
> +  void record_ranges_from_stmt (gimple *);
> +
> +  class vr_values vr_values;
> +
> + private:
> +  DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
> +  void push_value_range (tree var, value_range *vr);
> +  value_range *pop_value_range (tree var);
> +  value_range *try_find_new_range (tree, tree op, tree_code code, tree 
> limit);
> +  void record_ranges_from_incoming_edge (basic_block);
> +  void record_ranges_from_phis (basic_block);
> +
> +  /* STACK holds the old VR.  */
> +  auto_vec<std::pair <tree, value_range*> > stack;
> +
> +  /* Temporary delegators.  */
> +  value_range *get_value_range (const_tree op)
> +    { return vr_values.get_value_range (op); }
> +  bool update_value_range (const_tree op, value_range *vr)
> +    { return vr_values.update_value_range (op, vr); }
> +  void extract_range_from_phi_node (gphi *phi, value_range *vr)
> +    { vr_values.extract_range_from_phi_node (phi, vr); }
> +  void adjust_range_with_scev (value_range *vr, struct loop *loop,
> +                               gimple *stmt, tree var)
> +    { vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
> +  void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
> +                                tree *output_p, value_range *vr)
> +    { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
> +  void set_defs_to_varying (gimple *stmt)
> +    { return vr_values.set_defs_to_varying (stmt); }
> +  void set_vr_value (tree name, value_range *vr)
> +    { vr_values.set_vr_value (name, vr); }
> +  void extract_range_for_var_from_comparison_expr (tree var,
> +                                                  enum tree_code cond_code,
> +                                                  tree op, tree limit,
> +                                                  value_range *vr_p)
> +    { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
> +                                                           op, limit, vr_p); 
> }
> +};
> +
> +#endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
> diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
> index 76eeb13c63e..5fa9cfb3538 100644
> --- a/gcc/gimple-ssa-evrp.c
> +++ b/gcc/gimple-ssa-evrp.c
> @@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "domwalk.h"
>  #include "tree-cfgcleanup.h"
>  #include "vr-values.h"
> +#include "gimple-ssa-evrp-analyze.h"
>
>  class evrp_folder : public substitute_and_fold_engine
>  {
> @@ -55,69 +56,6 @@ evrp_folder::get_value (tree op)
>    return vr_values->op_with_constant_singleton_value_range (op);
>  }
>
> -class evrp_range_analyzer
> -{
> - public:
> -  evrp_range_analyzer (void);
> -  ~evrp_range_analyzer (void) { stack.release (); }
> -
> -  void enter (basic_block);
> -  void leave (basic_block);
> -  void record_ranges_from_stmt (gimple *);
> -
> -  class vr_values vr_values;
> -
> - private:
> -  DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
> -  void push_value_range (tree var, value_range *vr);
> -  value_range *pop_value_range (tree var);
> -  value_range *try_find_new_range (tree, tree op, tree_code code, tree 
> limit);
> -  void record_ranges_from_incoming_edge (basic_block);
> -  void record_ranges_from_phis (basic_block);
> -
> -  /* STACK holds the old VR.  */
> -  auto_vec<std::pair <tree, value_range*> > stack;
> -
> -  /* Temporary delegators.  */
> -  value_range *get_value_range (const_tree op)
> -    { return vr_values.get_value_range (op); }
> -  bool update_value_range (const_tree op, value_range *vr)
> -    { return vr_values.update_value_range (op, vr); }
> -  void extract_range_from_phi_node (gphi *phi, value_range *vr)
> -    { vr_values.extract_range_from_phi_node (phi, vr); }
> -  void adjust_range_with_scev (value_range *vr, struct loop *loop,
> -                               gimple *stmt, tree var)
> -    { vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
> -  void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
> -                                tree *output_p, value_range *vr)
> -    { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
> -  void set_defs_to_varying (gimple *stmt)
> -    { return vr_values.set_defs_to_varying (stmt); }
> -  void set_vr_value (tree name, value_range *vr)
> -    { vr_values.set_vr_value (name, vr); }
> -  void extract_range_for_var_from_comparison_expr (tree var,
> -                                                  enum tree_code cond_code,
> -                                                  tree op, tree limit,
> -                                                  value_range *vr_p)
> -    { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
> -                                                           op, limit, vr_p); 
> }
> -};
> -
> -evrp_range_analyzer::evrp_range_analyzer () : stack (10)
> -{
> -  edge e;
> -  edge_iterator ei;
> -  basic_block bb;
> -
> -  FOR_EACH_BB_FN (bb, cfun)
> -    {
> -      bb->flags &= ~BB_VISITED;
> -      FOR_EACH_EDGE (e, ei, bb->preds)
> -       e->flags |= EDGE_EXECUTABLE;
> -    }
> -}
> -
> -
>  /* evrp_dom_walker visits the basic blocks in the dominance order and set
>     the Value Ranges (VR) for SSA_NAMEs in the scope.  Use this VR to
>     discover more VRs.  */
> @@ -154,246 +92,6 @@ public:
>      { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); }
>  };
>
> -void
> -evrp_range_analyzer::enter (basic_block bb)
> -{
> -  stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL));
> -  record_ranges_from_incoming_edge (bb);
> -  record_ranges_from_phis (bb);
> -}
> -
> -/* Find new range for NAME such that (OP CODE LIMIT) is true.  */
> -value_range *
> -evrp_range_analyzer::try_find_new_range (tree name,
> -                                   tree op, tree_code code, tree limit)
> -{
> -  value_range vr = VR_INITIALIZER;
> -  value_range *old_vr = get_value_range (name);
> -
> -  /* Discover VR when condition is true.  */
> -  extract_range_for_var_from_comparison_expr (name, code, op,
> -                                             limit, &vr);
> -  /* If we found any usable VR, set the VR to ssa_name and create a
> -     PUSH old value in the stack with the old VR.  */
> -  if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
> -    {
> -      if (old_vr->type == vr.type
> -         && vrp_operand_equal_p (old_vr->min, vr.min)
> -         && vrp_operand_equal_p (old_vr->max, vr.max))
> -       return NULL;
> -      value_range *new_vr = vr_values.vrp_value_range_pool.allocate ();
> -      *new_vr = vr;
> -      return new_vr;
> -    }
> -  return NULL;
> -}
> -
> -/* If BB is reached by a single incoming edge (ignoring loop edges),
> -   then derive ranges implied by traversing that edge.  */
> -
> -void
> -evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
> -{
> -  edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
> -  if (pred_e)
> -    {
> -      gimple *stmt = last_stmt (pred_e->src);
> -      tree op0 = NULL_TREE;
> -
> -      if (stmt
> -         && gimple_code (stmt) == GIMPLE_COND
> -         && (op0 = gimple_cond_lhs (stmt))
> -         && TREE_CODE (op0) == SSA_NAME
> -         && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
> -             || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
> -       {
> -         if (dump_file && (dump_flags & TDF_DETAILS))
> -           {
> -             fprintf (dump_file, "Visiting controlling predicate ");
> -             print_gimple_stmt (dump_file, stmt, 0);
> -           }
> -         /* Entering a new scope.  Try to see if we can find a VR
> -            here.  */
> -         tree op1 = gimple_cond_rhs (stmt);
> -         if (TREE_OVERFLOW_P (op1))
> -           op1 = drop_tree_overflow (op1);
> -         tree_code code = gimple_cond_code (stmt);
> -
> -         auto_vec<assert_info, 8> asserts;
> -         register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
> -         if (TREE_CODE (op1) == SSA_NAME)
> -           register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);
> -
> -         auto_vec<std::pair<tree, value_range *>, 8> vrs;
> -         for (unsigned i = 0; i < asserts.length (); ++i)
> -           {
> -             value_range *vr = try_find_new_range (asserts[i].name,
> -                                                   asserts[i].expr,
> -                                                   asserts[i].comp_code,
> -                                                   asserts[i].val);
> -             if (vr)
> -               vrs.safe_push (std::make_pair (asserts[i].name, vr));
> -           }
> -         /* Push updated ranges only after finding all of them to avoid
> -            ordering issues that can lead to worse ranges.  */
> -         for (unsigned i = 0; i < vrs.length (); ++i)
> -           push_value_range (vrs[i].first, vrs[i].second);
> -       }
> -    }
> -}
> -
> -void
> -evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
> -{
> -  /* Visit PHI stmts and discover any new VRs possible.  */
> -  bool has_unvisited_preds = false;
> -  edge_iterator ei;
> -  edge e;
> -  FOR_EACH_EDGE (e, ei, bb->preds)
> -    if (e->flags & EDGE_EXECUTABLE
> -       && !(e->src->flags & BB_VISITED))
> -      {
> -       has_unvisited_preds = true;
> -       break;
> -      }
> -
> -  for (gphi_iterator gpi = gsi_start_phis (bb);
> -       !gsi_end_p (gpi); gsi_next (&gpi))
> -    {
> -      gphi *phi = gpi.phi ();
> -      tree lhs = PHI_RESULT (phi);
> -      if (virtual_operand_p (lhs))
> -       continue;
> -
> -      value_range vr_result = VR_INITIALIZER;
> -      bool interesting = stmt_interesting_for_vrp (phi);
> -      if (!has_unvisited_preds && interesting)
> -       extract_range_from_phi_node (phi, &vr_result);
> -      else
> -       {
> -         set_value_range_to_varying (&vr_result);
> -         /* When we have an unvisited executable predecessor we can't
> -            use PHI arg ranges which may be still UNDEFINED but have
> -            to use VARYING for them.  But we can still resort to
> -            SCEV for loop header PHIs.  */
> -         struct loop *l;
> -         if (interesting
> -             && (l = loop_containing_stmt (phi))
> -             && l->header == gimple_bb (phi))
> -         adjust_range_with_scev (&vr_result, l, phi, lhs);
> -       }
> -      update_value_range (lhs, &vr_result);
> -
> -      /* Set the SSA with the value range.  */
> -      if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
> -       {
> -         if ((vr_result.type == VR_RANGE
> -              || vr_result.type == VR_ANTI_RANGE)
> -             && (TREE_CODE (vr_result.min) == INTEGER_CST)
> -             && (TREE_CODE (vr_result.max) == INTEGER_CST))
> -           set_range_info (lhs, vr_result.type,
> -                           wi::to_wide (vr_result.min),
> -                           wi::to_wide (vr_result.max));
> -       }
> -      else if (POINTER_TYPE_P (TREE_TYPE (lhs))
> -              && ((vr_result.type == VR_RANGE
> -                   && range_includes_zero_p (vr_result.min,
> -                                             vr_result.max) == 0)
> -                  || (vr_result.type == VR_ANTI_RANGE
> -                      && range_includes_zero_p (vr_result.min,
> -                                                vr_result.max) == 1)))
> -       set_ptr_nonnull (lhs);
> -    }
> -}
> -
> -/* Record any ranges created by statement STMT.  */
> -
> -void
> -evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
> -{
> -  tree output = NULL_TREE;
> -
> -  if (dyn_cast <gcond *> (stmt))
> -    ;
> -  else if (stmt_interesting_for_vrp (stmt))
> -    {
> -      edge taken_edge;
> -      value_range vr = VR_INITIALIZER;
> -      extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
> -      if (output && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE))
> -       {
> -         update_value_range (output, &vr);
> -
> -         /* Set the SSA with the value range.  */
> -         if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
> -           {
> -             if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
> -                 && (TREE_CODE (vr.min) == INTEGER_CST)
> -                 && (TREE_CODE (vr.max) == INTEGER_CST))
> -               set_range_info (output, vr.type,
> -                               wi::to_wide (vr.min),
> -                               wi::to_wide (vr.max));
> -           }
> -         else if (POINTER_TYPE_P (TREE_TYPE (output))
> -                  && ((vr.type == VR_RANGE
> -                       && range_includes_zero_p (vr.min, vr.max) == 0)
> -                      || (vr.type == VR_ANTI_RANGE
> -                          && range_includes_zero_p (vr.min, vr.max) == 1)))
> -           set_ptr_nonnull (output);
> -       }
> -      else
> -       set_defs_to_varying (stmt);
> -    }
> -  else
> -    set_defs_to_varying (stmt);
> -
> -  /* See if we can derive a range for any of STMT's operands.  */
> -  tree op;
> -  ssa_op_iter i;
> -  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
> -    {
> -      tree value;
> -      enum tree_code comp_code;
> -
> -      /* If OP is used in such a way that we can infer a value
> -        range for it, and we don't find a previous assertion for
> -        it, create a new assertion location node for OP.  */
> -      if (infer_value_range (stmt, op, &comp_code, &value))
> -       {
> -         /* If we are able to infer a nonzero value range for OP,
> -            then walk backwards through the use-def chain to see if OP
> -            was set via a typecast.
> -            If so, then we can also infer a nonzero value range
> -            for the operand of the NOP_EXPR.  */
> -         if (comp_code == NE_EXPR && integer_zerop (value))
> -           {
> -             tree t = op;
> -             gimple *def_stmt = SSA_NAME_DEF_STMT (t);
> -             while (is_gimple_assign (def_stmt)
> -                    && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code 
> (def_stmt))
> -                    && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
> -                    && POINTER_TYPE_P
> -                         (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
> -               {
> -                 t = gimple_assign_rhs1 (def_stmt);
> -                 def_stmt = SSA_NAME_DEF_STMT (t);
> -
> -                 /* Add VR when (T COMP_CODE value) condition is true.  */
> -                 value_range *op_range
> -                   = try_find_new_range (t, t, comp_code, value);
> -                 if (op_range)
> -                   push_value_range (t, op_range);
> -               }
> -           }
> -         /* Add VR when (OP COMP_CODE value) condition is true.  */
> -         value_range *op_range = try_find_new_range (op, op,
> -                                                     comp_code, value);
> -         if (op_range)
> -           push_value_range (op, op_range);
> -       }
> -    }
> -}
> -
>  edge
>  evrp_dom_walker::before_dom_children (basic_block bb)
>  {
> @@ -541,54 +239,6 @@ evrp_dom_walker::after_dom_children (basic_block bb)
>    evrp_range_analyzer.leave (bb);
>  }
>
> -/* Restore/pop VRs valid only for BB when we leave BB.  */
> -
> -void
> -evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED)
> -{
> -  gcc_checking_assert (!stack.is_empty ());
> -  while (stack.last ().first != NULL_TREE)
> -    pop_value_range (stack.last ().first);
> -  stack.pop ();
> -}
> -
> -/* Push the Value Range of VAR to the stack and update it with new VR.  */
> -
> -void
> -evrp_range_analyzer::push_value_range (tree var, value_range *vr)
> -{
> -  if (dump_file && (dump_flags & TDF_DETAILS))
> -    {
> -      fprintf (dump_file, "pushing new range for ");
> -      print_generic_expr (dump_file, var);
> -      fprintf (dump_file, ": ");
> -      dump_value_range (dump_file, vr);
> -      fprintf (dump_file, "\n");
> -    }
> -  stack.safe_push (std::make_pair (var, get_value_range (var)));
> -  set_vr_value (var, vr);
> -}
> -
> -/* Pop the Value Range from the vrp_stack and update VAR with it.  */
> -
> -value_range *
> -evrp_range_analyzer::pop_value_range (tree var)
> -{
> -  value_range *vr = stack.last ().second;
> -  gcc_checking_assert (var == stack.last ().first);
> -  if (dump_file && (dump_flags & TDF_DETAILS))
> -    {
> -      fprintf (dump_file, "popping range for ");
> -      print_generic_expr (dump_file, var);
> -      fprintf (dump_file, ", restoring ");
> -      dump_value_range (dump_file, vr);
> -      fprintf (dump_file, "\n");
> -    }
> -  set_vr_value (var, vr);
> -  stack.pop ();
> -  return vr;
> -}
> -
>  /* Perform any cleanups after the main phase of EVRP has completed.  */
>
>  void
>

Reply via email to