| /* Support for simple predicate analysis. |
| |
| Copyright (C) 2021-2022 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 () : m_preds (vNULL) { } |
| |
| /* 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 (); |
| } |
| |
| 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). */ |
| pred_chain_union m_preds; |
| }; |
| |
| /* 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 (), 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 |