1 /* Support routines for Value Range Propagation (VRP).
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
26 #include "tree-pass.h"
28 #include "gimple-pretty-print.h"
30 #include "gimple-fold.h"
32 #include "gimple-iterator.h"
34 #include "tree-ssa-loop-manip.h"
35 #include "tree-ssa-loop.h"
37 #include "tree-scalar-evolution.h"
38 #include "tree-ssa-propagate.h"
39 #include "alloc-pool.h"
41 #include "tree-cfgcleanup.h"
42 #include "vr-values.h"
43 #include "gimple-ssa-evrp-analyze.h"
45 class evrp_folder
: public substitute_and_fold_engine
48 evrp_folder () : m_range_analyzer (/*update_global_ranges=*/true),
49 m_vr_values (m_range_analyzer
.get_vr_values ())
55 m_vr_values
->cleanup_edges_and_switches ();
59 fprintf (dump_file
, "\nValue ranges after Early VRP:\n\n");
60 m_range_analyzer
.dump_all_value_ranges (dump_file
);
61 fprintf (dump_file
, "\n");
65 tree
get_value (tree op
, gimple
*stmt ATTRIBUTE_UNUSED
) OVERRIDE
67 return m_vr_values
->op_with_constant_singleton_value_range (op
);
70 void pre_fold_bb (basic_block bb
) OVERRIDE
72 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
73 fprintf (dump_file
, "evrp visiting BB%d\n", bb
->index
);
74 m_range_analyzer
.enter (bb
);
77 void pre_fold_stmt (gimple
*stmt
) OVERRIDE
79 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
81 fprintf (dump_file
, "evrp visiting stmt ");
82 print_gimple_stmt (dump_file
, stmt
, 0);
84 m_range_analyzer
.record_ranges_from_stmt (stmt
, false);
87 bool fold_stmt (gimple_stmt_iterator
*gsi
) OVERRIDE
89 return m_vr_values
->simplify_stmt_using_ranges (gsi
);
92 void post_fold_bb (basic_block bb
) OVERRIDE
94 m_range_analyzer
.leave (bb
);
97 void post_new_stmt (gimple
*stmt
) OVERRIDE
99 m_vr_values
->set_defs_to_varying (stmt
);
103 DISABLE_COPY_AND_ASSIGN (evrp_folder
);
104 class evrp_range_analyzer m_range_analyzer
;
105 class vr_values
*m_vr_values
;
108 /* Main entry point for the early vrp pass which is a simplified non-iterative
109 version of vrp where basic blocks are visited in dominance order. Value
110 ranges discovered in early vrp will also be used by ipa-vrp. */
115 /* Ideally this setup code would move into the ctor for the folder
116 However, this setup can change the number of blocks which
117 invalidates the internal arrays that are set up by the dominator
118 walker in substitute_and_fold_engine. */
119 loop_optimizer_init (LOOPS_NORMAL
| LOOPS_HAVE_RECORDED_EXITS
);
120 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
122 calculate_dominance_info (CDI_DOMINATORS
);
125 folder
.substitute_and_fold ();
128 loop_optimizer_finalize ();
134 const pass_data pass_data_early_vrp
=
136 GIMPLE_PASS
, /* type */
138 OPTGROUP_NONE
, /* optinfo_flags */
139 TV_TREE_EARLY_VRP
, /* tv_id */
140 PROP_ssa
, /* properties_required */
141 0, /* properties_provided */
142 0, /* properties_destroyed */
143 0, /* todo_flags_start */
144 ( TODO_cleanup_cfg
| TODO_update_ssa
| TODO_verify_all
),
147 class pass_early_vrp
: public gimple_opt_pass
150 pass_early_vrp (gcc::context
*ctxt
)
151 : gimple_opt_pass (pass_data_early_vrp
, ctxt
)
154 /* opt_pass methods: */
155 opt_pass
* clone () { return new pass_early_vrp (m_ctxt
); }
156 virtual bool gate (function
*)
158 return flag_tree_vrp
!= 0;
160 virtual unsigned int execute (function
*)
161 { return execute_early_vrp (); }
167 make_pass_early_vrp (gcc::context
*ctxt
)
169 return new pass_early_vrp (ctxt
);