Skip to content

add __traits(isReturnOnStack, func)#7908

Merged
wilzbach merged 1 commit intodlang:masterfrom
WalterBright:isReturnOnStack
Feb 26, 2018
Merged

add __traits(isReturnOnStack, func)#7908
wilzbach merged 1 commit intodlang:masterfrom
WalterBright:isReturnOnStack

Conversation

@WalterBright
Copy link
Copy Markdown
Member

@WalterBright WalterBright commented Feb 18, 2018

Determining if a function return value is on the stack or in registers is both complex, with a lot of special cases, and hard to accurately test for. With it as a testable __trait, at lease we can make the testing easy and accurate.

Spec Change: dlang/dlang.org#2216

@dlang-bot
Copy link
Copy Markdown
Contributor

Thanks for your pull request, @WalterBright!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

@WalterBright WalterBright force-pushed the isReturnOnStack branch 5 times, most recently from 84646db to 060cfb9 Compare February 18, 2018 04:40
@WalterBright
Copy link
Copy Markdown
Member Author

To get this to work, I had to move retStyle from toir.d to target.d

@JinShil JinShil added Review:Needs Spec PR A PR updating the language specification needs to be submitted to dlang.org Review:Needs Changelog A changelog entry needs to be added to /changelog labels Feb 18, 2018
@WalterBright WalterBright removed the Review:Needs Changelog A changelog entry needs to be added to /changelog label Feb 18, 2018
@WalterBright
Copy link
Copy Markdown
Member Author

@JinShil spec update is there now, too.

@JinShil JinShil removed the Review:Needs Spec PR A PR updating the language specification needs to be submitted to dlang.org label Feb 18, 2018
src/dmd/target.d Outdated
//printf(" 3 true\n");
return true;
}
else if ((global.params.isLinux || global.params.isOSX || global.params.isFreeBSD || global.params.isSolaris) &&
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing isDragonFlyBSD in the condition.


static assert(__traits(isReturnOnStack, test1) == false);
static assert(__traits(isReturnOnStack, test2) == true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding a test where a struct is not returned on the stack.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's quite a few different conditions and branches in the isReturnOnStack function. Are those covered by other tests? I guess they're implicitly covered by other tests?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the green lines in the code tab, they are lines that are covered.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the new code is green. The move of retStyle from one module to another is not new code. Also, the coverage tester does not test Windows specific code.

@@ -0,0 +1 @@
Implement https://dlang.org/spec/traits.html#isReturnOnStack
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a description, not just linking to the spec.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no real point to copy/pasting. That's what links are for.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The title is already a link. You can't put a link here. Check the preview at DAutoTest.

Also FWIW Ddoc doesn't detect URLs and you have to use LINK2...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ddoc does detect URLs starting with http: or https:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DAutoTest fails:

.generated/stable_dmd-2.078.2/dmd2/linux/bin64/rdmd --compiler=.generated/stable_dmd-2.078.2/dmd2/linux/bin64/dmd -conf=.generated/stable_dmd-2.078.2/dmd2/linux/bin64/dmd.conf -version=Contributors_Lib ../tools/changed.d \
	 -o changelog/pending.dd --version "2.080.0" \
	--date "To be released"
object.Exception@../tools/changed.d(214): Changelog entries should consist of one title line, a blank separator line, and a description.

To fix this you need add a blank line and copy part of description from your spec PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll approve this PR after this changelog entry issue is addressd.

* Returns:
* true if return value from function is on the stack
*/
extern (C++) static bool isReturnOnStack(TypeFunction tf)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although it's pretty obvious, you usually complain of missing Params: section 😉.

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Feb 18, 2018

To get this to work, I had to move retStyle from toir.d to target.d

Isn't retStyle called from other parts of the frontend also?

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Feb 18, 2018

Isn't retStyle called from other parts of the frontend also?

It is! Can you do this also please, which removes retStyle from the gluelayer module.

diff --git a/src/dmd/gluelayer.d b/src/dmd/gluelayer.d
index f163abadb..7caee33c5 100644
--- a/src/dmd/gluelayer.d
+++ b/src/dmd/gluelayer.d
@@ -47,7 +47,6 @@ version (NoBackend)
         Statement asmSemantic(AsmStatement s, Scope* sc) { assert(0); }
 
         // toir
-        RET retStyle(TypeFunction tf)               { return RET.regs; }
         void toObjFile(Dsymbol ds, bool multiobj)   {}
 
         extern(C++) abstract class ObjcGlue
@@ -77,7 +76,6 @@ else version (MARS)
 
         Statement asmSemantic(AsmStatement s, Scope* sc);
 
-        RET retStyle(TypeFunction tf);
         void toObjFile(Dsymbol ds, bool multiobj);
 
         extern(C++) abstract class ObjcGlue
@@ -96,7 +94,6 @@ else version (IN_GCC)
 
     extern (C++)
     {
-        RET retStyle(TypeFunction tf);
         Statement asmSemantic(AsmStatement s, Scope* sc);
     }
 
diff --git a/src/dmd/semantic3.d b/src/dmd/semantic3.d
index 52d827958..40c8bec0d 100644
--- a/src/dmd/semantic3.d
+++ b/src/dmd/semantic3.d
@@ -41,7 +41,6 @@ import dmd.expression;
 import dmd.expressionsem;
 import dmd.func;
 import dmd.globals;
-import dmd.gluelayer;
 import dmd.id;
 import dmd.identifier;
 import dmd.init;
@@ -564,7 +563,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                     }
                 }
 
