Skip to content

Restrict CopyForwarding (and destroy hoisting) to OSSA SIL. #34841

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

Merged
merged 1 commit into from
Nov 20, 2020

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Nov 20, 2020

The premise of CopyForwarding was that memory locations have their own
ownership lifetime. We knew this was unmaintainable at the time, and
that was the original incentive for SIL opaque values, aided by
OSSA. In the meantime, we've been relying on SILGen producing
reasonable SIL patterns. Unfortunately, the CopyForwarding pass is
still with us while we make major changes to SIL ownership patterns
and agressively optimize ownership. That introduces risk.

Ultimately, the entire CopyForwarding pass should be redesigned for
OSSA-only and destroy hoisting should be a simple OSSA utility where
most of the work is done by AccessPath::collectUses.

But in the meantime, we should remove the source of risk by limiting
the CopyForwarding pass to OSSA. Any performance regressions will be
recovered as OSSA moves later in the pipeline. After that, opaque
values will improve even more over the current state by handling
generic SIL using the more powerful CopyPropagation pass.

Fixes rdar://71584600 (miscompile in CopyForwarding's release hoisting)

Here's an example of the kind of SIL the CopyForwarding does not
anticipate (although it only actually miscompiles in much more obscure
scenarios, which is why it's so dangerous):

bb0(%0 : $AnyObject):
%alloc1 = alloc_stack $AnyObject
store %0 to %objaddr : $*AnyObject
%ref = load %objaddr : $*AnyObject
%alloc2 = alloc_stack $ObjWrapper

The in-memory reference is destroyed before retaining the loaded ref.

copy_addr [take] %alloc1 to [initialization] %alloc2 : $*ObjWrapper
retain_value %ref : $AnyObject

The premise of CopyForwarding was that memory locations have their own
ownership lifetime. We knew this was unmaintainable at the time, and
that was the original incentive for SIL opaque values, aided by
OSSA. In the meantime, we've been relying on SILGen producing
reasonable SIL patterns. Unfortunately, the CopyForwarding pass is
still with us while we make major changes to SIL ownership patterns
and agressively optimize ownership. That introduces risk.

Ultimately, the entire CopyForwarding pass should be redesigned for
OSSA-only and destroy hoisting should be a simple OSSA utility where
most of the work is done by AccessPath::collectUses.

But in the meantime, we should remove the source of risk by limiting
the CopyForwarding pass to OSSA. Any performance regressions will be
recovered as OSSA moves later in the pipeline. After that, opaque
values will improve even more over the current state by handling
generic SIL using the more powerful CopyPropagation pass.

Fixes rdar://71584600 (miscompile in CopyForwarding's release hoisting)

Here's an example of the kind of SIL the CopyForwarding does not
anticipate (although it only actually miscompiles in much more obscure
scenarios, which is why it's so dangerous):

bb0(%0 : $AnyObject):
  %alloc1 = alloc_stack $AnyObject
  store %0 to %objaddr : $*AnyObject
  %ref = load %objaddr : $*AnyObject
  %alloc2 = alloc_stack $ObjWrapper
  # The in-memory reference is destroyed before retaining the loaded ref.
  copy_addr [take] %alloc1 to [initialization] %alloc2 : $*ObjWrapper
  retain_value %ref : $AnyObject
@atrick atrick requested a review from eeckstein November 20, 2020 06:06
@atrick
Copy link
Contributor Author

atrick commented Nov 20, 2020

@swift-ci test

@atrick
Copy link
Contributor Author

atrick commented Nov 20, 2020

@swift-ci benchmark

@swift-ci
Copy link
Contributor

Performance: -O

Regression OLD NEW DELTA RATIO
UTF8Decode_InitFromData_ascii_as_ascii 641 715 +11.5% 0.90x (?)
Array2D 6688 7216 +7.9% 0.93x (?)
 
Improvement OLD NEW DELTA RATIO
FlattenListFlatMap 6763 6094 -9.9% 1.11x (?)
DataToStringLargeUnicode 7600 6850 -9.9% 1.11x (?)
Data.hash.Empty 77 71 -7.8% 1.08x (?)
DataToStringMedium 5800 5400 -6.9% 1.07x (?)

Code size: -O

Regression OLD NEW DELTA RATIO
RangeOverlaps.o 5798 6038 +4.1% 0.96x
DiffingMyers.o 6085 6277 +3.2% 0.97x
DictionaryBridgeToObjC.o 4944 5064 +2.4% 0.98x
DictionaryOfAnyHashableStrings.o 7912 8040 +1.6% 0.98x
ProtocolConformance.o 3799 3847 +1.3% 0.99x
FloatingPointConversion.o 41377 41873 +1.2% 0.99x
BucketSort.o 8587 8683 +1.1% 0.99x
 
Improvement OLD NEW DELTA RATIO
Suffix.o 22341 21116 -5.5% 1.06x
FloatingPointParsing.o 18882 17986 -4.7% 1.05x
RandomTree.o 11943 11775 -1.4% 1.01x

Performance: -Osize

Regression OLD NEW DELTA RATIO
StringBuilderLong 1470 1700 +15.6% 0.86x (?)
DataAccessBytesMedium 91 102 +12.1% 0.89x (?)
DataCountSmall 28 31 +10.7% 0.90x (?)
UTF8Decode_InitFromBytes_ascii_as_ascii 452 494 +9.3% 0.91x (?)
SuffixArrayLazy 11 12 +9.1% 0.92x
SuffixArray 11 12 +9.1% 0.92x
SuffixCountableRangeLazy 11 12 +9.1% 0.92x
Array2D 7520 8112 +7.9% 0.93x (?)
ObjectiveCBridgeFromNSDictionaryAnyObjectForced 9000 9700 +7.8% 0.93x (?)
 
Improvement OLD NEW DELTA RATIO
ObjectiveCBridgeStubFromNSDate 5810 4920 -15.3% 1.18x (?)
SuffixAnyCollection 65 59 -9.2% 1.10x
DataSubscriptSmall 37 34 -8.1% 1.09x

Code size: -Osize

Regression OLD NEW DELTA RATIO
DictionaryBridgeToObjC.o 4143 4276 +3.2% 0.97x
DiffingMyers.o 6090 6216 +2.1% 0.98x
FloatingPointConversion.o 39571 40067 +1.3% 0.99x
ProtocolConformance.o 3506 3543 +1.1% 0.99x
 
Improvement OLD NEW DELTA RATIO
Suffix.o 21199 20113 -5.1% 1.05x
FloatingPointParsing.o 17592 17088 -2.9% 1.03x

Performance: -Onone

Regression OLD NEW DELTA RATIO
RandomIntegersLCG 43934 54630 +24.3% 0.80x
RandomDoubleLCG 57454 71046 +23.7% 0.81x
RandomDoubleDef 93000 109200 +17.4% 0.85x (?)
ErrorHandling 4550 5030 +10.5% 0.90x (?)
RandomIntegersDef 62800 69300 +10.4% 0.91x (?)
Breadcrumbs.MutatedIdxToUTF16.ASCII 12 13 +8.3% 0.92x (?)
Dict.FilterAllMatch.28k 5282 5717 +8.2% 0.92x (?)
Dict.FilterAllMatch.16k 2792 3020 +8.2% 0.92x (?)
FlattenListFlatMap 236352 254148 +7.5% 0.93x (?)
 
Improvement OLD NEW DELTA RATIO
SevenBoom 2331 1755 -24.7% 1.33x (?)
NSStringConversion.Mutable 6601 5764 -12.7% 1.15x (?)
Dictionary4OfObjectsLegacy 1983 1740 -12.3% 1.14x (?)
Prims.NonStrongRef.Unmanaged.Closure 1686 1517 -10.0% 1.11x (?)
FindString.Rec3.String 948 855 -9.8% 1.11x (?)
Prims.NonStrongRef.Unmanaged 1646 1489 -9.5% 1.11x (?)
MapReduceShortString 270 246 -8.9% 1.10x (?)
FindString.Rec3.Substring 895 816 -8.8% 1.10x (?)
NSError 963 888 -7.8% 1.08x (?)
ArrayOfGenericPOD2 1110 1024 -7.7% 1.08x (?)
ArrayOfPOD 1134 1049 -7.5% 1.08x (?)
StringBuilderSmallReservingCapacity 3304 3068 -7.1% 1.08x (?)
CharIndexing_russian_unicodeScalars 153480 142640 -7.1% 1.08x (?)
Set.isStrictSubset.Seq.Int.Empty 1407 1312 -6.8% 1.07x (?)

Code size: -swiftlibs

How to read the data The tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.

If you see any unexpected regressions, you should consider fixing the
regressions before you merge the PR.

Noise: Sometimes the performance results (not code size!) contain false
alarms. Unexpected regressions which are marked with '(?)' are probably noise.
If you see regressions which you cannot explain you can try to run the
benchmarks again. If regressions still show up, please consult with the
performance team (@eeckstein).

Hardware Overview
  Model Name: Mac Pro
  Model Identifier: MacPro6,1
  Processor Name: 12-Core Intel Xeon E5
  Processor Speed: 2.7 GHz
  Number of Processors: 1
  Total Number of Cores: 12
  L2 Cache (per Core): 256 KB
  L3 Cache: 30 MB
  Memory: 64 GB

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

lgtm!

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 39db766

@atrick
Copy link
Contributor Author

atrick commented Nov 20, 2020

I've been seeing this failure a lot recently:
lldb-api :: lang/swift/unknown_self/TestSwiftUnknownSelf.py

@atrick
Copy link
Contributor Author

atrick commented Nov 20, 2020

@swift-ci smoke test and merge

@swift-ci swift-ci merged commit aa8ce55 into swiftlang:main Nov 20, 2020
@atrick atrick deleted the disable-cpf branch October 19, 2022 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants