Commit Graph

2864 Commits

Author SHA1 Message Date
Jordan Rose
1598a21e43 DI: Warn on non-delegating cross-module struct initializers
...as detected by initializing an individual field without having
initialized the whole object (via `self = value`).

This only applies in pre-Swift-5 mode because the next commit will
treat all cross-module struct initializers as delegating in Swift 5.
2017-11-09 11:24:28 -08:00
Michael Gottesman
b17935aff2 [pred-memopt] Rather than extracting values at the load site, extract at the store site.
Previously in PredMemOpts, we would insert any extracts at the load site, i.e.:

  store %foo to %0
  ...
  %1 = struct_element_addr %0, $Type, $Type.field
  %2 = load %1
  ...
  apply %use(%2)

would transform to:

  store %foo to %0
  ...
  %2 = struct_extract %foo
  apply %use(%2)

This framework will not work with Ownership enabled since the value stored is
considered consumed by the store. This change fixes the issue by moving such
non-destructive extracts to occur while %foo is considered live, i.e. before the
store:

  %2 = struct_extract %foo
  store %foo to %0
  ...
  apply %use(%2)

This means that we have to store insertion points for each store that provides
us with available values and insert the extracts at those points. This creates
some complications in the case where we have multiple stores since we need to
deal with phi nodes. Rather than dealing with it by hand, we just insert the
extracts at each point and then use the SSA updater to insert the relevant phi
nodes.

rdar://31521023
2017-11-08 10:40:39 -08:00
Michael Gottesman
49f5c761ff [pred-memopt] Change AvailableValue to be its own struct instead of a typealias to std::pair.
For pred-memopt to work with ownership, we need to insert instructions in two
different places:

1. When loading not-available values, we must insert the load at the site of the
load we are trying to promote.
2. When propagating an available value, we must destructure and or copy before
each one of the stores that provide our value.

By changing AvailableValue to be a struct, I am providing a cleaner API, but
more importantly the ability to start tracking that information.

rdar://31521023
2017-11-08 10:40:39 -08:00
Michael Gottesman
9b1760b8f8 [PMOpt] Restructure aggregateAvailableValues as a class.
This is in preparation for adding the distinction of destructive vs
non-destructive extracts.

NFC.

rdar://31521023
2017-11-06 12:28:49 -08:00
Michael Gottesman
c459a8e771 [PMOpt] Extract out a helper function from promoteLoad to make the method flow better when read.
NFC.

rdar://31521023
2017-11-06 11:57:42 -08:00
Michael Gottesman
245f07e361 [PMOpt] Rename extractSubElement => nonDestructivelyExtractSubElement.
In non-ownership SIL, PMOpt did not need to distinguish in between destructive
and non-destructive sub element extraction. This allowed PMOpt to just use the
"non-destructive" sub element (i.e. extractSubElement) everywhere. In
preparation for introducing this distinction (and a destructive sub element
extractor), rename extractSubElement to be nonDestructivelyExtractSubElement for
clarity.

NFC.

rdar://31521023
2017-11-06 11:39:32 -08:00
Michael Gottesman
9c78f7501b [pred-memopt] Reorganize file slightly to ease review of further changes.
rdar://31521023
2017-11-06 11:35:43 -08:00
Michael Gottesman
6c10f911c0 [di] When scalarizing tuples in DI use destructure_tuple.
Bug noticed on inspection.

rdar://31521023
2017-11-05 00:10:15 -05:00
Arnold Schwaighofer
2ec064af36 Fix of mandatory inliner's handling of unowned and guaranteed captures
And fix it's handling of guaranteed closure contexts.

Guaranteed/unowned captures and guaranteed contexts are *not* released
by a call of the closure.

I assume we have not seen this because we don't see code that would
trigger this comming out of the frontend ...

SR-5441
rdar://33255593
2017-11-04 11:53:29 -07:00
Michael Gottesman
90453acc20 [pred-memopt] Clean up file a little bit as a separate commit instead of clang-format going wild on further commits.
Just chopping this off from a larger commit to ease review.

