123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /* Header file for SSA dominator optimizations.
- Copyright (C) 2013-2019 Free Software Foundation, Inc.
- 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 GCC_TREE_SSA_SCOPED_TABLES_H
- #define GCC_TREE_SSA_SCOPED_TABLES_H
- /* Representation of a "naked" right-hand-side expression, to be used
- in recording available expressions in the expression hash table. */
- enum expr_kind
- {
- EXPR_SINGLE,
- EXPR_UNARY,
- EXPR_BINARY,
- EXPR_TERNARY,
- EXPR_CALL,
- EXPR_PHI
- };
- struct hashable_expr
- {
- tree type;
- enum expr_kind kind;
- union {
- struct { tree rhs; } single;
- struct { enum tree_code op; tree opnd; } unary;
- struct { enum tree_code op; tree opnd0, opnd1; } binary;
- struct { enum tree_code op; tree opnd0, opnd1, opnd2; } ternary;
- struct { gcall *fn_from; bool pure; size_t nargs; tree *args; } call;
- struct { size_t nargs; tree *args; } phi;
- } ops;
- };
- /* Structure for recording known value of a conditional expression.
- Clients build vectors of these objects to record known values
- that occur on edges. */
- struct cond_equivalence
- {
- /* The condition, in a HASHABLE_EXPR form. */
- struct hashable_expr cond;
- /* The result of the condition (true or false. */
- tree value;
- };
- /* Structure for entries in the expression hash table. */
- typedef class expr_hash_elt * expr_hash_elt_t;
- class expr_hash_elt
- {
- public:
- expr_hash_elt (gimple *, tree);
- expr_hash_elt (tree);
- expr_hash_elt (struct hashable_expr *, tree);
- expr_hash_elt (class expr_hash_elt &);
- ~expr_hash_elt ();
- void print (FILE *);
- tree vop (void) { return m_vop; }
- tree lhs (void) { return m_lhs; }
- struct hashable_expr *expr (void) { return &m_expr; }
- expr_hash_elt *stamp (void) { return m_stamp; }
- hashval_t hash (void) { return m_hash; }
- private:
- /* The expression (rhs) we want to record. */
- struct hashable_expr m_expr;
- /* The value (lhs) of this expression. */
- tree m_lhs;
- /* The virtual operand associated with the nearest dominating stmt
- loading from or storing to expr. */
- tree m_vop;
- /* The hash value for RHS. */
- hashval_t m_hash;
- /* A unique stamp, typically the address of the hash
- element itself, used in removing entries from the table. */
- struct expr_hash_elt *m_stamp;
- /* We should never be making assignments between objects in this class.
- Though it might allow us to exploit C++11 move semantics if we
- defined the move constructor and move assignment operator. */
- expr_hash_elt& operator= (const expr_hash_elt&);
- };
- /* Hashtable helpers. */
- struct expr_elt_hasher : pointer_hash <expr_hash_elt>
- {
- static inline hashval_t hash (const value_type &p)
- { return p->hash (); }
- static bool equal (const value_type &, const compare_type &);
- static inline void remove (value_type &element)
- { delete element; }
- };
- /* This class defines a unwindable expression equivalence table
- layered on top of the expression hash table.
- Essentially it's just a stack of available expression value pairs with
- a special marker (NULL, NULL) to indicate unwind points. */
- class avail_exprs_stack
- {
- public:
- /* We need access to the AVAIL_EXPR hash table so that we can
- remove entries from the hash table when unwinding the stack. */
- avail_exprs_stack (hash_table<expr_elt_hasher> *table)
- { m_stack.create (20); m_avail_exprs = table; }
- ~avail_exprs_stack (void) { m_stack.release (); }
- /* Push the unwinding marker onto the stack. */
- void push_marker (void) { record_expr (NULL, NULL, 'M'); }
- /* Restore the AVAIL_EXPRs table to its state when the last marker
- was pushed. */
- void pop_to_marker (void);
- /* Record a single available expression that can be unwound. */
- void record_expr (expr_hash_elt_t, expr_hash_elt_t, char);
- /* Get the underlying hash table. Would this be better as
- class inheritance? */
- hash_table<expr_elt_hasher> *avail_exprs (void)
- { return m_avail_exprs; }
- /* Lookup and conditionally insert an expression into the table,
- recording enough information to unwind as needed. */
- tree lookup_avail_expr (gimple *, bool, bool);
- void record_cond (cond_equivalence *);
- private:
- vec<std::pair<expr_hash_elt_t, expr_hash_elt_t> > m_stack;
- hash_table<expr_elt_hasher> *m_avail_exprs;
- /* For some assignments where the RHS is a binary operator, if we know
- a equality relationship between the operands, we may be able to compute
- a result, even if we don't know the exact value of the operands. */
- tree simplify_binary_operation (gimple *, class expr_hash_elt);
- /* We do not allow copying this object or initializing one
- from another. */
- avail_exprs_stack& operator= (const avail_exprs_stack&);
- avail_exprs_stack (class avail_exprs_stack &);
- };
- /* This class defines an unwindable const/copy equivalence table
- layered on top of SSA_NAME_VALUE/set_ssa_name_value.
- Essentially it's just a stack of name,prev value pairs with a
- special marker (NULL) to indicate unwind points. */
- class const_and_copies
- {
- public:
- const_and_copies (void) { m_stack.create (20); };
- ~const_and_copies (void) { m_stack.release (); }
- /* Push the unwinding marker onto the stack. */
- void push_marker (void) { m_stack.safe_push (NULL_TREE); }
- /* Restore the const/copies table to its state when the last marker
- was pushed. */
- void pop_to_marker (void);
- /* Record a single const/copy pair that can be unwound. This version
- may follow the value chain for the RHS. */
- void record_const_or_copy (tree, tree);
- /* Special entry point when we want to provide an explicit previous
- value for the first argument. Try to get rid of this in the future.
- This version may also follow the value chain for the RHS. */
- void record_const_or_copy (tree, tree, tree);
- private:
- /* Record a single const/copy pair that can be unwound. This version
- does not follow the value chain for the RHS. */
- void record_const_or_copy_raw (tree, tree, tree);
- vec<tree> m_stack;
- const_and_copies& operator= (const const_and_copies&);
- const_and_copies (class const_and_copies &);
- };
- void initialize_expr_from_cond (tree cond, struct hashable_expr *expr);
- void record_conditions (vec<cond_equivalence> *p, tree, tree);
- #endif /* GCC_TREE_SSA_SCOPED_TABLES_H */
|