Commit Graph

6319 Commits

Author SHA1 Message Date
Erik Eckstein
1baf009c06 refactoring: Split MemoryLifetime.cpp/h into three separate files
And rename MemoryDataflow -> BitDataflow.

MemoryLifetime contained MemoryLocations, MemoryDataflow and the MemoryLifetimeVerifier.
Three independent things, for which it makes sense to have them in three separated files.

NFC.
2021-03-13 10:41:30 +01:00
Erik Eckstein
ad8252654d RawSILInstLowering: delete dead load instructions when lowering assign_by_wrapper
If only the init-closure is used and the setter-closure is dead, the argument to the setter partial_apply also needs to be delete - in case it's a load.
Otherwise it would cause a memory lifetime failure.
2021-03-13 10:41:30 +01:00
Andrew Trick
11a641ff03 Enable mandatory copy propagation SIL pass.
This shortens -Onone lifetimes.

To eliminate ARC traffic, the optimizer reorders object
destruction. This changes observable program behavior. If a custom
deinitializer produces side effects, code may observe those side
effects earlier after optimization. Similarly, code that dereferences
a weak reference may observe a 'nil' reference after optimization,
while the unoptimized code observed a valid object.

Developers have overwhelmingly requested that object lifetimes have
similar behavior in -Onone and -O builds in order to find and diagnose
program bugs involving weak references and other lifetime assumptions.

Enabling the copy propagation at -Onone is simply a matter of flipping
a switch. -Onone runtime and code size will improve. By design, copy
propagation, has no direct affect on compile time. It will indirectly
improve optimized compile times, but in debug builds, it simply isn't
a factor.

To support debugging, a "poison" flag was (in prior commits) added to
new destroy_value instructions generated by copy propagation.  When
OwnershipModelEliminator lowers destroy_value [poison] it will
generate new debug_value instructions with a “poison” flag.

These additional poison stores to the stack could increase both code
size and -Onone runtime.

rdar://75012368 (-Onone compiler support for early object deinitialization with sentinel dead references)
2021-03-12 19:34:39 -08:00
Andrew Trick
97ec127d25 Lower and emit debug_value [poison].
OwnershipEliminator lowers destroy_value [poison] to debug_value
[poison].

IRGen overwrites all references in shadow copies with a sentinel value
in place of debug_value [poison].

Part 2/2: rdar://75012368 (-Onone compiler support for early object
deinitialization with sentinel dead references)
2021-03-12 19:33:23 -08:00
Andrew Trick
0b3027a37e Add destroy_value [poison] support to mandatory copy propagation.
Ensure that any object lifetime that will be shortened ends in
destroy_value [poison], indicating that the reference should not be
dereferenced (e.g. by the debugger) beyond this point.

This has no way of knowing whether the object will actually be
deallocated at this point. It conservatively avoids showing garbage to
debuggers.

Part 1/2: rdar://75012368 (-Onone compiler support for early object
deinitialization with sentinel dead references)
2021-03-12 19:32:55 -08:00
David Zarzycki
b80ca8e8eb Merge pull request #36234 from davezarzycki/pr36234
[AST] NFC: Make ExtInfo param Optional<>
2021-03-12 13:47:22 -05:00
eeckstein
6b87566f95 Merge pull request #36369 from eeckstein/dead-cast-elimination
SILCombine: remove dead unconditional_checked_cast
2021-03-10 12:40:24 +01:00
Joe Groff
872afda50b Merge pull request #36298 from jckarter/created-task-closure-context-leak
SIL: Clean up ownership handling in `createAsyncTask` builtins.
2021-03-09 14:17:13 -08:00
eeckstein
6650febc61 Merge pull request #36363 from eeckstein/diagnose-objc-weak
DiagnoseLifetimeIssues: handle ObjectiveC weak properties
2021-03-09 19:40:20 +01:00
Erik Eckstein
74fe92ffdb SILCombine: remove dead unconditional_checked_cast
rdar://72200045
2021-03-09 19:38:35 +01:00
Erik Eckstein
a7fa45c176 DiagnoseLifetimeIssues: handle ObjectiveC weak properties
Issue warnings if an object is stored to an ObjectiveC weak property (via a setter) and destroyed before the property is ever used again.

