Commit Graph

6634 Commits

Author SHA1 Message Date
Michael Gottesman
0688dbf607 [rcid] Teach RCIdentityAnalaysis::getRCUses() how to ignore certain uses that are inert from its perspective.
This includes:

1. Extract instructions which extracts a trivial part of an aggregate that has
one RCIdentity.
2. Instructions which take a pointer out of ARC's control by converting it to a
trivial type. This is safe to do since we can assume that the object that is
convered is alive when the conversion happens. So assuming that we can
conservatively find all RC users, we will have at least one RC user that
post dominates the use (since otherwise we would be touching a dangling
pointer). We leave it to the user of the pass to determine what is safe to do
with this information. Potentially in the future it might make sense to return
this information as well so that a user can use that information directly.

rdar://20305817

Swift SVN r26583
2015-03-26 07:19:41 +00:00
Roman Levenstein
332af2a892 Introduce a base class for ApplyInst and PartialApplyInst.
The new base class ApplyInstBase contains APIs that are common for ApplyInst and PartialApplyInst. It allows such optimization passes like generic specializer to treat both instructions in the same way whenever it is possible. Before this change, one had to duplicate and adjust a lot of implementation code in such passes, because ApplyInst and PartialApplyInst were not related to each other in any form.

The existing clients of both classes can continue using the usual APIs. No changes are required. Only new clients, which want to treat ApplyInst and PartialApplyInst in a uniform way, may do so. One of such new clients is the generic specializer, whose adjusted implementation will be submitted in the following commit.

Swift SVN r26581
2015-03-26 06:41:28 +00:00
Doug Gregor
3d77855b31 Start allowing extensions of protocol types.
Remove the semantic restrictions that prohibited extensions of
protocol types, and start making some systematic changes so that
protocol extensions start to make sense:
  - Replace a lot of occurrences of isa<ProtocolDecl> and
    dyn_cast<ProtocolDecl> on DeclContexts to use the new
    DeclContext::isProtocolOrProtocolExtensionContext(), where we want
    that behavior to apply equally to protocols and protocol extensions.
  - Eliminate ProtocolDecl::getSelf() in favor of
    DeclContext::getProtocolSelf(), which produces the appropriate
    generic type parameter for the 'Self' of a protocol or protocol
    extension. Update all of the callers of ProtocolDecl::getSelf()
    appropriately.
  - Update extension validation to appropriately form generic
    parameter lists for protocol extensions.
  - Methods in protocol extensions always use the witnesscc calling
  convention.

At this point, we can type check and SILGen very basic definitions of
protocol extensions with methods that can call protocol requirements,
generic free functions, and other methods within the same protocol
extension.

Regresses four compiler crashers but improves three compiler
crashers... we'll call that "progress"; the four regressions all hit
the same assertion in the constraint system that will likely be
addressed as protocol extensions starts working.

Swift SVN r26579
2015-03-26 04:50:51 +00:00
Luqman Aden
3f83973928 Handle multiple sib inputs.
Swift SVN r26572
2015-03-26 01:21:21 +00:00
Mark Lacey
1f23ff27bb Remove the transparent bit from apply instructions.
We no longer need or use it since we can always refer to the same bit on
the applied function when deciding whether to inline during mandatory
inlining.

Resolves rdar://problem/19478366.

Swift SVN r26534
2015-03-25 08:36:34 +00:00
Michael Gottesman
254c784c94 [+0 self][pin removal] Teach pinremoval how to use RCIdentityAnalysis when removing pins.
Previously, we were being very conservative and were not trying to look through
any RCId uses. Now we understand how to look through RCIdentical instructions to
pair a pin and unpin. We also understand how to use the new getRCUses API on
RCIdentityAnalysis to get all uses of a value, looking through RCIdentical
instructions.

I also added some code to COWArrayOpts to teach it how to look through enum insts (which I needed).

Additionally I got stuck and added support for automatic indentation in Debug
statements. This is better than having to indent by hand every time.

There were no significant perf changes since this code was not being emitted by
the frontend. But without this +0 self causes COW to break.

rdar://20267677

Swift SVN r26529
2015-03-25 06:21:11 +00:00
Michael Gottesman
3ec2d151f6 Shrink Projection to 24 bytes and Add some static assertions to make sure that SILValue and Projection stay the same size and standard layout.
Swift SVN r26526
2015-03-25 06:21:08 +00:00
Mark Lacey
bb66f0f9c0 Fix typo and reword sentence in comment.
Swift SVN r26517
2015-03-25 02:48:12 +00:00
Jordan Rose
8247c2d357 If imported calls return nil for 'NSArray * __nonnull', pretend it was [].
...and similar for NSDictionary and NSSet.

