diff options
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | debian/patches/go-escape-analysis6.diff | 209 | ||||
-rw-r--r-- | debian/rules.patch | 2 |
3 files changed, 213 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog index 17e96d0..efac9c4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,8 @@ gcc-5 (5.2.1-1) UNRELEASED; urgency=medium * Update to SVN 20150716 (r225880, 5.2.1) from the gcc-5-branch. * Require version 5.2 for the libstdc++6 cxx symbols. * Ignore missing libstdc++ symbols on sparc64 (work around #792204). + * Go escape analysis: analyze multiple result type assertions (taken + from the trunk). -- Matthias Klose <doko@debian.org> Thu, 16 Jul 2015 15:35:44 +0200 diff --git a/debian/patches/go-escape-analysis6.diff b/debian/patches/go-escape-analysis6.diff new file mode 100644 index 0000000..675e62e --- /dev/null +++ b/debian/patches/go-escape-analysis6.diff @@ -0,0 +1,209 @@ +# DP: escape: Analyze multiple result type assertions. + + For multi-result type assertions, the object being converted is hidden + behind unsafe conversions and calls to runtime methods. This change + allows the analysis to make edges between the result of the assertion + and the object being asserted. + +Index: gcc/go/gofrontend/expressions.h +=================================================================== +--- a/src/gcc/go/gofrontend/expressions.h (revision 225750) ++++ b/src/gcc/go/gofrontend/expressions.h (revision 225751) +@@ -32,6 +32,7 @@ + class Set_and_use_temporary_expression; + class String_expression; + class Type_conversion_expression; ++class Unsafe_type_conversion_expression; + class Unary_expression; + class Binary_expression; + class Call_expression; +@@ -571,6 +572,15 @@ + conversion_expression() + { return this->convert<Type_conversion_expression, EXPRESSION_CONVERSION>(); } + ++ // If this is an unsafe conversion expression, return the ++ // Unsafe_type_conversion_expression structure. Otherwise, return NULL. ++ Unsafe_type_conversion_expression* ++ unsafe_conversion_expression() ++ { ++ return this->convert<Unsafe_type_conversion_expression, ++ EXPRESSION_UNSAFE_CONVERSION>(); ++ } ++ + // Return whether this is the expression nil. + bool + is_nil_expression() const +@@ -1505,6 +1515,57 @@ + bool may_convert_function_types_; + }; + ++// An unsafe type conversion, used to pass values to builtin functions. ++ ++class Unsafe_type_conversion_expression : public Expression ++{ ++ public: ++ Unsafe_type_conversion_expression(Type* type, Expression* expr, ++ Location location) ++ : Expression(EXPRESSION_UNSAFE_CONVERSION, location), ++ type_(type), expr_(expr) ++ { } ++ ++ Expression* ++ expr() const ++ { return this->expr_; } ++ ++ protected: ++ int ++ do_traverse(Traverse* traverse); ++ ++ bool ++ do_is_immutable() const; ++ ++ Type* ++ do_type() ++ { return this->type_; } ++ ++ void ++ do_determine_type(const Type_context*) ++ { this->expr_->determine_type_no_context(); } ++ ++ Expression* ++ do_copy() ++ { ++ return new Unsafe_type_conversion_expression(this->type_, ++ this->expr_->copy(), ++ this->location()); ++ } ++ ++ Bexpression* ++ do_get_backend(Translate_context*); ++ ++ void ++ do_dump_expression(Ast_dump_context*) const; ++ ++ private: ++ // The type to convert to. ++ Type* type_; ++ // The expression to convert. ++ Expression* expr_; ++}; ++ + // A Unary expression. + + class Unary_expression : public Expression +@@ -2024,6 +2085,10 @@ + call() const + { return this->call_; } + ++ unsigned int ++ index() const ++ { return this->index_; } ++ + protected: + int + do_traverse(Traverse*); +Index: gcc/go/gofrontend/escape.cc +=================================================================== +--- a/src/gcc/go/gofrontend/escape.cc (revision 225750) ++++ b/src/gcc/go/gofrontend/escape.cc (revision 225751) +@@ -547,6 +547,41 @@ + expr = expr->type_guard_expression()->expr(); + break; + ++ case Expression::EXPRESSION_UNSAFE_CONVERSION: ++ { ++ Expression* e = expr->unsafe_conversion_expression()->expr(); ++ if (e->call_result_expression() != NULL ++ && e->call_result_expression()->index() == 0) ++ { ++ // a, ok := p.(T) gets lowered into a call to one of the interface ++ // to type conversion functions instead of a type guard expression. ++ // We only want to make a connection between a and p, the bool ++ // result should not escape because p escapes. ++ e = e->call_result_expression()->call(); ++ ++ Named_object* fn = ++ e->call_expression()->fn()->func_expression()->named_object(); ++ std::string fn_name = fn->name(); ++ if (fn->package() == NULL ++ && fn->is_function_declaration() ++ && !fn->func_declaration_value()->asm_name().empty()) ++ { ++ if (fn_name == "ifaceI2E2" ++ || fn_name == "ifaceI2I2") ++ e = e->call_expression()->args()->at(0); ++ else if (fn_name == "ifaceE2I2" ++ || fn_name == "ifaceI2I2" ++ || fn_name == "ifaceE2T2P" ++ || fn_name == "ifaceI2T2P" ++ || fn_name == "ifaceE2T2" ++ || fn_name == "ifaceI2T2") ++ e = e->call_expression()->args()->at(1); ++ } ++ } ++ expr = e; ++ } ++ break; ++ + default: + done = true; + break; +Index: gcc/go/gofrontend/expressions.cc +=================================================================== +--- a/src/gcc/go/gofrontend/expressions.cc (revision 225750) ++++ b/src/gcc/go/gofrontend/expressions.cc (revision 225751) +@@ -3391,53 +3391,8 @@ + return new Type_conversion_expression(type, val, location); + } + +-// An unsafe type conversion, used to pass values to builtin functions. ++// Class Unsafe_type_conversion_expression. + +-class Unsafe_type_conversion_expression : public Expression +-{ +- public: +- Unsafe_type_conversion_expression(Type* type, Expression* expr, +- Location location) +- : Expression(EXPRESSION_UNSAFE_CONVERSION, location), +- type_(type), expr_(expr) +- { } +- +- protected: +- int +- do_traverse(Traverse* traverse); +- +- bool +- do_is_immutable() const; +- +- Type* +- do_type() +- { return this->type_; } +- +- void +- do_determine_type(const Type_context*) +- { this->expr_->determine_type_no_context(); } +- +- Expression* +- do_copy() +- { +- return new Unsafe_type_conversion_expression(this->type_, +- this->expr_->copy(), +- this->location()); +- } +- +- Bexpression* +- do_get_backend(Translate_context*); +- +- void +- do_dump_expression(Ast_dump_context*) const; +- +- private: +- // The type to convert to. +- Type* type_; +- // The expression to convert. +- Expression* expr_; +-}; +- + // Traversal. + + int diff --git a/debian/rules.patch b/debian/rules.patch index 2c8635e..9a3e78e 100644 --- a/debian/rules.patch +++ b/debian/rules.patch @@ -85,6 +85,7 @@ debian_patches += \ go-escape-analysis3 \ go-escape-analysis4 \ go-escape-analysis5 \ + go-escape-analysis6 \ gccgo-sendfile-fix \ pr66368 \ @@ -94,6 +95,7 @@ debian_patches += \ # go-escape-analysis3 \ # go-escape-analysis4 \ # go-escape-analysis5 \ +# go-escape-analysis6 \ # $(if $(filter yes, $(DEB_CROSS)),,gcc-print-file-name) \ # libstdc++-nothumb-check \ |