Commit Graph

484 Commits

Author SHA1 Message Date
Slava Pestov
f4741aa7b6 SILGen: Introduce OpenClassExistentialComponent
This is an LValue component whose value is the class
reference inside of a class existential.

Unlike OpenOpaqueExistentialComponent, this is a logical
component, with a "writeback" consisting of wrapping the
new class reference in a class existential having the
same conformances as the original.

This is slightly awkward, but adding "by-address" operations
on class existentials, and projecting the payload out is
a big change and might not make sense for other reasons.
2017-05-15 18:17:24 -07:00
Slava Pestov
4b25945257 SILGen: Fix overlapping LoadExprs
When lowering a LoadExpr, SILGen constructs an LValue
and loads from it to produce an RValue.

If a LoadExpr contains another LoadExpr, the innermost
LoadExpr builds its own LValue, which is then loaded
to an RValue, and turned back into an LValue by creating
a single ValueComponent.

When evaluating an OpenExistentialExpr inside an LValue,
we record the base expression and evaluate it as an LValue
later when we encounter the corresponding OpaqueValueExpr.

The problem is when this is combined with a nested
LoadExpr, we might be inside of a different LValue than
the original LValue that contained the OpenExistentialExpr.

This would trigger an assertion, because the mapping from
OpaqueValueExprs to their base expressions was per-LValue;
instead, it needs to be per-SILGenFunction.
2017-05-15 15:16:48 -07:00
Slava Pestov
536480c2ec SILGen: Simplify curry thunk emission a little 2017-05-09 00:16:04 -07:00
John McCall
338825e73d Fix the emission of r-value pointer conversions to delay the
conversions and extend lifetimes over the call.

Apply this logic to string-to-pointer conversions as well as
array-to-pointer conversions.

Fix the AST verifier to not blow up on optional pointer conversions,
and make sure we SILGen them correctly.  There's still an AST bug
here, but I'll fix that in a follow-up patch.
2017-04-26 14:15:44 -04:00
John McCall
f7e73ccc48 Delay the formal accesses associated with inout-to-pointer and
array-to-pointer argument conversions until just before the call.

rdar://31781386
2017-04-25 03:54:49 -04:00
John McCall
978f0e05fe Add unpaired access marker instructions and use them to implement
dynamic access tracking in materializeForSet.
2017-04-22 22:52:13 -04:00
Michael Gottesman
081f2396e5 [silgen] Refactor emitLocalVariableWithCleanup to take an optional MarkUninitializedKind instead of a bool.
This enables me to refactor some code in SILGenConstructor. Specifically this
code passes in a false for uninitialized and then creates the mark uninitialized
for itself.
2017-04-14 18:55:20 -07:00
John McCall
5c725e6c2f Access markers for class properties (other than materializeForSet). 2017-04-14 00:09:55 -04:00
John McCall
79cc1d53b6 Start emitting begin_access markers for local and global vars.
NFC by default.

I had a much more comprehensive version of this patch that I had to
back out in order to just get something in to unblock progress.
There's a lot of technical debt in SILGen around l-values.

Enabling this will almost certainly not get past the SIL passes.
2017-04-05 01:43:21 -04:00
John McCall
305c94fc5b Pare down the Initialization interface and allow implementations
to insert code before performing an in-place initialization.

Intended to be NFC, but some of the clients needed more rewriting
than others.
2017-03-31 18:55:09 -04:00
Michael Gottesman
ba1e9f76d8 [silgen] Copy the body of emitEnumElementDispatch to emitEnumElementDispatchWithOwnership.
The reason I am doing this is that I am going to in the next couple of commits
change enum element dispatch to with or without semantic SIL use proper
ownership.