For APIs that don't have a reason to distinguish "empty" and "absent" cases,
we encourage standardizing on "empty" and marking the result as non-optional
(or in Objective-C, __nonnull). However, there are system APIs whose
implementations currently do return nil rather than an empty collection
instance. In these cases, we recommend /changing/ the API to return the
appropriate "empty" value instead.

However, this can cause problems for backwards-deployment: while the API is
truly non-optional on system vN, a program may encounter a nil return value
if run on system vN-1. Objective-C can generally deal with this (especially
if the only thing you do is ask for the count or try to iterate over the
collection) but Swift can't. Therefore, we've decided to "play nice" and
accept nil return values for the collection types (NSArray, NSDictionary,
and NSSet) and implicitly treat them as "empty" values if they are the
result of an imported function or method.

Note that the current implementation has a hole regarding subscript getters,
since we still make an AST-level thunk for these in the Clang importer.
We can probably get rid of those these days, but I didn't want to touch
them at this point. It seems unlikely that there will be a subscript that
(a) is for a collection type, and (b) mistakenly returned nil in the past
rather than an empty collection.

There's another hole where an ObjC client calls one of these mistakenly-nil-
returning methods and then immediately hands the result off by calling a
Swift method. However, we have to draw the line somewhere.

(We're actually going to do this for strings as well; coming soon.)

rdar://problem/19734621

Swift SVN r26479
2015-03-24 03:36:45 +00:00
John McCall
ee4aa14703 Stop reordering blocks in SILBuilder::emitBlock.
This change permits SILGen to make smarter decisions about
block placement by keeping related blocks together instead
of always inserting to the end to the function.  The
flipside is that SILGen needs to be somewhat careful to
create blocks in the right order.  Counter-intuitively,
that order is the reverse of the order in which the blocks
should be laid out, since blocks created later will be
inserted before blocks created earlier.  Note, however,
that this produces the right results for recursive
emission.

To that end, adjust a couple of places in SILGen to
create blocks in properly nested order.

All of the block-order differences in the tests seem
to be desirable; several of them even had confused
comments wondering how on earth a block got injected
where it did.

Also, fix the implementation of SILBuilder::moveBlockTo,
and fix a latent bug in epilogue emission where epilogBB
was erased from its parent (deleting it) and then
queried multiple times (!).

Swift SVN r26428
2015-03-23 06:38:20 +00:00
Arnold Schwaighofer
d6ec9f2640 Make isObjectiveCBridgeable an available function so it can be used elsewhere.
Swift SVN r26265
2015-03-18 17:43:09 +00:00
Roman Levenstein
1f875b9bcb Extend SILModule with an API for linking of SILFunctions by their SILDeclRef.
Before, providing a full SILFunction declaration object with a proper SILType was the only way to link a function. And constructing such a SILFunction declaration by hand using low-level SIL APIs is very annoying and requires a lot of code to be written. This new linkFunction API allows for a lookup using SILDeclRef and essentially performs linking of a SILFunction by its mangled name (assuming this name is unique), which is much easier to invoke. The new API is useful, e.g. when you need to link a well-known function from a standard library.

Swift SVN r26252
2015-03-18 06:11:22 +00:00
Arnold Schwaighofer
faeaea890e Add a convenience hasSemantics api to ApplyInst.
Swift SVN r26239
2015-03-17 23:27:18 +00:00
Joe Groff
7f886c924b SIL: Make 'isReferenceCounted' a bit on TypeLowering.
This allows types to be lowered as scalar reference-counted types without requiring them to have AST-level reference semantics. For now, put in a staging assertion to ensure isReferenceCounted == hasReferenceSemantics to make sure we set the bit properly everywhere.

Swift SVN r26238
2015-03-17 21:51:06 +00:00
Joe Groff
fdde2a8e99 SIL: Add instructions for boxed existential operations.
Parsing and serialization for {Alloc,Open,Dealloc}ExistentialBox instructions to represent operations on ErrorType boxes.

Swift SVN r26145
2015-03-15 03:32:37 +00:00
Chris Lattner
4f708c049b fix const correctness and standardize on names for the successor list of
TerminatorInsts.  Now you can walk over the successor list of a terminator
and actually modify the SILSuccessor directly, allowing better CFG
transformations.  NFC.




Swift SVN r26140
2015-03-14 17:52:27 +00:00
Roman Levenstein
9c62c5bdc9 Remove all the complex cast optimization logic from TypeSubstCloner.
This is a part of the re-factoring effort to centralize the logic for type casts optimizations. Now all those optimizations are performed by appropriate passes like sil-simplify-cfg and sil-combine.

Swift SVN r26121
2015-03-14 02:23:04 +00:00
Michael Gottesman
aaab6d4668 When emitting sorted SIL, emit BBs in RPOT order.
This makes it easier to diff and read SIL output. Since it is behind the -emit-sorted-sil
flag, there is no effect on normal compilation.

Swift SVN r26101
2015-03-13 15:56:26 +00:00
Joe Groff
84e2d4e8ba SIL.rst: Add discussion of existential container representations.
And adjust the names of ExistentialRepresentation cases to match the existing nomenclature instead of needlessly inventing new names.

Swift SVN r26069
2015-03-12 22:26:00 +00:00
Joe Groff
5f6c7180a0 SIL: Provide SILType APIs to track the representation of existential types.
Give SILType 'getPreferredExistentialRepresentation' and 'canUseExistentialRepresentation' methods, which track what types of container particular existential types may use--fixed-sized, class-constrained, metatype, or box. Allow for existentials to use a specialized representation for certain known concrete types by allowing these methods to take a concrete type. NFC yet, except to replace some ad-hoc verifier conditions with canUseExistentialRepresentation checks where appropriate.

Swift SVN r26062
2015-03-12 20:54:06 +00:00
Roman Levenstein
f8cb97b0c6 Perform folding of always failing unconditional_checked_cast_addr instructions during SIL cloning.
Replace a failing unconditional_checked_cast_addr by a trap, followed by an "unreachable" instruction.

Swift SVN r26030
2015-03-12 03:37:30 +00:00
Roman Levenstein
b5f73b2f34 Add support for removal of the dead code after "unreachable" even during SIL cloning and generic specialization.
SIL cloning is not always followed by sil-combine, which could do the clean-up. Therefore, take care of removing the dead code after "unreachable" instructions at the end of the cloning process.

Swift SVN r26029
2015-03-12 03:37:28 +00:00
Dave Abrahams
e88572391e Revert "Make sure that we do not try to create shared versions of stdlib_binary_only functions when specializing."
This reverts commit r26001; it broke validation-tests/stdlib/String.swift

Swift SVN r26005
2015-03-12 00:52:38 +00:00
Michael Gottesman
d88f3767c3 Make sure that we do not try to create shared versions of stdlib_binary_only functions when specializing.
This can only happen in the closure specializer and the generic
specializer since all other specializations either copy the linkage of
the original function (function signature opts) or clone closures/thunks
which have shared linkage.

I put in a verifier check that makes sure we do not create shared
versions of these functions. The real problem has to do with serializing
these sorts of functions, but since we always serialize shared
functions, it makes sense to just ban it.

rdar://20082696

Swift SVN r26001
2015-03-11 23:18:56 +00:00
Roman Levenstein
1489374e49 Fold always failing unconditional_check_cast instructions into traps followed by unreachable instruction during inlining and specialisation as well.
rdar://20115697

Swift SVN r25991
2015-03-11 20:34:46 +00:00
Mark Lacey
92a85f00f9 Move isClassOrClassMetatype into SILType.h.
This will be useful for further devirtualizer clean-up.

Swift SVN r25974
2015-03-11 08:25:48 +00:00
Joe Groff
962a87f444 SIL: Rename address-only existential instructions to '{init,deinit,open}_existential_addr'.
For better consistency with other address-only instruction variants, and to open the door to new exciting existential representations (such as a refcounted boxed representation for ErrorType).

Swift SVN r25902
2015-03-09 23:55:31 +00:00
Michael Gottesman
1bfdeed6e5 Fix comment.
Swift SVN r25830
2015-03-07 03:08:27 +00:00
Ted Kremenek
9e7471d68b Revert "Revert "Rework processing of @noescape closures a bit to fix rdar://19981118:""
Turns out llvm::DataLayoutPass is used in other places, so the bots are still unhappy.
Re-applying the original change so we can fix the problem holistically.

Swift SVN r25761
2015-03-04 20:15:45 +00:00
Ted Kremenek
6781ac7bec Revert "Rework processing of @noescape closures a bit to fix rdar://19981118:"
This is breaking the testing bot because DataLayoutPass was just removed from LLVM trunk.
Chris is the best one to fix this change, but we need to get the bots green.

Swift SVN r25760
2015-03-04 20:03:33 +00:00
Chris Lattner
ab43e444d6 Rework processing of @noescape closures a bit to fix rdar://19981118:
- Have Sema, not SILGen decide if a vardecl can be captured by address
  instead of by-box.  This is a non-local property that is best computed
  during capture set formation.  Sema captures this as a bit on the new
  CapturedValue entry.
- Rework some diagnostic emission to centralize a class of noescape 
  diagnostics in capture set calculation.  Previously, funcdecl closures
  produced their diagnostics there, but ClosureExprs produced them in
  MiscDiagnostics (NFC for this part).

This fixes <rdar://problem/19981118> Swift 1.2 beta 2: Closures nested in @noescape closures copy, rather than reference, captured vars.



Swift SVN r25759
2015-03-04 19:30:36 +00:00
Chris Lattner
feb350f201 rename CaptureKind::NoEscape -> CaptureKind::StorageAddress,
since the CaptureKind enum names describe "what happens", not
"why they are formed".  NFC.



Swift SVN r25750
2015-03-04 06:27:02 +00:00
Chris Lattner
3489840b8d rework our representation of capture lists to compute the "isDirect" bit up front
when computing the list.  This simplifies getLocalCaptures to *just* filter out
global captures, and paves the way for other enhancements.  NFC.


Swift SVN r25739
2015-03-04 01:56:48 +00:00
Mark Lacey
a9181b08ce Make witness/vtable look-up helper naming more consistent.
Swift SVN r25713
2015-03-03 09:14:18 +00:00
Roman Levenstein
a4055afc15 Third part of the cast folding and type-casts re-factoring. Addressing JoeG's comments.
This patch does the following:
- Improvements and correctness fixes for conversions of existential metatypes. They may succeed if you have a concrete or existential metatype that conforms to the protocol. Based on Joe's review of my previous patch.
- Removes special-cases for AnyObject. AnyObject is handled as any other class existential.
- Improves folding of conversions from class existential metatypes to concrete non-class metatypes
- Improves comments.
- Adds more tests to cover new test-cases.
- Adjusts a few existing tests.

Swift SVN r25690
2015-03-02 22:28:21 +00:00
Arnold Schwaighofer
44479683b3 SILBuilder: createBuiltinCmp -> createBuiltinBinaryFunction
Also add createBuiltinBinaryFunctionWithOverflow. NFC.

Swift SVN r25663
2015-03-02 01:05:33 +00:00
Joe Groff
5fa20867e9 SILGen: Implement thunking for C function pointer conversions.
If we have a C function pointer conversion, generate a thunk using the same logic we use for ObjC method thunks, and emit a pointer to that thunk as the C function pointer value. (This works for nongeneric, nonmember functions; generics will additionally need to apply generic parameters within the thunks. Static functions would need to gather the metatype as well.)

Swift SVN r25653
2015-03-01 06:18:58 +00:00
Arnold Schwaighofer
a95eefb934 Add a utility function to Operand to hoist projections rooted in an operand to
an earlier point.

Swift SVN r25618
2015-02-27 22:07:38 +00:00
Arnold Schwaighofer
360981a794 Add an API to SILInstruction to get the self argument operand.
Swift SVN r25617
2015-02-27 22:07:38 +00:00
Nadav Rotem
15f0254b36 Remove a debug message that depends on DEBUG_TYPE that's only available inside passes.
Swift SVN r25574
2015-02-27 00:32:04 +00:00
Mark Lacey
18dc6dd3d7 Small clean-up in cloning code.
Creation of witness_method instructions already handles creation of the
witness table in cases where it doesn't already exist, so this code is
not needed.

Swift SVN r25547
2015-02-26 07:59:13 +00:00
Arnold Schwaighofer
8677a27e87 TypeSubstCloner: Don't create an upcast from type to the same type
rdar://19956006

Swift SVN r25539
2015-02-26 02:09:36 +00:00
Roman Levenstein
c97f748fb9 Move the logic for folding type casts using statically known protocol conformances into DynamicCasts.cpp.
The logic for different special cases of type casting is spread over multiple places currently. This patch simply re-factors some of that  code (folding of of type casts using statically known protocol conformances) and moves it into one central place, which makes it easier to maintain. Plus, it allows other clients of DynamicCasts benefit from it as well, e.g. the inliner can use this now. NFC.

Swift SVN r25486
2015-02-23 21:30:48 +00:00
Justin Bogner
322005d027 InstrProf: Track the filename in coverage maps
If multiple swift files are compiled together, then guessing as to the
file when we emit IR obviously doesn't work. Find the filename when we
generate a function's coverage map and propagate it through SIL.

Swift SVN r25436
2015-02-20 21:26:20 +00:00
Luqman Aden
b9c360e864 Minor changes to incorporate feedback on r25416.
Swift SVN r25434
2015-02-20 19:48:07 +00:00
Justin Bogner
3dbd6ea9bd InstrProf: SILFunction doesn't live long enough for SILCoverageMap
Keeping a reference to the function here is dangerous. We only
actually care about the name, so save ourselves a copy of that
instead.

This fixes a crash that seems to happen only when the coverage data is
very large.

Swift SVN r25433
2015-02-20 19:36:33 +00:00
Luqman Aden
e1c60464d3 Fold getCmpFunction function into helper method on SILBuilder.
Swift SVN r25416
2015-02-20 04:08:08 +00:00
Michael Gottesman
6f8b468cb6 Change switches and selects to use NullablePtr<EnumElementDecl> instead of EnumElementDecl * when their API explicitly requires the user to check for nullptr. NFC.
This is just good to do and hopefully will help prevent people from forgetting
to check in the future by annotating the API explicitly as returning a
potentially nullptr.

Swift SVN r25364
2015-02-18 02:11:57 +00:00
Michael Gottesman
617ea48e8b Refactor getForwardingSubstitutions onto SILFunction. NFC.
This is also useful in general SIL passes when generating thunks. I am going to
use this in function signature optimization and closure specialization.

Swift SVN r25356
2015-02-17 21:03:24 +00:00
Michael Gottesman
4cb9eb72f4 [rc-id] Ensure that the reforming enum analysis properly handles no-payload incoming values.
One common problem in swift code is the "reforming enum problem". What
happens here is that we have some enum %0 : $Optional<T> and we break it
apart and reform it as a new enum as in the following:

   bb9:
     ...
     switch_enum %0 : $Optional<T>, #Optional.None: bb10,
                                    #Optional.Some: bb11

   bb10:
     %1 = enum $Optional<U>, #Optional.None
     br bb12(%1 : $Optional<U>)

   bb11:
     %2 = some_cast_to_u %0 : ...
     %3 = enum $Optional<U>, #Optional.Some, %2 : $U
     br bb12(%3 : $Optional<U>)

   bb12(%4 : $Optional<U>):
     retain_value %0 : $Optional<T> // id %5
     release_value %4 : $Optional<U> // id %6

We really would like to know that a retain on %4 is equivalent to a
retain on %0 so we can eliminate the retain, release pair. To be able to
do that safely, we need to know that along all paths %0 and %4 either:

1. Both refer to the same RCIdentity directly. An example of this is the
edge from bb11 -> bb12).
2. Both refer to the "null" RCIdentity (i.e. do not have a payload). An
example of this is the edge from bb10 -> bb12.

