public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1995] d: Missed RVO optimization with non-POD structs
@ 2021-07-03 11:08 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2021-07-03 11:08 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:152f4d0e4d3b524ce30d05f20e23a44b0dd29765

commit r12-1995-g152f4d0e4d3b524ce30d05f20e23a44b0dd29765
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Sat Jul 3 02:42:14 2021 +0200

    d: Missed RVO optimization with non-POD structs
    
    The D front-end semantic pass sometimes declares a temporary inside a
    return expression.  This is now detected with the RESULT_DECL replacing
    the temporary, allowing for RVO to be done.
    
            PR d/101273
    
    gcc/d/ChangeLog:
    
            * toir.cc (IRVisitor::visit (ReturnStatement *)): Detect returns that
            use a temporary, and replace with return value.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/torture/pr101273.d: New test.

Diff:
---
 gcc/d/toir.cc                           | 32 +++++++++++++++++++++++++--
 gcc/testsuite/gdc.dg/torture/pr101273.d | 39 +++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index 41d07a7b70e..eaee6f7e803 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -1034,14 +1034,37 @@ public:
 	/* Detect a call to a constructor function, or if returning a struct
 	   literal, write result directly into the return value.  */
 	StructLiteralExp *sle = NULL;
+	bool using_rvo_p = false;
 
 	if (DotVarExp *dve = (s->exp->op == TOKcall
 			      && s->exp->isCallExp ()->e1->op == TOKdotvar
 			      ? s->exp->isCallExp ()->e1->isDotVarExp ()
 			      : NULL))
 	  {
-	    sle = (dve->var->isCtorDeclaration ()
-		   ? dve->e1->isStructLiteralExp () : NULL);
+	    if (dve->var->isCtorDeclaration ())
+	      {
+		if (CommaExp *ce = dve->e1->isCommaExp ())
+		  {
+		    /* Temporary initialized inside a return expression, and
+		       used as the return value.  Replace it with the hidden
+			reference to allow RVO return.  */
+		    DeclarationExp *de = ce->e1->isDeclarationExp ();
+		    VarExp *ve = ce->e2->isVarExp ();
+		    if (de != NULL && ve != NULL
+			&& ve->var == de->declaration
+			&& ve->var->storage_class & STCtemp)
+		      {
+			tree var = get_symbol_decl (ve->var);
+			TREE_ADDRESSABLE (var) = 1;
+			SET_DECL_VALUE_EXPR (var, decl);
+			DECL_HAS_VALUE_EXPR_P (var) = 1;
+			SET_DECL_LANG_NRVO (var, this->func_->shidden);
+			using_rvo_p = true;
+		      }
+		  }
+		else
+		  sle = dve->e1->isStructLiteralExp ();
+	      }
 	  }
 	else
 	  sle = s->exp->isStructLiteralExp ();
@@ -1050,11 +1073,16 @@ public:
 	  {
 	    StructDeclaration *sd = type->baseElemOf ()->isTypeStruct ()->sym;
 	    sle->sym = build_address (this->func_->shidden);
+	    using_rvo_p = true;
 
 	    /* Fill any alignment holes in the return slot using memset.  */
 	    if (!identity_compare_p (sd) || sd->isUnionDeclaration ())
 	      add_stmt (build_memset_call (this->func_->shidden));
+	  }
 
+	if (using_rvo_p == true)
+	  {
+	    /* Generate: (expr, return <retval>);  */
 	    add_stmt (build_expr_dtor (s->exp));
 	  }
 	else
diff --git a/gcc/testsuite/gdc.dg/torture/pr101273.d b/gcc/testsuite/gdc.dg/torture/pr101273.d
new file mode 100644
index 00000000000..e300e03f199
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/torture/pr101273.d
@@ -0,0 +1,39 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101273
+// { dg-do run }
+
+struct S101273
+{
+    int x;
+    S101273* impl;
+    this(int x)
+    {
+        this.x = x;
+        this.impl = &this;
+    }
+    ~this() { }
+}
+
+S101273 makeS101273()
+{
+    return S101273(2);
+}
+
+S101273 nrvo101273()
+{
+    S101273 ret = makeS101273();
+    return ret;
+}
+
+S101273 rvo101273()
+{
+    return makeS101273();
+}
+
+void main()
+{
+    auto nrvo = nrvo101273();
+    assert(&nrvo is nrvo.impl);
+
+    auto rvo = rvo101273();
+    assert(&rvo is rvo.impl);
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-03 11:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-03 11:08 [gcc r12-1995] d: Missed RVO optimization with non-POD structs Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).