[AArch64] Avoid GET_MODE_NUNITS in v8.4 support
[official-gcc.git] / gcc / go / gofrontend / escape.h
blobac72b19a2a361707615df57e199a38b30483c41a
1 // escape.h -- Go escape analysis (based on Go compiler algorithm).
3 // Copyright 2016 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 #ifndef GO_ESCAPE_H
8 #define GO_ESCAPE_H
10 #include "gogo.h"
12 class Named_object;
13 class Expression;
14 class Statement;
15 class Escape_context;
17 // There can be loops in the escape graph that lead to arbitrary recursions.
18 // See comment in gc/esc.go.
19 static const int MIN_LEVEL = -2;
21 // Level models the escapement of a Node using two integers that are computed
22 // by backwards-analyzing the flow of a function from its sink and increasing or
23 // decreasing based on dereferences and addressing, respectively.
24 // One integer, known as the level's VALUE (think absolute value), is just the
25 // sum of indirections (via referencing or dereferencing) applied to the Node.
26 // The second, known as the level's SUFFIX_VALUE, is the amount of indirections
27 // applied after some data has been copied from the node. When accessing a
28 // field F of an object O and then applying indirections, for example, the field
29 // access O.F is assumed to copy that data from O before applying indirections.
30 // With this, even if O.F escapes, it might mean that the content of O escape,
31 // but not the object O itself.
33 class Level
35 public:
36 Level()
37 : value_(0), suffix_value_(0)
38 { }
40 Level(int value, int suffix)
41 : value_(value), suffix_value_(suffix)
42 { }
44 // Return this level's value.
45 int
46 value() const
47 { return this->value_; }
49 // Return this level's suffix value.
50 int
51 suffix_value() const
52 { return this->suffix_value_; }
54 // Increase the level because a node is dereferenced.
55 Level
56 increase() const
58 if (this->value_ <= MIN_LEVEL)
59 return Level(MIN_LEVEL, 0);
61 return Level(this->value_ + 1, this->suffix_value_ + 1);
64 // Decrease the level because a node is referenced.
65 Level
66 decrease() const
68 if (this->value_ <= MIN_LEVEL)
69 return Level(MIN_LEVEL, 0);
71 return Level(this->value_ - 1, this->suffix_value_ - 1);
74 // Model a node being copied.
75 Level
76 copy() const
78 return Level(this->value_, std::max(this->suffix_value_, 0));
81 // Return a level with the minimum values of this level and l.
82 Level
83 min(const Level& l) const
85 return Level(std::min(this->value_, l.value()),
86 std::min(this->suffix_value_, l.suffix_value()));
89 // Compare two levels for equality.
90 bool
91 operator==(const Level& l) const
93 return (this->value_ == l.value()
94 && this->suffix_value_ == l.suffix_value());
97 // Create a level from an integer value.
98 static Level
99 From(int i)
101 if (i <= MIN_LEVEL)
102 return Level(MIN_LEVEL, 0);
103 return Level(i, 0);
106 private:
107 // The sum of all references (-1) and indirects (+1) applied to a Node.
108 int value_;
109 // The sum of all references (-1) abd indirects (+1) applied to a copied Node.
110 int suffix_value_;
113 // A node in the escape graph. This node is an alias to a particular node
114 // in the Go parse tree. Specifically, it can represent an expression node,
115 // a statement node, or a named object node (a variable or function).
117 class Node
119 public:
120 // This classification represents type of nodes in the Go parse tree that are
121 // interesting during the analysis.
122 enum Node_classification
124 NODE_OBJECT,
125 NODE_EXPRESSION,
126 NODE_STATEMENT,
127 // A "fake" node that models the indirection of its child node.
128 // This node does not correspond to an AST node.
129 NODE_INDIRECT
132 // The state necessary to keep track of how a node escapes.
133 struct Escape_state
135 // The current function.
136 Named_object* fn;
137 // A list of source nodes that flow into this node.
138 std::set<Node*> flows;
139 // If the node is a function call, the list of nodes returned.
140 std::vector<Node*> retvals;
141 // The node's loop depth.
142 int loop_depth;
143 // There is an extra loop depth in the flood phase used to account for
144 // variables referenced across closures. This is the maximum value of the
145 // extra loop depth seen during the flood that touches this node.
146 int max_extra_loop_depth;
147 // The node's level.
148 Level level;
149 // An ID given to a node when it is encountered as a flow from the current
150 // dst node. This is used to avoid infinite recursion of cyclic nodes.
151 int flood_id;
153 Escape_state()
154 : fn(NULL), loop_depth(0), max_extra_loop_depth(0), flood_id(0)
158 // Note: values in this enum appear in export data, and therefore MUST NOT
159 // change.
160 enum Escapement_encoding
162 ESCAPE_UNKNOWN,
163 // Does not escape to heap, result, or parameters.
164 ESCAPE_NONE,
165 // Is returned or reachable from a return statement.
166 ESCAPE_RETURN,
167 // Reachable from the heap.
168 ESCAPE_HEAP,
169 // By construction will not escape.
170 ESCAPE_NEVER
173 // Multiple constructors for each classification.
174 Node(Named_object* no)
175 : classification_(NODE_OBJECT), state_(NULL), encoding_(ESCAPE_UNKNOWN),
176 child_(NULL)
177 { this->u_.object_val = no; }
179 Node(Expression* e)
180 : classification_(NODE_EXPRESSION), state_(NULL), encoding_(ESCAPE_UNKNOWN),
181 child_(NULL)
182 { this->u_.expression_val = e; }
184 Node(Statement* s)
185 : classification_(NODE_STATEMENT), state_(NULL), encoding_(ESCAPE_UNKNOWN),
186 child_(NULL)
187 { this->u_.statement_val = s; }
189 Node(Node *n)
190 : classification_(NODE_INDIRECT), state_(NULL), encoding_(ESCAPE_UNKNOWN),
191 child_(n)
194 // Return this node's type.
195 Type*
196 type() const;
198 // Return this node's location.
199 Location
200 location() const;
202 // Return the location where the node's underlying object is defined.
203 Location
204 definition_location() const;
206 // Return this node's AST formatted string.
207 std::string
208 ast_format(Gogo*) const;
210 // Return this node's detailed format string.
211 std::string
212 details();
214 std::string
215 op_format() const;
217 // Return this node's escape state.
218 Escape_state*
219 state(Escape_context* context, Named_object* fn);
221 // Return this node's escape encoding.
223 encoding();
225 // Set the node's escape encoding.
226 void
227 set_encoding(int enc);
229 bool
230 is_big(Escape_context*) const;
232 bool
233 is_sink() const;
235 // Methods to return the underlying value in the Node union.
236 Named_object*
237 object() const
239 return (this->classification_ == NODE_OBJECT
240 ? this->u_.object_val
241 : NULL);
244 Expression*
245 expr() const
247 return (this->classification_ == NODE_EXPRESSION
248 ? this->u_.expression_val
249 : NULL);
252 Statement*
253 statement() const
255 return (this->classification_ == NODE_STATEMENT
256 ? this->u_.statement_val
257 : NULL);
260 bool
261 is_indirect() const
262 { return this->classification_ == NODE_INDIRECT; }
264 // Return its child node.
265 // Child node is used only in indirect node, and in expression node
266 // representing slicing an array.
267 Node*
268 child() const
269 { return this->child_; }
271 // Set the child node.
272 void
273 set_child(Node* n)
274 { this->child_ = n; }
276 // Static creation methods for each value supported in the union.
277 static Node*
278 make_node(Named_object*);
280 static Node*
281 make_node(Expression*);
283 static Node*
284 make_node(Statement*);
286 static Node*
287 make_indirect_node(Node*);
289 // Return the maximum of an existing escape encoding E and a new
290 // escape type.
291 static int
292 max_encoding(int e, int etype);
294 // Return a modified encoding for an input parameter that flows into an
295 // output parameter.
296 static int
297 note_inout_flows(int e, int index, Level level);
299 private:
300 // The classification of this Node.
301 Node_classification classification_;
302 // The value union.
303 union
305 // If NODE_OBJECT.
306 Named_object* object_val;
307 // If NODE_EXPRESSION.
308 Expression* expression_val;
309 // If NODE_STATEMENT.
310 Statement* statement_val;
311 } u_;
312 // The node's escape state.
313 Escape_state* state_;
314 // The node's escape encoding.
315 // The encoding:
316 // | Return Encoding: (width - ESCAPE_RETURN_BITS) |
317 // | Content Escapes bit: 1 |
318 // | Escapement_encoding: ESCAPE_BITS |
319 int encoding_;
321 // Child node, used only in indirect node, and expression node representing
322 // slicing an array.
323 Node* child_;
325 // Cache all the Nodes created via Node::make_node to make the API simpler.
326 static std::map<Named_object*, Node*> objects;
327 static std::map<Expression*, Node*> expressions;
328 static std::map<Statement*, Node*> statements;
331 // The amount of bits used for the escapement encoding.
332 static const int ESCAPE_BITS = 3;
334 // Mask used to extract encoding.
335 static const int ESCAPE_MASK = (1 << ESCAPE_BITS) - 1;
337 // Value obtained by indirect of parameter escapes to heap.
338 static const int ESCAPE_CONTENT_ESCAPES = 1 << ESCAPE_BITS;
340 // The amount of bits used in encoding of return values.
341 static const int ESCAPE_RETURN_BITS = ESCAPE_BITS + 1;
343 // For each output, the number of bits for a tag.
344 static const int ESCAPE_BITS_PER_OUTPUT_IN_TAG = 3;
346 // The bit max to extract a single tag.
347 static const int ESCAPE_BITS_MASK_FOR_TAG = (1 << ESCAPE_BITS_PER_OUTPUT_IN_TAG) - 1;
349 // The largest level that can be stored in a tag.
350 static const int ESCAPE_MAX_ENCODED_LEVEL = ESCAPE_BITS_MASK_FOR_TAG - 1;
352 // A helper for converting escape notes from encoded integers to a
353 // textual format and vice-versa.
355 class Escape_note
357 public:
358 // Return the string representation of an escapement encoding.
359 static std::string
360 make_tag(int encoding);
362 // Return the escapement encoding for a string tag.
363 static int
364 parse_tag(std::string* tag);
367 // The escape context for a set of functions being analyzed.
369 class Escape_context
371 public:
372 Escape_context(Gogo* gogo, bool recursive);
374 // Return the Go IR.
375 Gogo*
376 gogo() const
377 { return this->gogo_; }
379 // Return the current function being analyzed.
380 Named_object*
381 current_function() const
382 { return this->current_function_; }
384 // Change the function being analyzed.
385 void
386 set_current_function(Named_object* fn)
387 { this->current_function_ = fn; }
389 // Return the name of the current function.
390 std::string
391 current_function_name() const;
393 // Return true if this is the context for a mutually recursive set of functions.
394 bool
395 recursive() const
396 { return this->recursive_; }
398 // Return the special sink node for this context.
399 Node*
400 sink()
401 { return this->sink_; }
403 // Return the current loop depth.
405 loop_depth() const
406 { return this->loop_depth_; }
408 // Increase the loop depth.
409 void
410 increase_loop_depth()
411 { this->loop_depth_++; }
413 // Decrease the loop depth.
414 void
415 decrease_loop_depth()
416 { this->loop_depth_--; }
418 void
419 set_loop_depth(int depth)
420 { this->loop_depth_ = depth; }
422 // Return the destination nodes encountered in this context.
423 const std::set<Node*>&
424 dsts() const
425 { return this->dsts_; }
427 // Add a destination node.
428 void
429 add_dst(Node* dst)
430 { this->dsts_.insert(dst); }
432 // Return the nodes initially marked as non-escaping before flooding.
433 const std::vector<Node*>&
434 non_escaping_nodes() const
435 { return this->noesc_; }
437 // Initialize the dummy return values for this Node N using the results
438 // in FNTYPE.
439 void
440 init_retvals(Node* n, Function_type* fntype);
442 // Return the indirection of Node N.
443 Node*
444 add_dereference(Node* n);
446 // Keep track of possibly non-escaping node N.
447 void
448 track(Node* n);
451 flood_id() const
452 { return this->flood_id_; }
454 void
455 increase_flood_id()
456 { this->flood_id_++; }
459 pdepth() const
460 { return this->pdepth_; }
462 void
463 increase_pdepth()
464 { this->pdepth_++; }
466 void
467 decrease_pdepth()
468 { this->pdepth_--; }
470 private:
471 // The Go IR.
472 Gogo* gogo_;
473 // The current function being analyzed.
474 Named_object* current_function_;
475 // Return whether this is the context for a recursive function or a group of mutually
476 // recursive functions.
477 bool recursive_;
478 // The sink for this escape context. Nodes whose reference objects created
479 // outside the current function are assigned to the sink as well as nodes that
480 // the analysis loses track of.
481 Node* sink_;
482 // Used to detect nested loop scopes.
483 int loop_depth_;
484 // All the destination nodes considered in this set of analyzed functions.
485 std::set<Node*> dsts_;
486 // All the nodes that were noted as possibly not escaping in this context.
487 std::vector<Node*> noesc_;
488 // An ID given to each dst and the flows discovered through DFS of that dst.
489 // This is used to avoid infinite recursion from nodes that point to each
490 // other within the flooding phase.
491 int flood_id_;
492 // The current level of recursion within a flooded section; used to debug.
493 int pdepth_;
496 #endif // !defined(GO_ESCAPE_H)