]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/gimple-ssa-evrp.c
rs6000: New iterator CCEITHER
[thirdparty/gcc.git] / gcc / gimple-ssa-evrp.c
index 609ce38f2182d38e7fea1135eb3f347b1876378c..5b993886912c62379b28acdc06346ecf501349d7 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for Value Range Propagation (VRP).
-   Copyright (C) 2005-2017 Free Software Foundation, Inc.
+   Copyright (C) 2005-2019 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -47,6 +47,8 @@ class evrp_folder : public substitute_and_fold_engine
  public:
   tree get_value (tree) FINAL OVERRIDE;
   evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { }
+  bool simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
+    { return vr_values->simplify_stmt_using_ranges (gsi); }
   class vr_values *vr_values;
 
  private:
@@ -68,6 +70,7 @@ class evrp_dom_walker : public dom_walker
 public:
   evrp_dom_walker ()
     : dom_walker (CDI_DOMINATORS),
+      evrp_range_analyzer (true),
       evrp_folder (evrp_range_analyzer.get_vr_values ())
     {
       need_eh_cleanup = BITMAP_ALLOC (NULL);
@@ -108,8 +111,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 
       value_range *vr = evrp_range_analyzer.get_value_range (lhs);
       /* Mark PHIs whose lhs we fully propagate for removal.  */
-      tree val = value_range_constant_singleton (vr);
-      if (val && may_propagate_copy (lhs, val))
+      tree val;
+      if (vr->singleton_p (&val) && may_propagate_copy (lhs, val))
        {
          stmts_to_remove.safe_push (phi);
          continue;
@@ -134,7 +137,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
          print_gimple_stmt (dump_file, stmt, 0);
        }
 
-      evrp_range_analyzer.record_ranges_from_stmt (stmt);
+      evrp_range_analyzer.record_ranges_from_stmt (stmt, false);
 
       if (gcond *cond = dyn_cast <gcond *> (stmt))
        {
@@ -159,10 +162,9 @@ evrp_dom_walker::before_dom_children (basic_block bb)
              value_range *vr = evrp_range_analyzer.get_value_range (output);
 
              /* Mark stmts whose output we fully propagate for removal.  */
-             if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
-                 && (val = value_range_constant_singleton (vr))
+             if (vr->singleton_p (&val)
                  && may_propagate_copy (output, val)
-                 && !stmt_could_throw_p (stmt)
+                 && !stmt_could_throw_p (cfun, stmt)
                  && !gimple_has_side_effects (stmt))
                {
                  stmts_to_remove.safe_push (stmt);
@@ -173,6 +175,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 
       /* Try folding stmts with the VR discovered.  */
       bool did_replace = evrp_folder.replace_uses_in (stmt);
+      gimple_stmt_iterator prev_gsi = gsi;
+      gsi_prev (&prev_gsi);
       if (fold_stmt (&gsi, follow_single_use_edges)
          || did_replace)
        {
@@ -180,9 +184,30 @@ evrp_dom_walker::before_dom_children (basic_block bb)
          update_stmt (stmt);
          did_replace = true;
        }
+      if (evrp_folder.simplify_stmt_using_ranges (&gsi))
+       {
+         stmt = gsi_stmt (gsi);
+         update_stmt (stmt);
+         did_replace = true;
+       }
 
       if (did_replace)
        {
+         /* If we wound up generating new stmts during folding
+            drop all their defs to VARYING.  We can't easily
+            process them because we've already instantiated
+            ranges on uses on STMT that only hold after it.  */
+         if (gsi_end_p (prev_gsi))
+           prev_gsi = gsi_start_bb (bb);
+         else
+           gsi_next (&prev_gsi);
+         while (gsi_stmt (prev_gsi) != gsi_stmt (gsi))
+           {
+             evrp_range_analyzer.get_vr_values ()
+               ->set_defs_to_varying (gsi_stmt (prev_gsi));
+             gsi_next (&prev_gsi);
+           }
+
          /* If we cleaned up EH information from the statement,
             remove EH edges.  */
          if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
@@ -219,8 +244,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
              || virtual_operand_p (arg))
            continue;
          value_range *vr = evrp_range_analyzer.get_value_range (arg);
-         tree val = value_range_constant_singleton (vr);
-         if (val && may_propagate_copy (arg, val))
+         tree val;
+         if (vr->singleton_p (&val) && may_propagate_copy (arg, val))
            propagate_value (use_p, val);
        }
     }
@@ -279,6 +304,8 @@ evrp_dom_walker::cleanup (void)
       gimple *stmt = stmts_to_fixup.pop ();
       fixup_noreturn_call (stmt);
     }
+
+  evrp_folder.vr_values->cleanup_edges_and_switches ();
 }
 
 /* Main entry point for the early vrp pass which is a simplified non-iterative