This is an archive of the discontinued LLVM Phabricator instance.

[clang] Short-circuit trivial constexpr array constructors
ClosedPublic

Authored by tbaeder on Jul 29 2022, 11:36 AM.

Diff Detail

Event Timeline

tbaeder created this revision.Jul 29 2022, 11:36 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 29 2022, 11:36 AM
tbaeder requested review of this revision.Jul 29 2022, 11:36 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 29 2022, 11:36 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Thank you for working on this! This should also include test coverage (hmmm, we don't have a reasonable way to lit test performance regressions though.... so perhaps we just need to ensure there's at least one test that would normally have been unreasonably slow?) and a release note.

clang/lib/AST/ExprConstant.cpp
10836–10838

The big question this raises for me is: will this cause constexpr to fail because of the note diagnostics when the type does not have a trivial default constructor? Or does this just bump the failure up a bit so that we fail before we start walking over the array elements?

Thank you for working on this! This should also include test coverage (hmmm, we don't have a reasonable way to lit test performance regressions though.... so perhaps we just need to ensure there's at least one test that would normally have been unreasonably slow?) and a release note.

I think generally for pure-perf fixes we don't include any testing. (like switching a container type, adding caching, etc) But may be worth double-checking that there's reasonable test coverage for the feature.

also: What about zero length arrays? (which are supported as an extension) - this change would cause failures that wouldn't be emitted in the old code?

also: What about zero length arrays? (which are supported as an extension) - this change would cause failures that wouldn't be emitted in the old code?

There's a if (FinalSize == 0) return true; case above, so this code will never be reached for zero-length arrays. That loop here is pretty confusing... OldElts is either zero (for the first iteration), or one (for the second iteration, where N == FinalSize). I tried to untangle this, but it doesn't work very well since the APValue we pass to VisitCXXConstructExpr() must be in an array APValue...

As for testing: I didn't include a test because of what you two mentioned, I can't really test that a test case finished in under X seconds...

clang/lib/AST/ExprConstant.cpp
10836–10838

I can't come up with an example that would make this fail, or fail differently than it did before. For a constructor that is not marked constexpr and where CheckTrivialDefaultConstructor returns false, the first VisitCXXConstructExpr will return false and no diagnostic will be emitted. In the cases I tried, Info.EvalStatus.Diag is nullptr anyway, so yeah. If it did emit a diagnostic, I would assume that the failure just happens a little early, yes.

The alternative would be to try to integrate the CheckTrivialDefaultConstructor call into the loop, but I'm not a fan of that loop anyway :)

tbaeder updated this revision to Diff 449182.Aug 1 2022, 9:57 PM
aaron.ballman accepted this revision.Aug 2 2022, 9:56 AM

LGTM! I agree that test coverage for the performance issue is basically impossible with our testing system. I was thinking "well good, add a test with a huge initializer to make sure it doesn't crash" but then I realized that will slow down running the tests significantly and will always be susceptible to a slightly larger array than the test uses being a problem. So I think it's fine to land this without tests.

This revision is now accepted and ready to land.Aug 2 2022, 9:56 AM
This revision was landed with ongoing or failed builds.Aug 3 2022, 1:41 AM
This revision was automatically updated to reflect the committed changes.