Commit Graph

430 Commits

Author SHA1 Message Date
Slava Pestov
3e7f2e195c SILGen: Refactoring MaterializeForSet to support default witness thunk emission
Previously we would emit two types of MaterializeForSet implementations
in SILGen:

- materializeForSet for a concrete storage declaration

- materializeForSet witness thunk in a conformance

This refactoring decouples the code from taking a conformance, which is
needed for two new types of materializeForSet that we need:

- materializeForSet witness thunk in a default witness table -- this is
  necessary in order to be able to resiliently add storage requirements
  with default implementations to protocols

- materializeForSet vtable thunk -- this is necessary to fix a missing
  re-abstraction case with overriding storage in a subclass

This patch brings us closer to implementing these two. For default
implementations, we still have an issue in that the materializeForSet
has a different "generic signature abstraction pattern" in concrete
and default witnesses, so default and concrete witnesses for
materializeForSet are currently ABI-incompatible because the type
metadata for the storage is passed differently to the callback.
2016-03-07 17:05:06 -08:00
Slava Pestov
10e0151b16 SILGen: Small cleanup from recent change, NFC 2016-03-03 07:53:19 -08:00
Slava Pestov
c2a38c1c84 SILGen: Emit default witness thunks for constructors and methods
This patch wires up SILGenDefaultWitnessTable to actually emit
thunks and add them to the SILDefaultWitnessTable, using the
new logic in Sema for inferring default implementations.

Note that default witness thunks are mangled like the protocol
requirement itself.

After emitting thunks, SILGen populates a SILDefaultWitnessTable
for consumption by IRGen.

Default witness thunks for properties and subscripts are not
supported yet; a bit more refactoring in MaterializeForSet
emission is necessary.
2016-03-03 07:37:00 -08:00
Slava Pestov
4887d4fdc8 SILGen: Prepare witness thunk emission for default witnesses, NFC
In this case we do not have a conformance, and the default witness
thunk uses the same signature and context archetypes as the protocol
requirement.

There might still be an abstraction change between the requirement
and witness, though.

Tests are in the next patch that actually adds the ability to emit
these thunks. This is just a refactoring.
2016-03-03 07:36:59 -08:00
Adrian Prantl
310b0433a9 Reapply "Serialize debug scope and location info in the SIL assembler language.""
This ireapplies commit 255c52de9f.

Original commit message:

Serialize debug scope and location info in the SIL assembler language.
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. This change enable us
to write targeted testcases for single SIL optimization passes.

The new syntax is as follows:

 sil-scope-ref ::= 'scope' [0-9]+
 sil-scope ::= 'sil_scope' [0-9]+ '{'
                 sil-loc
                 'parent' scope-parent
                 ('inlined_at' sil-scope-ref )?
               '}'
 scope-parent ::= sil-function-name ':' sil-type
 scope-parent ::= sil-scope-ref
 sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+

Each instruction may have a debug location and a SIL scope reference
at the end.  Debug locations consist of a filename, a line number, and
a column number.  If the debug location is omitted, it defaults to the
location in the SIL source file.  SIL scopes describe the position
inside the lexical scope structure that the Swift expression a SIL
instruction was generated from had originally. SIL scopes also hold
inlining information.

<rdar://problem/22706994>
2016-02-26 13:28:57 -08:00
Adrian Prantl
255c52de9f Revert "Serialize debug scope and location info in the SIL assembler language."
Temporarily reverting while updating the validation test suite.

This reverts commit c9927f66f0.
2016-02-26 11:51:57 -08:00
Adrian Prantl
c9927f66f0 Serialize debug scope and location info in the SIL assembler language.
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. This change enable us
to write targeted testcases for single SIL optimization passes.

The new syntax is as follows:

 sil-scope-ref ::= 'scope' [0-9]+
 sil-scope ::= 'sil_scope' [0-9]+ '{'
                 sil-loc
                 'parent' scope-parent
                 ('inlined_at' sil-scope-ref )?
               '}'
 scope-parent ::= sil-function-name ':' sil-type
 scope-parent ::= sil-scope-ref
 sil-loc ::= 'loc' string-literal ':' [0-9]+ ':' [0-9]+

Each instruction may have a debug location and a SIL scope reference
at the end.  Debug locations consist of a filename, a line number, and
a column number.  If the debug location is omitted, it defaults to the
location in the SIL source file.  SIL scopes describe the position
inside the lexical scope structure that the Swift expression a SIL
instruction was generated from had originally. SIL scopes also hold
inlining information.

