]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/gimple-ssa-evrp.c
* gimple-ssa-evrp.c (evrp_dom_walker): Add cleanup method.
[thirdparty/gcc.git] / gcc / gimple-ssa-evrp.c
1 /* Support routines for Value Range Propagation (VRP).
2 Copyright (C) 2005-2017 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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)
9 any later version.
10
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.
15
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/>. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "tree.h"
25 #include "gimple.h"
26 #include "tree-pass.h"
27 #include "ssa.h"
28 #include "gimple-pretty-print.h"
29 #include "cfganal.h"
30 #include "gimple-fold.h"
31 #include "tree-eh.h"
32 #include "gimple-iterator.h"
33 #include "tree-cfg.h"
34 #include "tree-ssa-loop-manip.h"
35 #include "tree-ssa-loop.h"
36 #include "cfgloop.h"
37 #include "tree-scalar-evolution.h"
38 #include "tree-ssa-propagate.h"
39 #include "alloc-pool.h"
40 #include "domwalk.h"
41 #include "tree-cfgcleanup.h"
42 #include "vr-values.h"
43
44 class evrp_folder : public substitute_and_fold_engine
45 {
46 public:
47 tree get_value (tree) FINAL OVERRIDE;
48
49 class vr_values *vr_values;
50 };
51
52 tree
53 evrp_folder::get_value (tree op)
54 {
55 return vr_values->op_with_constant_singleton_value_range (op);
56 }
57
58 /* evrp_dom_walker visits the basic blocks in the dominance order and set
59 the Value Ranges (VR) for SSA_NAMEs in the scope. Use this VR to
60 discover more VRs. */
61
62 class evrp_dom_walker : public dom_walker
63 {
64 public:
65 evrp_dom_walker ()
66 : dom_walker (CDI_DOMINATORS), stack (10)
67 {
68 need_eh_cleanup = BITMAP_ALLOC (NULL);
69 }
70 ~evrp_dom_walker ()
71 {
72 BITMAP_FREE (need_eh_cleanup);
73 }
74 virtual edge before_dom_children (basic_block);
75 virtual void after_dom_children (basic_block);
76 void cleanup (void);
77
78 private:
79 DISABLE_COPY_AND_ASSIGN (evrp_dom_walker);
80 void push_value_range (tree var, value_range *vr);
81 value_range *pop_value_range (tree var);
82 value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
83
84 /* STACK holds the old VR. */
85 auto_vec<std::pair <tree, value_range*> > stack;
86 bitmap need_eh_cleanup;
87 auto_vec<gimple *> stmts_to_fixup;
88 auto_vec<gimple *> stmts_to_remove;
89
90 class vr_values vr_values;
91
92 /* Temporary delegators. */
93 value_range *get_value_range (const_tree op)
94 { return vr_values.get_value_range (op); }
95 bool update_value_range (const_tree op, value_range *vr)
96 { return vr_values.update_value_range (op, vr); }
97 void extract_range_from_phi_node (gphi *phi, value_range *vr)
98 { vr_values.extract_range_from_phi_node (phi, vr); }
99 void extract_range_for_var_from_comparison_expr (tree var,
100 enum tree_code cond_code,
101 tree op, tree limit,
102 value_range *vr_p)
103 { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
104 op, limit, vr_p); }
105 void adjust_range_with_scev (value_range *vr, struct loop *loop,
106 gimple *stmt, tree var)
107 { vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
108 tree op_with_constant_singleton_value_range (tree op)
109 { return vr_values.op_with_constant_singleton_value_range (op); }
110 void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
111 tree *output_p, value_range *vr)
112 { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
113 void set_defs_to_varying (gimple *stmt)
114 { return vr_values.set_defs_to_varying (stmt); }
115 void set_vr_value (tree name, value_range *vr)
116 { vr_values.set_vr_value (name, vr); }
117 void simplify_cond_using_ranges_2 (gcond *stmt)
118 { vr_values.simplify_cond_using_ranges_2 (stmt); }
119 void vrp_visit_cond_stmt (gcond *cond, edge *e)
120 { vr_values.vrp_visit_cond_stmt (cond, e); }
121 };
122
123 /* Find new range for NAME such that (OP CODE LIMIT) is true. */
124
125 value_range *
126 evrp_dom_walker::try_find_new_range (tree name,
127 tree op, tree_code code, tree limit)
128 {
129 value_range vr = VR_INITIALIZER;
130 value_range *old_vr = get_value_range (name);
131
132 /* Discover VR when condition is true. */
133 extract_range_for_var_from_comparison_expr (name, code, op,
134 limit, &vr);
135 /* If we found any usable VR, set the VR to ssa_name and create a
136 PUSH old value in the stack with the old VR. */
137 if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
138 {
139 if (old_vr->type == vr.type
140 && vrp_operand_equal_p (old_vr->min, vr.min)
141 && vrp_operand_equal_p (old_vr->max, vr.max))
142 return NULL;
143 value_range *new_vr = vr_values.vrp_value_range_pool.allocate ();
144 *new_vr = vr;
145 return new_vr;
146 }
147 return NULL;
148 }
149
150 /* See if there is any new scope is entered with new VR and set that VR to
151 ssa_name before visiting the statements in the scope. */
152
153 edge
154 evrp_dom_walker::before_dom_children (basic_block bb)
155 {
156 if (dump_file && (dump_flags & TDF_DETAILS))
157 fprintf (dump_file, "Visiting BB%d\n", bb->index);
158
159 stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL));
160
161 edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
162 if (pred_e)
163 {
164 gimple *stmt = last_stmt (pred_e->src);
165 tree op0 = NULL_TREE;
166
167 if (stmt
168 && gimple_code (stmt) == GIMPLE_COND
169 && (op0 = gimple_cond_lhs (stmt))
170 && TREE_CODE (op0) == SSA_NAME
171 && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
172 || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
173 {
174 if (dump_file && (dump_flags & TDF_DETAILS))
175 {
176 fprintf (dump_file, "Visiting controlling predicate ");
177 print_gimple_stmt (dump_file, stmt, 0);
178 }
179 /* Entering a new scope. Try to see if we can find a VR
180 here. */
181 tree op1 = gimple_cond_rhs (stmt);
182 if (TREE_OVERFLOW_P (op1))
183 op1 = drop_tree_overflow (op1);
184 tree_code code = gimple_cond_code (stmt);
185
186 auto_vec<assert_info, 8> asserts;
187 register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
188 if (TREE_CODE (op1) == SSA_NAME)
189 register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);
190
191 auto_vec<std::pair<tree, value_range *>, 8> vrs;
192 for (unsigned i = 0; i < asserts.length (); ++i)
193 {
194 value_range *vr = try_find_new_range (asserts[i].name,
195 asserts[i].expr,
196 asserts[i].comp_code,
197 asserts[i].val);
198 if (vr)
199 vrs.safe_push (std::make_pair (asserts[i].name, vr));
200 }
201 /* Push updated ranges only after finding all of them to avoid
202 ordering issues that can lead to worse ranges. */
203 for (unsigned i = 0; i < vrs.length (); ++i)
204 push_value_range (vrs[i].first, vrs[i].second);
205 }
206 }
207
208 /* Visit PHI stmts and discover any new VRs possible. */
209 bool has_unvisited_preds = false;
210 edge_iterator ei;
211 edge e;
212 FOR_EACH_EDGE (e, ei, bb->preds)
213 if (e->flags & EDGE_EXECUTABLE
214 && !(e->src->flags & BB_VISITED))
215 {
216 has_unvisited_preds = true;
217 break;
218 }
219
220 for (gphi_iterator gpi = gsi_start_phis (bb);
221 !gsi_end_p (gpi); gsi_next (&gpi))
222 {
223 gphi *phi = gpi.phi ();
224 tree lhs = PHI_RESULT (phi);
225 if (virtual_operand_p (lhs))
226 continue;
227 value_range vr_result = VR_INITIALIZER;
228 bool interesting = stmt_interesting_for_vrp (phi);
229 if (interesting && dump_file && (dump_flags & TDF_DETAILS))
230 {
231 fprintf (dump_file, "Visiting PHI node ");
232 print_gimple_stmt (dump_file, phi, 0);
233 }
234 if (!has_unvisited_preds
235 && interesting)
236 extract_range_from_phi_node (phi, &vr_result);
237 else
238 {
239 set_value_range_to_varying (&vr_result);
240 /* When we have an unvisited executable predecessor we can't
241 use PHI arg ranges which may be still UNDEFINED but have
242 to use VARYING for them. But we can still resort to
243 SCEV for loop header PHIs. */
244 struct loop *l;
245 if (interesting
246 && (l = loop_containing_stmt (phi))
247 && l->header == gimple_bb (phi))
248 adjust_range_with_scev (&vr_result, l, phi, lhs);
249 }
250 update_value_range (lhs, &vr_result);
251
252 /* Mark PHIs whose lhs we fully propagate for removal. */
253 tree val = op_with_constant_singleton_value_range (lhs);
254 if (val && may_propagate_copy (lhs, val))
255 {
256 stmts_to_remove.safe_push (phi);
257 continue;
258 }
259
260 /* Set the SSA with the value range. */
261 if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
262 {
263 if ((vr_result.type == VR_RANGE
264 || vr_result.type == VR_ANTI_RANGE)
265 && (TREE_CODE (vr_result.min) == INTEGER_CST)
266 && (TREE_CODE (vr_result.max) == INTEGER_CST))
267 set_range_info (lhs, vr_result.type,
268 wi::to_wide (vr_result.min),
269 wi::to_wide (vr_result.max));
270 }
271 else if (POINTER_TYPE_P (TREE_TYPE (lhs))
272 && ((vr_result.type == VR_RANGE
273 && range_includes_zero_p (vr_result.min,
274 vr_result.max) == 0)
275 || (vr_result.type == VR_ANTI_RANGE
276 && range_includes_zero_p (vr_result.min,
277 vr_result.max) == 1)))
278 set_ptr_nonnull (lhs);
279 }
280
281 edge taken_edge = NULL;
282
283 /* Visit all other stmts and discover any new VRs possible. */
284 for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
285 !gsi_end_p (gsi); gsi_next (&gsi))
286 {
287 gimple *stmt = gsi_stmt (gsi);
288 tree output = NULL_TREE;
289 gimple *old_stmt = stmt;
290 bool was_noreturn = (is_gimple_call (stmt)
291 && gimple_call_noreturn_p (stmt));
292
293 if (dump_file && (dump_flags & TDF_DETAILS))
294 {
295 fprintf (dump_file, "Visiting stmt ");
296 print_gimple_stmt (dump_file, stmt, 0);
297 }
298
299 if (gcond *cond = dyn_cast <gcond *> (stmt))
300 {
301 vrp_visit_cond_stmt (cond, &taken_edge);
302 if (taken_edge)
303 {
304 if (taken_edge->flags & EDGE_TRUE_VALUE)
305 gimple_cond_make_true (cond);
306 else if (taken_edge->flags & EDGE_FALSE_VALUE)
307 gimple_cond_make_false (cond);
308 else
309 gcc_unreachable ();
310 update_stmt (stmt);
311 }
312 }
313 else if (stmt_interesting_for_vrp (stmt))
314 {
315 edge taken_edge;
316 value_range vr = VR_INITIALIZER;
317 extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
318 if (output
319 && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE))
320 {
321 update_value_range (output, &vr);
322 vr = *get_value_range (output);
323
324 /* Mark stmts whose output we fully propagate for removal. */
325 tree val;
326 if ((val = op_with_constant_singleton_value_range (output))
327 && may_propagate_copy (output, val)
328 && !stmt_could_throw_p (stmt)
329 && !gimple_has_side_effects (stmt))
330 {
331 stmts_to_remove.safe_push (stmt);
332 continue;
333 }
334
335 /* Set the SSA with the value range. */
336 if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
337 {
338 if ((vr.type == VR_RANGE
339 || vr.type == VR_ANTI_RANGE)
340 && (TREE_CODE (vr.min) == INTEGER_CST)
341 && (TREE_CODE (vr.max) == INTEGER_CST))
342 set_range_info (output, vr.type,
343 wi::to_wide (vr.min),
344 wi::to_wide (vr.max));
345 }
346 else if (POINTER_TYPE_P (TREE_TYPE (output))
347 && ((vr.type == VR_RANGE
348 && range_includes_zero_p (vr.min,
349 vr.max) == 0)
350 || (vr.type == VR_ANTI_RANGE
351 && range_includes_zero_p (vr.min,
352 vr.max) == 1)))
353 set_ptr_nonnull (output);
354 }
355 else
356 set_defs_to_varying (stmt);
357 }
358 else
359 set_defs_to_varying (stmt);
360
361 /* See if we can derive a range for any of STMT's operands. */
362 tree op;
363 ssa_op_iter i;
364 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
365 {
366 tree value;
367 enum tree_code comp_code;
368
369 /* If OP is used in such a way that we can infer a value
370 range for it, and we don't find a previous assertion for
371 it, create a new assertion location node for OP. */
372 if (infer_value_range (stmt, op, &comp_code, &value))
373 {
374 /* If we are able to infer a nonzero value range for OP,
375 then walk backwards through the use-def chain to see if OP
376 was set via a typecast.
377 If so, then we can also infer a nonzero value range
378 for the operand of the NOP_EXPR. */
379 if (comp_code == NE_EXPR && integer_zerop (value))
380 {
381 tree t = op;
382 gimple *def_stmt = SSA_NAME_DEF_STMT (t);
383 while (is_gimple_assign (def_stmt)
384 && CONVERT_EXPR_CODE_P
385 (gimple_assign_rhs_code (def_stmt))
386 && TREE_CODE
387 (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
388 && POINTER_TYPE_P
389 (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
390 {
391 t = gimple_assign_rhs1 (def_stmt);
392 def_stmt = SSA_NAME_DEF_STMT (t);
393
394 /* Add VR when (T COMP_CODE value) condition is
395 true. */
396 value_range *op_range
397 = try_find_new_range (t, t, comp_code, value);
398 if (op_range)
399 push_value_range (t, op_range);
400 }
401 }
402 /* Add VR when (OP COMP_CODE value) condition is true. */
403 value_range *op_range = try_find_new_range (op, op,
404 comp_code, value);
405 if (op_range)
406 push_value_range (op, op_range);
407 }
408 }
409
410 /* Try folding stmts with the VR discovered. */
411 class evrp_folder evrp_folder;
412 evrp_folder.vr_values = &vr_values;
413 bool did_replace = evrp_folder.replace_uses_in (stmt);
414 if (fold_stmt (&gsi, follow_single_use_edges)
415 || did_replace)
416 {
417 stmt = gsi_stmt (gsi);
418 update_stmt (stmt);
419 did_replace = true;
420 }
421
422 if (did_replace)
423 {
424 /* If we cleaned up EH information from the statement,
425 remove EH edges. */
426 if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
427 bitmap_set_bit (need_eh_cleanup, bb->index);
428
429 /* If we turned a not noreturn call into a noreturn one
430 schedule it for fixup. */
431 if (!was_noreturn
432 && is_gimple_call (stmt)
433 && gimple_call_noreturn_p (stmt))
434 stmts_to_fixup.safe_push (stmt);
435
436 if (gimple_assign_single_p (stmt))
437 {
438 tree rhs = gimple_assign_rhs1 (stmt);
439 if (TREE_CODE (rhs) == ADDR_EXPR)
440 recompute_tree_invariant_for_addr_expr (rhs);
441 }
442 }
443 }
444
445 /* Visit BB successor PHI nodes and replace PHI args. */
446 FOR_EACH_EDGE (e, ei, bb->succs)
447 {
448 for (gphi_iterator gpi = gsi_start_phis (e->dest);
449 !gsi_end_p (gpi); gsi_next (&gpi))
450 {
451 gphi *phi = gpi.phi ();
452 use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
453 tree arg = USE_FROM_PTR (use_p);
454 if (TREE_CODE (arg) != SSA_NAME
455 || virtual_operand_p (arg))
456 continue;
457 tree val = op_with_constant_singleton_value_range (arg);
458 if (val && may_propagate_copy (arg, val))
459 propagate_value (use_p, val);
460 }
461 }
462
463 bb->flags |= BB_VISITED;
464
465 return taken_edge;
466 }
467
468 /* Restore/pop VRs valid only for BB when we leave BB. */
469
470 void
471 evrp_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
472 {
473 gcc_checking_assert (!stack.is_empty ());
474 while (stack.last ().first != NULL_TREE)
475 pop_value_range (stack.last ().first);
476 stack.pop ();
477 }
478
479 /* Push the Value Range of VAR to the stack and update it with new VR. */
480
481 void
482 evrp_dom_walker::push_value_range (tree var, value_range *vr)
483 {
484 if (dump_file && (dump_flags & TDF_DETAILS))
485 {
486 fprintf (dump_file, "pushing new range for ");
487 print_generic_expr (dump_file, var);
488 fprintf (dump_file, ": ");
489 dump_value_range (dump_file, vr);
490 fprintf (dump_file, "\n");
491 }
492 stack.safe_push (std::make_pair (var, get_value_range (var)));
493 set_vr_value (var, vr);
494 }
495
496 /* Pop the Value Range from the vrp_stack and update VAR with it. */
497
498 value_range *
499 evrp_dom_walker::pop_value_range (tree var)
500 {
501 value_range *vr = stack.last ().second;
502 gcc_checking_assert (var == stack.last ().first);
503 if (dump_file && (dump_flags & TDF_DETAILS))
504 {
505 fprintf (dump_file, "popping range for ");
506 print_generic_expr (dump_file, var);
507 fprintf (dump_file, ", restoring ");
508 dump_value_range (dump_file, vr);
509 fprintf (dump_file, "\n");
510 }
511 set_vr_value (var, vr);
512 stack.pop ();
513 return vr;
514 }
515
516 /* Perform any cleanups after the main phase of EVRP has completed. */
517
518 void
519 evrp_dom_walker::cleanup (void)
520 {
521 if (dump_file)
522 {
523 fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
524 vr_values.dump_all_value_ranges (dump_file);
525 fprintf (dump_file, "\n");
526 }
527
528 /* Remove stmts in reverse order to make debug stmt creation possible. */
529 while (! stmts_to_remove.is_empty ())
530 {
531 gimple *stmt = stmts_to_remove.pop ();
532 if (dump_file && dump_flags & TDF_DETAILS)
533 {
534 fprintf (dump_file, "Removing dead stmt ");
535 print_gimple_stmt (dump_file, stmt, 0);
536 fprintf (dump_file, "\n");
537 }
538 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
539 if (gimple_code (stmt) == GIMPLE_PHI)
540 remove_phi_node (&gsi, true);
541 else
542 {
543 unlink_stmt_vdef (stmt);
544 gsi_remove (&gsi, true);
545 release_defs (stmt);
546 }
547 }
548
549 if (!bitmap_empty_p (need_eh_cleanup))
550 gimple_purge_all_dead_eh_edges (need_eh_cleanup);
551
552 /* Fixup stmts that became noreturn calls. This may require splitting
553 blocks and thus isn't possible during the dominator walk. Do this
554 in reverse order so we don't inadvertedly remove a stmt we want to
555 fixup by visiting a dominating now noreturn call first. */
556 while (!stmts_to_fixup.is_empty ())
557 {
558 gimple *stmt = stmts_to_fixup.pop ();
559 fixup_noreturn_call (stmt);
560 }
561 }
562
563 /* Main entry point for the early vrp pass which is a simplified non-iterative
564 version of vrp where basic blocks are visited in dominance order. Value
565 ranges discovered in early vrp will also be used by ipa-vrp. */
566
567 static unsigned int
568 execute_early_vrp ()
569 {
570 edge e;
571 edge_iterator ei;
572 basic_block bb;
573
574 /* Ideally this setup code would move into the ctor for the dominator
575 walk. However, this setup can change the number of blocks which
576 invalidates the internal arrays that are set up by the dominator
577 walker. */
578 loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
579 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
580 scev_initialize ();
581 calculate_dominance_info (CDI_DOMINATORS);
582 FOR_EACH_BB_FN (bb, cfun)
583 {
584 bb->flags &= ~BB_VISITED;
585 FOR_EACH_EDGE (e, ei, bb->preds)
586 e->flags |= EDGE_EXECUTABLE;
587 }
588
589 /* Walk stmts in dominance order and propagate VRP. */
590 evrp_dom_walker walker;
591 walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
592 walker.cleanup ();
593
594 scev_finalize ();
595 loop_optimizer_finalize ();
596 return 0;
597 }
598
599 namespace {
600
601 const pass_data pass_data_early_vrp =
602 {
603 GIMPLE_PASS, /* type */
604 "evrp", /* name */
605 OPTGROUP_NONE, /* optinfo_flags */
606 TV_TREE_EARLY_VRP, /* tv_id */
607 PROP_ssa, /* properties_required */
608 0, /* properties_provided */
609 0, /* properties_destroyed */
610 0, /* todo_flags_start */
611 ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
612 };
613
614 class pass_early_vrp : public gimple_opt_pass
615 {
616 public:
617 pass_early_vrp (gcc::context *ctxt)
618 : gimple_opt_pass (pass_data_early_vrp, ctxt)
619 {}
620
621 /* opt_pass methods: */
622 opt_pass * clone () { return new pass_early_vrp (m_ctxt); }
623 virtual bool gate (function *)
624 {
625 return flag_tree_vrp != 0;
626 }
627 virtual unsigned int execute (function *)
628 { return execute_early_vrp (); }
629
630 }; // class pass_vrp
631 } // anon namespace
632
633 gimple_opt_pass *
634 make_pass_early_vrp (gcc::context *ctxt)
635 {
636 return new pass_early_vrp (ctxt);
637 }
638