rdar://31521023
2017-11-03 22:48:58 -07:00
Huon Wilson
0236db7be1 [SIL] Witness methods store the conformance from which they come. 2017-11-01 11:33:26 -07:00
Greg Parker
d6e1866344 [SIL] Make @_silgen_name and @_cdecl functions immune to some optimizations (#12696)
@_silgen_name and @_cdecl functions are assumed to be referenced from
C code. Public and internal functions marked as such must not be deleted
by the optimizer, and their C symbols must be public or hidden respectively.

rdar://33924873, SR-6209
2017-11-01 01:41:05 -07:00
Michael Gottesman
c6696cee07 [pred-memopts] Eliminate all dead references to AssignInst.
AssignInst is eliminated by DI so we should /never/ see any AssignInst once DI
runs. So this code is dead.

Just shaved off of a larger commit to make it easier to review the larger
commit.

rdar://31521023
2017-10-29 16:49:19 -07:00
Michael Gottesman
71a8006615 [pred-memopt] Standardize function names in the file.
1/2 of the functions were CamelCase and the other half were camelCase. I
standardized on camelCase.
2017-10-26 11:39:09 -07:00
Slava Pestov
196559e7c6 DI: Only use collectClassInitSelfUses() for class initializers, not class-constrained protocol extensions 2017-10-20 16:42:11 -07:00
Slava Pestov
224aabfe5d DI: Add an assertion tracking stores to the 'self' box 2017-10-20 16:40:18 -07:00
Slava Pestov
16f9438b82 DI: Consistently use 'Use' instead of 'InstInfo' to name DIMemoryUse values 2017-10-20 16:10:34 -07:00
Slava Pestov
ff698f218f DI: Rip out the old 'self consumed' analysis now that it's dead 2017-10-20 16:10:33 -07:00
Slava Pestov
c69686f102 DI: Use new 'self initialized' analysis in conditional destroy lowering
This changes code generation a bit, because now the conditional
state bitmap uses a bit to track if the 'self' box was stored,
not if the 'self' value was consumed. In some cases, this
eliminates an extra bit, in other places it introduces an
extra bit, but it really doesn't matter because LLVM will
optimize this bit manipulation easily.
2017-10-20 16:10:33 -07:00
Slava Pestov
3d5a16a1ca DI: Use new 'self initialized' analysis in LifetimeChecker::isInitializedAtUse() 2017-10-20 16:10:33 -07:00
Slava Pestov
9d80f60607 DI: Use new 'self initialized' analysis in LifetimeChecker::handleSelfInitUse() 2017-10-20 16:10:33 -07:00
Slava Pestov
4c9d736ea0 DI: Use new 'self initialized' analysis in LifetimeChecker::handleStoreUse() 2017-10-20 16:10:32 -07:00
Slava Pestov
18c29b0cb4 DI: New analysis to replace the 'self consumed' analysis
In a throwing or failable initializer for a class, the typical pattern
is that an apply or try_apply consumes the self value, and returns
success or failure. On success, a new self value is produced.
On failure, there is no new self value. In both cases, the original
self value no longer exists.

We used to model this by attempting to look at the apply or try_apply
instruction, and figure out from subsequent control flow which
successor block was the success case and which was the error case.

The error blocks were marked as such, and a dataflow analysis was used
to compute whether 'self' had been consumed in each block reachable
from the entry block.

This analysis was used to prevent invalid use of 'self' in catch
blocks when the initializer delegation was wrapped in do/catch;
more importantly, it was also used to know when to release 'self'
on exit from the initializer.

For example, when we 'throw e' here, 'self' was already consumed
and does not need to be released -- doing so would cause a crash:

do {
  try self.init(...)
} catch let e {
  // do some other cleanup
  throw e
}

On the other hand, here we do have to release 'self', otherwise we
will exit leaking memory:

do {
  try someOtherThing()
  self.init(...)
} catch let e {
  // do some other cleanup
  throw e
}

The problem with the old analysis is that it was too brittle and did
not recognize certain patterns generated by SILGen. For example, it
did not correctly detect the failure block of a delegation to a
foreign throwing initializer, because those are not modeled as a
try_apply; instead, they return an Optional value.

For similar reasons, we did not correctly failure blocks emitted
after calls to initializers which are both throwing and failable.

The new analysis is simpler and more robust. The idea is that in the
success block, SILGen emits a store of the new 'self' value into
the self box. So all we need to do is seed the dataflow analysis with
the set of blocks where the 'self' box is stored to, excluding the
initial entry block.

The new analysis is called 'self initialized' rather than 'self
consumed'. In blocks dominated by the self.init() delegation,
the result is the logical not of the old analysis:

- If the old analysis said self was consumed, the new one says self
 is not initialized.

- If the old analysis said self was not consumed, the new analysis
  says that self *is* initialized.

- If the old analysis returned a partial result, the new analysis
  will also; it means the block in question can be reached from
  blocks where the 'self' box is both initialized and not.

Note that any blocks that precede the self.init() delegation now
report self as uninitialized, because they are not dominated by
a store into the box. So any clients of the old analysis must first
check if self is "live", meaning we're past the point of the
self.init() call. Only if self is live do we then go on to check
the 'self initialized' analysis.
2017-10-20 16:10:32 -07:00
Andrew Trick
8a8fdd8755 Fix a use-after-free in MandatoryInlining.
Bug introduced in @noescape lowering: https://github.com/apple/swift/pull/12420

Fixes <rdar://problem/35055251> FAILED: ASAN use-after-free in MandatoryInlining.
2017-10-19 00:33:17 -07:00
Andrew Trick
d369aa4070 Support @noescape SIL function types. (#12420)
Support for @noescape SILFunctionTypes.

These are the underlying SIL changes necessary to implement the new
closure capture ABI.

Note: This includes a change to function name mangling that
primarily affects reabstraction thunks.

The new ABI will allow stack allocation of non-escaping closures as a
simple optimization.

The new ABI, and the stack allocation optimization, also require
closure context to be @guaranteed. That will be implemented as the
next step.

Many SIL passes pattern match partial_apply sequences. These all
needed to be fixed to handle the convert_function that SILGen now
emits. The conversion is now needed whenever a function declaration,
which has an escaping type, is passed into a @NoEscape argument.

In addition to supporting new SIL patterns, some optimizations like
inlining and SIL combine are now stronger which could perturb some
benchmark results.

These underlying SIL changes should be merged now to avoid conflicting
with other work. Minor benchmark discrepancies can be investigated as part of
the stack-allocation work.

* Add a noescape attribute to SILFunctionType.

And set this attribute correctly when lowering formal function types to SILFunctionTypes based on @escaping.

This will allow stack allocation of closures, and unblock a related ABI change.

* Flip the polarity on @noescape on SILFunctionType and clarify that
we don't default it.

* Emit withoutActuallyEscaping using a convert_function instruction.

It might be better to use a specialized instruction here, but I'll leave that up to Andy.

Andy: And I'll leave that to Arnold who is implementing SIL support for guaranteed ownership of thick function types.

* Fix SILGen and SIL Parsing.

* Fix the LoadableByAddress pass.

* Fix ClosureSpecializer.

* Fix performance inliner constant propagation.

* Fix the PartialApplyCombiner.

* Adjust SILFunctionType for thunks.

* Add mangling for @noescape/@escaping.

* Fix test cases for @noescape attribute, mangling, convert_function, etc.

* Fix exclusivity test cases.

* Fix AccessEnforcement.

* Fix SILCombine of convert_function -> apply.

* Fix ObjC bridging thunks.

* Various MandatoryInlining fixes.

* Fix SILCombine optimizeApplyOfConvertFunction.

* Fix more test cases after merging (again).

* Fix ClosureSpecializer. Hande convert_function cloning.

Be conservative when combining convert_function. Most of our code doesn't know
how to deal with function type mismatches yet.

* Fix MandatoryInlining.

Be conservative with function conversion. The inliner does not yet know how to
cast arguments or convert between throwing forms.

* Fix PartialApplyCombiner.
2017-10-17 13:07:25 -07:00
swift-ci
3d53e7baa2 Merge pull request #12451 from lattner/SILValue-getLoc 2017-10-15 16:14:45 -07:00
Chris Lattner
cd99f859e3 NFC code cleanup changes:
- Hoist a duplicated static function with a fixme out to SILValue::getLoc()
 - Fix a whitespace issue.
2017-10-15 15:31:41 -07:00
Slava Pestov
d6bb97a57f DI: Factor out LifetimeChecker::emitSelfConsumedDiagnostic() 2017-10-14 23:53:03 -07:00
Slava Pestov
3e9a30be53 DI: Only call getSelfConsumedAtInst() inside initializers 2017-10-14 23:52:09 -07:00
Slava Pestov
d8153b3ae7 DI: Correctly flag escaping uses of 'self' when 'self' is passed as an argument to self/super.init
This fixes a regression from a previous patch, but it doesn't
fully address <https://bugs.swift.org/browse/SR-5682>, because
we now hit a SILGen crasher with the original test case.
2017-10-13 23:51:16 -07:00
Slava Pestov
1feaf9e2aa DI: Kill off checkClassSelfUpcastUsedBySuperInit() 2017-10-13 23:51:16 -07:00
Slava Pestov
1bcfc50ce3 DI: Kill off collectBorrowedSuperUses() 2017-10-13 23:51:16 -07:00
Slava Pestov
421797cb6e DI: Fold handleSuperInitUse() into handleSelfInitUse() 2017-10-13 23:51:15 -07:00
Slava Pestov
ff34f3bb8c DI: Remove shouldIgnoreClassMethodUseError() 2017-10-13 23:51:15 -07:00
Slava Pestov
94d4b5aa23 DI: Small cleanup now that SelfInit is only used for classes and class-bound protocols 2017-10-13 23:51:15 -07:00
Slava Pestov
b5eeae7446 DI: All enum initializers should be delegating
Again, since there's no distinction between an enum initializer that
delegates to 'self.init' from one that assigns to 'self', we can remove
the special handling of enum initializers in the 'root self' case.

Now, 'root self' is only used for designated initializers in classes
with no superclass, and struct initializers that perform memberwise
initialization of stored properties.

This regresses some diagnostics, because the logic for delegating
init diagnostics is missing some heuristics present in the root self
case. I will fix this in a subsequent patch.
2017-10-13 23:51:15 -07:00
Slava Pestov
0c16aedb60 DI: All protocol extension initializers should be delegating
Previously protocol extension initializers which called 'self.init' were
considered 'delegating', and ones that assign to 'self' were considered
'root'.

Both have the same SIL lowering so the distinction is not useful, and
removing it simplifies some code.
2017-10-13 23:51:14 -07:00
Slava Pestov
c3cf4acbbf DI: For value types, handle self.init like an assignment instead of vice versa
This allows, for example, an initializer to conditionally assign
to self or call self.init, along different control flow paths.

It also means that it is legal to call self.init() multiple times
in a value type initializer, but this... is fine. The old 'self'
is destroyed.

Fixes <rdar://problem/33137910>.
2017-10-13 23:51:14 -07:00
Slava Pestov
9a7a1de595 DI: Look through begin_access/end_access for assignment to self 2017-10-13 23:51:14 -07:00
Slava Pestov
5ffbd281c5 DI: Fix diagnostic for return from address-only initializer without calling self.init 2017-10-13 23:51:14 -07:00
Slava Pestov
e51556345d DI: Consolidate and clean up some diagnostics 2017-10-13 23:51:14 -07:00
Michael Gottesman
79e07c7db2 [di] DI assumes that all structs it analyzes will have /1/ property... this is not always true =><=.
The culprit here is NSManagedObject subclasses that only have @NSManaged
attributes.

This doesn't affect predictable mem opts since this issue is in the
DIMemoryUseCollector that only affects DI and that I have removed.

rdar://34589327
2017-10-10 13:58:34 -07:00
Erik Eckstein
ab934d0500 DefiniteInitialization: fixed crash for wrong super call with inout instance variable
Fixes rdar://problem/22960985
2017-10-10 09:24:46 -07:00
Slava Pestov
7bf3b90b62 SIL: Split off objc_method / objc_super_method from class_method / super_method
This replaces the '[volatile]' flag. Now, class_method and
super_method are only used for vtable dispatch.

The witness_method instruction is still overloaded for use
with both ObjC protocol requirements and Swift protocol
requirements; the next step is to make it only mean the
latter, also using objc_method for ObjC protocol calls.
2017-10-03 22:13:31 -07:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
Michael Gottesman
676d13846a [pred-memopt] More debriding of DI only stuff from DIMemoryUseCollector.
rdar://31521023
2017-09-13 21:07:19 -07:00
Michael Gottesman
dd17536922 [pred-memopts] Debride all dead MarkUninitialized related code from DIMemoryUseCollector.
rdar://31521023
2017-09-13 17:29:37 -07:00
Michael Gottesman
6b12d7d6cf [mandatory-inline] Move fixupReferenceCounts to /before/ inlining.
Once this lands, I can land my commit that turns on ownership for mandatory
inlining.

rdar://31521023
2017-09-13 13:39:32 -07:00
Michael Gottesman
7262673789 [mandatory-inline] Use prev_or_default to simplify code. NFC. 2017-09-12 14:29:43 -07:00
Michael Gottesman
baf293a0f6 Merge pull request #11846 from gottesmm/pr-0b7638743feaaad8531e324038be3fe1cd536022
[mandatory-inlining] Make fixupReferenceCounts not delete instructions.
2017-09-12 14:15:46 -07:00