<rdar://problem/22706994>
2016-02-26 10:46:29 -08:00
Joe Groff
a1ef412815 Sema/SILGen: Get property behavior implementations to codegen.
Fix some interface type/context type confusion in the AST synthesis from the previous patch, add a unique private mangling for behavior protocol conformances, and set up SILGen to emit the conformances when property declarations with behaviors are visited. Disable synthesis of the struct memberwise initializer if any instance properties use behaviors; codegen will need to be redesigned here.
2016-02-20 15:01:06 -08:00
practicalswift
2fb4750e7c [gardening] Fix recently introduced typo: "irredutable" → "irrefutable" 2016-02-19 14:20:02 +01:00
John McCall
e249fd680e Destructure result types in SIL function types.
Similarly to how we've always handled parameter types, we
now recursively expand tuples in result types and separately
determine a result convention for each result.

The most important code-generation change here is that
indirect results are now returned separately from each
other and from any direct results.  It is generally far
better, when receiving an indirect result, to receive it
as an independent result; the caller is much more likely
to be able to directly receive the result in the address
they want to initialize, rather than having to receive it
in temporary memory and then copy parts of it into the
target.

The most important conceptual change here that clients and
producers of SIL must be aware of is the new distinction
between a SILFunctionType's *parameters* and its *argument
list*.  The former is just the formal parameters, derived
purely from the parameter types of the original function;
indirect results are no longer in this list.  The latter
includes the indirect result arguments; as always, all
the indirect results strictly precede the parameters.
Apply instructions and entry block arguments follow the
argument list, not the parameter list.

A relatively minor change is that there can now be multiple
direct results, each with its own result convention.
This is a minor change because I've chosen to leave
return instructions as taking a single operand and
apply instructions as producing a single result; when
the type describes multiple results, they are implicitly
bound up in a tuple.  It might make sense to split these
up and allow e.g. return instructions to take a list
of operands; however, it's not clear what to do on the
caller side, and this would be a major change that can
be separated out from this already over-large patch.

Unsurprisingly, the most invasive changes here are in
SILGen; this requires substantial reworking of both call
emission and reabstraction.  It also proved important
to switch several SILGen operations over to work with
RValue instead of ManagedValue, since otherwise they
would be forced to spuriously "implode" buffers.
2016-02-18 01:26:28 -08:00
Slava Pestov
bbbe307980 SIL: Introduce SILDefaultWitnessTable and start plumbing
This will be used to help IRGen record protocol requirements
with resilient default implementations in protocol metadata.

To enable testing before all the Sema support is in place, this
patch adds SIL parser, printer and verifier support for default
witness tables.

For now, SILGen emits empty default witness tables for protocol
declarations in resilient modules, and IRGen ignores them when
emitting protocol metadata.
2016-02-05 20:57:11 -08:00
Jordan Rose
923b9a6201 Don't emit any check for #available of another platform.
Previously we treated the * platform as checking for the minimum
deployment target, but that's definitely unnecessary.

There is a bit of a hack here to avoid diagnosing the 'else' branch as
unreachable: if a constant true/false came from #available, ignore it.
2016-02-03 14:27:13 -08:00
Slava Pestov
cca5644a50 SIL: Replace TypeLowering::getInterfaceTypeOutOfContext() with ArchetypeBuilder::mapTypeOutOfContext(), NFC
This is where the AllowLoweredTypes flag to Type::subst() is important,
since this function is used on both canonical AST types, and lowered
AST types.
2016-02-01 20:49:13 -08:00
Erik Eckstein
845b3fe08e SIL: remove isValid() from SILValue. NFC 2016-01-25 15:00:49 -08:00
Erik Eckstein
506ab9809f SIL: remove getTyp() from SILValue 2016-01-25 15:00:49 -08:00
Slava Pestov
c75f443c83 Sema: Better fix for duplicate emission of accessors
When compiling a module with multiple FileUnits (eg, while running
swiftc without -whole-module-optimization), we emit all decls
in the ExternalDeclarations list for every FileUnit, leading to
duplicate symbols if any of those decls were public.

Joe's workaround skipped decls on ExternalDefinitions that were
already emitted in the current FileUnit, but that was not sufficient;
the right fix is to not put stuff on ExternalDeclarations at all,
if we're going to emit it as part of a decl inside our file.

