xref: /dflybsd-src/contrib/gcc-8.0/gcc/tree-ssa-scopedtables.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Header file for SSA dominator optimizations.
2*38fd1498Szrj    Copyright (C) 2013-2018 Free Software Foundation, Inc.
3*38fd1498Szrj 
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj 
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj 
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*38fd1498Szrj  for more details.
15*38fd1498Szrj 
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
19*38fd1498Szrj 
20*38fd1498Szrj #ifndef GCC_TREE_SSA_SCOPED_TABLES_H
21*38fd1498Szrj #define GCC_TREE_SSA_SCOPED_TABLES_H
22*38fd1498Szrj 
23*38fd1498Szrj /* Representation of a "naked" right-hand-side expression, to be used
24*38fd1498Szrj    in recording available expressions in the expression hash table.  */
25*38fd1498Szrj 
26*38fd1498Szrj enum expr_kind
27*38fd1498Szrj {
28*38fd1498Szrj   EXPR_SINGLE,
29*38fd1498Szrj   EXPR_UNARY,
30*38fd1498Szrj   EXPR_BINARY,
31*38fd1498Szrj   EXPR_TERNARY,
32*38fd1498Szrj   EXPR_CALL,
33*38fd1498Szrj   EXPR_PHI
34*38fd1498Szrj };
35*38fd1498Szrj 
36*38fd1498Szrj struct hashable_expr
37*38fd1498Szrj {
38*38fd1498Szrj   tree type;
39*38fd1498Szrj   enum expr_kind kind;
40*38fd1498Szrj   union {
41*38fd1498Szrj     struct { tree rhs; } single;
42*38fd1498Szrj     struct { enum tree_code op;  tree opnd; } unary;
43*38fd1498Szrj     struct { enum tree_code op;  tree opnd0, opnd1; } binary;
44*38fd1498Szrj     struct { enum tree_code op;  tree opnd0, opnd1, opnd2; } ternary;
45*38fd1498Szrj     struct { gcall *fn_from; bool pure; size_t nargs; tree *args; } call;
46*38fd1498Szrj     struct { size_t nargs; tree *args; } phi;
47*38fd1498Szrj   } ops;
48*38fd1498Szrj };
49*38fd1498Szrj 
50*38fd1498Szrj /* Structure for recording known value of a conditional expression.
51*38fd1498Szrj 
52*38fd1498Szrj    Clients build vectors of these objects to record known values
53*38fd1498Szrj    that occur on edges.  */
54*38fd1498Szrj 
55*38fd1498Szrj struct cond_equivalence
56*38fd1498Szrj {
57*38fd1498Szrj   /* The condition, in a HASHABLE_EXPR form.  */
58*38fd1498Szrj   struct hashable_expr cond;
59*38fd1498Szrj 
60*38fd1498Szrj   /* The result of the condition (true or false.  */
61*38fd1498Szrj   tree value;
62*38fd1498Szrj };
63*38fd1498Szrj 
64*38fd1498Szrj /* Structure for entries in the expression hash table.  */
65*38fd1498Szrj 
66*38fd1498Szrj typedef class expr_hash_elt * expr_hash_elt_t;
67*38fd1498Szrj 
68*38fd1498Szrj class expr_hash_elt
69*38fd1498Szrj {
70*38fd1498Szrj  public:
71*38fd1498Szrj   expr_hash_elt (gimple *, tree);
72*38fd1498Szrj   expr_hash_elt (tree);
73*38fd1498Szrj   expr_hash_elt (struct hashable_expr *, tree);
74*38fd1498Szrj   expr_hash_elt (class expr_hash_elt &);
75*38fd1498Szrj   ~expr_hash_elt ();
76*38fd1498Szrj   void print (FILE *);
vop(void)77*38fd1498Szrj   tree vop (void) { return m_vop; }
lhs(void)78*38fd1498Szrj   tree lhs (void) { return m_lhs; }
expr(void)79*38fd1498Szrj   struct hashable_expr *expr (void) { return &m_expr; }
stamp(void)80*38fd1498Szrj   expr_hash_elt *stamp (void) { return m_stamp; }
hash(void)81*38fd1498Szrj   hashval_t hash (void) { return m_hash; }
82*38fd1498Szrj 
83*38fd1498Szrj  private:
84*38fd1498Szrj   /* The expression (rhs) we want to record.  */
85*38fd1498Szrj   struct hashable_expr m_expr;
86*38fd1498Szrj 
87*38fd1498Szrj   /* The value (lhs) of this expression.  */
88*38fd1498Szrj   tree m_lhs;
89*38fd1498Szrj 
90*38fd1498Szrj   /* The virtual operand associated with the nearest dominating stmt
91*38fd1498Szrj      loading from or storing to expr.  */
92*38fd1498Szrj   tree m_vop;
93*38fd1498Szrj 
94*38fd1498Szrj   /* The hash value for RHS.  */
95*38fd1498Szrj   hashval_t m_hash;
96*38fd1498Szrj 
97*38fd1498Szrj   /* A unique stamp, typically the address of the hash
98*38fd1498Szrj      element itself, used in removing entries from the table.  */
99*38fd1498Szrj   struct expr_hash_elt *m_stamp;
100*38fd1498Szrj 
101*38fd1498Szrj   /* We should never be making assignments between objects in this class.
102*38fd1498Szrj      Though it might allow us to exploit C++11 move semantics if we
103*38fd1498Szrj      defined the move constructor and move assignment operator.  */
104*38fd1498Szrj   expr_hash_elt& operator= (const expr_hash_elt&);
105*38fd1498Szrj };
106*38fd1498Szrj 
107*38fd1498Szrj /* Hashtable helpers.  */
108*38fd1498Szrj 
109*38fd1498Szrj struct expr_elt_hasher : pointer_hash <expr_hash_elt>
110*38fd1498Szrj {
hashexpr_elt_hasher111*38fd1498Szrj   static inline hashval_t hash (const value_type &p)
112*38fd1498Szrj     { return p->hash (); }
113*38fd1498Szrj   static bool equal (const value_type &, const compare_type &);
removeexpr_elt_hasher114*38fd1498Szrj   static inline void remove (value_type &element)
115*38fd1498Szrj     { delete element; }
116*38fd1498Szrj };
117*38fd1498Szrj 
118*38fd1498Szrj 
119*38fd1498Szrj /* This class defines a unwindable expression equivalence table
120*38fd1498Szrj    layered on top of the expression hash table.
121*38fd1498Szrj 
122*38fd1498Szrj    Essentially it's just a stack of available expression value pairs with
123*38fd1498Szrj    a special marker (NULL, NULL) to indicate unwind points.   */
124*38fd1498Szrj 
125*38fd1498Szrj class avail_exprs_stack
126*38fd1498Szrj {
127*38fd1498Szrj  public:
128*38fd1498Szrj   /* We need access to the AVAIL_EXPR hash table so that we can
129*38fd1498Szrj      remove entries from the hash table when unwinding the stack.  */
avail_exprs_stack(hash_table<expr_elt_hasher> * table)130*38fd1498Szrj   avail_exprs_stack (hash_table<expr_elt_hasher> *table)
131*38fd1498Szrj     { m_stack.create (20); m_avail_exprs = table; }
~avail_exprs_stack(void)132*38fd1498Szrj   ~avail_exprs_stack (void) { m_stack.release (); }
133*38fd1498Szrj 
134*38fd1498Szrj   /* Push the unwinding marker onto the stack.  */
push_marker(void)135*38fd1498Szrj   void push_marker (void) { record_expr (NULL, NULL, 'M'); }
136*38fd1498Szrj 
137*38fd1498Szrj   /* Restore the AVAIL_EXPRs table to its state when the last marker
138*38fd1498Szrj      was pushed.  */
139*38fd1498Szrj   void pop_to_marker (void);
140*38fd1498Szrj 
141*38fd1498Szrj   /* Record a single available expression that can be unwound.  */
142*38fd1498Szrj   void record_expr (expr_hash_elt_t, expr_hash_elt_t, char);
143*38fd1498Szrj 
144*38fd1498Szrj   /* Get the underlying hash table.  Would this be better as
145*38fd1498Szrj      class inheritance?  */
avail_exprs(void)146*38fd1498Szrj   hash_table<expr_elt_hasher> *avail_exprs (void)
147*38fd1498Szrj     { return m_avail_exprs; }
148*38fd1498Szrj 
149*38fd1498Szrj   /* Lookup and conditionally insert an expression into the table,
150*38fd1498Szrj      recording enough information to unwind as needed.  */
151*38fd1498Szrj   tree lookup_avail_expr (gimple *, bool, bool);
152*38fd1498Szrj 
153*38fd1498Szrj   void record_cond (cond_equivalence *);
154*38fd1498Szrj 
155*38fd1498Szrj  private:
156*38fd1498Szrj   vec<std::pair<expr_hash_elt_t, expr_hash_elt_t> > m_stack;
157*38fd1498Szrj   hash_table<expr_elt_hasher> *m_avail_exprs;
158*38fd1498Szrj 
159*38fd1498Szrj   /* For some assignments where the RHS is a binary operator, if we know
160*38fd1498Szrj      a equality relationship between the operands, we may be able to compute
161*38fd1498Szrj      a result, even if we don't know the exact value of the operands.  */
162*38fd1498Szrj   tree simplify_binary_operation (gimple *, class expr_hash_elt);
163*38fd1498Szrj 
164*38fd1498Szrj   /* We do not allow copying this object or initializing one
165*38fd1498Szrj      from another.  */
166*38fd1498Szrj   avail_exprs_stack& operator= (const avail_exprs_stack&);
167*38fd1498Szrj   avail_exprs_stack (class avail_exprs_stack &);
168*38fd1498Szrj };
169*38fd1498Szrj 
170*38fd1498Szrj /* This class defines an unwindable const/copy equivalence table
171*38fd1498Szrj    layered on top of SSA_NAME_VALUE/set_ssa_name_value.
172*38fd1498Szrj 
173*38fd1498Szrj    Essentially it's just a stack of name,prev value pairs with a
174*38fd1498Szrj    special marker (NULL) to indicate unwind points.  */
175*38fd1498Szrj 
176*38fd1498Szrj class const_and_copies
177*38fd1498Szrj {
178*38fd1498Szrj  public:
const_and_copies(void)179*38fd1498Szrj   const_and_copies (void) { m_stack.create (20); };
~const_and_copies(void)180*38fd1498Szrj   ~const_and_copies (void) { m_stack.release (); }
181*38fd1498Szrj 
182*38fd1498Szrj   /* Push the unwinding marker onto the stack.  */
push_marker(void)183*38fd1498Szrj   void push_marker (void) { m_stack.safe_push (NULL_TREE); }
184*38fd1498Szrj 
185*38fd1498Szrj   /* Restore the const/copies table to its state when the last marker
186*38fd1498Szrj      was pushed.  */
187*38fd1498Szrj   void pop_to_marker (void);
188*38fd1498Szrj 
189*38fd1498Szrj   /* Record a single const/copy pair that can be unwound.  This version
190*38fd1498Szrj      may follow the value chain for the RHS.  */
191*38fd1498Szrj   void record_const_or_copy (tree, tree);
192*38fd1498Szrj 
193*38fd1498Szrj   /* Special entry point when we want to provide an explicit previous
194*38fd1498Szrj      value for the first argument.  Try to get rid of this in the future.
195*38fd1498Szrj 
196*38fd1498Szrj      This version may also follow the value chain for the RHS.  */
197*38fd1498Szrj   void record_const_or_copy (tree, tree, tree);
198*38fd1498Szrj 
199*38fd1498Szrj  private:
200*38fd1498Szrj   /* Record a single const/copy pair that can be unwound.  This version
201*38fd1498Szrj      does not follow the value chain for the RHS.  */
202*38fd1498Szrj   void record_const_or_copy_raw (tree, tree, tree);
203*38fd1498Szrj 
204*38fd1498Szrj   vec<tree> m_stack;
205*38fd1498Szrj   const_and_copies& operator= (const const_and_copies&);
206*38fd1498Szrj   const_and_copies (class const_and_copies &);
207*38fd1498Szrj };
208*38fd1498Szrj 
209*38fd1498Szrj void initialize_expr_from_cond (tree cond, struct hashable_expr *expr);
210*38fd1498Szrj void record_conditions (vec<cond_equivalence> *p, tree, tree);
211*38fd1498Szrj 
212*38fd1498Szrj #endif /* GCC_TREE_SSA_SCOPED_TABLES_H */
213