* gcc-interface/trans.c (node_has_volatile_full_access) <N_Identifier>:
[official-gcc.git] / gcc / go / gofrontend / escape.cc
blob51e80e446451388f251a4a25679c7828da87e80d
1 // escape.cc -- 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 #include "go-system.h"
9 #include <limits>
10 #include <stack>
11 #include <sstream>
13 #include "gogo.h"
14 #include "types.h"
15 #include "expressions.h"
16 #include "statements.h"
17 #include "escape.h"
18 #include "lex.h"
19 #include "ast-dump.h"
20 #include "go-optimize.h"
21 #include "go-diagnostics.h"
22 #include "go-sha1.h"
24 // class Node.
26 // Return the node's type, if it makes sense for it to have one.
28 Type*
29 Node::type() const
31 if (this->object() != NULL
32 && this->object()->is_variable())
33 return this->object()->var_value()->type();
34 else if (this->object() != NULL
35 && this->object()->is_function())
36 return this->object()->func_value()->type();
37 else if (this->expr() != NULL)
38 return this->expr()->type();
39 else if (this->is_indirect())
41 if (this->child()->type()->deref()->is_void_type())
42 // This is a void*. The referred type can be actually any type,
43 // which may also be pointer. We model it as another void*, so
44 // we don't lose pointer-ness.
45 return this->child()->type();
46 else
47 return this->child()->type()->deref();
49 else if (this->statement() != NULL
50 && this->statement()->temporary_statement() != NULL)
51 return this->statement()->temporary_statement()->type();
52 else
53 return NULL;
56 // A helper for reporting; return this node's location.
58 Location
59 Node::location() const
61 if (this->object() != NULL && !this->object()->is_sink())
62 return this->object()->location();
63 else if (this->expr() != NULL)
64 return this->expr()->location();
65 else if (this->statement() != NULL)
66 return this->statement()->location();
67 else if (this->is_indirect())
68 return this->child()->location();
69 else
70 return Linemap::unknown_location();
73 // A helper for reporting; return the location where the underlying
74 // object is defined.
76 Location
77 Node::definition_location() const
79 if (this->object() != NULL && !this->object()->is_sink())
81 Named_object* no = this->object();
82 if (no->is_variable() || no->is_result_variable())
83 return no->location();
85 else if (this->expr() != NULL)
87 Var_expression* ve = this->expr()->var_expression();
88 if (ve != NULL)
90 Named_object* no = ve->named_object();
91 if (no->is_variable() || no->is_result_variable())
92 return no->location();
94 Enclosed_var_expression* eve = this->expr()->enclosed_var_expression();
95 if (eve != NULL)
97 Named_object* no = eve->variable();
98 if (no->is_variable() || no->is_result_variable())
99 return no->location();
102 return this->location();
105 // To match the cmd/gc debug output, strip away the packed prefixes on functions
106 // and variable/expressions.
108 std::string
109 strip_packed_prefix(Gogo* gogo, const std::string& s)
111 std::string packed_prefix = "." + gogo->pkgpath() + ".";
112 std::string fmt = s;
113 for (size_t pos = fmt.find(packed_prefix);
114 pos != std::string::npos;
115 pos = fmt.find(packed_prefix))
116 fmt.erase(pos, packed_prefix.length());
117 return fmt;
120 // A helper for debugging; return this node's AST formatted string.
121 // This is an implementation of gc's Nconv with obj.FmtShort.
123 std::string
124 Node::ast_format(Gogo* gogo) const
126 std::ostringstream ss;
127 if (this->is_sink())
128 ss << ".sink";
129 else if (this->object() != NULL)
131 Named_object* no = this->object();
132 if (no->is_function() && no->func_value()->enclosing() != NULL)
133 return "func literal";
134 ss << no->message_name();
136 else if (this->expr() != NULL)
138 Expression* e = this->expr();
139 bool is_call = e->call_expression() != NULL;
140 if (is_call)
141 e->call_expression()->fn();
142 Func_expression* fe = e->func_expression();;
144 bool is_closure = fe != NULL && fe->closure() != NULL;
145 if (is_closure)
147 if (is_call)
148 return "(func literal)()";
149 return "func literal";
151 Ast_dump_context::dump_to_stream(this->expr(), &ss);
153 else if (this->statement() != NULL)
155 Statement* s = this->statement();
156 Goto_unnamed_statement* unnamed = s->goto_unnamed_statement();
157 if (unnamed != NULL)
159 Statement* derived = unnamed->unnamed_label()->derived_from();
160 if (derived != NULL)
162 switch (derived->classification())
164 case Statement::STATEMENT_FOR:
165 case Statement::STATEMENT_FOR_RANGE:
166 return "for loop";
167 break;
169 case Statement::STATEMENT_SWITCH:
170 return "switch";
171 break;
173 case Statement::STATEMENT_TYPE_SWITCH:
174 return "type switch";
175 break;
177 default:
178 break;
182 Temporary_statement* tmp = s->temporary_statement();
183 if (tmp != NULL)
185 // Temporary's format can never match gc's output, and
186 // temporaries are inserted differently anyway. We just
187 // print something convenient.
188 ss << "tmp." << (uintptr_t) tmp;
189 if (tmp->init() != NULL)
191 ss << " [ = ";
192 Ast_dump_context::dump_to_stream(tmp->init(), &ss);
193 ss << " ]";
196 else
197 Ast_dump_context::dump_to_stream(s, &ss);
199 else if (this->is_indirect())
200 return "*(" + this->child()->ast_format(gogo) + ")";
202 std::string s = strip_packed_prefix(gogo, ss.str());
204 // trim trailing space
205 return s.substr(0, s.find_last_not_of(' ') + 1);
208 // A helper for debugging; return this node's detailed format string.
209 // This is an implementation of gc's Jconv with obj.FmtShort.
211 std::string
212 Node::details()
214 std::stringstream details;
216 if (!this->is_sink())
217 details << " l(" << Linemap::location_to_line(this->location()) << ")";
219 bool is_varargs = false;
220 bool is_address_taken = false;
221 bool is_in_heap = false;
222 bool is_assigned = false;
223 std::string class_name;
225 Expression* e = this->expr();
226 Named_object* node_object = NULL;
227 if (this->object() != NULL)
228 node_object = this->object();
229 else if (e != NULL && e->var_expression() != NULL)
230 node_object = e->var_expression()->named_object();
232 if (node_object)
234 // TODO(cmang): For named variables and functions, we want to output
235 // the function depth.
236 if (node_object->is_variable())
238 Variable* var = node_object->var_value();
239 is_varargs = var->is_varargs_parameter();
240 is_address_taken = (var->is_address_taken()
241 || var->is_non_escaping_address_taken());
242 is_in_heap = var->is_in_heap();
243 is_assigned = var->init() != NULL;
245 if (var->is_global())
246 class_name = "PEXTERN";
247 else if (var->is_parameter())
248 class_name = "PPARAM";
249 else if (var->is_closure())
250 class_name = "PPARAMREF";
251 else
252 class_name = "PAUTO";
254 else if (node_object->is_result_variable())
255 class_name = "PPARAMOUT";
256 else if (node_object->is_function()
257 || node_object->is_function_declaration())
258 class_name = "PFUNC";
260 else if (e != NULL && e->enclosed_var_expression() != NULL)
262 Named_object* enclosed = e->enclosed_var_expression()->variable();
263 if (enclosed->is_variable())
265 Variable* var = enclosed->var_value();
266 is_address_taken = (var->is_address_taken()
267 || var->is_non_escaping_address_taken());
269 else
271 Result_variable* var = enclosed->result_var_value();
272 is_address_taken = (var->is_address_taken()
273 || var->is_non_escaping_address_taken());
275 class_name = "PPARAMREF";
278 if (!class_name.empty())
280 details << " class(" << class_name;
281 if (is_in_heap)
282 details << ",heap";
283 details << ")";
286 switch ((this->encoding() & ESCAPE_MASK))
288 case Node::ESCAPE_UNKNOWN:
289 break;
291 case Node::ESCAPE_HEAP:
292 details << " esc(h)";
293 break;
295 case Node::ESCAPE_NONE:
296 details << " esc(no)";
297 break;
299 case Node::ESCAPE_NEVER:
300 details << " esc(N)";
301 break;
303 default:
304 details << " esc(" << this->encoding() << ")";
305 break;
308 if (this->state_ != NULL && this->state_->loop_depth != 0)
309 details << " ld(" << this->state_->loop_depth << ")";
311 if (is_varargs)
312 details << " isddd(1)";
313 if (is_address_taken)
314 details << " addrtaken";
315 if (is_assigned)
316 details << " assigned";
318 return details.str();
321 std::string
322 Node::op_format() const
324 std::stringstream op;
325 Ast_dump_context adc(&op, false);
326 if (this->expr() != NULL)
328 Expression* e = this->expr();
329 switch (e->classification())
331 case Expression::EXPRESSION_UNARY:
332 adc.dump_operator(e->unary_expression()->op());
333 break;
335 case Expression::EXPRESSION_BINARY:
336 adc.dump_operator(e->binary_expression()->op());
337 break;
339 case Expression::EXPRESSION_CALL:
340 op << "function call";
341 break;
343 case Expression::EXPRESSION_FUNC_REFERENCE:
344 if (e->func_expression()->is_runtime_function())
346 switch (e->func_expression()->runtime_code())
348 case Runtime::GOPANIC:
349 op << "panic";
350 break;
352 case Runtime::GROWSLICE:
353 op << "append";
354 break;
356 case Runtime::SLICECOPY:
357 case Runtime::SLICESTRINGCOPY:
358 case Runtime::TYPEDSLICECOPY:
359 op << "copy";
360 break;
362 case Runtime::MAKECHAN:
363 case Runtime::MAKECHAN64:
364 case Runtime::MAKEMAP:
365 case Runtime::MAKESLICE:
366 case Runtime::MAKESLICE64:
367 op << "make";
368 break;
370 case Runtime::DEFERPROC:
371 op << "defer";
372 break;
374 case Runtime::GORECOVER:
375 op << "recover";
376 break;
378 case Runtime::CLOSE:
379 op << "close";
380 break;
382 default:
383 break;
386 break;
388 case Expression::EXPRESSION_ALLOCATION:
389 op << "new";
390 break;
392 case Expression::EXPRESSION_RECEIVE:
393 op << "<-";
394 break;
396 default:
397 break;
401 if (this->statement() != NULL)
403 switch (this->statement()->classification())
405 case Statement::STATEMENT_DEFER:
406 op << "defer";
407 break;
409 case Statement::STATEMENT_RETURN:
410 op << "return";
411 break;
413 default:
414 break;
417 if (this->is_indirect())
418 op << "*";
419 return op.str();
422 // Return this node's state, creating it if has not been initialized.
424 Node::Escape_state*
425 Node::state(Escape_context* context, Named_object* fn)
427 if (this->state_ == NULL)
429 if (this->expr() != NULL && this->expr()->var_expression() != NULL)
431 // Tie state of variable references to underlying variables.
432 Named_object* var_no = this->expr()->var_expression()->named_object();
433 Node* var_node = Node::make_node(var_no);
434 this->state_ = var_node->state(context, fn);
436 else
438 this->state_ = new Node::Escape_state;
439 if (fn == NULL)
440 fn = context->current_function();
442 this->state_->fn = fn;
445 go_assert(this->state_ != NULL);
446 return this->state_;
449 Node::~Node()
451 if (this->state_ != NULL)
453 if (this->expr() == NULL || this->expr()->var_expression() == NULL)
454 // Var expression Node is excluded since it shares state with the
455 // underlying var Node.
456 delete this->state_;
461 Node::encoding()
463 if (this->expr() != NULL
464 && this->expr()->var_expression() != NULL)
466 // Get the underlying object's encoding.
467 Named_object* no = this->expr()->var_expression()->named_object();
468 int enc = Node::make_node(no)->encoding();
469 this->encoding_ = enc;
471 return this->encoding_;
474 void
475 Node::set_encoding(int enc)
477 this->encoding_ = enc;
478 if (this->expr() != NULL)
480 if (this->expr()->var_expression() != NULL)
482 // Set underlying object as well.
483 Named_object* no = this->expr()->var_expression()->named_object();
484 Node::make_node(no)->set_encoding(enc);
486 else if (this->expr()->func_expression() != NULL)
488 // Propagate the escape state to the underlying
489 // closure (heap expression).
490 Expression* closure = this->expr()->func_expression()->closure();
491 if (closure != NULL)
492 Node::make_node(closure)->set_encoding(enc);
497 bool
498 Node::is_big(Escape_context* context) const
500 Type* t = this->type();
501 if (t == NULL
502 || t->is_call_multiple_result_type()
503 || t->is_sink_type()
504 || t->is_void_type()
505 || t->is_abstract())
506 return false;
508 int64_t size;
509 bool ok = t->backend_type_size(context->gogo(), &size);
510 bool big = ok && (size < 0 || size > 10 * 1024 * 1024);
512 if (this->expr() != NULL)
514 if (this->expr()->allocation_expression() != NULL)
516 ok = t->deref()->backend_type_size(context->gogo(), &size);
517 big = big || size <= 0 || size >= (1 << 16);
519 else if (this->expr()->call_expression() != NULL)
521 Call_expression* call = this->expr()->call_expression();
522 Func_expression* fn = call->fn()->func_expression();
523 if (fn != NULL
524 && fn->is_runtime_function()
525 && (fn->runtime_code() == Runtime::MAKESLICE
526 || fn->runtime_code() == Runtime::MAKESLICE64))
528 // Second argument is length.
529 Expression_list::iterator p = call->args()->begin();
530 ++p;
532 Expression* e = *p;
533 if (e->temporary_reference_expression() != NULL)
535 Temporary_reference_expression* tre = e->temporary_reference_expression();
536 if (tre->statement() != NULL && tre->statement()->init() != NULL)
537 e = tre->statement()->init();
540 Numeric_constant nc;
541 unsigned long v;
542 if (e->numeric_constant_value(&nc)
543 && nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_VALID)
544 big = big || v >= (1 << 16);
549 return big;
552 bool
553 Node::is_sink() const
555 if (this->object() != NULL
556 && this->object()->is_sink())
557 return true;
558 else if (this->expr() != NULL
559 && this->expr()->is_sink_expression())
560 return true;
561 return false;
564 std::map<Named_object*, Node*> Node::objects;
565 std::map<Expression*, Node*> Node::expressions;
566 std::map<Statement*, Node*> Node::statements;
567 std::vector<Node*> Node::indirects;
569 // Make a object node or return a cached node for this object.
571 Node*
572 Node::make_node(Named_object* no)
574 if (Node::objects.find(no) != Node::objects.end())
575 return Node::objects[no];
577 Node* n = new Node(no);
578 std::pair<Named_object*, Node*> val(no, n);
579 Node::objects.insert(val);
580 return n;
583 // Make an expression node or return a cached node for this expression.
585 Node*
586 Node::make_node(Expression* e)
588 if (Node::expressions.find(e) != Node::expressions.end())
589 return Node::expressions[e];
591 Node* n = new Node(e);
592 std::pair<Expression*, Node*> val(e, n);
593 Node::expressions.insert(val);
594 return n;
597 // Make a statement node or return a cached node for this statement.
599 Node*
600 Node::make_node(Statement* s)
602 if (Node::statements.find(s) != Node::statements.end())
603 return Node::statements[s];
605 Node* n = new Node(s);
606 std::pair<Statement*, Node*> val(s, n);
607 Node::statements.insert(val);
608 return n;
611 // Make an indirect node with given child.
613 Node*
614 Node::make_indirect_node(Node* child)
616 Node* n = new Node(child);
617 Node::indirects.push_back(n);
618 return n;
621 // Returns the maximum of an exisiting escape value
622 // (and its additional parameter flow flags) and a new escape type.
625 Node::max_encoding(int e, int etype)
627 if ((e & ESCAPE_MASK) > etype)
628 return e;
629 if (etype == Node::ESCAPE_NONE || etype == Node::ESCAPE_RETURN)
630 return (e & ~ESCAPE_MASK) | etype;
631 return etype;
634 // Return a modified encoding for an input parameter that flows into an
635 // output parameter.
638 Node::note_inout_flows(int e, int index, Level level)
640 // Flow+level is encoded in two bits.
641 // 00 = not flow, xx = level+1 for 0 <= level <= maxEncodedLevel.
642 // 16 bits for Esc allows 6x2bits or 4x3bits or 3x4bits if additional
643 // information would be useful.
644 if (level.value() <= 0 && level.suffix_value() > 0)
645 return Node::max_encoding(e|ESCAPE_CONTENT_ESCAPES, Node::ESCAPE_NONE);
646 if (level.value() < 0)
647 return Node::ESCAPE_HEAP;
648 if (level.value() > ESCAPE_MAX_ENCODED_LEVEL)
649 level = Level::From(ESCAPE_MAX_ENCODED_LEVEL);
651 int encoded = level.value() + 1;
652 int shift = ESCAPE_BITS_PER_OUTPUT_IN_TAG * index + ESCAPE_RETURN_BITS;
653 int old = (e >> shift) & ESCAPE_BITS_MASK_FOR_TAG;
654 if (old == 0
655 || (encoded != 0 && encoded < old))
656 old = encoded;
658 int encoded_flow = old << shift;
659 if (((encoded_flow >> shift) & ESCAPE_BITS_MASK_FOR_TAG) != old)
661 // Failed to encode. Put this on the heap.
662 return Node::ESCAPE_HEAP;
665 return (e & ~(ESCAPE_BITS_MASK_FOR_TAG << shift)) | encoded_flow;
668 // Class Escape_context.
670 Escape_context::Escape_context(Gogo* gogo, bool recursive)
671 : gogo_(gogo), current_function_(NULL), recursive_(recursive),
672 sink_(Node::make_node(Named_object::make_sink())), loop_depth_(0),
673 flood_id_(0), pdepth_(0)
675 // The sink always escapes to heap and strictly lives outside of the
676 // current function i.e. loop_depth == -1.
677 Node::Escape_state* state = this->sink_->state(this, NULL);
678 state->loop_depth = -1;
681 std::string
682 debug_function_name(Named_object* fn)
684 if (fn == NULL)
685 return "<S>";
687 if (!fn->is_function())
688 return Gogo::unpack_hidden_name(fn->name());
690 std::string fnname = Gogo::unpack_hidden_name(fn->name());
691 if (fn->func_value()->is_method())
693 // Methods in gc compiler are named "T.m" or "(*T).m" where
694 // T is the receiver type. Add the receiver here.
695 Type* rt = fn->func_value()->type()->receiver()->type();
696 switch (rt->classification())
698 case Type::TYPE_NAMED:
699 fnname = rt->named_type()->name() + "." + fnname;
700 break;
702 case Type::TYPE_POINTER:
704 Named_type* nt = rt->points_to()->named_type();
705 if (nt != NULL)
706 fnname = "(*" + nt->name() + ")." + fnname;
707 break;
710 default:
711 break;
715 return fnname;
718 // Return the name of the current function.
720 std::string
721 Escape_context::current_function_name() const
723 return debug_function_name(this->current_function_);
726 // Initialize the dummy return values for this Node N using the results
727 // in FNTYPE.
729 void
730 Escape_context::init_retvals(Node* n, Function_type* fntype)
732 if (fntype == NULL || fntype->results() == NULL)
733 return;
735 Node::Escape_state* state = n->state(this, NULL);
736 state->retvals.clear();
737 Location loc = n->location();
739 int i = 0;
740 char buf[50];
741 for (Typed_identifier_list::const_iterator p = fntype->results()->begin();
742 p != fntype->results()->end();
743 ++p, ++i)
745 snprintf(buf, sizeof buf, ".out%d", i);
746 Variable* dummy_var = new Variable(p->type(), NULL, false, false,
747 false, loc);
748 dummy_var->set_is_used();
749 Named_object* dummy_no =
750 Named_object::make_variable(buf, NULL, dummy_var);
751 Node* dummy_node = Node::make_node(dummy_no);
752 // Initialize the state of the dummy output node.
753 Node::Escape_state* dummy_node_state = dummy_node->state(this, NULL);
754 dummy_node_state->loop_depth = this->loop_depth_;
756 // Add dummy node to the retvals of n.
757 state->retvals.push_back(dummy_node);
762 // Apply an indirection to N and return the result.
764 Node*
765 Escape_context::add_dereference(Node* n)
767 Expression* e = n->expr();
768 Location loc = n->location();
769 Node* ind;
770 if (e != NULL
771 && e->type()->points_to() != NULL
772 && !e->type()->points_to()->is_void_type())
774 // We don't dereference void*, which can be actually any pointer type.
775 Expression* deref_expr = Expression::make_unary(OPERATOR_MULT, e, loc);
776 ind = Node::make_node(deref_expr);
778 else
779 // The gc compiler simply makes an OIND node. We can't do it
780 // for non-pointer type because that will result in a type error.
781 // Instead, we model this by making a node with a special flavor.
782 ind = Node::make_indirect_node(n);
784 // Initialize the state.
785 Node::Escape_state* state = ind->state(this, NULL);
786 state->loop_depth = n->state(this, NULL)->loop_depth;
787 return ind;
790 void
791 Escape_context::track(Node* n)
793 n->set_encoding(Node::ESCAPE_NONE);
794 // Initialize this node's state if it hasn't been encountered
795 // before.
796 Node::Escape_state* state = n->state(this, NULL);
797 state->loop_depth = this->loop_depth_;
799 this->noesc_.push_back(n);
802 // Return the string representation of an escapement encoding.
804 std::string
805 Escape_note::make_tag(int encoding)
807 char buf[50];
808 snprintf(buf, sizeof buf, "esc:0x%x", encoding);
809 return buf;
812 // Return the escapement encoding for a string tag.
815 Escape_note::parse_tag(std::string* tag)
817 if (tag == NULL || tag->substr(0, 4) != "esc:")
818 return Node::ESCAPE_UNKNOWN;
819 int encoding = (int)strtol(tag->substr(4).c_str(), NULL, 0);
820 if (encoding == 0)
821 return Node::ESCAPE_UNKNOWN;
822 return encoding;
826 // The -fgo-optimize-alloc flag activates this escape analysis.
828 Go_optimize optimize_allocation_flag("allocs", true);
830 // A helper function to compute whether a function name has a
831 // matching hash value.
833 static bool
834 escape_hash_match(std::string suffix, std::string name)
836 if (suffix.empty())
837 return true;
838 if (suffix.at(0) == '-')
839 return !escape_hash_match(suffix.substr(1), name);
841 const char* p = name.c_str();
842 Go_sha1_helper* sha1_helper = go_create_sha1_helper();
843 sha1_helper->process_bytes(p, strlen(p));
844 std::string s = sha1_helper->finish();
845 delete sha1_helper;
847 int j = suffix.size() - 1;
848 for (int i = s.size() - 1; i >= 0; i--)
850 char c = s.at(i);
851 for (int k = 0; k < 8; k++, j--, c>>=1)
853 if (j < 0)
854 return true;
855 char bit = suffix.at(j) - '0';
856 if ((c&1) != bit)
857 return false;
860 return false;
863 // Analyze the program flow for escape information.
865 void
866 Gogo::analyze_escape()
868 if (saw_errors())
869 return;
871 if (!optimize_allocation_flag.is_enabled()
872 && !this->compiling_runtime())
873 // We always run escape analysis when compiling runtime.
874 return;
876 // Discover strongly connected groups of functions to analyze for escape
877 // information in this package.
878 this->discover_analysis_sets();
880 if (!this->debug_escape_hash().empty())
881 std::cerr << "debug-escape-hash " << this->debug_escape_hash() << "\n";
883 for (std::vector<Analysis_set>::iterator p = this->analysis_sets_.begin();
884 p != this->analysis_sets_.end();
885 ++p)
887 std::vector<Named_object*> stack = p->first;
889 if (!this->debug_escape_hash().empty())
891 bool match = false;
892 for (std::vector<Named_object*>::const_iterator fn = stack.begin();
893 fn != stack.end();
894 ++fn)
895 match = match || escape_hash_match(this->debug_escape_hash(), (*fn)->message_name());
896 if (!match)
898 // Escape analysis won't run on these functions, but still
899 // need to tag them, so the caller knows.
900 for (std::vector<Named_object*>::iterator fn = stack.begin();
901 fn != stack.end();
902 ++fn)
903 if ((*fn)->is_function())
905 Function_type* fntype = (*fn)->func_value()->type();
906 fntype->set_is_tagged();
908 std::cerr << "debug-escape-hash disables " << debug_function_name(*fn) << "\n";
911 continue;
913 for (std::vector<Named_object*>::const_iterator fn = stack.begin();
914 fn != stack.end();
915 ++fn)
916 if ((*fn)->is_function())
917 std::cerr << "debug-escape-hash triggers " << debug_function_name(*fn) << "\n";
920 Escape_context* context = new Escape_context(this, p->second);
922 // Analyze the flow of each function; build the connection graph.
923 // This is the assign phase.
924 for (std::vector<Named_object*>::reverse_iterator fn = stack.rbegin();
925 fn != stack.rend();
926 ++fn)
928 context->set_current_function(*fn);
929 this->assign_connectivity(context, *fn);
932 // Propagate levels across each dst. This is the flood phase.
933 std::set<Node*> dsts = context->dsts();
934 Unordered_map(Node*, int) escapes;
935 for (std::set<Node*>::iterator n = dsts.begin();
936 n != dsts.end();
937 ++n)
939 escapes[*n] = (*n)->encoding();
940 this->propagate_escape(context, *n);
942 for (;;)
944 // Reflood if the roots' escape states increase. Run until fix point.
945 // This is rare.
946 bool done = true;
947 for (std::set<Node*>::iterator n = dsts.begin();
948 n != dsts.end();
949 ++n)
951 if ((*n)->object() == NULL
952 && ((*n)->expr() == NULL
953 || ((*n)->expr()->var_expression() == NULL
954 && (*n)->expr()->enclosed_var_expression() == NULL
955 && (*n)->expr()->func_expression() == NULL)))
956 continue;
957 if (escapes[*n] != (*n)->encoding())
959 done = false;
960 if (this->debug_escape_level() > 2)
961 go_inform((*n)->location(), "Reflooding %s %s",
962 debug_function_name((*n)->state(context, NULL)->fn).c_str(),
963 (*n)->ast_format(this).c_str());
964 escapes[*n] = (*n)->encoding();
965 this->propagate_escape(context, *n);
968 if (done)
969 break;
972 // Tag each exported function's parameters with escape information.
973 for (std::vector<Named_object*>::iterator fn = stack.begin();
974 fn != stack.end();
975 ++fn)
976 this->tag_function(context, *fn);
978 if (this->debug_escape_level() != 0)
980 std::vector<Node*> noesc = context->non_escaping_nodes();
981 for (std::vector<Node*>::const_iterator n = noesc.begin();
982 n != noesc.end();
983 ++n)
985 Node::Escape_state* state = (*n)->state(context, NULL);
986 if ((*n)->encoding() == Node::ESCAPE_NONE)
987 go_inform((*n)->location(), "%s %s does not escape",
988 strip_packed_prefix(this, debug_function_name(state->fn)).c_str(),
989 (*n)->ast_format(this).c_str());
992 delete context;
996 // Traverse the program, discovering the functions that are roots of strongly
997 // connected components. The goal of this phase to produce a set of functions
998 // that must be analyzed in order.
1000 class Escape_analysis_discover : public Traverse
1002 public:
1003 Escape_analysis_discover(Gogo* gogo)
1004 : Traverse(traverse_functions | traverse_func_declarations),
1005 gogo_(gogo), component_ids_()
1009 function(Named_object*);
1012 function_declaration(Named_object*);
1015 visit(Named_object*);
1018 visit_code(Named_object*, int);
1020 private:
1021 // A counter used to generate the ID for the function node in the graph.
1022 static int id;
1024 // Type used to map functions to an ID in a graph of connected components.
1025 typedef Unordered_map(Named_object*, int) Component_ids;
1027 // The Go IR.
1028 Gogo* gogo_;
1029 // The list of functions encountered during connected component discovery.
1030 Component_ids component_ids_;
1031 // The stack of functions that this component consists of.
1032 std::stack<Named_object*> stack_;
1035 int Escape_analysis_discover::id = 0;
1037 // Visit each function.
1040 Escape_analysis_discover::function(Named_object* fn)
1042 this->visit(fn);
1043 return TRAVERSE_CONTINUE;
1047 Escape_analysis_discover::function_declaration(Named_object* fn)
1049 this->visit(fn);
1050 return TRAVERSE_CONTINUE;
1053 // Visit a function FN, adding it to the current stack of functions
1054 // in this connected component. If this is the root of the component,
1055 // create a set of functions to be analyzed later.
1057 // Finding these sets is finding strongly connected components
1058 // in the static call graph. The algorithm for doing that is taken
1059 // from Sedgewick, Algorithms, Second Edition, p. 482, with two
1060 // adaptations.
1062 // First, a closure (fn->func_value()->enclosing() == NULL) cannot be the
1063 // root of a connected component. Refusing to use it as a root
1064 // forces it into the component of the function in which it appears.
1065 // This is more convenient for escape analysis.
1067 // Second, each function becomes two virtual nodes in the graph,
1068 // with numbers n and n+1. We record the function's node number as n
1069 // but search from node n+1. If the search tells us that the component
1070 // number (min) is n+1, we know that this is a trivial component: one function
1071 // plus its closures. If the search tells us that the component number is
1072 // n, then there was a path from node n+1 back to node n, meaning that
1073 // the function set is mutually recursive. The escape analysis can be
1074 // more precise when analyzing a single non-recursive function than
1075 // when analyzing a set of mutually recursive functions.
1078 Escape_analysis_discover::visit(Named_object* fn)
1080 Component_ids::const_iterator p = this->component_ids_.find(fn);
1081 if (p != this->component_ids_.end())
1082 // Already visited.
1083 return p->second;
1085 this->id++;
1086 int id = this->id;
1087 this->component_ids_[fn] = id;
1088 this->id++;
1089 int min = this->id;
1091 this->stack_.push(fn);
1092 min = this->visit_code(fn, min);
1093 if ((min == id || min == id + 1)
1094 && ((fn->is_function() && fn->func_value()->enclosing() == NULL)
1095 || fn->is_function_declaration()))
1097 bool recursive = min == id;
1098 std::vector<Named_object*> group;
1100 for (; !this->stack_.empty(); this->stack_.pop())
1102 Named_object* n = this->stack_.top();
1103 if (n == fn)
1105 this->stack_.pop();
1106 break;
1109 group.push_back(n);
1110 this->component_ids_[n] = std::numeric_limits<int>::max();
1112 group.push_back(fn);
1113 this->component_ids_[fn] = std::numeric_limits<int>::max();
1115 std::reverse(group.begin(), group.end());
1116 this->gogo_->add_analysis_set(group, recursive);
1119 return min;
1122 // Helper class for discovery step. Traverse expressions looking for
1123 // function calls and closures to visit during the discovery step.
1125 class Escape_discover_expr : public Traverse
1127 public:
1128 Escape_discover_expr(Escape_analysis_discover* ead, int min)
1129 : Traverse(traverse_expressions),
1130 ead_(ead), min_(min)
1134 min()
1135 { return this->min_; }
1138 expression(Expression** pexpr);
1140 private:
1141 // The original discovery analysis.
1142 Escape_analysis_discover* ead_;
1143 // The minimum component ID in this group.
1144 int min_;
1147 // Visit any calls or closures found when discovering expressions.
1150 Escape_discover_expr::expression(Expression** pexpr)
1152 Expression* e = *pexpr;
1153 Named_object* fn = NULL;
1154 if (e->call_expression() != NULL
1155 && e->call_expression()->fn()->func_expression() != NULL)
1157 // Method call or function call.
1158 fn = e->call_expression()->fn()->func_expression()->named_object();
1160 else if (e->func_expression() != NULL
1161 && e->func_expression()->closure() != NULL)
1163 // Closure.
1164 fn = e->func_expression()->named_object();
1167 if (fn != NULL)
1168 this->min_ = std::min(this->min_, this->ead_->visit(fn));
1169 return TRAVERSE_CONTINUE;
1172 // Visit the body of each function, returns ID of the minimum connected
1173 // component found in the body.
1176 Escape_analysis_discover::visit_code(Named_object* fn, int min)
1178 if (!fn->is_function())
1179 return min;
1181 Escape_discover_expr ede(this, min);
1182 fn->func_value()->traverse(&ede);
1183 return ede.min();
1186 // Discover strongly connected groups of functions to analyze.
1188 void
1189 Gogo::discover_analysis_sets()
1191 Escape_analysis_discover ead(this);
1192 this->traverse(&ead);
1195 // Traverse all label and goto statements and mark the underlying label
1196 // as looping or not looping.
1198 class Escape_analysis_loop : public Traverse
1200 public:
1201 Escape_analysis_loop()
1202 : Traverse(traverse_statements)
1206 statement(Block*, size_t*, Statement*);
1210 Escape_analysis_loop::statement(Block*, size_t*, Statement* s)
1212 if (s->label_statement() != NULL)
1213 s->label_statement()->label()->set_nonlooping();
1214 else if (s->goto_statement() != NULL)
1216 if (s->goto_statement()->label()->nonlooping())
1217 s->goto_statement()->label()->set_looping();
1219 return TRAVERSE_CONTINUE;
1222 // Traversal class used to look at all interesting statements within a function
1223 // in order to build a connectivity graph between all nodes within a context's
1224 // scope.
1226 class Escape_analysis_assign : public Traverse
1228 public:
1229 Escape_analysis_assign(Escape_context* context, Named_object* fn)
1230 : Traverse(traverse_statements
1231 | traverse_expressions),
1232 context_(context), fn_(fn)
1235 // Model statements within a function as assignments and flows between nodes.
1237 statement(Block*, size_t*, Statement*);
1239 // Model expressions within a function as assignments and flows between nodes.
1241 expression(Expression**);
1243 // Model calls within a function as assignments and flows between arguments
1244 // and results.
1245 void
1246 call(Call_expression* call);
1248 // Model the assignment of DST to SRC.
1249 void
1250 assign(Node* dst, Node* src);
1252 // Model the assignment of DST to dereference of SRC.
1253 void
1254 assign_deref(Node* dst, Node* src);
1256 // Model the input-to-output assignment flow of one of a function call's
1257 // arguments, where the flow is encoding in NOTE.
1259 assign_from_note(std::string* note, const std::vector<Node*>& dsts,
1260 Node* src);
1262 // Record the flow of SRC to DST in DST.
1263 void
1264 flows(Node* dst, Node* src);
1266 private:
1267 // The escape context for this set of functions.
1268 Escape_context* context_;
1269 // The current function being analyzed.
1270 Named_object* fn_;
1273 // Helper function to detect self assignment like the following.
1275 // func (b *Buffer) Foo() {
1276 // n, m := ...
1277 // b.buf = b.buf[n:m]
1278 // }
1280 static bool
1281 is_self_assignment(Expression* lhs, Expression* rhs)
1283 Unary_expression* lue =
1284 (lhs->field_reference_expression() != NULL
1285 ? lhs->field_reference_expression()->expr()->unary_expression()
1286 : lhs->unary_expression());
1287 Var_expression* lve =
1288 (lue != NULL && lue->op() == OPERATOR_MULT ? lue->operand()->var_expression() : NULL);
1289 Array_index_expression* raie = rhs->array_index_expression();
1290 String_index_expression* rsie = rhs->string_index_expression();
1291 Expression* rarray =
1292 (raie != NULL && raie->end() != NULL && raie->array()->type()->is_slice_type()
1293 ? raie->array()
1294 : (rsie != NULL && rsie->type()->is_string_type() ? rsie->string() : NULL));
1295 Unary_expression* rue =
1296 (rarray != NULL && rarray->field_reference_expression() != NULL
1297 ? rarray->field_reference_expression()->expr()->unary_expression()
1298 : (rarray != NULL ? rarray->unary_expression() : NULL));
1299 Var_expression* rve =
1300 (rue != NULL && rue->op() == OPERATOR_MULT ? rue->operand()->var_expression() : NULL);
1301 return lve != NULL && rve != NULL
1302 && lve->named_object() == rve->named_object();
1305 // Model statements within a function as assignments and flows between nodes.
1308 Escape_analysis_assign::statement(Block*, size_t*, Statement* s)
1310 // Adjust the loop depth as we enter/exit blocks related to for statements.
1311 bool is_for_statement = (s->is_block_statement()
1312 && s->block_statement()->is_lowered_for_statement());
1313 if (is_for_statement)
1314 this->context_->increase_loop_depth();
1316 s->traverse_contents(this);
1318 if (is_for_statement)
1319 this->context_->decrease_loop_depth();
1321 Gogo* gogo = this->context_->gogo();
1322 int debug_level = gogo->debug_escape_level();
1323 if (debug_level > 1
1324 && s->unnamed_label_statement() == NULL
1325 && s->expression_statement() == NULL
1326 && !s->is_block_statement())
1328 Node* n = Node::make_node(s);
1329 std::string fn_name = this->context_->current_function_name();
1330 go_inform(s->location(), "[%d] %s esc: %s",
1331 this->context_->loop_depth(), fn_name.c_str(),
1332 n->ast_format(gogo).c_str());
1335 switch (s->classification())
1337 case Statement::STATEMENT_VARIABLE_DECLARATION:
1339 Named_object* var = s->variable_declaration_statement()->var();
1340 Node* var_node = Node::make_node(var);
1341 Node::Escape_state* state = var_node->state(this->context_, NULL);
1342 state->loop_depth = this->context_->loop_depth();
1344 // Set the loop depth for this declaration.
1345 if (var->is_variable()
1346 && var->var_value()->init() != NULL)
1348 Node* init_node = Node::make_node(var->var_value()->init());
1349 this->assign(var_node, init_node);
1352 break;
1354 case Statement::STATEMENT_TEMPORARY:
1356 Expression* init = s->temporary_statement()->init();
1357 if (init != NULL)
1358 this->assign(Node::make_node(s), Node::make_node(init));
1360 break;
1362 case Statement::STATEMENT_LABEL:
1364 Label_statement* label_stmt = s->label_statement();
1365 if (label_stmt->label()->looping())
1366 this->context_->increase_loop_depth();
1368 if (debug_level > 1)
1370 std::string label_type = (label_stmt->label()->looping()
1371 ? "looping"
1372 : "nonlooping");
1373 go_inform(s->location(), "%s %s label",
1374 label_stmt->label()->name().c_str(),
1375 label_type.c_str());
1378 break;
1380 case Statement::STATEMENT_SWITCH:
1381 case Statement::STATEMENT_TYPE_SWITCH:
1382 // Want to model the assignment of each case variable to the switched upon
1383 // variable. This should be lowered into assignment statements; nothing
1384 // to here if that's the case.
1385 break;
1387 case Statement::STATEMENT_ASSIGNMENT:
1389 Assignment_statement* assn = s->assignment_statement();
1390 Expression* lhs = assn->lhs();
1391 Expression* rhs = assn->rhs();
1392 Node* lhs_node = Node::make_node(lhs);
1393 Node* rhs_node = Node::make_node(rhs);
1395 // Filter out the following special case.
1397 // func (b *Buffer) Foo() {
1398 // n, m := ...
1399 // b.buf = b.buf[n:m]
1400 // }
1402 // This assignment is a no-op for escape analysis,
1403 // it does not store any new pointers into b that were not already there.
1404 // However, without this special case b will escape.
1405 if (is_self_assignment(lhs, rhs))
1407 if (debug_level != 0)
1408 go_inform(s->location(), "%s ignoring self-assignment to %s",
1409 strip_packed_prefix(gogo, this->context_->current_function_name()).c_str(),
1410 lhs_node->ast_format(gogo).c_str());
1411 break;
1414 this->assign(lhs_node, rhs_node);
1416 break;
1418 case Statement::STATEMENT_SEND:
1420 Node* sent_node = Node::make_node(s->send_statement()->val());
1421 this->assign(this->context_->sink(), sent_node);
1423 break;
1425 case Statement::STATEMENT_DEFER:
1426 if (this->context_->loop_depth() == 1)
1428 // Defer statement may need to allocate a thunk. When it is
1429 // not inside a loop, this can be stack allocated, as it
1430 // runs before the function finishes.
1431 Node* n = Node::make_node(s);
1432 n->set_encoding(Node::ESCAPE_NONE);
1433 break;
1435 // fallthrough
1437 case Statement::STATEMENT_GO:
1439 // Defer f(x) or go f(x).
1440 // Both f and x escape to the heap.
1441 Thunk_statement* thunk = s->thunk_statement();
1442 if (thunk->call()->call_expression() == NULL)
1443 break;
1445 Call_expression* call = thunk->call()->call_expression();
1446 Node* func_node = Node::make_node(call->fn());
1447 this->assign(this->context_->sink(), func_node);
1448 if (call->args() != NULL)
1450 for (Expression_list::const_iterator p = call->args()->begin();
1451 p != call->args()->end();
1452 ++p)
1454 Node* arg_node = Node::make_node(*p);
1455 this->assign(this->context_->sink(), arg_node);
1459 break;
1461 default:
1462 break;
1464 return TRAVERSE_SKIP_COMPONENTS;
1467 // Helper function to emit moved-to-heap diagnostics.
1469 static void
1470 move_to_heap(Gogo* gogo, Expression *expr)
1472 Named_object* no;
1473 if (expr->var_expression() != NULL)
1474 no = expr->var_expression()->named_object();
1475 else if (expr->enclosed_var_expression() != NULL)
1476 no = expr->enclosed_var_expression()->variable();
1477 else
1478 return;
1480 if ((no->is_variable()
1481 && !no->var_value()->is_global())
1482 || no->is_result_variable())
1484 Node* n = Node::make_node(expr);
1485 if (gogo->debug_escape_level() != 0)
1486 go_inform(n->definition_location(),
1487 "moved to heap: %s",
1488 n->ast_format(gogo).c_str());
1489 if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
1490 go_error_at(expr->location(),
1491 "%s escapes to heap, not allowed in runtime",
1492 n->ast_format(gogo).c_str());
1496 // Model expressions within a function as assignments and flows between nodes.
1499 Escape_analysis_assign::expression(Expression** pexpr)
1501 Gogo* gogo = this->context_->gogo();
1502 int debug_level = gogo->debug_escape_level();
1504 // Big stuff escapes unconditionally.
1505 Node* n = Node::make_node(*pexpr);
1506 if ((n->encoding() & ESCAPE_MASK) != int(Node::ESCAPE_HEAP)
1507 && n->is_big(this->context_))
1509 if (debug_level > 1)
1510 go_inform((*pexpr)->location(), "%s too large for stack",
1511 n->ast_format(gogo).c_str());
1512 move_to_heap(gogo, *pexpr);
1513 n->set_encoding(Node::ESCAPE_HEAP);
1514 (*pexpr)->address_taken(true);
1515 this->assign(this->context_->sink(), n);
1518 if ((*pexpr)->func_expression() == NULL)
1519 (*pexpr)->traverse_subexpressions(this);
1521 if (debug_level > 1)
1523 Node* n = Node::make_node(*pexpr);
1524 std::string fn_name = this->context_->current_function_name();
1525 go_inform((*pexpr)->location(), "[%d] %s esc: %s",
1526 this->context_->loop_depth(), fn_name.c_str(),
1527 n->ast_format(gogo).c_str());
1530 switch ((*pexpr)->classification())
1532 case Expression::EXPRESSION_CALL:
1534 Call_expression* call = (*pexpr)->call_expression();
1535 if (call->is_builtin())
1537 Builtin_call_expression* bce = call->builtin_call_expression();
1538 switch (bce->code())
1540 case Builtin_call_expression::BUILTIN_PANIC:
1542 // Argument could leak through recover.
1543 Node* panic_arg = Node::make_node(call->args()->front());
1544 this->assign(this->context_->sink(), panic_arg);
1546 break;
1548 case Builtin_call_expression::BUILTIN_APPEND:
1550 // The contents being appended leak.
1551 if (call->is_varargs())
1553 // append(slice1, slice2...) -- slice2 itself does not escape, but contents do
1554 Node* appended = Node::make_node(call->args()->back());
1555 this->assign_deref(this->context_->sink(), appended);
1556 if (debug_level > 2)
1557 go_inform((*pexpr)->location(),
1558 "special treatment of append(slice1, slice2...)");
1560 else
1562 for (Expression_list::const_iterator pa =
1563 call->args()->begin() + 1;
1564 pa != call->args()->end();
1565 ++pa)
1567 Node* arg = Node::make_node(*pa);
1568 this->assign(this->context_->sink(), arg);
1572 // The content of the original slice leaks as well.
1573 Node* appendee = Node::make_node(call->args()->front());
1574 this->assign_deref(this->context_->sink(), appendee);
1576 break;
1578 case Builtin_call_expression::BUILTIN_COPY:
1580 // Lose track of the copied content.
1581 Node* copied = Node::make_node(call->args()->back());
1582 this->assign_deref(this->context_->sink(), copied);
1584 break;
1586 default:
1587 break;
1589 break;
1591 Func_expression* fe = call->fn()->func_expression();
1592 if (fe != NULL && fe->is_runtime_function())
1594 switch (fe->runtime_code())
1596 case Runtime::MAKECHAN:
1597 case Runtime::MAKECHAN64:
1598 case Runtime::MAKEMAP:
1599 case Runtime::MAKESLICE:
1600 case Runtime::MAKESLICE64:
1601 this->context_->track(n);
1602 break;
1604 case Runtime::MAPASSIGN:
1606 // Map key escapes. The last argument is the address
1607 // of the key.
1608 Node* key_node = Node::make_node(call->args()->back());
1609 this->assign_deref(this->context_->sink(), key_node);
1611 break;
1613 case Runtime::SELECTSEND:
1615 // Send to a channel, lose track. The last argument is
1616 // the address of the value to send.
1617 Node* arg_node = Node::make_node(call->args()->back());
1618 this->assign_deref(this->context_->sink(), arg_node);
1620 break;
1622 case Runtime::IFACEE2T2:
1623 case Runtime::IFACEI2T2:
1625 // x, ok = v.(T), where T is non-pointer non-interface,
1626 // is lowered to
1627 // ok = IFACEI2T2(type, v, (void*)&tmp_x)
1628 // Here v flows to tmp_x.
1629 // Note: other IFACEX2Y2 returns the conversion result.
1630 // Those are handled in ::assign.
1631 Node* src_node = Node::make_node(call->args()->at(1));
1632 Node* dst_node;
1633 Expression* arg2 = call->args()->at(2);
1634 // Try to pull tmp_x out of the arg2 expression, and let v
1635 // flows into it, instead of simply dereference arg2,
1636 // which looks like dereference of an arbitrary pointer
1637 // and causes v immediately escape.
1638 // The expression form matches statement.cc,
1639 // Tuple_type_guard_assignment_statement::lower_to_object_type.
1640 Unary_expression* ue =
1641 (arg2->conversion_expression() != NULL
1642 ? arg2->conversion_expression()->expr()->unary_expression()
1643 : arg2->unary_expression());
1644 if (ue != NULL && ue->op() == OPERATOR_AND)
1646 if (!ue->operand()->type()->has_pointer())
1647 // Don't bother flowing non-pointer.
1648 break;
1649 dst_node = Node::make_node(ue->operand());
1651 else
1652 dst_node = this->context_->add_dereference(Node::make_node(arg2));
1653 this->assign(dst_node, src_node);
1655 break;
1657 default:
1658 break;
1661 else
1662 this->call(call);
1664 break;
1666 case Expression::EXPRESSION_ALLOCATION:
1667 // This is Runtime::NEW.
1668 this->context_->track(n);
1669 break;
1671 case Expression::EXPRESSION_STRING_CONCAT:
1672 this->context_->track(n);
1673 break;
1675 case Expression::EXPRESSION_CONVERSION:
1677 Type_conversion_expression* tce = (*pexpr)->conversion_expression();
1678 Type* ft = tce->expr()->type();
1679 Type* tt = tce->type();
1680 if ((ft->is_string_type() && tt->is_slice_type())
1681 || (ft->is_slice_type() && tt->is_string_type())
1682 || (ft->integer_type() != NULL && tt->is_string_type()))
1684 // string([]byte), string([]rune), []byte(string), []rune(string), string(rune)
1685 this->context_->track(n);
1686 break;
1688 Node* tce_node = Node::make_node(tce);
1689 Node* converted = Node::make_node(tce->expr());
1690 this->context_->track(tce_node);
1692 this->assign(tce_node, converted);
1694 break;
1696 case Expression::EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
1697 case Expression::EXPRESSION_SLICE_CONSTRUCTION:
1699 Node* array_node = Node::make_node(*pexpr);
1700 if ((*pexpr)->slice_literal() != NULL)
1701 this->context_->track(array_node);
1703 Expression_list* vals = ((*pexpr)->slice_literal() != NULL
1704 ? (*pexpr)->slice_literal()->vals()
1705 : (*pexpr)->array_literal()->vals());
1707 if (vals != NULL)
1709 // Connect the array to its values.
1710 for (Expression_list::const_iterator p = vals->begin();
1711 p != vals->end();
1712 ++p)
1713 if ((*p) != NULL)
1714 this->assign(array_node, Node::make_node(*p));
1717 break;
1719 case Expression::EXPRESSION_STRUCT_CONSTRUCTION:
1721 Node* struct_node = Node::make_node(*pexpr);
1722 Expression_list* vals = (*pexpr)->struct_literal()->vals();
1723 if (vals != NULL)
1725 // Connect the struct to its values.
1726 for (Expression_list::const_iterator p = vals->begin();
1727 p != vals->end();
1728 ++p)
1730 if ((*p) != NULL)
1731 this->assign(struct_node, Node::make_node(*p));
1735 break;
1737 case Expression::EXPRESSION_HEAP:
1739 Node* pointer_node = Node::make_node(*pexpr);
1740 Node* lit_node = Node::make_node((*pexpr)->heap_expression()->expr());
1741 this->context_->track(pointer_node);
1743 // Connect pointer node to literal node; if the pointer node escapes, so
1744 // does the literal node.
1745 this->assign(pointer_node, lit_node);
1747 break;
1749 case Expression::EXPRESSION_BOUND_METHOD:
1751 Node* bound_node = Node::make_node(*pexpr);
1752 this->context_->track(bound_node);
1754 Expression* obj = (*pexpr)->bound_method_expression()->first_argument();
1755 Node* obj_node = Node::make_node(obj);
1757 // A bound method implies the receiver will be used outside of the
1758 // lifetime of the method in some way. We lose track of the receiver.
1759 this->assign(this->context_->sink(), obj_node);
1761 break;
1763 case Expression::EXPRESSION_MAP_CONSTRUCTION:
1765 Map_construction_expression* mce = (*pexpr)->map_literal();
1766 Node* map_node = Node::make_node(mce);
1767 this->context_->track(map_node);
1769 // All keys and values escape to memory.
1770 if (mce->vals() != NULL)
1772 for (Expression_list::const_iterator p = mce->vals()->begin();
1773 p != mce->vals()->end();
1774 ++p)
1776 if ((*p) != NULL)
1777 this->assign(this->context_->sink(), Node::make_node(*p));
1781 break;
1783 case Expression::EXPRESSION_FUNC_REFERENCE:
1785 Func_expression* fe = (*pexpr)->func_expression();
1786 if (fe->closure() != NULL)
1788 // Connect captured variables to the closure.
1789 Node* closure_node = Node::make_node(fe);
1790 this->context_->track(closure_node);
1792 // A closure expression already exists as the heap expression:
1793 // &struct{f func_code, v []*Variable}{...}.
1794 // Link closure to the addresses of the variables enclosed.
1795 Heap_expression* he = fe->closure()->heap_expression();
1796 Struct_construction_expression* sce = he->expr()->struct_literal();
1798 // First field is function code, other fields are variable
1799 // references.
1800 Expression_list::const_iterator p = sce->vals()->begin();
1801 ++p;
1802 for (; p != sce->vals()->end(); ++p)
1804 Node* enclosed_node = Node::make_node(*p);
1805 this->context_->track(enclosed_node);
1806 this->assign(closure_node, enclosed_node);
1810 break;
1812 case Expression::EXPRESSION_UNARY:
1814 if ((*pexpr)->unary_expression()->op() != OPERATOR_AND)
1815 break;
1817 Node* addr_node = Node::make_node(*pexpr);
1818 this->context_->track(addr_node);
1820 Expression* operand = (*pexpr)->unary_expression()->operand();
1821 Named_object* var = NULL;
1822 if (operand->var_expression() != NULL)
1823 var = operand->var_expression()->named_object();
1824 else if (operand->enclosed_var_expression() != NULL)
1825 var = operand->enclosed_var_expression()->variable();
1827 if (var == NULL)
1828 break;
1830 if (var->is_variable()
1831 && !var->var_value()->is_parameter())
1833 // For &x, use the loop depth of x if known.
1834 Node::Escape_state* addr_state =
1835 addr_node->state(this->context_, NULL);
1836 Node* operand_node = Node::make_node(operand);
1837 Node::Escape_state* operand_state =
1838 operand_node->state(this->context_, NULL);
1839 if (operand_state->loop_depth != 0)
1840 addr_state->loop_depth = operand_state->loop_depth;
1842 else if ((var->is_variable()
1843 && var->var_value()->is_parameter())
1844 || var->is_result_variable())
1846 Node::Escape_state* addr_state =
1847 addr_node->state(this->context_, NULL);
1848 addr_state->loop_depth = 1;
1851 break;
1853 case Expression::EXPRESSION_ARRAY_INDEX:
1855 Array_index_expression* aie = (*pexpr)->array_index_expression();
1856 if (aie->end() != NULL && !aie->array()->type()->is_slice_type())
1858 // Slicing an array.
1859 Expression* addr = Expression::make_unary(OPERATOR_AND, aie->array(),
1860 aie->location());
1861 Node* addr_node = Node::make_node(addr);
1862 n->set_child(addr_node);
1863 this->context_->track(addr_node);
1866 break;
1868 default:
1869 break;
1871 return TRAVERSE_SKIP_COMPONENTS;
1874 // Model calls within a function as assignments and flows between arguments
1875 // and results.
1877 void
1878 Escape_analysis_assign::call(Call_expression* call)
1880 Gogo* gogo = this->context_->gogo();
1881 int debug_level = gogo->debug_escape_level();
1883 Func_expression* fn = call->fn()->func_expression();
1884 Function_type* fntype = call->get_function_type();
1885 bool indirect = false;
1887 // Interface method calls or closure calls are indirect calls.
1888 if (fntype == NULL
1889 || (fntype->is_method()
1890 && fntype->receiver()->type()->interface_type() != NULL)
1891 || fn == NULL
1892 || (fn->named_object()->is_function()
1893 && fn->named_object()->func_value()->enclosing() != NULL))
1894 indirect = true;
1896 Node* call_node = Node::make_node(call);
1897 std::vector<Node*> arg_nodes;
1898 if (call->fn()->interface_field_reference_expression() != NULL)
1900 Interface_field_reference_expression* ifre =
1901 call->fn()->interface_field_reference_expression();
1902 Node* field_node = Node::make_node(ifre->expr());
1903 arg_nodes.push_back(field_node);
1906 if (call->args() != NULL)
1908 for (Expression_list::const_iterator p = call->args()->begin();
1909 p != call->args()->end();
1910 ++p)
1911 arg_nodes.push_back(Node::make_node(*p));
1914 if (indirect)
1916 // We don't know what happens to the parameters through indirect calls.
1917 // Be conservative and assume they all flow to theSink.
1918 for (std::vector<Node*>::iterator p = arg_nodes.begin();
1919 p != arg_nodes.end();
1920 ++p)
1922 if (debug_level > 2)
1923 go_inform(call->location(),
1924 "esccall:: indirect call <- %s, untracked",
1925 (*p)->ast_format(gogo).c_str());
1926 this->assign(this->context_->sink(), *p);
1929 this->context_->init_retvals(call_node, fntype);
1931 // It could be a closure call that returns captured variable.
1932 // Model this by flowing the func expression to result.
1933 // See issue #14409.
1934 Node* fn_node = Node::make_node(call->fn());
1935 std::vector<Node*> retvals = call_node->state(this->context_, NULL)->retvals;
1936 for (std::vector<Node*>::const_iterator p = retvals.begin();
1937 p != retvals.end();
1938 ++p)
1939 this->assign_deref(*p, fn_node);
1941 return;
1944 // If FN is an untagged function.
1945 if (fn != NULL
1946 && fn->named_object()->is_function()
1947 && !fntype->is_tagged())
1949 if (debug_level > 2)
1950 go_inform(call->location(), "esccall:: %s in recursive group",
1951 call_node->ast_format(gogo).c_str());
1953 Function* f = fn->named_object()->func_value();
1954 const Bindings* callee_bindings = f->block()->bindings();
1955 Function::Results* results = f->result_variables();
1956 if (results != NULL)
1958 // Setup output list on this call node.
1959 Node::Escape_state* state = call_node->state(this->context_, NULL);
1960 for (Function::Results::const_iterator p1 = results->begin();
1961 p1 != results->end();
1962 ++p1)
1964 Node* result_node = Node::make_node(*p1);
1965 state->retvals.push_back(result_node);
1969 std::vector<Node*>::iterator p = arg_nodes.begin();
1970 if (fntype->is_method())
1972 std::string rcvr_name = fntype->receiver()->name();
1973 if (rcvr_name.empty() || Gogo::is_sink_name(rcvr_name)
1974 || !fntype->receiver()->type()->has_pointer())
1976 else
1978 Named_object* rcvr_no =
1979 callee_bindings->lookup_local(fntype->receiver()->name());
1980 go_assert(rcvr_no != NULL);
1981 Node* rcvr_node = Node::make_node(rcvr_no);
1982 if (fntype->receiver()->type()->points_to() == NULL
1983 && (*p)->expr()->type()->points_to() != NULL)
1984 // This is a call to a value method that has been lowered into a call
1985 // to a pointer method. Gccgo generates a pointer method for all
1986 // method calls and takes the address of the value passed as the
1987 // receiver then immediately dereferences it within the function.
1988 // In this case, the receiver address does not escape; its content
1989 // flows to the call.
1990 this->assign_deref(rcvr_node, *p);
1991 else
1992 this->assign(rcvr_node, *p);
1994 ++p;
1997 const Typed_identifier_list* til = fntype->parameters();
1998 if (til != NULL)
2000 for (Typed_identifier_list::const_iterator p1 = til->begin();
2001 p1 != til->end();
2002 ++p1, ++p)
2004 if (p1->name().empty() || Gogo::is_sink_name(p1->name()))
2005 continue;
2007 Named_object* param_no =
2008 callee_bindings->lookup_local(p1->name());
2009 go_assert(param_no != NULL);
2010 Expression* arg = (*p)->expr();
2011 if (arg->var_expression() != NULL
2012 && arg->var_expression()->named_object() == param_no)
2013 continue;
2015 Node* param_node = Node::make_node(param_no);
2016 this->assign(param_node, *p);
2019 for (; p != arg_nodes.end(); ++p)
2021 if (debug_level > 2)
2022 go_inform(call->location(), "esccall:: ... <- %s, untracked",
2023 (*p)->ast_format(gogo).c_str());
2024 this->assign(this->context_->sink(), *p);
2028 return;
2031 if (debug_level > 2)
2032 go_inform(call->location(), "esccall:: %s not recursive",
2033 call_node->ast_format(gogo).c_str());
2035 Node::Escape_state* call_state = call_node->state(this->context_, NULL);
2036 if (!call_state->retvals.empty())
2037 go_error_at(Linemap::unknown_location(),
2038 "esc already decorated call %s",
2039 call_node->ast_format(gogo).c_str());
2040 this->context_->init_retvals(call_node, fntype);
2042 // Receiver.
2043 std::vector<Node*>::iterator p = arg_nodes.begin();
2044 if (fntype->is_method()
2045 && p != arg_nodes.end())
2047 // First argument to call will be the receiver.
2048 std::string* note = fntype->receiver()->note();
2049 if (fntype->receiver()->type()->points_to() == NULL
2050 && (*p)->expr()->type()->points_to() != NULL)
2051 // This is a call to a value method that has been lowered into a call
2052 // to a pointer method. Gccgo generates a pointer method for all
2053 // method calls and takes the address of the value passed as the
2054 // receiver then immediately dereferences it within the function.
2055 // In this case, the receiver address does not escape; its content
2056 // flows to the call.
2057 this->assign_from_note(note, call_state->retvals,
2058 this->context_->add_dereference(*p));
2059 else
2061 if (!Type::are_identical(fntype->receiver()->type(),
2062 (*p)->expr()->type(), true, NULL))
2064 // This will be converted later, preemptively track it instead
2065 // of its conversion expression which will show up in a later pass.
2066 this->context_->track(*p);
2068 this->assign_from_note(note, call_state->retvals, *p);
2070 p++;
2073 const Typed_identifier_list* til = fntype->parameters();
2074 if (til != NULL)
2076 for (Typed_identifier_list::const_iterator pn = til->begin();
2077 pn != til->end() && p != arg_nodes.end();
2078 ++pn, ++p)
2080 if (!Type::are_identical(pn->type(), (*p)->expr()->type(),
2081 true, NULL))
2083 // This will be converted later, preemptively track it instead
2084 // of its conversion expression which will show up in a later pass.
2085 this->context_->track(*p);
2088 Type* t = pn->type();
2089 if (t != NULL
2090 && t->has_pointer())
2092 std::string* note = pn->note();
2093 int enc = this->assign_from_note(note, call_state->retvals, *p);
2094 if (enc == Node::ESCAPE_NONE
2095 && !call->is_deferred()
2096 && !call->is_concurrent())
2098 // TODO(cmang): Mark the argument as strictly non-escaping?
2099 // In the gc compiler this is for limiting the lifetime of
2100 // temporaries. We probably don't need this?
2105 for (; p != arg_nodes.end(); ++p)
2107 if (debug_level > 2)
2108 go_inform(call->location(), "esccall:: ... <- %s, untracked",
2109 (*p)->ast_format(gogo).c_str());
2110 this->assign(this->context_->sink(), *p);
2115 // Model the assignment of DST to SRC.
2116 // Assert that SRC somehow gets assigned to DST.
2117 // DST might need to be examined for evaluations that happen inside of it.
2118 // For example, in [DST]*f(x) = [SRC]y, we lose track of the indirection and
2119 // DST becomes the sink in our model.
2121 void
2122 Escape_analysis_assign::assign(Node* dst, Node* src)
2124 Gogo* gogo = this->context_->gogo();
2125 int debug_level = gogo->debug_escape_level();
2126 if (debug_level > 1)
2127 go_inform(dst->location(), "[%d] %s escassign: %s(%s)[%s] = %s(%s)[%s]",
2128 this->context_->loop_depth(),
2129 strip_packed_prefix(gogo, this->context_->current_function_name()).c_str(),
2130 dst->ast_format(gogo).c_str(), dst->details().c_str(),
2131 dst->op_format().c_str(),
2132 src->ast_format(gogo).c_str(), src->details().c_str(),
2133 src->op_format().c_str());
2135 if (dst->is_indirect())
2136 // Lose track of the dereference.
2137 dst = this->context_->sink();
2138 else if (dst->expr() != NULL)
2140 // Analyze the lhs of the assignment.
2141 // Replace DST with this->context_->sink() if we can't track it.
2142 Expression* e = dst->expr();
2143 switch (e->classification())
2145 case Expression::EXPRESSION_VAR_REFERENCE:
2147 // If DST is a global variable, we have no way to track it.
2148 Named_object* var = e->var_expression()->named_object();
2149 if (var->is_variable() && var->var_value()->is_global())
2150 dst = this->context_->sink();
2152 break;
2154 case Expression::EXPRESSION_FIELD_REFERENCE:
2156 Expression* strct = e->field_reference_expression()->expr();
2157 if (strct->heap_expression() != NULL)
2159 // When accessing the field of a struct reference, we lose
2160 // track of the indirection.
2161 dst = this->context_->sink();
2162 break;
2165 // Treat DST.x = SRC as if it were DST = SRC.
2166 Node* struct_node = Node::make_node(strct);
2167 this->assign(struct_node, src);
2168 return;
2171 case Expression::EXPRESSION_ARRAY_INDEX:
2173 Array_index_expression* are = e->array_index_expression();
2174 if (!are->array()->type()->is_slice_type())
2176 // Treat DST[i] = SRC as if it were DST = SRC if DST if a fixed
2177 // array.
2178 Node* array_node = Node::make_node(are->array());
2179 this->assign(array_node, src);
2180 return;
2183 // Lose track of the slice dereference.
2184 dst = this->context_->sink();
2186 break;
2188 case Expression::EXPRESSION_UNARY:
2189 // Lose track of the dereference.
2190 if (e->unary_expression()->op() == OPERATOR_MULT)
2191 dst = this->context_->sink();
2192 break;
2194 case Expression::EXPRESSION_MAP_INDEX:
2196 // Lose track of the map's key and value.
2197 Expression* index = e->map_index_expression()->index();
2198 Node* index_node = Node::make_node(index);
2199 this->assign(this->context_->sink(), index_node);
2201 dst = this->context_->sink();
2203 break;
2205 case Expression::EXPRESSION_TEMPORARY_REFERENCE:
2207 // Temporary is tracked through the underlying Temporary_statement.
2208 Statement* t = dst->expr()->temporary_reference_expression()->statement();
2209 dst = Node::make_node(t);
2211 break;
2213 default:
2214 // TODO(cmang): Add debugging info here: only a few expressions
2215 // should leave DST unmodified.
2216 break;
2220 if (src->object() != NULL)
2221 this->flows(dst, src);
2222 else if (src->is_indirect())
2223 this->flows(dst, src);
2224 else if (src->expr() != NULL)
2226 Expression* e = src->expr();
2227 switch (e->classification())
2229 case Expression::EXPRESSION_VAR_REFERENCE:
2230 case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
2231 // DST = var
2232 case Expression::EXPRESSION_HEAP:
2233 // DST = &T{...}.
2234 case Expression::EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
2235 case Expression::EXPRESSION_SLICE_CONSTRUCTION:
2236 // DST = [...]T{...}.
2237 case Expression::EXPRESSION_MAP_CONSTRUCTION:
2238 // DST = map[T]V{...}.
2239 case Expression::EXPRESSION_STRUCT_CONSTRUCTION:
2240 // DST = T{...}.
2241 case Expression::EXPRESSION_ALLOCATION:
2242 // DST = new(T).
2243 case Expression::EXPRESSION_BOUND_METHOD:
2244 // DST = x.M.
2245 case Expression::EXPRESSION_STRING_CONCAT:
2246 // DST = str1 + str2
2247 this->flows(dst, src);
2248 break;
2250 case Expression::EXPRESSION_UNSAFE_CONVERSION:
2252 Expression* underlying = e->unsafe_conversion_expression()->expr();
2253 Node* underlying_node = Node::make_node(underlying);
2254 this->assign(dst, underlying_node);
2256 break;
2258 case Expression::EXPRESSION_CALL:
2260 Call_expression* call = e->call_expression();
2261 if (call->is_builtin())
2263 Builtin_call_expression* bce = call->builtin_call_expression();
2264 if (bce->code() == Builtin_call_expression::BUILTIN_APPEND)
2266 // Append returns the first argument.
2267 // The subsequent arguments are already leaked because
2268 // they are operands to append.
2269 Node* appendee = Node::make_node(call->args()->front());
2270 this->assign(dst, appendee);
2272 break;
2274 Func_expression* fe = call->fn()->func_expression();
2275 if (fe != NULL && fe->is_runtime_function())
2277 switch (fe->runtime_code())
2279 case Runtime::MAKECHAN:
2280 case Runtime::MAKECHAN64:
2281 case Runtime::MAKEMAP:
2282 case Runtime::MAKESLICE:
2283 case Runtime::MAKESLICE64:
2284 // DST = make(...).
2285 this->flows(dst, src);
2286 break;
2288 default:
2289 break;
2291 break;
2293 else if (fe != NULL
2294 && fe->named_object()->is_function()
2295 && fe->named_object()->func_value()->is_method()
2296 && (call->is_deferred()
2297 || call->is_concurrent()))
2299 // For a method call thunk, lose track of the call and treat it
2300 // as if DST = RECEIVER.
2301 Node* rcvr_node = Node::make_node(call->args()->front());
2302 this->assign(dst, rcvr_node);
2303 break;
2306 // Result flows to dst.
2307 Node* call_node = Node::make_node(e);
2308 Node::Escape_state* call_state = call_node->state(this->context_, NULL);
2309 std::vector<Node*> retvals = call_state->retvals;
2310 for (std::vector<Node*>::const_iterator p = retvals.begin();
2311 p != retvals.end();
2312 ++p)
2313 this->flows(dst, *p);
2315 break;
2317 case Expression::EXPRESSION_CALL_RESULT:
2319 Call_result_expression* cre = e->call_result_expression();
2320 Call_expression* call = cre->call()->call_expression();
2321 if (call->is_builtin())
2322 break;
2323 if (call->fn()->func_expression() != NULL
2324 && call->fn()->func_expression()->is_runtime_function())
2326 switch (call->fn()->func_expression()->runtime_code())
2328 case Runtime::IFACEE2E2:
2329 case Runtime::IFACEI2E2:
2330 case Runtime::IFACEE2I2:
2331 case Runtime::IFACEI2I2:
2332 case Runtime::IFACEE2T2P:
2333 case Runtime::IFACEI2T2P:
2335 // x, ok = v.(T), where T is a pointer or interface,
2336 // is lowered to
2337 // x, ok = IFACEI2E2(v), or
2338 // x, ok = IFACEI2I2(type, v)
2339 // The last arg flows to the first result.
2340 // Note: IFACEX2T2 has different signature, handled by
2341 // ::expression.
2342 if (cre->index() != 0)
2343 break;
2344 Node* arg_node = Node::make_node(call->args()->back());
2345 this->assign(dst, arg_node);
2347 break;
2349 default:
2350 break;
2352 break;
2355 Node* call_node = Node::make_node(call);
2356 Node* ret_node = call_node->state(context_, NULL)->retvals[cre->index()];
2357 this->assign(dst, ret_node);
2359 break;
2361 case Expression::EXPRESSION_FUNC_REFERENCE:
2362 if (e->func_expression()->closure() != NULL)
2363 this->flows(dst, src);
2364 break;
2366 case Expression::EXPRESSION_CONVERSION:
2368 Type_conversion_expression* tce = e->conversion_expression();
2369 Type* ft = tce->expr()->type();
2370 Type* tt = tce->type();
2371 if ((ft->is_string_type() && tt->is_slice_type())
2372 || (ft->is_slice_type() && tt->is_string_type())
2373 || (ft->integer_type() != NULL && tt->is_string_type()))
2375 // string([]byte), string([]rune), []byte(string), []rune(string), string(rune)
2376 this->flows(dst, src);
2377 break;
2379 // Conversion preserves input value.
2380 Expression* underlying = tce->expr();
2381 this->assign(dst, Node::make_node(underlying));
2383 break;
2385 case Expression::EXPRESSION_FIELD_REFERENCE:
2387 // A non-pointer can't escape from a struct.
2388 if (!e->type()->has_pointer())
2389 break;
2391 // Fall through.
2393 case Expression::EXPRESSION_TYPE_GUARD:
2394 case Expression::EXPRESSION_ARRAY_INDEX:
2395 case Expression::EXPRESSION_STRING_INDEX:
2397 Expression* left = NULL;
2398 if (e->field_reference_expression() != NULL)
2400 left = e->field_reference_expression()->expr();
2401 if (left->unary_expression() != NULL
2402 && left->unary_expression()->op() == OPERATOR_MULT)
2404 // DST = (*x).f
2405 this->flows(dst, src);
2406 break;
2409 else if (e->type_guard_expression() != NULL)
2410 left = e->type_guard_expression()->expr();
2411 else if (e->array_index_expression() != NULL)
2413 Array_index_expression* aie = e->array_index_expression();
2414 if (aie->end() != NULL)
2415 // slicing
2416 if (aie->array()->type()->is_slice_type())
2417 left = aie->array();
2418 else
2420 // slicing an array
2421 // The gc compiler has an implicit address operator.
2422 go_assert(src->child() != NULL);
2423 this->assign(dst, src->child());
2424 break;
2426 else if (!aie->array()->type()->is_slice_type())
2428 // Indexing an array preserves the input value.
2429 Node* array_node = Node::make_node(aie->array());
2430 this->assign(dst, array_node);
2431 break;
2433 else
2435 this->flows(dst, src);
2436 break;
2439 else if (e->string_index_expression() != NULL)
2441 String_index_expression* sie = e->string_index_expression();
2442 if (e->type()->is_string_type())
2443 // slicing
2444 left = sie->string();
2445 else
2447 this->flows(dst, src);
2448 break;
2451 go_assert(left != NULL);
2453 // Conversions, field access, and slicing all preserve the input
2454 // value.
2455 Node* left_node = Node::make_node(left);
2456 this->assign(dst, left_node);
2458 break;
2460 case Expression::EXPRESSION_BINARY:
2462 switch (e->binary_expression()->op())
2464 case OPERATOR_PLUS:
2465 case OPERATOR_MINUS:
2466 case OPERATOR_XOR:
2467 case OPERATOR_OR:
2468 case OPERATOR_MULT:
2469 case OPERATOR_DIV:
2470 case OPERATOR_MOD:
2471 case OPERATOR_LSHIFT:
2472 case OPERATOR_RSHIFT:
2473 case OPERATOR_AND:
2474 case OPERATOR_BITCLEAR:
2476 Node* left = Node::make_node(e->binary_expression()->left());
2477 this->assign(dst, left);
2478 Node* right = Node::make_node(e->binary_expression()->right());
2479 this->assign(dst, right);
2481 break;
2483 default:
2484 break;
2487 break;
2489 case Expression::EXPRESSION_UNARY:
2491 switch (e->unary_expression()->op())
2493 case OPERATOR_PLUS:
2494 case OPERATOR_MINUS:
2495 case OPERATOR_XOR:
2497 Node* op_node =
2498 Node::make_node(e->unary_expression()->operand());
2499 this->assign(dst, op_node);
2501 break;
2503 case OPERATOR_MULT:
2504 // DST = *x
2505 case OPERATOR_AND:
2506 // DST = &x
2507 this->flows(dst, src);
2508 break;
2510 default:
2511 break;
2514 break;
2516 case Expression::EXPRESSION_TEMPORARY_REFERENCE:
2518 Statement* temp = e->temporary_reference_expression()->statement();
2519 this->assign(dst, Node::make_node(temp));
2521 break;
2523 default:
2524 // TODO(cmang): Add debug info here; this should not be reachable.
2525 // For now, just to be conservative, we'll just say dst flows to src.
2526 break;
2529 else if (src->statement() != NULL && src->statement()->temporary_statement() != NULL)
2530 this->flows(dst, src);
2533 // Model the assignment of DST to an indirection of SRC.
2535 void
2536 Escape_analysis_assign::assign_deref(Node* dst, Node* src)
2538 if (src->expr() != NULL)
2540 switch (src->expr()->classification())
2542 case Expression::EXPRESSION_BOOLEAN:
2543 case Expression::EXPRESSION_STRING:
2544 case Expression::EXPRESSION_INTEGER:
2545 case Expression::EXPRESSION_FLOAT:
2546 case Expression::EXPRESSION_COMPLEX:
2547 case Expression::EXPRESSION_NIL:
2548 case Expression::EXPRESSION_IOTA:
2549 // No need to try indirections on literal values
2550 // or numeric constants.
2551 return;
2553 default:
2554 break;
2558 this->assign(dst, this->context_->add_dereference(src));
2561 // Model the input-to-output assignment flow of one of a function call's
2562 // arguments, where the flow is encoded in NOTE.
2565 Escape_analysis_assign::assign_from_note(std::string* note,
2566 const std::vector<Node*>& dsts,
2567 Node* src)
2569 int enc = Escape_note::parse_tag(note);
2570 if (src->expr() != NULL)
2572 switch (src->expr()->classification())
2574 case Expression::EXPRESSION_BOOLEAN:
2575 case Expression::EXPRESSION_STRING:
2576 case Expression::EXPRESSION_INTEGER:
2577 case Expression::EXPRESSION_FLOAT:
2578 case Expression::EXPRESSION_COMPLEX:
2579 case Expression::EXPRESSION_NIL:
2580 case Expression::EXPRESSION_IOTA:
2581 // There probably isn't a note for a literal value. Literal values
2582 // usually don't escape unless we lost track of the value some how.
2583 return enc;
2585 default:
2586 break;
2590 if (this->context_->gogo()->debug_escape_level() > 2)
2591 go_inform(src->location(), "assignfromtag:: src=%s em=%s",
2592 src->ast_format(context_->gogo()).c_str(),
2593 Escape_note::make_tag(enc).c_str());
2595 if (enc == Node::ESCAPE_UNKNOWN)
2597 // Lost track of the value.
2598 this->assign(this->context_->sink(), src);
2599 return enc;
2601 else if (enc == Node::ESCAPE_NONE)
2602 return enc;
2604 // If the content inside a parameter (reached via indirection) escapes to
2605 // the heap, mark it.
2606 if ((enc & ESCAPE_CONTENT_ESCAPES) != 0)
2607 this->assign(this->context_->sink(), this->context_->add_dereference(src));
2609 int save_enc = enc;
2610 enc >>= ESCAPE_RETURN_BITS;
2611 for (std::vector<Node*>::const_iterator p = dsts.begin();
2612 enc != 0 && p != dsts.end();
2613 ++p)
2615 // Prefer the lowest-level path to the reference (for escape purposes).
2616 // Two-bit encoding (for example. 1, 3, and 4 bits are other options)
2617 // 01 = 0-level
2618 // 10 = 1-level, (content escapes),
2619 // 11 = 2-level, (content of content escapes).
2620 int bits = enc & ESCAPE_BITS_MASK_FOR_TAG;
2621 if (bits > 0)
2623 Node* n = src;
2624 for (int i = 0; i < bits - 1; ++i)
2626 // Encode level > 0 as indirections.
2627 n = this->context_->add_dereference(n);
2629 this->assign(*p, n);
2631 enc >>= ESCAPE_BITS_PER_OUTPUT_IN_TAG;
2634 // If there are too many outputs to fit in the tag, that is handled on the
2635 // encoding end as ESCAPE_HEAP, so there is no need to check here.
2636 return save_enc;
2639 // Record the flow of SRC to DST in DST.
2641 void
2642 Escape_analysis_assign::flows(Node* dst, Node* src)
2644 // Don't bother capturing the flow from scalars.
2645 if (src->type() != NULL && !src->type()->has_pointer())
2646 return;
2648 // Don't confuse a blank identifier with the sink.
2649 if (dst->is_sink() && dst != this->context_->sink())
2650 return;
2652 Node::Escape_state* dst_state = dst->state(this->context_, NULL);
2653 Node::Escape_state* src_state = src->state(this->context_, NULL);
2654 if (dst == src
2655 || dst_state == src_state
2656 || dst_state->flows.find(src) != dst_state->flows.end())
2657 return;
2659 Gogo* gogo = this->context_->gogo();
2660 if (gogo->debug_escape_level() > 2)
2661 go_inform(Linemap::unknown_location(), "flows:: %s <- %s",
2662 dst->ast_format(gogo).c_str(), src->ast_format(gogo).c_str());
2664 if (dst_state->flows.empty())
2665 this->context_->add_dst(dst);
2667 dst_state->flows.insert(src);
2670 // Build a connectivity graph between nodes in the function being analyzed.
2672 void
2673 Gogo::assign_connectivity(Escape_context* context, Named_object* fn)
2675 // Must be defined outside of this package.
2676 if (!fn->is_function())
2677 return;
2679 int save_depth = context->loop_depth();
2680 context->set_loop_depth(1);
2682 Escape_analysis_assign ea(context, fn);
2683 Function::Results* res = fn->func_value()->result_variables();
2684 if (res != NULL)
2686 for (Function::Results::const_iterator p = res->begin();
2687 p != res->end();
2688 ++p)
2690 Node* res_node = Node::make_node(*p);
2691 Node::Escape_state* res_state = res_node->state(context, fn);
2692 res_state->fn = fn;
2693 res_state->loop_depth = 0;
2695 // If this set of functions is recursive, we lose track of the return values.
2696 // Just say that the result flows to the sink.
2697 if (context->recursive())
2698 ea.flows(context->sink(), res_node);
2702 const Bindings* callee_bindings = fn->func_value()->block()->bindings();
2703 Function_type* fntype = fn->func_value()->type();
2704 Typed_identifier_list* params = (fntype->parameters() != NULL
2705 ? fntype->parameters()->copy()
2706 : new Typed_identifier_list);
2707 if (fntype->receiver() != NULL)
2708 params->push_back(*fntype->receiver());
2710 for (Typed_identifier_list::const_iterator p = params->begin();
2711 p != params->end();
2712 ++p)
2714 if (p->name().empty() || Gogo::is_sink_name(p->name()))
2715 continue;
2717 Named_object* param_no = callee_bindings->lookup_local(p->name());
2718 go_assert(param_no != NULL);
2719 Node* param_node = Node::make_node(param_no);
2720 Node::Escape_state* param_state = param_node->state(context, fn);
2721 param_state->fn = fn;
2722 param_state->loop_depth = 1;
2724 if (!p->type()->has_pointer())
2725 continue;
2727 // External function? Parameters must escape unless //go:noescape is set.
2728 // TODO(cmang): Implement //go:noescape directive.
2729 if (fn->package() != NULL)
2730 param_node->set_encoding(Node::ESCAPE_HEAP);
2731 else
2733 param_node->set_encoding(Node::ESCAPE_NONE);
2734 context->track(param_node);
2738 Escape_analysis_loop el;
2739 fn->func_value()->traverse(&el);
2741 fn->func_value()->traverse(&ea);
2742 context->set_loop_depth(save_depth);
2745 class Escape_analysis_flood
2747 public:
2748 Escape_analysis_flood(Escape_context* context)
2749 : context_(context)
2752 // Use the escape information in dst to update the escape information in src
2753 // and src's upstream.
2754 void
2755 flood(Level, Node* dst, Node* src, int);
2757 private:
2758 // The escape context for the group of functions being flooded.
2759 Escape_context* context_;
2762 // Whenever we hit a dereference node, the level goes up by one, and whenever
2763 // we hit an address-of, the level goes down by one. as long as we're on a
2764 // level > 0 finding an address-of just means we're following the upstream
2765 // of a dereference, so this address doesn't leak (yet).
2766 // If level == 0, it means the /value/ of this node can reach the root of this
2767 // flood so if this node is an address-of, its argument should be marked as
2768 // escaping iff its current function and loop depth are different from the
2769 // flood's root.
2770 // Once an object has been moved to the heap, all of its upstream should be
2771 // considered escaping to the global scope.
2772 // This is an implementation of gc/esc.go:escwalkBody.
2774 void
2775 Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
2776 int extra_loop_depth)
2778 // No need to flood src if it is a literal.
2779 if (src->expr() != NULL)
2781 switch (src->expr()->classification())
2783 case Expression::EXPRESSION_BOOLEAN:
2784 case Expression::EXPRESSION_STRING:
2785 case Expression::EXPRESSION_INTEGER:
2786 case Expression::EXPRESSION_FLOAT:
2787 case Expression::EXPRESSION_COMPLEX:
2788 case Expression::EXPRESSION_NIL:
2789 case Expression::EXPRESSION_IOTA:
2790 return;
2792 default:
2793 break;
2797 Node::Escape_state* src_state = src->state(this->context_, NULL);
2798 if (src_state->flood_id == this->context_->flood_id())
2800 // Esclevels are vectors, do not compare as integers,
2801 // and must use "min" of old and new to guarantee
2802 // convergence.
2803 level = level.min(src_state->level);
2804 if (level == src_state->level)
2806 // Have we been here already with an extraloopdepth,
2807 // or is the extraloopdepth provided no improvement on
2808 // what's already been seen?
2809 if (src_state->max_extra_loop_depth >= extra_loop_depth
2810 || src_state->loop_depth >= extra_loop_depth)
2811 return;
2812 src_state->max_extra_loop_depth = extra_loop_depth;
2815 else
2816 src_state->max_extra_loop_depth = -1;
2818 src_state->flood_id = this->context_->flood_id();
2819 src_state->level = level;
2820 int mod_loop_depth = std::max(extra_loop_depth, src_state->loop_depth);
2822 Gogo* gogo = this->context_->gogo();
2823 int debug_level = gogo->debug_escape_level();
2824 if (debug_level > 1)
2825 go_inform(Linemap::unknown_location(),
2826 "escwalk: level:{%d %d} depth:%d "
2827 "op=%s %s(%s) "
2828 "scope:%s[%d] "
2829 "extraloopdepth=%d",
2830 level.value(), level.suffix_value(), this->context_->pdepth(),
2831 src->op_format().c_str(),
2832 src->ast_format(gogo).c_str(),
2833 src->details().c_str(),
2834 debug_function_name(src_state->fn).c_str(),
2835 src_state->loop_depth,
2836 extra_loop_depth);
2838 this->context_->increase_pdepth();
2840 // Input parameter flowing into output parameter?
2841 Named_object* src_no = NULL;
2842 if (src->expr() != NULL && src->expr()->var_expression() != NULL)
2843 src_no = src->expr()->var_expression()->named_object();
2844 else
2845 src_no = src->object();
2846 bool src_is_param = (src_no != NULL
2847 && src_no->is_variable()
2848 && src_no->var_value()->is_parameter());
2850 Named_object* dst_no = NULL;
2851 if (dst->expr() != NULL && dst->expr()->var_expression() != NULL)
2852 dst_no = dst->expr()->var_expression()->named_object();
2853 else
2854 dst_no = dst->object();
2855 bool dst_is_result = dst_no != NULL && dst_no->is_result_variable();
2856 Node::Escape_state* dst_state = dst->state(this->context_, NULL);
2858 if (src_is_param
2859 && dst_is_result
2860 && src_state->fn == dst_state->fn
2861 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_HEAP)
2862 && dst->encoding() != Node::ESCAPE_HEAP)
2864 // This case handles:
2865 // 1. return in
2866 // 2. return &in
2867 // 3. tmp := in; return &tmp
2868 // 4. return *in
2869 if (debug_level != 0)
2871 if (debug_level == 1)
2872 go_inform(src->definition_location(),
2873 "leaking param: %s to result %s level=%d",
2874 src->ast_format(gogo).c_str(),
2875 dst->ast_format(gogo).c_str(),
2876 level.value());
2877 else
2878 go_inform(src->definition_location(),
2879 "leaking param: %s to result %s level={%d %d}",
2880 src->ast_format(gogo).c_str(),
2881 dst->ast_format(gogo).c_str(),
2882 level.value(), level.suffix_value());
2885 if ((src->encoding() & ESCAPE_MASK) != Node::ESCAPE_RETURN)
2887 int enc =
2888 Node::ESCAPE_RETURN | (src->encoding() & ESCAPE_CONTENT_ESCAPES);
2889 src->set_encoding(enc);
2892 int enc = Node::note_inout_flows(src->encoding(),
2893 dst_no->result_var_value()->index(),
2894 level);
2895 src->set_encoding(enc);
2897 // In gc/esc.go:escwalkBody, this is a goto to the label for recursively
2898 // flooding the connection graph. Inlined here for convenience.
2899 level = level.copy();
2900 for (std::set<Node*>::const_iterator p = src_state->flows.begin();
2901 p != src_state->flows.end();
2902 ++p)
2903 this->flood(level, dst, *p, extra_loop_depth);
2904 return;
2907 // If parameter content escape to heap, set ESCAPE_CONTENT_ESCAPES.
2908 // Note minor confusion around escape from pointer-to-struct vs
2909 // escape from struct.
2910 if (src_is_param
2911 && dst->encoding() == Node::ESCAPE_HEAP
2912 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_HEAP)
2913 && level.value() > 0)
2915 int enc =
2916 Node::max_encoding((src->encoding() | ESCAPE_CONTENT_ESCAPES),
2917 Node::ESCAPE_NONE);
2918 src->set_encoding(enc);
2919 if (debug_level != 0)
2920 go_inform(src->definition_location(), "mark escaped content: %s",
2921 src->ast_format(gogo).c_str());
2924 // A src object leaks if its value or address is assigned to a dst object
2925 // in a different scope (at a different loop depth).
2926 bool src_leaks = (level.value() <= 0
2927 && level.suffix_value() <= 0
2928 && dst_state->loop_depth < mod_loop_depth);
2929 src_leaks = src_leaks || (level.value() <= 0
2930 && (dst->encoding() & ESCAPE_MASK) == Node::ESCAPE_HEAP);
2931 // old src encoding, used to prevent duplicate error messages
2932 int osrcesc = src->encoding();
2934 if (src_is_param
2935 && (src_leaks || dst_state->loop_depth < 0)
2936 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_HEAP))
2938 if (level.suffix_value() > 0)
2940 int enc =
2941 Node::max_encoding((src->encoding() | ESCAPE_CONTENT_ESCAPES),
2942 Node::ESCAPE_NONE);
2943 src->set_encoding(enc);
2944 if (debug_level != 0 && osrcesc != src->encoding())
2945 go_inform(src->definition_location(), "leaking param content: %s",
2946 src->ast_format(gogo).c_str());
2948 else
2950 if (debug_level != 0)
2951 go_inform(src->definition_location(), "leaking param: %s",
2952 src->ast_format(gogo).c_str());
2953 src->set_encoding(Node::ESCAPE_HEAP);
2956 else if (src->expr() != NULL)
2958 Expression* e = src->expr();
2959 if (e->enclosed_var_expression() != NULL)
2961 if (src_leaks && debug_level != 0)
2962 go_inform(src->location(), "leaking closure reference %s",
2963 src->ast_format(gogo).c_str());
2965 Node* enclosed_node =
2966 Node::make_node(e->enclosed_var_expression()->variable());
2967 this->flood(level, dst, enclosed_node, -1);
2969 else if (e->heap_expression() != NULL
2970 || (e->unary_expression() != NULL
2971 && e->unary_expression()->op() == OPERATOR_AND))
2973 // Pointer literals and address-of expressions.
2974 Expression* underlying;
2975 if (e->heap_expression())
2976 underlying = e->heap_expression()->expr();
2977 else
2978 underlying = e->unary_expression()->operand();
2979 Node* underlying_node = Node::make_node(underlying);
2981 // If the address leaks, the underyling object must be moved
2982 // to the heap.
2983 underlying->address_taken(src_leaks);
2984 if (src_leaks)
2986 src->set_encoding(Node::ESCAPE_HEAP);
2987 if (osrcesc != src->encoding())
2989 move_to_heap(gogo, underlying);
2990 if (debug_level > 1)
2991 go_inform(src->location(),
2992 "%s escapes to heap, level={%d %d}, "
2993 "dst.eld=%d, src.eld=%d",
2994 src->ast_format(gogo).c_str(), level.value(),
2995 level.suffix_value(), dst_state->loop_depth,
2996 mod_loop_depth);
2997 else if (debug_level > 0)
2998 go_inform(src->location(), "%s escapes to heap",
2999 src->ast_format(gogo).c_str());
3002 this->flood(level.decrease(), dst,
3003 underlying_node, mod_loop_depth);
3004 extra_loop_depth = mod_loop_depth;
3006 else
3008 // Decrease the level each time we take the address of the object.
3009 this->flood(level.decrease(), dst, underlying_node, -1);
3012 else if (e->slice_literal() != NULL)
3014 Slice_construction_expression* slice = e->slice_literal();
3015 if (slice->vals() != NULL)
3017 for (Expression_list::const_iterator p = slice->vals()->begin();
3018 p != slice->vals()->end();
3019 ++p)
3021 if ((*p) != NULL)
3022 this->flood(level.decrease(), dst, Node::make_node(*p), -1);
3025 if (src_leaks)
3027 src->set_encoding(Node::ESCAPE_HEAP);
3028 if (debug_level != 0 && osrcesc != src->encoding())
3029 go_inform(src->location(), "%s escapes to heap",
3030 src->ast_format(gogo).c_str());
3031 extra_loop_depth = mod_loop_depth;
3034 else if (e->call_expression() != NULL)
3036 Call_expression* call = e->call_expression();
3037 if (call->is_builtin())
3039 Builtin_call_expression* bce = call->builtin_call_expression();
3040 if (bce->code() == Builtin_call_expression::BUILTIN_APPEND)
3042 // Propagate escape information to appendee.
3043 Expression* appendee = call->args()->front();
3044 this->flood(level, dst, Node::make_node(appendee), -1);
3047 else if (call->fn()->func_expression() != NULL
3048 && call->fn()->func_expression()->is_runtime_function())
3050 switch (call->fn()->func_expression()->runtime_code())
3052 case Runtime::MAKECHAN:
3053 case Runtime::MAKECHAN64:
3054 case Runtime::MAKEMAP:
3055 case Runtime::MAKESLICE:
3056 case Runtime::MAKESLICE64:
3057 if (src_leaks)
3059 src->set_encoding(Node::ESCAPE_HEAP);
3060 if (debug_level != 0 && osrcesc != src->encoding())
3061 go_inform(src->location(), "%s escapes to heap",
3062 src->ast_format(gogo).c_str());
3063 extra_loop_depth = mod_loop_depth;
3065 break;
3067 default:
3068 break;
3071 else if (src_state->retvals.size() > 0)
3073 // In this case a link went directly to a call, but should really go
3074 // to the dummy .outN outputs that were created for the call that
3075 // themselves link to the inputs with levels adjusted.
3076 // See e.g. #10466.
3077 // This can only happen with functions returning a single result.
3078 go_assert(src_state->retvals.size() == 1);
3079 if (debug_level > 2)
3080 go_inform(src->location(), "[%d] dst %s escwalk replace src: %s with %s",
3081 this->context_->loop_depth(),
3082 dst->ast_format(gogo).c_str(),
3083 src->ast_format(gogo).c_str(),
3084 src_state->retvals[0]->ast_format(gogo).c_str());
3085 src = src_state->retvals[0];
3086 src_state = src->state(this->context_, NULL);
3089 else if (e->allocation_expression() != NULL && src_leaks)
3091 // Calls to Runtime::NEW get lowered into an allocation expression.
3092 src->set_encoding(Node::ESCAPE_HEAP);
3093 if (debug_level != 0 && osrcesc != src->encoding())
3094 go_inform(src->location(), "%s escapes to heap",
3095 src->ast_format(gogo).c_str());
3096 extra_loop_depth = mod_loop_depth;
3098 else if ((e->map_literal() != NULL
3099 || e->string_concat_expression() != NULL
3100 || (e->func_expression() != NULL && e->func_expression()->closure() != NULL)
3101 || e->bound_method_expression() != NULL)
3102 && src_leaks)
3104 src->set_encoding(Node::ESCAPE_HEAP);
3105 if (debug_level != 0 && osrcesc != src->encoding())
3106 go_inform(src->location(), "%s escapes to heap",
3107 src->ast_format(gogo).c_str());
3108 extra_loop_depth = mod_loop_depth;
3110 else if (e->conversion_expression() != NULL && src_leaks)
3112 Type_conversion_expression* tce = e->conversion_expression();
3113 Type* ft = tce->expr()->type();
3114 Type* tt = tce->type();
3115 if ((ft->is_string_type() && tt->is_slice_type())
3116 || (ft->is_slice_type() && tt->is_string_type())
3117 || (ft->integer_type() != NULL && tt->is_string_type()))
3119 // string([]byte), string([]rune), []byte(string), []rune(string), string(rune)
3120 src->set_encoding(Node::ESCAPE_HEAP);
3121 if (debug_level != 0 && osrcesc != src->encoding())
3122 go_inform(src->location(), "%s escapes to heap",
3123 src->ast_format(gogo).c_str());
3124 extra_loop_depth = mod_loop_depth;
3127 else if (e->array_index_expression() != NULL
3128 && !e->array_index_expression()->array()->type()->is_slice_type())
3130 Array_index_expression* aie = e->array_index_expression();
3131 if (aie->end() != NULL)
3133 // Slicing an array.
3134 // Flow its implicit address-of node to DST.
3135 this->flood(level, dst, src->child(), -1);
3137 else
3139 // Indexing an array.
3140 // An array element flowing to DST behaves like the array
3141 // flowing to DST.
3142 Expression* underlying = e->array_index_expression()->array();
3143 Node* underlying_node = Node::make_node(underlying);
3144 this->flood(level, dst, underlying_node, -1);
3147 else if ((e->field_reference_expression() != NULL
3148 && e->field_reference_expression()->expr()->unary_expression() == NULL)
3149 || e->type_guard_expression() != NULL
3150 || (e->array_index_expression() != NULL
3151 && e->array_index_expression()->end() != NULL)
3152 || (e->string_index_expression() != NULL
3153 && e->type()->is_string_type()))
3155 Expression* underlying;
3156 if (e->field_reference_expression() != NULL)
3157 underlying = e->field_reference_expression()->expr();
3158 else if (e->type_guard_expression() != NULL)
3159 underlying = e->type_guard_expression()->expr();
3160 else if (e->array_index_expression() != NULL)
3161 underlying = e->array_index_expression()->array();
3162 else
3163 underlying = e->string_index_expression()->string();
3165 Node* underlying_node = Node::make_node(underlying);
3166 this->flood(level, dst, underlying_node, -1);
3168 else if ((e->field_reference_expression() != NULL
3169 && e->field_reference_expression()->expr()->unary_expression() != NULL)
3170 || e->array_index_expression() != NULL
3171 || e->map_index_expression() != NULL
3172 || (e->unary_expression() != NULL
3173 && e->unary_expression()->op() == OPERATOR_MULT))
3175 Expression* underlying;
3176 if (e->field_reference_expression() != NULL)
3178 underlying = e->field_reference_expression()->expr();
3179 underlying = underlying->unary_expression()->operand();
3181 else if (e->array_index_expression() != NULL)
3182 underlying = e->array_index_expression()->array();
3183 else if (e->map_index_expression() != NULL)
3184 underlying = e->map_index_expression()->map();
3185 else
3186 underlying = e->unary_expression()->operand();
3188 // Increase the level for a dereference.
3189 Node* underlying_node = Node::make_node(underlying);
3190 this->flood(level.increase(), dst, underlying_node, -1);
3192 else if (e->temporary_reference_expression() != NULL)
3194 Statement* t = e->temporary_reference_expression()->statement();
3195 this->flood(level, dst, Node::make_node(t), -1);
3198 else if (src->is_indirect())
3199 // Increase the level for a dereference.
3200 this->flood(level.increase(), dst, src->child(), -1);
3202 level = level.copy();
3203 for (std::set<Node*>::const_iterator p = src_state->flows.begin();
3204 p != src_state->flows.end();
3205 ++p)
3206 this->flood(level, dst, *p, extra_loop_depth);
3208 this->context_->decrease_pdepth();
3211 // Propagate escape information across the nodes modeled in this Analysis_set.
3212 // This is an implementation of gc/esc.go:escflood.
3214 void
3215 Gogo::propagate_escape(Escape_context* context, Node* dst)
3217 if (dst->object() == NULL
3218 && (dst->expr() == NULL
3219 || (dst->expr()->var_expression() == NULL
3220 && dst->expr()->enclosed_var_expression() == NULL
3221 && dst->expr()->func_expression() == NULL)))
3222 return;
3224 Node::Escape_state* state = dst->state(context, NULL);
3225 Gogo* gogo = context->gogo();
3226 if (gogo->debug_escape_level() > 1)
3227 go_inform(Linemap::unknown_location(), "escflood:%d: dst %s scope:%s[%d]",
3228 context->flood_id(), dst->ast_format(gogo).c_str(),
3229 debug_function_name(state->fn).c_str(),
3230 state->loop_depth);
3232 Escape_analysis_flood eaf(context);
3233 for (std::set<Node*>::const_iterator p = state->flows.begin();
3234 p != state->flows.end();
3235 ++p)
3237 context->increase_flood_id();
3238 eaf.flood(Level::From(0), dst, *p, -1);
3242 class Escape_analysis_tag
3244 public:
3245 Escape_analysis_tag(Escape_context* context)
3246 : context_(context)
3249 // Add notes to the function's type about the escape information of its
3250 // input parameters.
3251 void
3252 tag(Named_object* fn);
3254 private:
3255 Escape_context* context_;
3258 void
3259 Escape_analysis_tag::tag(Named_object* fn)
3261 // External functions are assumed unsafe
3262 // unless //go:noescape is given before the declaration.
3263 if (fn->package() != NULL)
3264 return;
3266 if (fn->is_function_declaration())
3268 Function_declaration* fdcl = fn->func_declaration_value();
3269 if ((fdcl->pragmas() & GOPRAGMA_NOESCAPE) != 0)
3271 Function_type* fntype = fdcl->type();
3272 if (fntype->parameters() != NULL)
3274 const Typed_identifier_list* til = fntype->parameters();
3275 int i = 0;
3276 for (Typed_identifier_list::const_iterator p = til->begin();
3277 p != til->end();
3278 ++p, ++i)
3279 if (p->type()->has_pointer())
3280 fntype->add_parameter_note(i, Node::ESCAPE_NONE);
3285 if (!fn->is_function())
3286 return;
3288 Function_type* fntype = fn->func_value()->type();
3289 Bindings* bindings = fn->func_value()->block()->bindings();
3291 if (fntype->is_method()
3292 && !fntype->receiver()->name().empty()
3293 && !Gogo::is_sink_name(fntype->receiver()->name()))
3295 Named_object* rcvr_no = bindings->lookup(fntype->receiver()->name());
3296 go_assert(rcvr_no != NULL);
3297 Node* rcvr_node = Node::make_node(rcvr_no);
3298 switch ((rcvr_node->encoding() & ESCAPE_MASK))
3300 case Node::ESCAPE_NONE: // not touched by flood
3301 case Node::ESCAPE_RETURN:
3302 if (fntype->receiver()->type()->has_pointer())
3303 // Don't bother tagging for scalars.
3304 fntype->add_receiver_note(rcvr_node->encoding());
3305 break;
3307 case Node::ESCAPE_HEAP: // flooded, moved to heap.
3308 break;
3310 default:
3311 break;
3315 int i = 0;
3316 if (fntype->parameters() != NULL)
3318 const Typed_identifier_list* til = fntype->parameters();
3319 for (Typed_identifier_list::const_iterator p = til->begin();
3320 p != til->end();
3321 ++p, ++i)
3323 if (p->name().empty() || Gogo::is_sink_name(p->name()))
3325 // Parameter not used in the function body, does not escape.
3326 if (p->type()->has_pointer())
3327 fntype->add_parameter_note(i, Node::ESCAPE_NONE);
3328 continue;
3331 Named_object* param_no = bindings->lookup(p->name());
3332 go_assert(param_no != NULL);
3333 Node* param_node = Node::make_node(param_no);
3334 switch ((param_node->encoding() & ESCAPE_MASK))
3336 case Node::ESCAPE_NONE: // not touched by flood
3337 case Node::ESCAPE_RETURN:
3338 if (p->type()->has_pointer())
3339 // Don't bother tagging for scalars.
3340 fntype->add_parameter_note(i, param_node->encoding());
3341 break;
3343 case Node::ESCAPE_HEAP: // flooded, moved to heap.
3344 break;
3346 default:
3347 break;
3351 fntype->set_is_tagged();
3354 // Tag each top-level function with escape information that will be used to
3355 // retain analysis results across imports.
3357 void
3358 Gogo::tag_function(Escape_context* context, Named_object* fn)
3360 Escape_analysis_tag eat(context);
3361 eat.tag(fn);
3364 // Reclaim memory of escape analysis Nodes.
3366 void
3367 Gogo::reclaim_escape_nodes()
3369 Node::reclaim_nodes();
3372 void
3373 Node::reclaim_nodes()
3375 for (std::map<Named_object*, Node*>::iterator p = Node::objects.begin();
3376 p != Node::objects.end();
3377 ++p)
3378 delete p->second;
3379 Node::objects.clear();
3381 for (std::map<Expression*, Node*>::iterator p = Node::expressions.begin();
3382 p != Node::expressions.end();
3383 ++p)
3384 delete p->second;
3385 Node::expressions.clear();
3387 for (std::map<Statement*, Node*>::iterator p = Node::statements.begin();
3388 p != Node::statements.end();
3389 ++p)
3390 delete p->second;
3391 Node::statements.clear();
3393 for (std::vector<Node*>::iterator p = Node::indirects.begin();
3394 p != Node::indirects.end();
3395 ++p)
3396 delete *p;
3397 Node::indirects.clear();