In this commit, I just did the copy and eliminated any parts of the code that
were predicated on having an address.
2017-03-27 10:28:08 -07:00
Devin Coughlin
fdd9ea6c7d SILGen: Reapply 'Add experimental TSan instrumentation for inout accesses.'
(This re-applies #7736 with an update to the
tsan-inout.swift execution test to handle configurations where
TSan's ignore_interceptors_accesses is enabled by default.)

Add SILGen instrumentation to treat inout accesses as Thread Sanitizer writes.
The goal is to catch races on inout accesses even when there is a not an
llvm-level read/write to a particular address. Ultimately
this will enable TSan to, for example, report racy writes to distinct
stored properties of a common struct as a data race.

This instrumentation is off by default. It can be enabled with the
'enable-experimental-tsan-inout-instrumentation' frontend flag.

The high-level approach is to add a SIL-level builtin that represents a call
to a TSan routine in compiler-rt. Then, when emitting an address for an LValue
as part of an inout expression, we call this builtin for each path component
that represents an LValue. I've added an 'isRValue()' method to PathComponent
that tracks whether a component represents an RValue or an LValue. Right the
only PathComponent that sometimes returns 'true' is ValueComponent().

For now, we're instrumenting only InoutExprs, but in the future it probably
makes sense to instrument all LValue accesses. In this patch I've
added a 'TSanKind' parameter to SILGenFunction::emitAddressOfLValue() and
its helpers to limit instrumentation to inout accesses. I envision that this
parameter will eventually go away.
2017-03-18 20:10:19 -07:00
Michael Gottesman
b99c47c006 [silgen] Scope argument cleanups with a new scope called "ArgumentScope".
Once this is in, I will be able to finish the SILGenApply part of Semantic SIL.

rdar://30955427
2017-03-18 17:03:41 -07:00
Michael Gottesman
f4f41337e3 [gardening] Change some CalleeTypeInfo '&' parameters to be 'const &' parameters. NFC. 2017-03-18 14:40:50 -07:00
Greg Parker
c17cfb69d8 Revert "SILGen: Add experimental TSan instrumentation for inout accesses. (#7736)"
This reverts commit 52d5178a3e.
2017-03-16 21:11:58 -07:00
Devin Coughlin
52d5178a3e SILGen: Add experimental TSan instrumentation for inout accesses. (#7736)
Add SILGen instrumentation to treat inout accesses as Thread Sanitizer writes.
The goal is to catch races on inout accesses even when there is a not an
llvm-level read/write to a particular address. Ultimately
this will enable TSan to, for example, report racy writes to distinct
stored properties of a common struct as a data race.

This instrumentation is off by default. It can be enabled with the
'enable-experimental-tsan-inout-instrumentation' frontend flag.

The high-level approach is to add a SIL-level builtin that represents a call
to a TSan routine in compiler-rt. Then, when emitting an address for an LValue
as part of an inout expression, we call this builtin for each path component
that represents an LValue. I've added an 'isRValue()' method to PathComponent
that tracks whether a component represents an RValue or an LValue. Right the
only PathComponent that sometimes returns 'true' is ValueComponent().

For now, we're instrumenting only InoutExprs, but in the future it probably
makes sense to instrument all LValue accesses. In this patch I've
added a 'TSanKind' parameter to SILGenFunction::emitAddressOfLValue() and
its helpers to limit instrumentation to inout accesses. I envision that this
parameter will eventually go away.
2017-03-16 17:08:48 -07:00
Slava Pestov
64adf7495e SILGen: Change ArchetypeOpenings map to be keyed by ArchetypeType * and not CanType 2017-03-14 17:46:54 -07:00
Michael Gottesman
213ddd753f [silgen] Compute the ResultPlan outside of SILGenApply so that we can untangle indirect result/normal argument lifetime scopes.
rdar://30955427
2017-03-14 00:39:53 -07:00
Michael Gottesman
4552355ff2 [silgen] Refactor SILGenFunction::apply to take a new struct called CalleeTypeInfo.
This structure contains all of the type information that we use to build a
ResultPlanPtr. In a subsequent commit, I am going to move ResultPlanPtr creation
out of emitApply and place it before the creation of arguments. This is to
enable indirect result initializations to belong to the scope outside of any
argument based scopes.

Without this the lifetimes of the indirect result initializations and arguments
can not be separated without using hacks. There is no reason why we can't emit
the indirect result temporaries before we emit any arguments since they will
remain dormant until after the final apply/any future committed argument scopes
being popped.

rdar://30955427
2017-03-14 00:39:41 -07:00
Slava Pestov
76eb5dd66d SILGen: Clean up ad-hoc SubstitutionList construction when calling intrinsics
Change emitApplyOfLibraryIntrinsic() to take a SubstitutionMap,
and use the correct abstractions to build the map.

This gets rid of the last remaining uses of gatherAllSubstitutions()
in SIL.
2017-03-08 13:54:29 -08:00
Slava Pestov
5465c8ca8f SIL: Remove most usages of TypeBase::gatherAllSubstitutions() 2017-03-08 13:54:28 -08:00
Michael Gottesman
455c126238 [semantic-sil] Pass the uncasted argument as an @owned arg in the failed checked_cast_br cast.
Previously, we would put a destroy_value directly on the value that we tried to
cast. Since checked_cast_br is consuming, this would cause the destroy_value on
the failure path to be flagged as a double consume.

This commit causes SILGen to emit the value consumed by checked_cast_br as an
@owned argument to the failure BB, allowing semantic arc rules to be respected.

As an additional benefit, I also upgraded the ownership_model_eliminator test to
use semantic sil verification.

One issue that did come up though is that I was unable to use the new code in
all locations in the compiler. Specifically, there is one location in
SILGenPattern that uses argument unforwarding. I am going to need to undo
argument unforwarding in SILGenPattern in order to completely eliminate the old
code path.
2017-02-28 17:29:03 -05:00
Michael Gottesman
5a15f880ee [silgen] Change a bunch of self accesses to use true formal evaluation scopes and formal accesses.
This is in preparation for removing the +0 self hack.

This commit in more detail does the following:

1. It adds Formal Evaluation Scopes to certain places where the scopes were
missing. Specifically:

   a. The SILGenLValue cases are places where we are invoking accessors. In each
      one of these cases, we had a formal evaluation scope in the accessor
      itself, but we did not have a scope that closed over the base access and
      the accessor access. The base access is a formal evaluation in the sense
      that just like with inout bases, we must create a new reference to the
      base and re-destroy the base in a chain of accesses. This is to ensure
      that we do not extend the lifetime of the base inappropriately.

   b. The SILGenPoly case is a place where we have never properly placed a
      Formal Evaluation Scope and have completely been relying on the +0 self
      hack to make sure that archetype callees are properly destroyed
      immediately after a +0 call.

2. It changes all of the places in SILGen that emit self to using formal access
cleanups instead of normal cleanups.

rdar://29791263
2017-02-23 10:36:48 -08:00
Michael Gottesman
784d5d16fc [silgen] Change emitClassConstructorInitializer to use ownership and make calling designated/chaining initializes use proper ownership.
rdar://29791263
2017-02-23 08:48:58 -08:00
Michael Gottesman
26a266b15e [silgen] Cleanup emitPreconditionOptionalHasValue and its uses so that they use proper ownership.
The big change here is that this routine will not emit switch_enum as a +1 value
and create a proper owned argument with cleanup.

rdar://29791263
2017-02-19 22:19:47 -08:00
Michael Gottesman
5920daa373 [silgen] Refactor getAddressForInPlaceInitialization onto SGFContext(). 2017-02-19 10:58:43 -08:00
Michael Gottesman
c6b32aea2c [silgen] Add APIs for creating managed buffers and managed rvalues in a FormalEvaluation context.
Eventually I want to move all of these emit* APIs to SILGenBuilder and make them
private details of SILGenBuilder. But that is a refactoring for another time.

rdar://29791263
2017-02-19 01:41:47 -08:00
Michael Gottesman
d051583378 [semantic-sil] When emitting a base for an accessor use a load_borrow when appropriate.
This builds on 92bf345. I am very pleased that a couple of the cases I needed to
update, a retain/release was eliminated on the base.

rdar://29791263
2017-02-18 00:55:36 -08:00
Michael Gottesman
03a926b256 [silgen] When emitting lvalue gets into temporaries, cleanup the temporaries as early as possible.
Previously, we were emitting these cleanups at the end of the lexical scope
instead of at the end of the formal evaluation scope. This change ensures that
we always emit the cleanup immediately at the end of the formal evaluation
scope.

Previously in most cases we got away with this due to the +0 self
hack. Basically we would emit a get for a self parameter and then immediately
use that self parameter as a guaranteed parameter. Then the hack would insert
the destroy value forwarding the lexical scope level cleanup at the same time.

rdar://29791263
2017-02-17 23:26:13 -08:00
Arnold Schwaighofer
ae0b6b1e06 Merge pull request #7186 from aschwaighofer/cow_exist_silgen_support
SIL/SILGen support for copy-on-write existentials
2017-02-15 17:41:10 -08:00
Michael Gottesman
58c3959e90 [silgen] Remove ManagedBorrowedValue in favor of the usage of FormalEvaluationScopes.
rdar://29791263
2017-02-15 15:28:14 -08:00
Arnold Schwaighofer
ec802fe9cd SILGen: Thread AccessKind to openExistential()
We will eventually create different open_existential_addr instructions depending on the kind of access to the opened value
2017-02-15 14:22:18 -08:00
Michael Gottesman
9747214e92 [silgen] Refactor WritebackScope functionality into a new FormalEvaluationScope.
As per John, WritebackScope was always an unfortunate name. Generally these
scopes are meant for formal evaluations of inout parameters. The cases that I am
interested in generalizing them to be used for are borrows of the base of a
class that will then be used as an lvalue.

This also eliminates the out of line vector of lvalue writebacks.

rdar://29791263
2017-02-14 13:15:23 -08:00
Slava Pestov
3519e0cd25 AST: Introduce new SubstitutionList type to replace ArrayRef<Substitution>
SubstitutionList is going to be a more compact representation of
a SubstitutionMap, suitable for inline allocation inside another
object.

For now, it's just a typedef for ArrayRef<Substitution>.
2017-02-06 21:36:33 -08:00
Slava Pestov
0babb28e17 SILGen: Clean up re-abstraction thunk emission's SubstitutionMap construction
Use GenericSignature::getSubstitutionMap() instead of calling
addSubstitution() and addConformance() on the SubstitutionMap.
2017-02-06 16:14:09 -08:00
Slava Pestov
162b1c0de0 SIL: Remove uncurryLevel parameter from type lowering
There was only one place where we lowered AST types with a non-zero
uncurry level, in SILGenApply.cpp. Add a new overload of the
getSILFunctionType() method that takes an uncurry level. All the
other methods no longer have to thread it through.
2017-02-06 15:24:03 -08:00
Michael Gottesman
77c1dfcb3a [semantic-sil] Use borrow semantics when emitting a struct_extract sequence.
rdar://29791263
2017-01-26 16:46:42 -08:00
Andrew Trick
1abeddcc5d [SILType] SILFunctionConventions API.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.

Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.

Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
2017-01-26 15:35:48 -08:00
Michael Gottesman
1dbabed576 [silgen] Extract SILGenBuilder into its own header/cpp file.
NFC.
2017-01-18 16:46:14 -08:00
Michael Gottesman
17b4d05e4e [semantic-sil] Rename EndBorrowInst::get{Src,Dest} => get{BorrowedValue,OriginalValue}.
This is a clearer name that makes it easier to remember what each part of the
end borrow is meant to accomplish.
2017-01-17 17:01:14 -08:00
Michael Gottesman
592f7d9dea [gardening] Fix header include guard of SILGenFunction.h 2017-01-13 12:36:57 -08:00
Erik Eckstein
1eb3a0532b DeadFunctionElimination: don’t eliminate public methods which are called via a thunk.
For this we need to store the linkage of the “original” method implementation in the vtable.
Otherwise DeadFunctionElimination thinks that the method implementation is not public but private (which is the linkage of the thunk).

The big part of this change is to extend SILVTable to store the linkage (+ serialization, printing, etc.).

fixes rdar://problem/29841635
2017-01-06 16:06:32 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Slava Pestov
a72eba1119 SILGen: Implement function conversions involving opened existentials
Suppose we have a protocol requirement returning Self:

protocol Clonable {
  func clone() -> Self
}

If we have a value 'x' of existential type 'Clonable',
the partial application 'x.clone' has formal type
'() -> Clonable'. However the actual type of the
method substitutes in an "opened" existential type
for 'Self'.

In order to implement the partial application we must
wrap the method in a thunk which 'erases' the opened
existential, so the thunk has type

<T : Clonable> (() -> T) -> () -> Clonable

The thunk is called with a substitution replacing 'T'
with the opened existential type.

Fixes <rdar://problem/21391055>.
2017-01-03 21:49:43 -08:00
Slava Pestov
2517701cd4 SILGen: Emit local types with a separate pass instead of while walking statements
Otherwise we might miss emitting a local type that's inside
unreachable code. Normally such a type cannot be found via
name lookup either, but IRGen will walk the list of local types
and try to emit a class with no SIL vtable, which will crash.

Fixes <https://bugs.swift.org/browse/SR-1924>.
2017-01-03 19:05:40 -08:00
Michael Gottesman
fd5b46d7ed Mirror +1 rvalue SILGenFunction convenience APIs for +0 rvalues.
These APIs just make it easy to create ManagedValues from SILValues ensuring
that the appropriate cleanup is created if necessary.

rdar://29791263
2017-01-03 17:01:25 -08:00
Michael Gottesman
b5e35240f2 Introduce a new Cleanup called EndBorrowCleanup
This will enable the usage of ManagedValue and scopes to manage shared borrowed
values.

rdar://29791263
2017-01-03 17:01:23 -08:00
Michael Gottesman
96837babda Merge pull request #5920 from gottesmm/vacation_gardening
Vacation gardening
2016-11-25 09:17:21 -06:00
Michael Gottesman
bf6920650c [gardening] Drop BB from all argument related code in SILBasicBlock.
Before this commit all code relating to handling arguments in SILBasicBlock had
somewhere in the name BB. This is redundant given that the class's name is
already SILBasicBlock. This commit drops those names.

Some examples:

getBBArg() => getArgument()
BBArgList => ArgumentList
bbarg_begin() => args_begin()
2016-11-25 01:14:36 -06:00
practicalswift
797b80765f [gardening] Use the correct base URL (https://swift.org) in references to the Swift website
Remove all references to the old non-TLS enabled base URL (http://swift.org)
2016-11-20 17:36:03 +01:00