Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift: Improve getABaseType implementions #14252

Merged
merged 10 commits into from
Sep 22, 2023
Merged

Conversation

geoffw0
Copy link
Contributor

@geoffw0 geoffw0 commented Sep 18, 2023

Improve the predicates getABaseType, getABaseTypeDecl, getADerivedType and getADerivedTypeDecl on Type and TypeDecl:

  • they behave consistently now.
  • they all explore through type aliases in the declared base type now.
    • i.e. from B to the underlying A in class B : A_alias
    • however they don't resolve a type alias they are called directly upon, i.e. TypeAlias.getABaseType() has no result now. Previously there was special code to make this work for Type (but not TypeDecl). See below * for more discussion of this point.
  • they all explore through protocols added in extensions now.
  • the TODO in TypeDecl.qll added by @redsun82 in Swift: rename base_types in TypeDecl to inherited_types #14208 is resolved.
  • some QLDoc comments added.

* - regarding the old special case for TypeAlias.getABaseType(). We could restore the old behaviour (and extend it to TypeDecl), but I currently don't think it's the right thing to do and I want to discuss that (and perhaps be persuaded to change my mind). Consider:

typealias A_alias = A
class B : A_alias { }
typealias B_alias = B

As this PR stands now, getABaseType takes us from B to A and getADerivedType from A to B. Simple. It's the users job to call .getUnderlyingType if they might be working with a B_alias.

If we have getABaseType take us from B_alias to A as well (that is from both B and B_alias to A), then (assuming we keep the symmetry between them...) getADerivedType has two results for A, one of which is itself an alias. But then surely we want getADerivedType to work in the other direction from A_alias - implying additional results from getABaseType as well. That means both functions are many-to-many, and hard to think clearly about. Especially if there are more type aliases than in the example above...

As this PR stands I have removed the special case, updated the existing code that relied on it, and called it out explicitly in the change note.


There's a good chance this change will affect results on tests I haven't run locally. Once CI passes, I will do a DCA run as well.

@geoffw0 geoffw0 added the Swift label Sep 18, 2023
@geoffw0 geoffw0 requested a review from a team as a code owner September 18, 2023 21:59
MathiasVP
MathiasVP previously approved these changes Sep 19, 2023
Copy link
Contributor

@MathiasVP MathiasVP left a comment

Choose a reason for hiding this comment

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

I think this is a good direction to move in (and hence my approval). I'll wait with clicking merge to see if there are anyone else who disagree with this change.

@geoffw0
Copy link
Contributor Author

geoffw0 commented Sep 19, 2023

Thanks for the review. I agree about giving others chance to comment.

DCA shows a substantial analysis performance regression (14.9%), definitely worth looking into...

@geoffw0
Copy link
Contributor Author

geoffw0 commented Sep 20, 2023

... I was able to identify interpretElement0 as the culprit, specifically the two special cases for extensions which are now handled in getABaseType / getADerivedType as well (and in a more general way). I assume covering this case in two places gave us an N^2 explosion of ways to explore paths that used the extension case - hence the performance slowdown. In any case the solutions was deleting some ugly lines of code, so I'm pretty happy with it. I will confirm performance with another DCA run.

@geoffw0
Copy link
Contributor Author

geoffw0 commented Sep 21, 2023

DCA shows a reduced (7.3%) analysis performance regression now. Stage timings now blames Synth::Synth#378(swift/incomplete-hostname-regexp on calleluks__Tofu, but I think that might be a red herring (Synth stuff is prone to wobble; and I can't reproduce locally). I'm re-running DCA to get a better picture.

@geoffw0
Copy link
Contributor Author

geoffw0 commented Sep 22, 2023

The repeat DCA run shows a different spike (database run-queries on HelioMesquita__Swiftmazing) and an overall small analysis time improvement this time. I think the problem is solved and we're just looking at normal wobble.

@geoffw0
Copy link
Contributor Author

geoffw0 commented Sep 22, 2023

@redsun82 are you happy with the changes here / direction for getABaseType?

Copy link
Contributor

@redsun82 redsun82 left a comment

Choose a reason for hiding this comment

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

I definitely agree with you about type aliases, and the changes LGTM.

@geoffw0
Copy link
Contributor Author

geoffw0 commented Sep 22, 2023

Great, lets merge this! 🎉

@geoffw0 geoffw0 merged commit ab6e8b9 into github:main Sep 22, 2023
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.

3 participants