In this case, the synthesized _code accessors for an ErrorType
conformance do not belong in ExternalDefinitions, because they're
part of an ExtensionDecl that is in the current FileUnit.

Finally add some tests for this stuff, because it appears our
existing coverage was insufficient.
2016-01-21 22:30:56 -08:00
Joe Groff
8da10e3825 SILGen: Minimal workaround for multiple-emission bug with Clang-importer-synthesized properties on enums.
If you extend a C/ObjC enum type to conform to ErrorType, then the synthesized _code getter ends up registered as an external decl, but appears to already get synthesized due to @slavapestov's changes. I'm not sure whether this is reliable enough that we can simply stop registering the external decls, so just to keep the build from crashing, insert a check in emitExternalDecls that we didn't already emit the decl and skip emission. Low-risk workaround for rdar://problem/24287125.
2016-01-21 17:32:55 -08:00
Erik Eckstein
8110b1ebc8 [SIL] Let alloc_box return a single value.
And use project_box to get to the address value.
SILGen now generates a project_box for each alloc_box.
And IRGen re-uses the address value from the alloc_box if the operand of project_box is an alloc_box.
This lets the generated code be the same as before.

Other than that most changes of this (quite large) commit are straightforward.
2016-01-19 08:59:24 -08:00
Slava Pestov
df38bd1764 SILGen: More interface type abstraction pattern goodness, NFC 2016-01-18 23:17:17 -08:00
Slava Pestov
548cd68b84 SILGen: Switch some abstraction patterns over to interface types
Now that all the pieces are in place, we can finally start seeing
some benefits. In particular, the code for witness thunk emission
is much simpler now.
2016-01-18 21:43:55 -08:00
practicalswift
9d9aaee9d4 Use // or /// instead of /* … */ for multi-line comments. 2016-01-13 23:37:06 +01:00
Erik Eckstein
b3c6fd49c2 Revert "SILGen: Correctly emit accessors synthesized to witness protocol requirements"
It breaks the swiftpm build.

This reverts commit 10c8ce824f.
2016-01-13 11:08:56 -08:00
Slava Pestov
10c8ce824f SILGen: Correctly emit accessors synthesized to witness protocol requirements
We weren't adding them as external decls unless they were for
storage on an imported type, which meant SILGen wasn't emitting
them if the conforming type was from a different Swift source
file, or in whole-module mode, a different module. This led
to linker errors.

Instead, always add accessors to the external decl list, but
skip them in SILGen if they are contained in the DeclContext
we are currently emitting (which is a source file or module).

Note that they are still emitted with the wrong linkage, from a
resilience perspective. Clients must only ever see public
exports for getters, setters and materializeForSet emitted
because they are required by resilience or the access pattern;
'accidental' accessors synthesized for protocol conformance
should not be public.
2016-01-11 21:40:25 -08:00
Slava Pestov
9bdb7d377d Clean up handling of external declarations, NFC
This is the first in a series of patches that fixes some resilience-related
issues with synthesized accessors and materializeForSet.

Previously we maintained two lists of external declarations encountered while
type checking:

- ASTContext::ExternalDefinitions
- TypeChecker::implicitlyDefinedFunctions

The former contained the following:

- Imported nominal types from Clang, so that SILGen can emit witness tables
- Functions and variables with Clang decls, so that IRGen can instruct Clang
  to emit them
- Synthesized accessors

The latter contained synthesized functions for derived conformances.

Since the second list was not visible outside Sema, we relied on the Clang
importer to add the type that contained the declaration to the
ExternalDefinitions list. In practice, we only synthesized members of enums
in this manner.

Because of this, SILGenModule::emitExternalDefinitions() had special logic to
skip members of enums, since it would visit them when visiting the enum itself.

Instead, it appears that we can remove implicitlyDefinedFunctions completely,
changing usage sites to add the decl to ExternalDefinitions instead, and
simplify SILGenModule::emitExternalDefinition() a bit in the process.

Also, it looks like we never had Modules appear in ExternalDefinitions, so
assert if those come up instead of skipping them.
2016-01-10 17:05:31 -08:00
Slava Pestov
627c906ef3 SILGen: Emit alloc_global when initializing global variables
It is still not clear to me when we access global variables from other
modules directly, versus using accessors; it seems to be controlled
by the -sil-serialize-all flag, rather than any language feature.