rdar://74620325
2021-03-09 13:23:24 +01:00
David Zarzycki
c0ec6c3235 [AST] NFC: Make ExtInfo param Optional<>
While it is very convenient to default the ExtInfo state when creating
new function types, it also make the intent unclear to those looking to
extend ExtInfo state. For example, did a given call site intend to have
the default ExtInfo state or does it just happen to work? This matters a
lot because function types are regularly unpacked and rebuilt and it's
really easy to accidentally drop ExtInfo state.

By changing the ExtInfo state to an optional, we can track when it is
actually needed.
2021-03-09 05:57:39 -05:00
Joe Groff
d9798c0868 Concurrency: Redo non-_f variants of swift_task_create to accept closures as is.
In their previous form, the non-`_f` variants of these entry points were unused, and IRGen
lowered the `createAsyncTask` builtins to use the `_f` variants with a large amount of caller-side
codegen to manually unpack closure values. Amid all this, it also failed to make anyone responsible
for releasing the closure context after the task completed, causing every task creation to leak.
Redo the `swift_task_create_*` entry points to accept the two words of an async closure value
directly, and unpack the closure to get its invocation entry point and initial context size
inside the runtime. (Also get rid of the non-future `swift_task_create` variant, since it's unused
and it's subtly different in a lot of hairy ways from the future forms. Better to add it later
when it's needed than to have a broken unexercised version now.)
2021-03-08 16:54:19 -08:00
Erik Eckstein
2d73b21b2b StringOptimization: optimize C string literals.
Replace a String initializer followed by String.utf8CString with a (UTF8 encoded) string literal.
This code pattern is generated when calling C functions with string literals, e.g.

  puts("hello!")

rdar://74941849
2021-03-08 08:34:53 +01:00
Erik Eckstein
78a7887244 SILCombine: optimize mark_dependence of a string literal.
This pattern can occur after StringOptimization when a utf8CString of a literal is replace by the string_literal itself.
2021-03-08 08:34:53 +01:00
Erik Eckstein
9f1ccdebe9 MemoryLifetime: support select_enum_addr, existential_metatype, value_metatype, is_unique and fix_lifetime 2021-03-07 09:10:22 +01:00
Erik Eckstein
45f08bd7c4 MemoryLifetime: support init_existential_addr and open_existential_addr
Also, relax the check for enums a bit. Instead of only accepting single-payload enums, just require that the payload type is the same for an enum location.
2021-03-07 09:10:22 +01:00
Erik Eckstein
b73285d20d MemoryLifetime: support unchecked_ref_cast_addr and unconditional_checked_cast_addr instructions 2021-03-07 09:10:22 +01:00
Erik Eckstein
54e0a5403e MemoryLifetime: support checked_cast_addr_br 2021-03-07 09:10:22 +01:00
Erik Eckstein
85a5826d2c CastOptimizer: fix a small deficiency when optimizing checked_cast_addr_br instructions.
Handle destroy_addr of the destination. When replacing the cast, just remove such destroys.
In real world SIL there will always be a destroy_addr in the success-branch of the cast.
Not sure if this optimization could have ever kicked in for real world code.
2021-03-07 09:10:22 +01:00
Meghana Gupta
6e0e4dcb88 Merge pull request #36174 from meg-gupta/fixcastoptimizer
Fix verifier error in CastOptimizer
2021-03-05 21:52:27 -08:00
Slava Pestov
7ccc41a7b7 SIL: Preliminary support for 'apply [noasync]' calls
Refactor SILGen's ApplyOptions into an OptionSet, add a
DoesNotAwait flag to go with DoesNotThrow, and sink it
all down into SILInstruction.h.

Then, replace the isNonThrowing() flag in ApplyInst and
BeginApplyInst with getApplyOptions(), and plumb it
through to TryApplyInst as well.

Set the flag when SILGen emits a sync call to a reasync
function.

When set, this disables the SIL verifier check against
calling async functions from sync functions.

Finally, this allows us to add end-to-end tests for
rdar://problem/71098795.
2021-03-04 22:41:46 -05:00
Meghana Gupta
eb1c656d0c Remove unnecessary #ifndef in PhiArgumentOptimizations.cpp 2021-03-04 13:24:29 -08:00
Meghana Gupta
df93b5cba4 Fix verifier error in CastOptimizer
While removing an invalid cast and inserting traps, we are currently
inserting a store of undef to the cast destination and delete all
instructions after the cast except for dealloc_stack.
If the cast destination was an alloc_stack, the verifier could raise
an error saying the cast destination was initialized at the dealloc.

This PR deletes the store to undef, destroy_addr of the cast src,
and gets rid of the code that was retaining the dealloc_stack.
None of this is necessary anymore and the SIL is going to be legal
because we insert unreachable instruction.
2021-03-04 13:19:42 -08:00
eeckstein
c4f6fc32c5 Merge pull request #36253 from eeckstein/fix-assign-by-wrapper
SIL: some improvements/fixes around assign_by_wrapper
2021-03-04 20:07:14 +01:00
Meghana Gupta
1f89d9ff89 Verify critical edges when -sil-verify-all is enabled 2021-03-03 23:45:56 -08:00
Erik Eckstein
9055e93af9 SIL: some improvements/fixes around assign_by_wrapper
* Refactoring: replace "Destination" and the ownership qualifier by a single "Mode".  This represents much better the mode how the instruction is to be lowered. NFC
* Make assign_by_wrapper printable and parseable.
* Fix lowering of the assign modes for indirect results of the init-closure: The indirect result was initialized and not assigned to. The fix is to insert a destroy_addr before calling the init closure. This fixes a memory lifetime error and/or a memory leak. Found by inspection.
* Fix an iterator-invalidation crash in RawSILInstLowering
* Add tests for lowering assign_by_wrapper.
2021-03-03 18:57:02 +01:00
Andrew Trick
291467c8a5 Merge branch 'main' into mandatory-copyprop 2021-03-03 05:53:51 -08:00
Andrew Trick
b41e268a7e CopyPropagation: respect -Xfrontend -disable-sil-ownership-verifier 2021-03-02 22:20:13 -08:00
Andrew Trick
a77ced8423 Add frontend flags for developers to easily control copy propagation:
-enable-copy-propagation: enables whatever form of copy propagation
 the current pipeline runs (mandatory-copy-propagation at -Onone,
 regular copy-propation at -O).

-disable-copy-propagation: similarly disables any form of copy
 propagation in the current pipelien.
2021-03-02 22:20:13 -08:00
Andrew Trick
b689b1dabe Rename GuaranteedARCOpts to MandatoryARCOpts.
This bleeds into the implementation where "guaranteed" is used
everywhere to talk about optimization of guaranteed values. We need to
use mandatory to indicate we're talking about the pass pipeline.
2021-03-02 22:20:13 -08:00
Andrew Trick
cb1ed89c9a [NFC] Add support for a mandatory-copy-propagation pass.
It is currently disabled so this commit is NFC.

MandatoryCopyPropagation canonicalizes all all OSSA lifetimes with
either CopyValue or DestroyValue operations. While regular
CopyPropagation only canonicalizes lifetimes with copies. This ensures
that more lifetime program bugs are found in debug builds. Eventually,
regular CopyPropagation will also canonicalize all lifetimes, but for
now, we don't want to expose optimized code to more behavior change
than necessary.

Add frontend flags for developers to easily control copy propagation:

-enable-copy-propagation: enables whatever form of copy propagation
 the current pipeline runs (mandatory-copy-propagation at -Onone,
 regular copy-propation at -O).

-disable-copy-propagation: similarly disables any form of copy
 propagation in the current pipelien.

To control a specific variant of the passes, use
   -Xllvm -disable-pass=mandatory-copy-propagation
or -Xllvm -disable-pass=copy-propagation instead.

The meaning of these flags will stay the same as we adjust the
defaults. Soon mandatory-copy-propagation will be enabled by
default. There are two reasons to do this, both related to predictable
behavior across Debug and Release builds.

1. Shortening object lifetimes can cause observable changes in program
   behavior in the presense of weak/unowned reference and
   deinitializer side effects.

2. Programmers need to know reliably whether a given code pattern will
   copy the storage for copy-on-write types (Array, Set). Eliminating
   the "unexpected" copies the same way at -Onone and -O both makes
   debugging tractable and provides assurance that the code isn't
   relying on the luck of the optimizer in a particular compiler
   release.
2021-03-02 22:19:47 -08:00
Erik Eckstein
aa16864a2c SIL: verify store_borrow
Verify that
* the destination address is an alloc_stack
* the stack location is not modified beside a store_borrow
* the stack location has been initialized when used
2021-03-02 12:02:54 +01:00
Erik Eckstein
d6736e93e0 MemoryLifetime: support partial_apply arguments in memory lifetime verification. 2021-03-02 12:02:54 +01:00
Erik Eckstein
fa11bdff1a RawSILInstLowering: delete an unused partial_apply when lowering assign_by_wrapper
So far we left this cleanup to SILCombine.
But the unused partial_apply (i.e. the "set" in case it's an init or the "init" in case it's a set) violates memory lifetime rules in case "self" is an inout.
Once we verify that, it would result in a memory lifetime violation.
2021-03-02 12:02:54 +01:00
Andrew Trick
ecc7127be8 Merge pull request #36183 from atrick/fix-dce-fixlifetime
Disable fix_lifetime DCE.
2021-02-26 14:37:31 -08:00
Andrew Trick
f470b29747 Disable fix_lifetime DCE.
Unless the type is a trivial scalar. As a follow-up we could try to
prove that the referenced object is unique, but that seems more
natural for DeadObjectElimination.

This optimization was never correct because references may alias. See
rdar://36038096 ([SR-6608] DeadCodeElimination removes fix_lifetime
instructions.)