Only in such cases is it safe to match up %5, %6 and eliminate them. If
this is not true along all paths like in the following:

   bb9:
     ...
     cond_br %foo, bb10, bb11

   bb10:
     %1 = enum $Optional<U>, #Optional.None
     br bb12(%1 : $Optional<U>)

   bb11:
     %2 = some_cast_to_u %0 : ...
     %3 = enum $Optional<U>, #Optional.Some, %2 : $U
     br bb12(%3 : $Optional<U>)

   bb12(%4 : $Optional<U>):
     retain_value %0 : $Optional<T> // id %5
     release_value %4 : $Optional<U> // id %6

then we may have that %0 is always non-payloaded coming into bb12. Then
by matching up %0 and %4, if we go from bb9 -> bb11, we will lose a
retain.

Perf Changes:

TITLE..................OLD...........NEW...........NEW/OLD
LevenshteinDistance....1398195.00....1177397.00....0.84
Memset.................26541.00......23701.00......0.89
CaptureProp............5603.00.......5031.00.......0.90
ImageProc..............1281.00.......1196.00.......0.93
InsertionSort..........109828.00.....104129.00.....0.95
StringWalk.............6813.00.......7456.00.......1.09
Chars..................27182.00......30443.00......1.12

The StringWalk, Chars are both reproducible for me. When I turn back on parts of
the recursion (I took the recursion out to make this change more conservative),
the Chars regression goes away, but the StringWalk stays. I have not had a
chance to look at what is going on with StringWalk.

rdar://19724405

Swift SVN r25339
2015-02-17 01:30:19 +00:00