compiler: Don't create a closure if not needed.

From-SVN: r187898
This commit is contained in:
Ian Lance Taylor 2012-05-25 21:14:50 +00:00
parent a2f96eb49d
commit 43d0a54732
1 changed files with 11 additions and 23 deletions

View File

@ -1312,30 +1312,18 @@ Func_expression::do_get_tree(Translate_context* context)
&& TREE_CODE(TREE_OPERAND(fnaddr, 0)) == FUNCTION_DECL);
TREE_ADDRESSABLE(TREE_OPERAND(fnaddr, 0)) = 1;
// For a normal non-nested function call, that is all we have to do.
if (!this->function_->is_function()
|| this->function_->func_value()->enclosing() == NULL)
{
go_assert(this->closure_ == NULL);
return fnaddr;
}
// If there is no closure, that is all have to do.
if (this->closure_ == NULL)
return fnaddr;
// For a nested function call, we have to always allocate a
// trampoline. If we don't always allocate, then closures will not
// be reliably distinct.
Expression* closure = this->closure_;
tree closure_tree;
if (closure == NULL)
closure_tree = null_pointer_node;
else
{
// Get the value of the closure. This will be a pointer to
// space allocated on the heap.
closure_tree = closure->get_tree(context);
if (closure_tree == error_mark_node)
return error_mark_node;
go_assert(POINTER_TYPE_P(TREE_TYPE(closure_tree)));
}
go_assert(this->function_->func_value()->enclosing() != NULL);
// Get the value of the closure. This will be a pointer to space
// allocated on the heap.
tree closure_tree = this->closure_->get_tree(context);
if (closure_tree == error_mark_node)
return error_mark_node;
go_assert(POINTER_TYPE_P(TREE_TYPE(closure_tree)));
// Now we need to build some code on the heap. This code will load
// the static chain pointer with the closure and then jump to the