Commit Graph

271 Commits

Author SHA1 Message Date
Raj Barik
d9a051ecdc Concrete type propagation using ProtocolConformanceAnalysis 2018-08-22 11:08:29 -07:00
Raj Barik
484925c26f Extend SILCombiner code to handle existential self concrete type propagation using ProtocolConformanceAnalysis 2018-08-01 14:25:52 -07:00
Ben Cohen
2b04e9f105 Suppress a number of warnings in no-assert builds (#17721)
* Supress a number of warnings about things used only in asserts

* Re-use a couple of variables instead of supressing the warning
2018-07-04 07:15:14 -07:00
Slava Pestov
13e1c83410 SILCombiner: Remove bogus dump() call (#17553) 2018-06-27 01:14:10 -07:00
Andrew Trick
9d4b4c755c Rewrite SILCombiner::propagateConcreteTypeOfInitExistential. (#17315)
Fixes <rdar://40555427> [SR-7773]:
SILCombiner::propagateConcreteTypeOfInitExistential fails to full propagate type
substitutions.

Fixes <rdar://problem/40923849>
SILCombiner::propagateConcreteTypeOfInitExistential crashes on protocol
compositions.

This rewrite fixes several fundamental bugs in the SILCombiner optimization that
propagates concrete types. In particular, the pass needs to handle:

- Arguments of callee Self type in non-self position.
- Indirect and direct return values of Self type.
- Types that indirectly depend on Self within callee function signature.
- Protocol composition existentials.
- All of the above need to work for protocol extensions as well as witness methods.
- For protocol extensions, conformance lookup should be based on the existential's conformance list.

Additionally, the optimization should not depend on a SILFunction's DeclContext,
which is not serialized. (In fact, we should prevent SIL passes from using
DeclContext). Furthermore, the code needs to be expressed in a way that one can
reason about correctness and invariants.

The root cause of these bugs is that SIL passes are written based on untested
assumptions of Swift type system. A SIL pass needs to handle all verifiable SIL
input because passes need to be composable. Bail-out logic can be added to
simplify the design; however, _the bail-out logic itself cannot make any
assumptions about the language or type system_ that aren't clearly and
explicitly enforced in the SIL verifier. This is a common mistake and major
source of bugs.

I created as many unit tests as I reasonably could to prevent this code from
regressing. Creating enough unit tests to cover all corner cases that were
broken in the original code would be intractable. But the code has been
simplified such that many corner cases disappear.

This opens up some oportunity for generalizing the optimization and eliminating
special cases. However, I want this PR to be limited to fixing correctness
issues only. In the long term, it would be preferable to replace this
optimization entirely with a much more powerful general type propagation pass.
2018-06-26 19:33:31 -07:00
Raj Barik
c277c90be6 Reorganizing the code to find init_existential; Move them to Existential.cpp/h in order for other passes such as ExistentialSpecializer to use it apart from SILCombiner 2018-06-04 11:07:12 -07:00
Slava Pestov
bd6281c558 AST: Change SubstitutionMap conformance lookup callbacks to take ProtocolDecl and not ProtocolType 2018-05-19 01:09:17 -07:00
Doug Gregor
ef020c74aa Eliminate all vestiges of Substitution and SubstitutionList.
Introduced during the bring-up of the generics system in July, 2012,
Substitution (and SubstitutionList) has been completely superseded by
SubstitutionMap. R.I.P.
2018-05-11 21:43:40 -07:00
Doug Gregor
911ed60a98 Eliminate dead code making use of SubstitutionList. 2018-05-11 17:37:27 -07:00
Doug Gregor
4b5abbddbc [SIL] Teach *ApplyInst to traffic in SubstitutionMap.
Push SubstitutionMaps through most of SILGen and the SIL optimizers
that involve the various *ApplyInsts.
2018-05-11 13:18:06 -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
Raj Barik
612d771b9e Handle global_addr for concrete type propagation 2018-04-30 14:38:13 -07:00
Davide Italiano
b4d563802b [SILInstruction] Introduce isDebugInstruction().
This is a property of an instruction and should be a member
function of `SILInstruction` and not a free function in
`DebugUtils`. Discussed with Adrian.
2018-04-11 10:14:21 -07:00
Andrew Trick
e7b63e53b8 Fix closure inlining after witness devirtualization.
Certain patterns of directly applied partial_apply's were not being
inlined. This can happen when a closure is defined in the
implementation of a generic witness method. I noticed this issue while
debugging SR-6254: "Fix (or explain) strange ways to make code >3
times faster/slower".

After the witness method is devirtualization and specialized, the
closure application looks like this:

  %pa = partial_apply [callee_guaranteed] %fn() : $@convention(thin) (@in Int) -> @out Int
  %cvt = convert_escape_to_noescape %pa
  apply %cvt(...)

SILCombine already removes the partial_apply and convert_escape_to_noescape generating:

  %thick = thin_to_thick %fn
  apply %thick(...)

However, surprisingly, neither the inliner nor SILCombine can handle this.

I cleaned up the code in SILCombine's apply visitor that handles
thin_to_thick and generalized it to handle this and other patterns.

I also added a restriction to this code so that it doesn't break SIL
ownership in the future, as I discussed with Arnold.
2018-03-08 13:36:59 -08:00
Erik Eckstein
1c20806d44 Revert "Fix closure inlining after witness devirtualization."
This reverts commit 8990ed4f78.
2018-03-07 16:48:05 -08:00
Andrew Trick
8990ed4f78 Fix closure inlining after witness devirtualization.
Certain patterns of directly applied partial_apply's were not being
inlined. This can happen when a closure is defined in the
implementation of a generic witness method. I noticed this issue while
debugging SR-6254: "Fix (or explain) strange ways to make code >3
times faster/slower".

After the witness method is devirtualization and specialized, the
closure application looks like this:

  %pa = partial_apply [callee_guaranteed] %fn() : $@convention(thin) (@in Int) -> @out Int
  %cvt = convert_escape_to_noescape %pa
  apply %cvt(...)

SILCombine already removes the partial_apply and convert_escape_to_noescape generating:

  %thick = thin_to_thick %fn
  apply %thick(...)

However, surprisingly, neither the inliner nor SILCombine can handle this.

I cleaned up the code in SILCombine's apply visitor that handles
thin_to_thick and generalized it to handle this and other patterns.

I also added a restriction to this code so that it doesn't break SIL
ownership in the future, as I discussed with Arnold.
2018-03-07 11:25:19 -08:00
Arnold Schwaighofer
390ba419fc Add an effects(releasenone) function effects attribute
A ``@effects(releasenone)`` function might read/write global state but does not
perform a release.
2018-03-05 07:03:54 -08:00
Adrian Prantl
9b6a9946ec Be explicit about whether a DebugInfo-carying SILInstruction has debug info.
This patch both makes debug variable information it optional on
alloc_stack and alloc_box instructions, and forced variable
information on debug_value and debug_value_addr instructions. The
change of the interface uncovered a plethora of bugs in SILGen,
SILTransform, and IRGen's LoadableByAddress pass.

Most importantly this fixes the previously commented part of the
DebugInfo/local-vars.swift.gyb testcase.

rdar://problem/37720555
2018-02-21 10:50:19 -08:00
Arnold Schwaighofer
a05f0398a1 SILCombiner: Fixes for convert_escape_to_noescape
- also combine thin_to_thick_function and convert_escape_to_noescape
2018-02-13 04:19:59 -08:00
Andrew Trick
113bebb035 Centralize logic for access marker and exclusivity verification.
Create helpers in InstructionUtils.h wherever we need a guarantee that the diagnostics cover the same patterns as the verifier. Eventually this will be called from both SILVerifier and the diagnostic pass:
- findAccessedAddressBase
- isPossibleFormalAccessBase
- isPartialApplyOfReabstractionThunk
- findClosureForAppliedArg
- visitAccessedAddress

Add partial_apply verification assert.

This applies the normal "find a closure" logic inside the "find all partial_apply uses" verification. Making the verifier round-trip ensures that we don't have holes in exclusivity enforcement related to this logic.
2018-02-05 18:43:30 -08:00
John McCall
b13f30ff30 Move a convenience API for changing a SILFunctionType into the AST. NFC. 2017-12-15 18:19:07 -05:00
Andrew Trick
32a8dbcfa8 Fix a dangling stack pointer in SILCombine.
The bug was introduced recently:
commit ac8a48b2
Date:   Fri Oct 6 12:34:14 2017 -0700

Fixes <rdar://35800315> (crash using freed OpenedArchetypesTracker).
2017-12-04 10:04:48 -08:00
Andrew Trick
708aadfada Cleanup SILCombine code in preparation for a bug fix.
This is not NFC because the isUseAfterFree helper and surrounding code
is rewritten. The previous code's intention is unclear, but it was at
best imprecise and unsafe w.r.t. future SIL changes.

Pattern matching code that becomes highly complicated should
be commented with motivating SIL examples.
2017-12-04 10:04:48 -08:00
Slava Pestov
1f79af7504 SIL: Use objc_method instruction for Objective-C protocol method calls
Fixes <rdar://problem/15933365>.
2017-11-29 16:26:43 -08:00
Arnold Schwaighofer
ea9907ae15 Revert "SIL: Use objc_method instruction for Objective-C protocol method calls" 2017-11-29 11:19:46 -08:00
Slava Pestov
1ee0970934 SIL: Use objc_method instruction for Objective-C protocol method calls
Fixes <rdar://problem/15933365>.
2017-11-29 01:22:05 -08:00
Slava Pestov
fb2a6d2025 SILOptimizer: Fix convert_function -> apply peephole for metatype conversions
Fixes <rdar://problem/35492775>.
2017-11-13 22:10:14 -08:00
Arnold Schwaighofer
3d349ae2f8 SILCombine: Fix @callee_guaranteed combine of try_apply
I missed another place where we were releasing the context.

SR-5441
rdar://33255593
2017-11-10 15:18:01 -08:00
Arnold Schwaighofer
1c67e1ebb3 Use emitDestroyValueOperation instead of createStrongRelease 2017-11-04 15:13:49 -07:00
Arnold Schwaighofer
b5fab6145f SILCombiner: Fix partial_apply optimization of @callee_guaranteed
closures

@callee_guaranteed closure contexts must not be released when replacing
a closure application.

SR-5441
rdar://33255593
2017-11-04 14:03:56 -07:00
Huon Wilson
0236db7be1 [SIL] Witness methods store the conformance from which they come. 2017-11-01 11:33:26 -07:00
Joe Shajrawi
8fdca7c5a6 Relax SILCombiner's archtype tracker: better existential_metatype support 2017-10-23 16:27:44 -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
Joe Shajrawi
39c7612cca Merge pull request #12411 from shajrawi/silcombine_bugfix
SILCombiner: fix an infinite loop corner-case
2017-10-12 17:05:28 -07:00
Joe Shajrawi
bdafb354bd SILCombiner: fix an infinite loop corner-case 2017-10-12 16:34:31 -07:00
Doug Gregor
cd3c63cbfd [AST] Stop including GenericSignature.h in other headers.
Except GenericEnvironment.h, because you can't meaningfully use a
GenericEnvironment without its signature. Lots less depends on
GenericSignature.h now. NFC
2017-10-12 14:23:46 -07:00
Joe Shajrawi
ac8a48b2c2 Fixes a bug in SILCombiner that caused a use-after-free 2017-10-10 13:40:14 -07:00
Erik Eckstein
a51d9b950b SILCombine: fix propagation of existential self into witness method call
In case of a mutating method call we replaced the self argument with the source of a copy_addr. This let the call modify the wrong self value.

rdar://problem/34753633
2017-10-02 16:04:21 -07:00
Roman Levenstein
d9d58bc6c5 [sil-combine] Fix a bug in the convert_function peephole
Bail if the return type of the converted function is different from the
return type of the apply instruction.

Fixes rdar://problem/34603304
2017-09-28 09:03:40 -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
Slava Pestov
de0a7a066a SILCombiner: Remove another usage of ProtocolConformanceRef::getInherited()
This codepath consumed the result of getConformanceAndConcreteType(),
which already maps inherited conformances to exact conformances.
2017-09-01 00:46:18 -07:00
Slava Pestov
96ee1157f7 SILCombiner: Use ASTContext::getExistentialSignature()
This addresses the unsupported case outlined in the FIXME.

We have an init_existential_{addr,ref} instruction which
constructs an existential of type R from a value whose
concrete type conforms to R.

Later on, we have a witness_method invoking a method of P,
where R refines Q refines P.

In order to give the witness_method instruction the correct
conformance after substituting the concrete type, we would
call ProtocolConformanceRef::getInherited().

However, this only supported a single level of protocol
refinement, so we would just bail out in the unsupported
case. Instead, this patch builds a SubstitutionMap from the
generic signature <T : R>, and uses the SubstitutionMap to
perform the conformance lookup of T to P.
2017-09-01 00:46:18 -07:00
Slava Pestov
6607058f7b SILCombiner: Clean up getConformanceAndConcreteType()
Instead of using an out parameter and a tuple return value,
return everything in the tuple.
2017-09-01 00:46:18 -07:00
Roman Levenstein
87719df70c Support concrete type propagation into witness_method instructions only for directly inherited conformances for now
Indirectly inherited conformances cannot be properly handled yet due to some representation issues with init_existential_* instructions.

This fixes a compiler crash reported in rdar://34022255.
2017-08-30 17:00:08 -07:00
Erik Eckstein
020a283bbb SIL: Let the OpenedArchetypesTracker be constructed with a null SILFunction.
NFC
2017-08-23 09:15:00 -07:00
Michael Gottesman
3aadede925 [sil-combine] Make sure that (apply (partial_apply)) -> (apply') bails if we have an argument with a dependent type.
What is going on here is that currently this optimization if itneeds to perform
lfietime extension always creates an alloc_stack at the beginning/end of a
function. If the object whose lifetime is being extended has a dependent type,
then the alloc_stack will be created before the dependent type exists resulting
in the compiler crashing.

rdar://33595317
2017-07-28 17:20:54 -07:00
Michael Gottesman
fcafd6baad [gardening] Reflow some comments to make them easier to read. NFC. 2017-07-28 13:06:30 -07:00
Roman Levenstein
f909858f53 Remove dead code that became obsolete after re-factoring 2017-05-10 08:04:28 -07:00
Roman Levenstein
45c2c4af0e Re-factoring: Get rid of useless arguments in "create*Apply" functions
Till now createApply, createTryApply, createPartialApply were taking some arguments like SubstCalleeType or ResultType. But these arguments are redundant and can be easily derived from other arguments of these functions. There is no need to put the burden of their computation on the clients of these APIs.

The removal of these redundant parameters simplifies the APIs and reduces the possibility of providing mismatched types by clients, which often happened in the past.
2017-05-10 08:03:37 -07:00
practicalswift
492f5cd35a [gardening] Remove redundant repetition of type names (DRY): RepeatedTypeName foo = dyn_cast<RepeatedTypeName>(bar)
Replace `NameOfType foo = dyn_cast<NameOfType>(bar)` with DRY version `auto foo = dyn_cast<NameOfType>(bar)`.

The DRY auto version is by far the dominant form already used in the repo, so this PR merely brings the exceptional cases (redundant repetition form) in line with the dominant form (auto form).

See the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names) for a general discussion on why to use `auto` to avoid redundant repetition of type names.
2017-05-05 09:45:53 +02:00