compiler: only check whether struct or array types are big

Fetching the size of a type typically involves a hash table lookup,
    and is generally non-trivial.  The escape analysis code calls is_big
    more than one might expect.  So only fetch the size if we need it.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/197699

From-SVN: r276187
This commit is contained in:
Ian Lance Taylor 2019-09-27 17:34:58 +00:00
parent df43545684
commit 51c3b7c6ec
2 changed files with 18 additions and 6 deletions

View File

@ -1,4 +1,4 @@
d1fa6c34e56eade6fb5b6291f0a727b1a12bf6f1
27d1f3031197428b5745d09c167f982d638b8776
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -511,16 +511,28 @@ Node::is_big(Escape_context* context) const
|| t->is_abstract())
return false;
int64_t size;
bool ok = t->backend_type_size(context->gogo(), &size);
bool big = ok && (size < 0 || size > 10 * 1024 * 1024);
bool big = false;
if (t->struct_type() != NULL
|| (t->array_type() != NULL && !t->is_slice_type()))
{
int64_t size;
bool ok = t->backend_type_size(context->gogo(), &size);
big = ok && (size < 0 || size > 10 * 1024 * 1024);
}
if (this->expr() != NULL)
{
if (this->expr()->allocation_expression() != NULL)
{
ok = t->deref()->backend_type_size(context->gogo(), &size);
big = big || size <= 0 || size >= (1 << 16);
Type* pt = t->deref();
if (pt->struct_type() != NULL
|| (pt->array_type() != NULL && !pt->is_slice_type()))
{
int64_t size;
bool ok = pt->backend_type_size(context->gogo(), &size);
if (ok)
big = big || size <= 0 || size >= (1 << 16);
}
}
else if (this->expr()->call_expression() != NULL)
{