1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
/* Support for simple predicate analysis.
Copyright (C) 2021-2024 Free Software Foundation, Inc.
Contributed by Martin Sebor <msebor@redhat.com>
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 GIMPLE_PREDICATE_ANALYSIS_H_INCLUDED
#define GIMPLE_PREDICATE_ANALYSIS_H_INCLUDED
/* Represents a simple Boolean predicate. */
struct pred_info
{
tree pred_lhs;
tree pred_rhs;
enum tree_code cond_code;
bool invert;
};
/* The type to represent a sequence of predicates grouped
with .AND. operation. */
typedef vec<pred_info, va_heap, vl_ptr> pred_chain;
/* The type to represent a sequence of pred_chains grouped
with .OR. operation. */
typedef vec<pred_chain, va_heap, vl_ptr> pred_chain_union;
/* Represents a complex Boolean predicate expression. */
class predicate
{
public:
/* Construct with the specified EVAL object. */
predicate (bool empty_val) : m_preds (vNULL), m_cval (empty_val) { }
/* Copy. */
predicate (const predicate &rhs) : m_preds (vNULL) { *this = rhs; }
~predicate ();
/* Assign. */
predicate& operator= (const predicate &);
bool is_empty () const
{
return m_preds.is_empty ();
}
bool is_true () const
{
return is_empty () && m_cval;
}
bool is_false () const
{
return is_empty () && !m_cval;
}
bool empty_val () const
{
return m_cval;
}
const pred_chain_union chain () const
{
return m_preds;
}
void init_from_control_deps (const vec<edge> *, unsigned, bool);
void dump (FILE *) const;
void dump (FILE *, gimple *, const char *) const;
void debug () const;
void normalize (gimple * = NULL, bool = false);
void simplify (gimple * = NULL, bool = false);
bool superset_of (const predicate &) const;
private:
bool includes (const pred_chain &) const;
void push_pred (const pred_info &);
/* Normalization functions. */
void normalize (pred_chain *, pred_info, tree_code, pred_chain *,
hash_set<tree> *);
void normalize (const pred_info &);
void normalize (const pred_chain &);
/* Simplification functions. */
bool simplify_2 ();
bool simplify_3 ();
bool simplify_4 ();
/* Representation of the predicate expression(s). The predicate is
m_cval || m_preds[0] || ... */
pred_chain_union m_preds;
bool m_cval;
};
/* Represents a complex Boolean predicate expression. */
class uninit_analysis
{
public:
/* Base function object type used to determine whether an expression
is of interest. */
struct func_t
{
typedef unsigned phi_arg_set_t;
/* Return a bitset of PHI arguments of interest. By default returns
bitset with a bit set for each argument. Should be called in
the overriden function first and, if nonzero, the result then
refined as appropriate. */
virtual phi_arg_set_t phi_arg_set (gphi *);
/* Maximum number of PHI arguments supported by phi_arg_set(). */
static constexpr unsigned max_phi_args =
sizeof (phi_arg_set_t) * CHAR_BIT;
};
/* Construct with the specified EVAL object. */
uninit_analysis (func_t &eval)
: m_phi_def_preds (false), m_eval (eval) { }
/* Copy. */
uninit_analysis (const uninit_analysis &rhs) = delete;
/* Assign. */
uninit_analysis& operator= (const uninit_analysis&) = delete;
/* Return true if the use by a statement in the basic block of
a PHI operand is ruled out (i.e., guarded) by *THIS. */
bool is_use_guarded (gimple *, basic_block, gphi *, unsigned);
private:
bool is_use_guarded (gimple *, basic_block, gphi *, unsigned,
hash_set<gphi *> *);
bool prune_phi_opnds (gphi *, unsigned, gphi *, tree, tree_code,
hash_set<gphi *> *, bitmap *);
bool overlap (gphi *, unsigned, hash_set<gphi *> *, const predicate &);
void collect_phi_def_edges (gphi *, basic_block, vec<edge> *,
hash_set<gimple *> *);
bool init_from_phi_def (gphi *);
bool init_use_preds (predicate &, basic_block, basic_block);
/* Representation of the predicate expression(s). */
predicate m_phi_def_preds;
/* Callback to evaluate an operand. Return true if it's interesting. */
func_t &m_eval;
};
/* Bit mask handling macros. */
#define MASK_SET_BIT(mask, pos) mask |= (1 << pos)
#define MASK_TEST_BIT(mask, pos) (mask & (1 << pos))
#define MASK_EMPTY(mask) (mask == 0)
#endif // GIMPLE_PREDICATE_ANALYSIS_H_INCLUDED
|