Commit Graph

754 Commits

Author SHA1 Message Date
Michael Gottesman
3e730d4fa6 [silgen] Rename {was,}InWritebackScope => {was,}InFormalEvaluationScope. 2017-09-06 16:31:20 -07:00
Michael Gottesman
aa16226530 [silgen] Rename emitRValueForPropertyLoad parameter isGuaranteedValid => isBaseGuaranteed. (#11767)
This name makes it easier to infer the use of the parameter without reading the body of
the method.
2017-09-05 12:35:39 -07:00
Michael Gottesman
5f638f8471 Merge pull request #11755 from gottesmm/pr-b75c319423e03aa68eb76d43d5f1e8415fe0b813
[gardening] Rename a bunch of isGuaranteedValid parameters to => is{Base,Addr,Address}Guaranteed parameters.
2017-09-05 10:06:19 -07:00
Michael Gottesman
dc8b1c2c3a [silgen] When pushing an RValue through a scope, use dealloc_box on any boxes we create instead of destroy_value.
It is only safe to perform a destroy_value on an alloc_box that contains an
initialized value. We preserve the original cleanups for the value we are
pushing through the scope implying that the box will not contain an initialized
value when its lifetime ends (just like an alloc_stack). Thus we must use
dealloc_box here.

The surprising thing about tracking down this error is that I was not hitting
any memory issues at -Onone. Instead what was happening was that at -O, we were
miscompiling (creating non-dominating uses of SSA values) in the face of an
address being taken twice.

This does not seem to hit any SILGen tests today (I hit this when testing a
patch I am trying to land today).

rdar://31521023
2017-09-04 10:46:37 -07:00
Michael Gottesman
92162e2174 [gardening] Rename a bunch of isGuaranteedValid parameters to => is{Base,Addr,Address}Guaranteed parameters.
These names are not perfect, but they provide more descriptive background on
what the parameter actually does. Simply, these parameters say that the
underlying base address will last longer than the usage of the underlying value,
so a begin_borrow/load_borrow could be used to access the underlying value from
the base. If the base is destroyed before the borrow finishes, we have an
ownership violation. =><=.

I also copy-edited/added doxygen comments above some of these methods as well.
2017-09-04 09:45:53 -07:00
Michael Gottesman
daeddd0075 [silgen] Enable ownership on objc factory constructor test and fix exposed problems.
The specific exposed problem had to do with my using the same emission routine
for both lvalues using delegating init self (where we want formal accesses) and
for routines that wanted normal access to self. By splitting them the issue is
resolved.

As a benefit, I added a small peephole that I needed to add for my own purposes
(i.e. to maintain invariants), but that also incidentally improve codegen in
other places!

rdar://31521023
2017-08-31 16:39:12 -07:00
Michael Gottesman
9d5f28039a [silgen] Update SILGen objc deallocators and enable ownership on objc_dealloc.swift
rdar://33358110
2017-08-29 15:16:38 -07:00
Michael Gottesman
afe402ff86 [silgen] Begin splitting emitRValue into two different APIs: SILGenFunction::emitPlus{One,Zero}RValue(...).
Today, SILGenFunction::emitRValue assumes the caller will create any cleanup
scopes that are needed to cleanup side-effects relating to the rvalue
evaluation.  The API also provides the ability for the caller to specify that a
+0 rvalues is an "ok" result. The API then tries to produce a +0 rvalue and
returns a +1 rvalue otherwise. These two properties create conflicting
requirements on the caller since the caller does not know whether or not it
should create a scope (if a +1 rvalue will be returned) or not (if a +0 rvalue
would be returned).

The key issue here is the optionality of returning a +0 rvalue. This change
begins to resolve this difference by creating two separate APIs that guarantee
to the caller whether or not a +0 or a +1 rvalue is returned and also creates
local scopes for the caller as appropriate. So by using these APIs, the caller
knows that the +0 or +1 rvalue that is returned has properly been put into the
caller scope. So the caller no longer needs to create its own scopes anymore.

emitPlusOneRValue is emitRValue except that it scopes the rvalue emission and
then *pushes* the produced rvalue through the scope. emitPlusZeroRValue is
currently a stub implementation that just calls emitPlusOneRValue and then
borrows the resulting +1 RValue in the outer scope, creating the +0 RValue that
was requested by the caller.

rdar://33358110
2017-08-14 13:24:43 -07:00
Michael Gottesman
bd32f9eaea [silgen] Perform last gen => SGF. Now SILGen always uses SGF. 2017-08-10 22:55:42 -07:00
John McCall
c0b3bf1711 Suppress access enforcement when an l-value is converted to a pointer
just for pointer identity.

The current technique for deciding whether that's the case is *extremely*
hacky and need to be replaced with an attribute, but I'm reluctant to
take that on so late in the schedule.  The hack is terrible but not too
hard to back out in the future.  Anyone who names a method like this just
to get the magic behavior knows well that they are not on the side of
righteousness.

rdar://33265254
2017-07-21 23:40:04 -04:00
John McCall
80b180a9a1 Implement a syntactic peephole to recognize explicit bridging
conversions that reverse an implicit conversion done to align
foreign declarations with their imported types.

For example, consider an Objective-C method that returns an NSString*:
  - (nonnull NSString*) foo;
This will be imported into Swift as a method returning a String:
  func foo() -> String
A call to this method will implicitly convert the result to String
behind the scenes.  If the user then casts the result back to NSString*,
that would normally be compiled as an additional conversion.  The
compiler cannot simply eliminate the conversion because that is not
necessarily semantically equivalent.

This peephole recognizes as-casts that immediately reverse a bridging
conversion as a special case and gives them special power to eliminate
both conversions.  For example, 'foo() as NSString' will simply return
the original return value.  In addition to call results, this also
applies to call arguments, property accesses, and subscript accesses.
2017-07-15 01:13:41 -04:00
John McCall
7f22faf968 Substantially rework how SILGen handles bridging as part of laying the
ground work for the syntactic bridging peephole.

- Pass source and dest formal types to the bridging routines in addition
  to the dest lowered type.  The dest lowered type is still necessary
  in order to handle non-standard abstraction patterns for the dest type.

- Change bridging abstraction patterns to store bridged formal types
  instead of the formal type.

- Improve how SIL type lowering deals with import-as-member patterns.

- Fix some AST bugs where inadequate information was being stored in
  various expressions.

- Introduce the idea of a converting SGFContext and use it to regularize
  the existing id-as-Any conversion peephole.

- Improve various places in SILGen to emit directly into contexts.
2017-07-11 12:45:13 -04:00
Michael Gottesman
fc4079ec5d [silgen] Add support for creating guaranteed phi arguments.
The main thing here is that we create a cleanup that inserts the
end_borrow_argument. Once I merge end_borrow with end_borrow_argument, there
will only be one cleanup.

rdar://31880847
2017-07-05 17:57:32 -07:00
Robert Widmann
a2a01cf8e8 Remove some uses of setLet 2017-06-28 15:59:56 -07:00
Slava Pestov
46bc2b160d SILGen: Remove 'overrideLocationForMagicIdentifiers' hack 2017-06-11 21:54:41 -07:00
John McCall
44fda629aa Teach SILGen to handle more bridging cases and thread SGFContexts
through a few places.

This patch should be NFC for existing patterns, but it's preparing for
using SILGen's built-in bridging capabilities for more things.
2017-06-11 01:39:51 -04:00
Slava Pestov
29cd885996 SILGen: Remove SILGenFunction::ArchetypeOpenings
SILBuilder now tracks data dependencies between instructions
that open existentials and uses of the opened type, so
SILGen's mechanism for this is no longer needed.

In particular, this simplifies ArchetypeCalleeBuilder.
2017-06-02 01:35:11 -07:00
John McCall
bb5fe8046f Fix the emission of open-existential-metatype l-values.
rdar://32288618
2017-05-22 20:47:25 -04:00
Joe Groff
c8a7a442ae Runtime: Include source location information in log messages about deprecated implicit Objective-C entry points.
Make it easier for migration by pinpointing exactly where to insert @objc to keep the entry points in Swift 4 mode. rdar://problem/32230003
2017-05-16 19:02:47 -07:00
Slava Pestov
31efc6a40a SILGen: Use emitOpenExistentialLValue() when lowering OpenExistentialExprs with lvalue base 2017-05-15 18:17:26 -07:00
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