mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Use the new EscapeAnalysis infrastructure to make ARC code motion and ARC sequence opts much more powerful and fix a latent bug in AliasAnalysis. Adds a new API `EscapeAnalysis::mayReleaseContent()`. This replaces all uses if `EscapeAnalysis::canEscapeValueTo()`, which affects `AliasAnalysis::can[Apply|Builtin]DecrementRefCount()`. Also rewrite `AliasAnalysis::mayValueReleaseInterferWithInstruction` to directly use `EscapeAnalysis::mayReleaseContent`. The new implementation in `EscapeAnalysis::mayReleaseContent()` generalizes the logic to handle more cases while avoiding an incorrect assumption in the prior code. In particular, it adds support for disambiguating local references from accessed addresses. This helps handle cases in which inlining was defeating ARC optimization. The incorrect assumption was that a non-escaping address is never reachable via a reference. However, if a reference does not escape, then an address into its object also does not escape. The bug in `AliasAnalysis::mayValueReleaseInterfereWithInstruction()` appears not to have broken anything yet because it is always called by `AliasAnalysis::mayHaveSymmetricInteference()`, which later checks whether the accessed address may alias with the released reference using a separate query, `EscapeAnalysis::canPointToSameMemory()`. This happens to work because an address into memory that is directly released when destroying a reference necesasarilly points to the same memory object. For this reason, I couldn't figure out a simple way to hand-code SIL tests to expose this bug. The changes in diff order: Replace EscapeAnalysis `canEscapeToValue` with `mayReleaseContent` to make the semantics clear. It queries: "Can the given reference release the content pointed to the given address". Change `AliasAnalysis::canApplyDecrementRefCount` to use `mayReleaseContent` instead if 'canEscapeToValue'. Change `AliasAnalysis::mayValueReleaseInterferWithInstruction`: after getting the memory address accessed by the instruction, simply call `EscapeAnalysis::mayReleaseContent`, which now implements all the logic. This avoids the bad assumption made by AliasAnalysis. Handle two cases in mayReleaseContent: non-escaping instruction addresses and non-escaping referenecs. Fix the non-escaping address case by following all content nodes to determine whether the address is reachable from the released reference. Introduce a new optimization for the case in which the reference being released is allocated locally. The following test case is now optimized in arcsequenceopts.sil: remove_as_local_object_indirectly_escapes_to_callee. It was trying to test that ARC optimization was not too aggressive when it removed a retain/release of a child object whose parent container is still in use. But the retain/release should be removed. The original example already over-releases the parent object. Add new unit tests to late_release_hoisting.sil.
29 KiB
29 KiB