-                if (!funcdecl.inferRetType && retStyle(f) != RET.stack)
+                if (!funcdecl.inferRetType && !Target.isReturnOnStack(f))
                     funcdecl.nrvo_can = 0;
 
                 bool inferRef = (f.isref && (funcdecl.storage_class & STC.auto_));
@@ -618,7 +617,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
                     if (funcdecl.storage_class & STC.auto_)
                         funcdecl.storage_class &= ~STC.auto_;
                 }
-                if (retStyle(f) != RET.stack)
+                if (!Target.isReturnOnStack(f))
                     funcdecl.nrvo_can = 0;
 
                 if (funcdecl.fbody.isErrorStatement())

@WalterBright
Copy link
Copy Markdown
Member Author

Isn't retStyle called from other parts of the frontend also?

In semantic3(), but it appeared that importing toir.d directly by traits.d caused it to fail on some platforms. It properly belongs in target.d anyway.

@WalterBright
Copy link
Copy Markdown
Member Author

@ibuclaw that indeed was the culprit.

@WalterBright WalterBright force-pushed the isReturnOnStack branch 2 times, most recently from 81b44c1 to cc0a605 Compare February 18, 2018 09:32
if (e.ident == Id.isReturnOnStack)
{
/* Extract as a boolean if function return value is in registers
* https://dlang.org/spec/traits.html#isReturnOnStack
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW we could easily generate the spec from this. It's in the PR queue for a few months already and just needs an approval: #6877

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That PR is labeled "Needs Work" and the title contains "[Proof of Concept]".

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW it was labelled PoC because it has never been formally approved as this would be a precedent in the spec depending on the actual implementation.
"Needs work" was just a result of merge conflicts that happened over the time ...

@WalterBright WalterBright force-pushed the isReturnOnStack branch 3 times, most recently from 4710fe3 to 87a0811 Compare February 18, 2018 10:04
TEST_OUTPUT:
---
fail_compilation/isreturnonstack.d(11): Error: argument to `__traits(isReturnOnStack, int)` is not a function
fail_compilation/isreturnonstack.d(12): Error: expected 1 arguments for `isReturnOnStack` but had 2
Copy link
Copy Markdown
Contributor

@jacob-carlborg jacob-carlborg Feb 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it a bit inconsistent to have __traits(isReturnOnStack ... in one error message and only isReturnOnStack in another?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's consistent with all the other error messages put out by traits.d. If you want to redo all that, that's ok, but it would be a separate PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know that.

@Geod24
Copy link
Copy Markdown
Member

Geod24 commented Feb 18, 2018

What's the motivation behind this ?

@WalterBright
Copy link
Copy Markdown
Member Author

What's the motivation behind this ?

See the opening comment.

@JinShil
Copy link
Copy Markdown
Contributor

JinShil commented Feb 18, 2018

What's the motivation behind this ?

I suspect it has to do with @WalterBright taking an interest in #6246, but I'm only speculating. @WalterBright, you could elaborate more about why this is needed.

@WalterBright
Copy link
Copy Markdown
Member Author

why

Determining if a function return value is on the stack or in registers is both complex, with a lot of special cases, and hard to accurately test for. With it as a testable __trait, at lease we can make the testing easy and accurate.

$(BEST_PRACTICE This has applications in:
    $(OL
    $(LI Returning values in registers is often faster, so this can be used as
    a check on a hot function to ensure it is using the fastest method.)
    $(LI When using inline assembly to correctly call a function.)
    $(LI Testing that the compiler does this correctly is normally hackish and awkward,
    this enables efficient, direct, and simple testing.)
    ))

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Feb 26, 2018

I would merge this myself, but someone seems to have revoked that ability from me... @wilzbach. :-)

@wilzbach
Copy link
Copy Markdown
Contributor

@wilzbach
Copy link
Copy Markdown
Contributor

but someone seems to have revoked that ability from me..

That someone wasn't me - this time I'm innocent!
Merging manually...

@wilzbach wilzbach merged commit 7c8dc62 into dlang:master Feb 26, 2018
@WalterBright WalterBright deleted the isReturnOnStack branch February 27, 2018 02:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants