aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/statements.cc
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-05-16 04:35:15 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-05-16 04:35:15 +0000
commite8e91b845496603168161015ccd5325524abbf7e (patch)
tree042ec42badf35137c4249ed7ab62797a8a50cf48 /gcc/go/gofrontend/statements.cc
parent92b8603c7c6789806879307a29ae3b85adaaaf14 (diff)
downloadgcc-e8e91b845496603168161015ccd5325524abbf7e.zip
gcc-e8e91b845496603168161015ccd5325524abbf7e.tar.gz
gcc-e8e91b845496603168161015ccd5325524abbf7e.tar.bz2
compiler: improve escape analysis on interface conversions
If an interface does not escape, it doesn't need a heap allocation to hold the data (for non-direct interface type). This CL improves the escape analysis to track interface conversions, and reduces these allocations. Implicit interface conversions were mostly added late in the compilation pipeline, after the escape analysis. For the escape analysis to see them, we move the introduction of these conversions earlier, right before the escape analysis. Now that the compiler can generate interface conversions inlined, gcc/testsuite/go.test/test/nilptr2.go needs to be adjusted as in golang.org/cl/176579, so the use function does an actual use. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/176459 * go.test/test/nilptr2.go: Change use function to actually do something. From-SVN: r271276
Diffstat (limited to 'gcc/go/gofrontend/statements.cc')
-rw-r--r--gcc/go/gofrontend/statements.cc56
1 files changed, 56 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index cd1b601..c850b49 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -324,6 +324,22 @@ Variable_declaration_statement::do_flatten(Gogo* gogo, Named_object* function,
return this;
}
+// Add explicit type conversions.
+
+void
+Variable_declaration_statement::do_add_conversions()
+{
+ Variable* var = this->var_->var_value();
+ Expression* init = var->init();
+ if (init == NULL)
+ return;
+ Type* lt = var->type();
+ Type* rt = init->type();
+ if (!Type::are_identical(lt, rt, 0, NULL)
+ && lt->interface_type() != NULL)
+ var->set_init(Expression::make_cast(lt, init, this->location()));
+}
+
// Convert a variable declaration to the backend representation.
Bstatement*
@@ -582,6 +598,20 @@ Temporary_statement::do_flatten(Gogo*, Named_object*, Block*,
return this;
}
+// Add explicit type conversions.
+
+void
+Temporary_statement::do_add_conversions()
+{
+ if (this->init_ == NULL)
+ return;
+ Type* lt = this->type();
+ Type* rt = this->init_->type();
+ if (!Type::are_identical(lt, rt, 0, NULL)
+ && lt->interface_type() != NULL)
+ this->init_ = Expression::make_cast(lt, this->init_, this->location());
+}
+
// Convert to backend representation.
Bstatement*
@@ -960,6 +990,18 @@ Assignment_statement::do_flatten(Gogo*, Named_object*, Block*,
return this;
}
+// Add explicit type conversions.
+
+void
+Assignment_statement::do_add_conversions()
+{
+ Type* lt = this->lhs_->type();
+ Type* rt = this->rhs_->type();
+ if (!Type::are_identical(lt, rt, 0, NULL)
+ && lt->interface_type() != NULL)
+ this->rhs_ = Expression::make_cast(lt, this->rhs_, this->location());
+}
+
// Convert an assignment statement to the backend representation.
Bstatement*
@@ -2638,6 +2680,8 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
// just for the call statement now. The other types are known.
call_statement->determine_types();
+ gogo->add_conversions_in_block(b);
+
gogo->flatten_block(function, b);
if (may_call_recover
@@ -4543,6 +4587,18 @@ Send_statement::do_flatten(Gogo*, Named_object*, Block*,
return this;
}
+// Add explicit type conversions.
+
+void
+Send_statement::do_add_conversions()
+{
+ Type* lt = this->channel_->type()->channel_type()->element_type();
+ Type* rt = this->val_->type();
+ if (!Type::are_identical(lt, rt, 0, NULL)
+ && lt->interface_type() != NULL)
+ this->val_ = Expression::make_cast(lt, this->val_, this->location());
+}
+
// Convert a send statement to the backend representation.
Bstatement*