Commit Graph

291 Commits

Author SHA1 Message Date
Andrew Trick
e400b66897 Cleanup replaceAllUsesAndErase, return an iterator, allow erase handlers.
This will make the forthcoming CanonicalizeInstruction interface more
clear.

This is generally the better approach to utilities that mutate the
instruction stream. It avoids the temptation to assume that only a
single instruction will be deleted or that only instructions before
the current iterator will be deleted. This often happens to work but
eventually fails in the presense of debug and end-of-scope
instructions.

A function returning an iterator has a more clear contract than one
accepting some iterator reference of unknown
providence. Unfortunately, it doesn't work at the lowest level of
utilities, such as recursivelyDeleteTriviallyDeadInstructions, where
we want to handle instruction batches.
2019-05-06 08:36:56 -07:00
Erik Eckstein
86fb74a34e DI: support assign_by_delegate instruction 2019-04-23 11:32:28 -07:00
Slava Pestov
8915f96e3e SIL: Replace SILType::isTrivial(SILModule) with isTrivial(SILFunction) 2019-03-12 01:16:04 -04:00
Azoy
5af2663c57 Textualize assign init kind
Rename [assign] to [reassign]

fix some tests

AssignOwnershipQualifier

formatting

moar formatting
2019-02-12 20:16:25 -06:00
Azoy
fcd6a8adf3 Lower Assign to store [assign] & Remove MandatoryOptUtils
update debug_type
2019-02-12 18:10:17 -06:00
Azoy
397b96c917 [SILOptimizer] Don't lower AssignInst in DI 2019-02-12 18:10:17 -06:00
Jordan Rose
425c190086 Restore initializing entry points for @objc convenience initializers (#21815)
This undoes some of Joe's work in 8665342 to add a guarantee: if an
@objc convenience initializer only calls other @objc initializers that
eventually call a designated initializer, it won't result in an extra
allocation. While Objective-C /allows/ returning a different object
from an initializer than the allocation you were given, doing so
doesn't play well with some very hairy implementation details of
compiled nib files (or NSCoding archives with cyclic references in
general).

This guarantee only applies to
(1) calling `self.init`
(2) where the delegated-to initializer is @objc
because convenience initializers must do dynamic dispatch when they
delegate, and Swift only stores allocating entry points for
initializers in a class's vtable. To dynamically find an initializing
entry point, ObjC dispatch must be used instead.

(It's worth noting that this patch does NOT check that the calling
initializer is a convenience initializer when deciding whether to use
ObjC dispatch for `self.init`. If we ever add peer delegation to
designated initializers, which is totally a valid feature, that should
use static dispatch and therefore should not go through objc_msgSend.)

This change doesn't /always/ result in fewer allocations; if the
delegated-to initializer ends up returning a different object after
all, the original allocation was wasted. Objective-C has the same
problem (one of the reasons why factory methods exist for things like
NSNumber and NSArray).

We do still get most of the benefits of Joe's original change. In
particular, vtables only ever contain allocating initializer entry
points, never the initializing ones, and never /both/ (which was a
thing that could happen with 'required' before).

rdar://problem/46823518
2019-01-14 13:06:50 -08:00
Slava Pestov
84ed245f2f DI: Fix transformation of value_metatype inside convenience init in Swift 5 mode
In Swift 5 mode, 'self' in a convenience init has a DynamicSelfType, so
the value_metatype instruction returns a DynamicSelfType metatype.

However, the metatype argument to the constructor is a plain class metatype
because it's an interface type, so we have to "open" it by bitcasting it
to a DynamicSelfType.

Fixes <https://bugs.swift.org/browse/SR-9430>, <rdar://problem/46982573>.
2019-01-11 15:53:37 -05:00
Michael Gottesman
c6f5995254 [definite-init] Convert always true bool return value to void.
Just a small cleanup.
2019-01-02 09:45:11 -08:00
Saleem Abdulrasool
cde0862468 Merge pull request #21537 from compnerd/optimize-incorrectly
SILOptimizer: fix a few instances of use-after-free
2019-01-02 08:28:44 -08:00
Michael Gottesman
9620bedf7a [di] Rename: DIMemoryUseCollector{Ownership,}.{cpp,h}
This was done early on during the split of predictable mem opts from DI. This
has been done for a long time, so eliminate the "Ownership" basename suffix.
2018-12-30 16:11:56 -08:00
Saleem Abdulrasool
bd93229428 SILOptimizer: fix a few instances of use-after-free
When building on Windows, the std::string being passed will on the
stack, where the destructor will be invoked before the return, nil'ing
out reference.  This causes incorrect behaviour when building the
diagnostic or FIXITs.  Explicitly create the StringRef to prevent the
std::string from being invalidated.
2018-12-23 16:24:04 -08:00
Slava Pestov
a5f9619062 DI: Lower AssignInst in a post-processing pass
Compiler passes that intermingle analysis with mutation of the CFG
are fraught with danger. The bug here was that a single AssignInst
could appear twice in DI's Uses list, once as a store use and once
as a load use.

When processing Uses, we would lower AssignInsts on the fly. We would
take care to erase the instruction pointer from the current Use, but
if a subsequent Use *also* referenced the now-deleted AssignInst, we
would crash.

Handle this in the standard way: instead of lowering assignments
right away, just build a list of assignments that we're planning on
lowering and process them all at the very end.

This has the added benefit of simplifying the code, because we no
longer have to work as hard to keep the state of the Uses list
consistent while lowering AssignInsts. The rest of DI should not
care that the lowering got postponed either, since it was already
expected to handle any ordering of elements in the Uses list, so
it could not assume that any particular AssignInst has been lowered.

Fixes <https://bugs.swift.org/browse/SR-9451>.
2018-12-10 00:03:08 -05:00
Slava Pestov
38263ca000 DI: Small cleanups
- Handle DIMemoryUse::Kind::IndirectIn just like Load
- Consolidate duplicated 'only touches trivial elements' check
2018-12-10 00:03:08 -05:00
Saleem Abdulrasool
15d3bf15db SILOptimizer: avoid use-after-free with the name
On Windows at least, the std::string associated with the name of the
property would be copy constructed before being passed to the diagnostic
engine.  The resultant DiagnosticArgument in the InFlightDiagnostic
would hold a StringRef to the copy-constructed std::string.  However,
because the arguments are inalloca'ed on Windows, the copy constructed
string would be destructed before the return of the argument.
Fortunately, this would result in the standard library overwriting the
string and the use-after-free would fail to print the argument.
Explicitly construct the StringRef before passing the name to the
diagnostic to avoid the use-after-free.
2018-11-26 13:04:06 -08:00
Andrew Trick
fe10da1b6e Don't create critical edges in definite-initialization. 2018-10-20 01:55:15 -07:00
Joe Groff
9c5432c0dd Make __consuming meaningful for code generation.
Previously, the `__consuming` decl modifier failed to get propagated to the value ownership of the
method's `self` parameter, causing it to effectively be a no-op. Fix this, and address some of the
downstream issues this exposes:

- `coerceCallArguments` in the type checker failing to handle the single `__owned` parameter case
- Various places in SILGen and optimizer passes that made inappropriate assertions that `self`
  was always passed guaranteed
2018-09-28 14:09:59 -07:00
Michael Gottesman
c62f31f5dc Inject llvm::SmallBitVector into namespace swift;
I also eliminated all llvm:: before SmallBitVector in the code base.
2018-09-21 09:49:25 -07:00
Joe Groff
5a55b4fc4f Small cleanups to type(of: self) handling in DI
Should be NFC
2018-09-13 15:33:15 -07:00
Joe Groff
b44ddf59d5 SILOptimizer: Turn type(of: self) from uninitialized self stack space into the self argument.
Before we changed convenience inits into allocating entry points, we allowed type(of: self) to be invoked on the uninitialized object, which was fine. This no longer Just Works when self doesn't even exist before `self.init` is called, but to maintain the old semantics and source compatibility, we can still just use the metatype value we were passed in.
2018-09-13 12:31:27 -07:00
John McCall
b80618fc80 Replace materializeForSet with the modify coroutine.
Most of this patch is just removing special cases for materializeForSet
or other fairly mechanical replacements.  Unfortunately, the rest is
still a fairly big change, and not one that can be easily split apart
because of the quite reasonable reliance on metaprogramming throughout
the compiler.  And, of course, there are a bunch of test updates that
have to be sync'ed with the actual change to code-generation.

This is SR-7134.
2018-08-27 03:24:43 -04:00
John McCall
b2f20c063f Fix and improve DI diagnostics around inout uses of immutable constants.
The only real bug here is that we were looking specifically for `apply`
instructions, so we failed to diagnose `try_apply` calls to mutating
throwing functions on immutable existentials.  Fixing this is a
source-compatibility break, but it's clearly in the "obvious bug" category
rather than something we need to emulate.  (I found this bug because DI
stopped diagnosing a modification of a property of a `let` existential
when it started being done with `modify`, which of course is called with
`begin_apply`.)
2018-08-20 02:51:44 -04:00
Slava Pestov
c7fff66c5d DI: Don't forget to check inout uses for try_apply too
Fixes <https://bugs.swift.org/browse/SR-8368>, <rdar://problem/42597950>.
2018-07-27 17:40:29 -07:00
Bob Wilson
8e330ee344 NFC: Fix indentation around the newly renamed LLVM_DEBUG macro.
Jordan used a sed command to rename DEBUG to LLVM_DEBUG. That caused some
lines to wrap and messed up indentiation for multi-line arguments.
2018-07-21 00:56:18 -07:00
Jordan Rose
cefb0b62ba Replace old DEBUG macro with new LLVM_DEBUG
...using a sed command provided by Vedant:

$ find . -name \*.cpp -print -exec sed -i "" -E "s/ DEBUG\(/ LLVM_DEBUG(/g" {} \;
2018-07-20 14:37:26 -07:00
John McCall
34b0cbc11d Merge pull request #16237 from davezarzycki/metaprogram_ref_storage_types
[AST] NFC: Enable reference storage type meta-programming
2018-07-05 14:45:38 -04:00
Ravi Kandhadai
895c1f0355 [DefiniteInitialization] Check whether globals captured by top-level
defer statements are initialized.

<rdar://30720636>
2018-07-02 11:40:21 -07:00
David Zarzycki
03b7eae9ed [SILOptimizer] NFC: Adopt reference storage type meta-programming macros 2018-06-30 06:44:33 -04:00
Ravi Kandhadai
964397c9a8 Revert "[DefiniteInitialization] Fix the bug that allows overwriting immutable"
This reverts commit 82abf974f2 as it breaks
compatability of some existing benchmarks.

<rdar://41501480>
2018-06-27 11:45:58 -07:00
swift-ci
bc67ab4c08 Merge pull request #17271 from ravikandhadai/DIOptWritePR 2018-06-25 17:38:07 -07:00
Ravi Kandhadai
82abf974f2 [DefiniteInitialization] Fix the bug that allows overwriting immutable
variables of optional type (SR-7226, rdar://38624845)
2018-06-22 14:55:21 -07:00
Slava Pestov
296ce3f312 AST: Remove hack-around for getInterfaceType() on ParamDecl returning InOutType
Most callers did not want the InOutType here, and checked
the ParamDecl's flags instead.
2018-06-13 15:38:52 -07:00
Slava Pestov
003ef6cef9 DI: Remove unnecessary assertion
It's totally fine to have a conditional destroy of 'self' because
we now uniformly treat assignment to self and self.init delegation,
both of which can appear multiple times in a value type
initializer.

This change removes the assertion and adds some tFileCheck tests to
ensure that DI was already capable of inserting the correct memory
management operations in this scenario.

Fixes <rdar://problem/40417944>, <https://bugs.swift.org/browse/SR-7727>.
2018-06-03 23:57:38 -07:00
Michael Gottesman
8886368854 [definite-init] Treat destroys of mark_uninitialized [var] container to be a load + destroy.
This ensures that DI creates dealloc_box in cases where the box is uninitialized
conditionally.

In the process, I also discovered that we were missing a test case for DI being
used by LLDB. Long term we shouldn't support that code pattern in the general
case, but for now we at least need a test case for it.

rdar://40332620
2018-05-30 14:25:50 -07:00
Michael Gottesman
2872389826 [definite-init] Split raw SIL instruction lowering out of DI into its own pass run after DI.
I am doing this so I can start writing DI tests without this lowering occuring.
There never was a real reason for this code to be in DI beyond convenience. Now
it just makes writing tests more difficult. To prevent any test delta, I changed
all current DI tests to run this pass after DI.
2018-05-22 18:18:22 -07:00
David Zarzycki
8c0c55539f [SIL] NFC: Rename misleading getSwiftRValueType() to getASTType()
Reference storage types are not RValues. Also, use more SILType helper
methods to avoid line wrap.
2018-05-04 08:14:38 -04:00
Arnold Schwaighofer
e36655fddc SILGen: Remove PostponedCleanup in favor or the SIL pass that fixes
closure lifetimes.

SILGen will now unconditionally emit

  %cvt = convert_escape_to_noescape [guaranteed] %op

instructions. The mandatory ClosureLifetimeFixup pass ensures that %op's
lifetime spans %cvt's uses.

The code in DefiniteInitialization that handled a subset of cases is
removed.
2018-04-13 13:44:09 -07:00
Arnold Schwaighofer
36d5408125 SIL: Add an [escaped] attribute to convert_escape_to_noescape instruction
To mark when a user of it is known to escape the value. This happens
with materializeForSet arguments which are captured and used in the
write-back. This means we need to keep the context alive until after
the write-back.

Follow-up patches to fully replace the PostponedCleanup hack in SILGen
by a mandatory SIL transformation pass to guarantee the proper lifetime
will use this flag to be more conservative when extending the lifetime.

The problem:

%pa = partial_apply %f(%some_context)
%cvt = convert_escape_to_noescape [not_guaranteed] [escaped] %pa
%ptr = %materialize_for_set(..., %cvt)
...  write_back
... // <-- %pa needs to be alive until after write_back
2018-04-13 12:40:10 -07:00
Arnold Schwaighofer
8f0976d5aa Really fix the logic error in fixupConvertEscapeToNoEscapeLifetime 2018-03-30 12:55:41 -07:00
Arnold Schwaighofer
f40ac5d6d9 Rewrite DI to always guaranteed the lifetime of the convert_escape_to_noescape [not_guaranteed] operand
Either through a peephole or we keep the closure operand alive to the end of the function

rdar://38124009
2018-03-30 09:27:53 -07:00
Arnold Schwaighofer
a9786978b2 Ensure lifetimes of optional convert_escape_to_noescape closures
rdar://38124009
2018-03-30 06:20:13 -07:00
Slava Pestov
34fd4ae512 AST: Use DeclBaseName::Kind::Constructor
Fixes <rdar://problem/35852727>, <https://bugs.swift.org/browse/SR-1660>,
<https://bugs.swift.org/browse/SR-6557>.
2018-03-16 00:25:56 -07:00
Sho Ikeda
422136e1a2 [gardening][enum class] Replace unsigned char with uint8_t for consistency
Before the changes:

- `git grep -E "enum class .+ : uint8_t \{" | wc -l`: 90
- `git grep -E "enum class .+ : unsigned char \{" | wc -l`: 26
2018-03-12 13:57:36 +09:00
Andrew Trick
4734920222 Don't rerun diagnostic passes on deserialized SIL. 2018-02-09 09:55:47 -08:00
Mark Lacey
b4b66bc8e8 Replace getAnyOptionalObjectType with getOptionalObjectType. 2018-02-05 23:59:00 -08:00
Joe Groff
6e9a428543 DefiniteInitialization: Storing back to the 'self' box in a class init is OK.
SILGen does this now to maintain ownership balance when a class initializer delegation gets interrupted, such as by an error propagation through one of the arguments to the delegatee. Fixes rdar://problem/37007554 .
2018-02-03 10:01:15 -08:00
Davide Italiano
3d9eb3d7e5 [LifetimeChecker] Update the debug scope when changing insertion point.
<rdar://problem/36679700>
2018-01-22 14:45:08 -08:00
Adrian Prantl
c74ae5f375 Remove the redundant SILLocation::getCompilerGenerated interface (NFC) 2018-01-17 11:09:23 -08:00
Davide Italiano
1a153d410a [DefiniteInit] Correctly set the debug scope when creating a store.
Fixes https://bugs.swift.org/browse/SR-6745

<rdar://problem/36474392>
2018-01-14 14:43:41 -08:00
John McCall
52bb547a7e Merge pull request #13866 from rjmccall/accessor-decl
Split AccessorDecl out from FuncDecl.  NFC.
2018-01-12 17:02:35 -05:00