analyzer: fix feasibility false +ve on jumps through function ptrs [PR107582]
[platform/upstream/gcc.git] / gcc / gimple-predicate-analysis.h
1 /* Support for simple predicate analysis.
2
3    Copyright (C) 2021-2022 Free Software Foundation, Inc.
4    Contributed by Martin Sebor <msebor@redhat.com>
5
6    This file is part of GCC.
7
8    GCC is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3, or (at your option)
11    any later version.
12
13    GCC is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21
22 #ifndef GIMPLE_PREDICATE_ANALYSIS_H_INCLUDED
23 #define GIMPLE_PREDICATE_ANALYSIS_H_INCLUDED
24
25
26 /* Represents a simple Boolean predicate.  */
27 struct pred_info
28 {
29   tree pred_lhs;
30   tree pred_rhs;
31   enum tree_code cond_code;
32   bool invert;
33 };
34
35 /* The type to represent a sequence of predicates grouped
36    with .AND. operation.  */
37 typedef vec<pred_info, va_heap, vl_ptr> pred_chain;
38
39 /* The type to represent a sequence of pred_chains grouped
40    with .OR. operation.  */
41 typedef vec<pred_chain, va_heap, vl_ptr> pred_chain_union;
42
43 /* Represents a complex Boolean predicate expression.  */
44 class predicate
45 {
46  public:
47   /* Construct with the specified EVAL object.  */
48   predicate () : m_preds (vNULL) { }
49
50   /* Copy.  */
51   predicate (const predicate &rhs) : m_preds (vNULL) { *this = rhs; }
52
53   ~predicate ();
54
55   /* Assign.  */
56   predicate& operator= (const predicate &);
57
58   bool is_empty () const
59   {
60     return m_preds.is_empty ();
61   }
62
63   const pred_chain_union chain () const
64   {
65     return m_preds;
66   }
67
68   void init_from_control_deps (const vec<edge> *, unsigned, bool);
69
70   void dump (FILE *) const;
71   void dump (FILE *, gimple *, const char *) const;
72   void debug () const;
73
74   void normalize (gimple * = NULL, bool = false);
75   void simplify (gimple * = NULL, bool = false);
76
77   bool superset_of (const predicate &) const;
78
79 private:
80
81   bool includes (const pred_chain &) const;
82   void push_pred (const pred_info &);
83
84   /* Normalization functions.  */
85   void normalize (pred_chain *, pred_info, tree_code, pred_chain *,
86                   hash_set<tree> *);
87   void normalize (const pred_info &);
88   void normalize (const pred_chain &);
89
90   /* Simplification functions.  */
91   bool simplify_2 ();
92   bool simplify_3 ();
93   bool simplify_4 ();
94
95   /* Representation of the predicate expression(s).  */
96   pred_chain_union m_preds;
97 };
98
99 /* Represents a complex Boolean predicate expression.  */
100 class uninit_analysis
101 {
102  public:
103   /* Base function object type used to determine whether an expression
104      is of interest.  */
105   struct func_t
106   {
107     typedef unsigned phi_arg_set_t;
108
109     /* Return a bitset of PHI arguments of interest.  By default returns
110        bitset with a bit set for each argument.  Should be called in
111        the overriden function first and, if nonzero, the result then
112        refined as appropriate.  */
113     virtual phi_arg_set_t phi_arg_set (gphi *);
114
115     /* Maximum number of PHI arguments supported by phi_arg_set().  */
116     static constexpr unsigned max_phi_args =
117       sizeof (phi_arg_set_t) * CHAR_BIT;
118   };
119
120   /* Construct with the specified EVAL object.  */
121   uninit_analysis (func_t &eval)
122     : m_phi_def_preds (), m_eval (eval) { }
123
124   /* Copy.  */
125   uninit_analysis (const uninit_analysis &rhs) = delete;
126
127   /* Assign.  */
128   uninit_analysis& operator= (const uninit_analysis&) = delete;
129
130   /* Return true if the use by a statement in the basic block of
131      a PHI operand is ruled out (i.e., guarded) by *THIS.  */
132   bool is_use_guarded (gimple *, basic_block, gphi *, unsigned);
133
134 private:
135   bool is_use_guarded (gimple *, basic_block, gphi *, unsigned,
136                        hash_set<gphi *> *);
137   bool prune_phi_opnds (gphi *, unsigned, gphi *, tree, tree_code,
138                         hash_set<gphi *> *, bitmap *);
139   bool overlap (gphi *, unsigned, hash_set<gphi *> *, const predicate &);
140
141   void collect_phi_def_edges (gphi *, basic_block, vec<edge> *,
142                               hash_set<gimple *> *);
143   bool init_from_phi_def (gphi *);
144   bool init_use_preds (predicate &, basic_block, basic_block);
145
146
147   /* Representation of the predicate expression(s).  */
148   predicate m_phi_def_preds;
149   /* Callback to evaluate an operand.  Return true if it's interesting.  */
150   func_t &m_eval;
151 };
152
153 /* Bit mask handling macros.  */
154 #define MASK_SET_BIT(mask, pos) mask |= (1 << pos)
155 #define MASK_TEST_BIT(mask, pos) (mask & (1 << pos))
156 #define MASK_EMPTY(mask) (mask == 0)
157
158 #endif // GIMPLE_PREDICATE_ANALYSIS_H_INCLUDED