Until/if we add a @_fixed_layout equivalent for globals, I can't really
test direct access of globals from other modules; when we figure out
the story here I'll be able to add more tests and also tighten up
some isResilient() checks in the global code, but what's in there now
seems to work.
2016-01-08 19:56:00 -08:00
John McCall
2df6880617 Introduce ProtocolConformanceRef. NFC.
The main idea here is that we really, really want to be
able to recover the protocol requirement of a conformance
reference even if it's abstract due to the conforming type
being abstract (e.g. an archetype).  I've made the conversion
from ProtocolConformance* explicit to discourage casual
contamination of the Ref with a null value.

As part of this change, always make conformance arrays in
Substitutions fully parallel to the requirements, as opposed
to occasionally being empty when the conformances are abstract.

As another part of this, I've tried to proactively fix
prospective bugs with partially-concrete conformances, which I
believe can happen with concretely-bound archetypes.

In addition to just giving us stronger invariants, this is
progress towards the removal of the archetype from Substitution.
2016-01-08 00:19:59 -08:00
Slava Pestov
6af7f95a5a We don't need to plumb a resilience expansion through mangling, NFC
I'm going to be adding deployment target info ResilienceExpansion
soon so removing unnecessary usages helps reduce the amount of
work there.
2016-01-07 08:15:26 -08:00
Erik Eckstein
6ff2f09796 [SIL] Let alloc_stack return a single value.
Having a separate address and container value returned from alloc_stack is not really needed in SIL.
Even if they differ we have both addresses available during IRGen, because a dealloc_stack is always dominated by the corresponding alloc_stack in the same function.

Although this commit quite large, most changes are trivial. The largest non-trivial change is in IRGenSIL.

