Skip to content

Comments

semantic: avoid runtime _d_arraysetlength call when .length = 0#11912

Merged
dlang-bot merged 2 commits intodlang:masterfrom
ljmf00:optimize-length-0
Oct 30, 2020
Merged

semantic: avoid runtime _d_arraysetlength call when .length = 0#11912
dlang-bot merged 2 commits intodlang:masterfrom
ljmf00:optimize-length-0

Conversation

@ljmf00
Copy link
Member

@ljmf00 ljmf00 commented Oct 27, 2020

Signed-off-by: Luís Ferreira contact@lsferreira.net


This simple code

void main()
{
    int[] a;
    a.length = 0;
}

Produces this code with a runtime call on semantic analysis:

void main()
{
	int[] a = null;
	_d_arraysetlengthT(a, 0LU);
	return 0;
}

The runtime call _d_arraysetlengthT does internally slicing if new_length <= current_length

if (newlength <= (*p).length)
{
    *p = (*p)[0 .. newlength];
    void* newdata = (*p).ptr;
    return newdata[0 .. newlength];
}

For 0 as new length, this expression will always be true, no matter what, so this should be a = a[0 .. 0] instead of _d_arraysetlengthT(a, 0LU)

I'm not quite sure if this optimization should be made on the semantic analysis but I assumed it because the ArrayLengthExpr assignment is converted to _d_arraysetlengthT there.

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @ljmf00! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

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.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#11912"

@thewilsonator
Copy link
Contributor

tests?

@ljmf00
Copy link
Member Author

ljmf00 commented Oct 27, 2020

tests?

The behavior of .length = 0 is already being tested here https://github.com/dlang/dmd/blob/master/test/runnable/test28.d#L130 . I didn't found any test related to _d_arraysetlengthT call, so I assumed no furder tests needed.

I'm new to dmd compiler contributions, so, if there's any way to test the behavior of semantic analysis phase, could you guide me, if possible?

@thewilsonator
Copy link
Contributor

That test that the behaviour has not changed, not that the implementation is different. You probably want a codegen test here, but those are not very nice to write.

@UplinkCoder , @rainers , anyone else, any better ideas?

@rainers
Copy link
Member

rainers commented Oct 28, 2020

@UplinkCoder , @rainers , anyone else, any better ideas?

How about verifying the output of compilation with -vcg-ast?

@ibuclaw
Copy link
Member

ibuclaw commented Oct 28, 2020

Isn't this what POST_SCRIPT is for? Ensure there is no call to arraysetlength in the disassembled object file (though gdc and ldc is better at this ability in that they compile to assembly).

@ljmf00
Copy link
Member Author

ljmf00 commented Oct 28, 2020

How about verifying the output of compilation with -vcg-ast?

I done a test case for that using POST_SCRIPT, can you review?

@ljmf00
Copy link
Member Author

ljmf00 commented Oct 28, 2020

Maybe I'm missing something obvious, but the testcase runs locally with success.

@ljmf00 ljmf00 force-pushed the optimize-length-0 branch from aabb2bc to 597dc5a Compare October 28, 2020 18:05
@ljmf00
Copy link
Member Author

ljmf00 commented Oct 28, 2020

I solved the issue, the test case was malformed because it was testing only 64bit literals.

@thewilsonator
Copy link
Contributor

 ... fail_compilation/fail_arrayop3c.d -verrors=0 -o-  -fPIC ()
+ check_clean_git
+ git checkout test/compilable/issue17167.sh
+ rm -rf _generated
+ rm -f install.sh
+ rm -f test/compilable/vcg-ast.d.cg
+ make -f posix.mak check-clean-git
ERROR: Found the following residual temporary files.
ERROR: Temporary files should be stored in `test_results` or explicitly removed.
?? test/compilable/vcg-ast-arraylength.d.cg
posix.mak:69: recipe for target 'check-clean-git' failed
make: *** [check-clean-git] Error 1

# Test if a slice expr is applied for the above case
grep "arr = arr\[0..0\]" "${TEST_DIR}/${TEST_NAME}.d.cg"

rm_retry "${TEST_DIR}/${TEST_NAME}.d.cg"
Copy link
Contributor

Choose a reason for hiding this comment

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

I have no idea why that isn't working.

Copy link
Member Author

Choose a reason for hiding this comment

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

It seems an heisenberg issue. I don't know either.

Copy link
Member

@WalterBright WalterBright left a comment

Choose a reason for hiding this comment

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

see my comment

Signed-off-by: Luís Ferreira <contact@lsferreira.net>
@thewilsonator
Copy link
Contributor

You might need to remove the generated file manually , see

dmd/.circleci/run.sh

Lines 151 to 152 in 33cde05

# auto-removal of these files doesn't work on CirleCi
rm -f test/compilable/vcg-ast.d.cg

Signed-off-by: Luís Ferreira <contact@lsferreira.net>
@ljmf00 ljmf00 force-pushed the optimize-length-0 branch from 26d377a to ff3f007 Compare October 29, 2020 15:30
@ljmf00
Copy link
Member Author

ljmf00 commented Oct 29, 2020

You might need to remove the generated file manually , see

dmd/.circleci/run.sh

Lines 151 to 152 in 33cde05

# auto-removal of these files doesn't work on CirleCi
rm -f test/compilable/vcg-ast.d.cg

Done. I'll try to fix this later. I don't see a reason for this being hardcoded.

@thewilsonator
Copy link
Contributor

could you rebase now that dlang/ci#436 is in. I think that should be it.

@thewilsonator
Copy link
Contributor

restarted build kite, added auto merge.

@dlang-bot dlang-bot merged commit 9385296 into dlang:master Oct 30, 2020
@MoonlightSentinel
Copy link
Contributor

MoonlightSentinel commented Mar 4, 2021

This introduced a regression: https://issues.dlang.org/show_bug.cgi?id=21678


The problem is that the value of the expression changed from the new length (0) to the array slice.

Two possible solutions:

  • revert this PR
  • change the rewrite to yield 0, e.g.
a.length = 0;

(a = a[0 .. 0], 0) // Doesn't work for standalone assignments

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.

7 participants