Fixes rdar://74759728 (The compiler/optimizer seems to be shortening
the lifetime too early)
2021-02-26 11:06:10 -08:00
swift-ci
08638f23b5 Merge pull request #36182 from eeckstein/fix-destroyhoisting-debuginfo 2021-02-26 10:24:21 -08:00
Doug Gregor
3dec40cc05 Merge pull request #35874 from ktoso/wip-no-escape-group
[Concurrency] Reimplement Task.Group with accordance to Pitch #3
2021-02-26 08:57:26 -08:00
Slava Pestov
b007800aca Merge pull request #36170 from slavapestov/requirement-get-protocol-decl
AST: Factor out a new Requirement::getProtocolDecl() utility method
2021-02-26 11:19:32 -05:00
Erik Eckstein
9262c23b63 DestroyHoisting: create the correct debug info location kind for inserted destroys
Such locations should be cleanup locations and not regular locations.
Otherwise it could trigger a false unreachable-code warning.

rdar://74241814
2021-02-26 16:39:31 +01:00
Andrew Trick
7880a2f5e4 Merge pull request #36152 from atrick/fix-rauwclone
OSSA: Rewrite address cloning code to fix issues and fix an infinite loop in the ownership verifier.
2021-02-25 20:17:28 -08:00
Meghana Gupta
5e16e75e4f Merge pull request #36056 from meg-gupta/rlefixes
Fix ownershipKind of the phi's that the SILSSAUpdater creates for RLE
2021-02-25 19:13:51 -08:00
Slava Pestov
53e06d69b5 AST: Factor out a new Requirement::getProtocolDecl() utility method 2021-02-25 17:21:18 -05:00
Michael Gottesman
34e4e42642 [simplify-cfg] Only check if we can remove releases by performing simple jump threading if our block argument is not a trivial type.
Eliminates unnecessary work and reduces compile time.
2021-02-25 12:21:49 -08:00
Meghana Gupta
7445c5d7bb Fix ownershipKind of the phi's that the SILSSAUpdater creates for RLE
When the available values have none ownership on one side and owned on the other,
we need to merge their ownershipKind for their phi argument
2021-02-25 11:48:00 -08:00
Meghana Gupta
83b4aeb11c Print the name of the generic function for a specialized function
When debug printing for a function is turned on with
-sil-print-function, print the generic function is was derived from.
2021-02-25 11:30:27 -08:00
Andrew Trick
66752e9724 OSSA: Rewrite address cloning code to fix issues.
Generalize the AccessUseDefChainCloner in MemAccessUtils. It was
always meant to work this way, just needed a client.

Add a new API AccessUseDefChainCloner::canCloneUseDefChain().

Add a bailout for begin_borrow and mark_dependence. Those
projections may appear on an access path, but they can't be
individually cloned without compensating.

Delete InteriorPointerAddressRebaseUseDefChainCloner.

Add a check in OwnershipRAUWHelper for canCloneUseDefChain.

Add test cases for begin_borrow and mark_dependence.
2021-02-24 22:18:21 -08:00
Andrew Trick
7e19c4af03 Add a -sil-combine-canonicalize=false option for testing.
So I can test interesting ownership RAUW cases.
2021-02-24 21:27:42 -08:00
Konrad `ktoso` Malawski
6e525d7469 Merge branch 'main' into wip-no-escape-group 2021-02-25 10:37:20 +09:00