This commit is a NFC regarding the generated code. Even the generated SIL is the same (except removed #0, #1 and @local_storage).
2016-01-06 17:35:27 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Nadav Rotem
07d4558c1c [Mangler] Change the Swift mangler into a symbol builder.
This commit changes the Swift mangler from a utility that writes tokens into a
stream into a name-builder that has two phases: "building a name", and "ready".
This clear separation is needed for the implementation of the compression layer.

Users of the mangler can continue to build the name using the mangleXXX methods,
but to access the results the users of the mangler need to call the finalize()
method. This method can write the result into a stream, like before, or return
an std::string.
2015-12-25 21:40:25 -08:00
Nadav Rotem
6fa6ca563e [Mangler] Rename some of the mangler methods. NFC. 2015-12-24 14:35:33 -08:00
Nadav Rotem
b5e4197d33 [Mangler] Fix all of the places where users of the Mangler access the underlying buffer.
This commit fixes all of the places where users of the Mangler write to the stream that's used by the Mangler. The plan is to make the Mangler buffered, and this means that users can't assume that the mangler immediately writes the mangled tokens to the output stream.
2015-12-22 22:47:35 -08:00
Adrian Prantl
64cbec3805 Add SIL syntax for declaring debug variables.
Debug variable info may be attached to debug_value, debug_value_addr,
alloc_box, and alloc_stack instructions.

In order to write textual SIL -> SIL testcases that exercise the handling
of debug information by SIL passes, we need to make a couple of additions
to the textual SIL language. In memory, the debug information attached to
SIL instructions references information from the AST. If we want to create
debug info from parsing a textual .sil file, these bits need to be made
explicit.

Performance Notes: This is memory neutral for compilations from Swift
source code, because the variable name is still stored in the AST. For
compilations from textual source the variable name is stored in tail-
allocated memory following the SIL instruction that introduces the
variable.

<rdar://problem/22707128>
2015-12-14 10:29:50 -08:00
Slava Pestov
0a072484ec SILGen: Emit enum case constructors lazily
Now that we open-code enum construction, enum constructor entry points are
only needed when they are partially-applied, which is a rare case. So we
treat them like curry thunks and only emit them as needed.

The main consequence of this is that enum case constructors are no longer
part of our ABI.

To avoid a regression in the code path for diagnosing infinite value types,
force type lowering to walk a type when emitting its declaration, even if
there are no other references to the type in the program (which is now the
case for public enums which are otherwise not used).

Also XFAIL a DebugInfo test since it is not clear to me what the test does
or how to fix it. The obvious change of adding references to the enum
case constructor function to force it to be emitted did not work.
2015-12-10 16:39:48 -08:00
Michael Gottesman
1e5aa72f2d Add in clang-format changes that I forgot to commit with the previous commit (sorry).
I clang-formatted the previous commit, but forgot to amend the changes.
2015-12-06 16:29:52 -08:00
Michael Gottesman
302632cefb Make SILFunction::create() private and change all direct uses of SILFunction::create() to instead use SILMod.getOrCreateFunction().
This centralizes the entrypoints for creating SILFunctions. Creating a
SILFunction is intimately tied to a specific SILModule, so it makes sense to
either centralize the creation on SILModule or SILFunction. Since a SILFunction
is in a SILModule, it seems more natural to put it on SILModule.

I purposely created a new override on SILMod that exactly matches the signature
of SILFunction::create so that beyond the extra indirection through SILMod, this
change should be NFC. We can refactor individual cases in later iterations of
refactoring.
2015-12-06 16:23:44 -08:00
Slava Pestov
f25b887686 SILGen: Don't emit no-payload case constructors at all
With the change to open-code enum construction, it is no longer
possible to form a reference to a no-payload case constructor
function (at least until we allow enum cases to witness protocol
requirements), so only payload case constructors need to be
emitted now.

Currently, we still emit all the case constructor functions
for payload cases unconditionally, even though now this is only
necessary for the ones that are partially applied. This will
be addressed in a follow-on patch.
2015-12-05 01:44:44 -08:00
Joe Savage
fe3bd7d70a minor typo fixes 2015-12-03 23:10:42 +00:00
Adrian Prantl
7821341542 Add an argument-number field to DebugValueInst and friends.
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.

This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.

Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.

Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.

This reapplies ed2b16dc5a with a bugfix for
generic function arrguments and an additional testcase.

<rdar://problem/21185379&22705926>
2015-12-03 13:40:35 -08:00
Adrian Prantl
2740ad6976 Temporarily Revert "Add an argument-number field to DebugValueInst and friends."
while investigating buildbot breakage.

This reverts commit ed2b16dc5a.
2015-12-02 19:10:05 -08:00
Adrian Prantl
ed2b16dc5a Add an argument-number field to DebugValueInst and friends.
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.

This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.

Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2dd50
which removed 20 bytes from *every* SILInstruction.

Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.

<rdar://problem/21185379&22705926>
2015-12-02 18:33:07 -08:00
Slava Pestov
e6d35f29f2 Fix typos I noticed in IRGen and SILGen, NFC 2015-11-30 13:32:55 -08:00
Michael Gottesman
9fb54bf4bf Fix for upstream ilist changes. 2015-11-11 16:07:41 -08:00
Dmitri Hrybenko
130e79f2fa KnownIdentifiers: avoid generating 'Id__value', which is a reserved identifier
Swift SVN r32113
2015-09-21 17:28:54 +00:00
Dmitri Hrybenko
4375a463a7 stdlib: rename Int**.value and Float**.value to _value per naming convention
rdar://21357661

Swift SVN r32096
2015-09-20 00:01:13 +00:00
Chris Lattner
27d6f8a929 fix <rdar://problem/22312114> if case crashes swift - bools not supported in let/else yet
Swift SVN r31901
2015-09-11 18:57:32 +00:00
Joe Groff
88b83fd725 SILGen: Don't clobber variables from other pattern bindings in a PatternBindingDecl's initialization.
The PBD entry index got dropped on the way from SILGenModule to SILGenFunction. Oops. Fixes rdar://problem/22207407.

Swift SVN r31316
2015-08-18 23:05:28 +00:00
Slava Pestov
9b74a4b0d6 SILGen: Fix memory leak when sub-expression of ErasureExpr throws
If we didn't initialize the existential, we have to emit a cleanup
because we may have allocated a buffer on the heap to store the value.

Factor out the TakeExistentialCleanup that appears in a few places,
rename it to DeinitExistentialCleanup and add support for deallocating
boxed existentials.

Then, use a special Initialization subclass to keep track of the
state of the memory in emit{AddressOnly,Boxed}Erasure().

Swift SVN r31259
2015-08-16 16:45:44 +00:00
Erik Eckstein
388bc31ba7 Add a nothrow flag to the SIL apply_inst.
If the compiler can prove that a throwing function actually does not throw it can
replace a try_apply with an "apply [nothrow]". Such an apply_inst calls a function
with an error result but does not have the overhead of checking for the error case.

Currently this flag is not set, yet.



Swift SVN r31151
2015-08-12 00:18:36 +00:00
Joe Groff
5cabb04f46 SILGen: Handle indirect payloads in if/guard case patterns.
Reported externally by AirspeedVelocity, don't have an rdar handy yet.

Swift SVN r30499
2015-07-22 19:55:15 +00:00