Commit Graph

110 Commits

Author SHA1 Message Date
Arnold Schwaighofer
f2ec95951d IRGen: Call coro.alloca.free on the token not the address of a coro.alloca.alloc
rdar://43311065
2018-08-15 08:06:26 -07:00
Ben Cohen
a1adf9f347 Squash a few more unused warnings (#17743) 2018-07-05 08:24:17 -07:00
Arnold Schwaighofer
6267860a7e IRGen: Remove initializeBufferWithTakeOfBuffer in favor of memcpy
And update the existential container's initializeWithTake implementation
in the runtime. After only allowing bitwise takable values in the
inline buffer we can use memcpy to move existential container values.

rdar://31414907
SR-343
2018-05-22 13:05:00 -07:00
John McCall
2ed90771f4 Use the VWT for value ops on types with ABI-inaccessible children.
rdar://39763787
2018-05-15 15:07:32 -04:00
John McCall
14c0c39be2 Basic plumbing to propagate metadata-generation results in IRGen. 2018-03-26 01:13:45 -04:00
Arnold Schwaighofer
9d8c381ab4 Remove resilient tag indices 2018-03-20 13:19:56 -07:00
Arnold Schwaighofer
ce7608a7ce IRGen: Make resilient enum's tag indices resilient
This allows reordering enum cases resiliently.

rdar://24057946
2018-03-20 13:19:56 -07:00
John McCall
738bff0089 Move ValueWitnessFlags into MetadataValues.h. NFC. 2018-03-17 11:40:30 -04:00
John McCall
3c54c0edfc IRGen and basic optimizer support for coroutines. 2018-01-09 11:35:09 -05:00
John McCall
1f3f33e67d Clean up the internal APIs around dynamic allocas to structurally
discourage accidental use of them.  Relatedly, fix several bugs
where we were accidentally using dynamic allocas.
2017-12-19 00:29:43 -05:00
Erik Eckstein
90c21be191 Unify the implementation of optimization mode in various option classes.
This commit is mostly refactoring.

*) Introduce a new OptimizationMode enum and use that in SILOptions and IRGenOptions
*) Allow the optimization mode also be specified for specific SILFunctions. This is not used in this commit yet and thus still a NFC.

Also, fixes a minor bug: we didn’t run mandatory IRGen passes for functions with @_semantics("optimize.sil.never")
2017-11-14 11:25:02 -08:00
Arnold Schwaighofer
865d85bd1c Reapply the enum value witness patch
Revert "Revert "Merge pull request #12606 from aschwaighofer/single_payload_enum_witness""

This reverts commit c422f80307.
2017-10-31 17:28:15 -07:00
Arnold Schwaighofer
c422f80307 Revert "Merge pull request #12606 from aschwaighofer/single_payload_enum_witness"
This reverts commit 0b414e45c5, reversing
changes made to fb27e7d32a.

There are failures on the resilient bot and lldb test case fails.
2017-10-31 08:24:26 -07:00
Arnold Schwaighofer
53a967f953 Add a readonly function attribute to the getEnumTagSinglePayloadWitness
Conditionally (on Osize) outline the witness call - this saves two loads
2017-10-26 14:56:09 -07:00
Arnold Schwaighofer
43b9d13a2e Add value witnesses for single payload enums
So far single payload enums were implemented in terms of runtime functions which
internally emitted several calls to value witnesses.

This commit adds value witnesses to get and store the enum tag side stepping the
need for witness calls as this information is statically available in many cases

/// int (*getEnumTagSinglePayload)(const T* enum, UINT_TYPE emptyCases)
/// Given an instance of valid single payload enum with a payload of this
/// witness table's type (e.g Optional<ThisType>) , get the tag of the enum.

/// void (*storeEnumTagSinglePayload)(T* enum, INT_TYPE whichCase,
///                                   UINT_TYPE emptyCases)
/// Given uninitialized memory for an instance of a single payload enum with a
/// payload of this witness table's type (e.g Optional<ThisType>), store the
/// tag.

A simple 'for element in array' loop in generic code operating on a
ContigousArray of Int is ~25% faster on arm64.

rdar://31408033
2017-10-23 13:31:46 -07:00
Arnold Schwaighofer
8a85a9efd5 Use array copy runtime implementation instead of the array value witnesses
And add builtins for the added runtime functions (assign-take, assign-copy).

rdar://27412867
SR-3376
2017-09-12 12:43:26 -07:00
Arnold Schwaighofer
f4a810f7e4 IRGen: AttributeList related fixes for master next 2017-07-31 11:17:51 -07:00
John McCall
a0f20f673d Switch all of the indirect-call code in IRGen to FunctionPointer.
To make this stick, I've disallowed direct use of that overload of
CreateCall.  I've left the Constant overloads available, but eventually
we might want to consider fixing those, too, just to get all of this
code out of the business of manually remembering to pass around
attributes and calling conventions.

The test changes reflect the fact that we weren't really setting
attributes consistently at all, in this case on value witnesses.
2017-07-28 23:26:35 -04:00
Arnold Schwaighofer
ca63326e1b Delete unused existential value witnesses from the old existential
implementation

And remove the SWIFT_RUNTIME_ENABLE_COW_EXISTENTIALS flag.
2017-06-02 14:34:41 -07:00
Huon Wilson
fba2ab49dc Merge pull request #8301 from huonw/symbol-list
Initial TBD push: list of (some) public symbols
2017-03-29 12:48:22 -07:00
Huon Wilson
655fa58620 [IRGen] Expose LinkEntity and ValueWitness publicly. 2017-03-23 15:58:29 -07:00
Arnold Schwaighofer
3ab228767d IRGen: Outline dynamic allocate/project/deallocateValueInBuffer functions 2017-03-22 08:51:58 -07:00
Arnold Schwaighofer
5634280307 Use the inline value buffer for allocate/project/deallocateValueBuffer functions
Also handle fixed size types.
2017-03-21 11:45:12 -07:00
Arnold Schwaighofer
d5cbb0bd62 Runtime changes for the copy-on-write existential implementation
Adds the runtime implementation for copy-on-write existentials. This support is
enabled if SWIFT_RUNTIME_ENABLE_COW_EXISTENTIALS is defined. Focus is on
correctness -- not performance yet.

Don't use allocate/deallocate/projectBuffer witnesses for globals in cow
existential mode.

Use SWIFT_RUNTIME_ENABLE_COW_EXISTENTIALS configuration to set the default for
SILOptions.

This includes an IRGen fix to use the right projection in
emitMetatypeOfOpaqueExistential if SWIFT_RUNTIME_ENABLE_COW_EXISTENTIALS is set.

Use unknownRetain instead of native retain in dynamicCastToExistential.
2017-03-15 14:54:55 -07:00
Arnold Schwaighofer
80732ead34 Non-witness implementations of init_existential_addr, deinit_existential_addr, open_existential_addr, copy_addr, destory_addr
For the boxed existential variant.
2017-03-09 17:22:35 -08:00
Roman Levenstein
cbe4b0d791 Teach IRGen how to work with archetypes of fixed sizes.
This allows IRGen to use direct loads and stores instead of calling value witness tables.
2017-02-08 07:31:28 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Arnold Schwaighofer
cd1037b799 IRGen: Allocate generic/resilient values on the stack instead of on the heap
Allocate buffers for local generic/resilient values on the stack. alloc_stack
instructions in the entry block are translated using a dynamic alloca
instruction with variables size. All other alloc_stack instructions in addition
use llvm's stacksave/restore instrinsics to reset the stack (they could be
executed multiple times and with varying sizes).
2016-12-20 07:24:02 -08: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
Roman Levenstein
de3b850ce8 Use more descriptive names for calling conventions.
Rename RuntimeCC into DefaultCC
Rename RuntimeCC1 into RegisterPreservingCC
Remove RuntimeCC0 because it was identical to DefaultCC.
2016-02-25 05:31:00 -08:00
Slava Pestov
34a4075116 IRGen: Implement resilient enum case numbering
Recent changes added support for resiliently-sized enums, and
enums resilient to changes in implementation strategy.

This patch adds resilient case numbering, fixing the problem
where adding new payload cases would break existing code by
changing the numbering of no-payload cases.

The problem is that internally, enum cases are numbered with payload
cases coming first, followed by no-payload cases. While each list
is itself in declaration order, with new additions coming at the
end, we need to partition it to give us a fast runtime test for
"is this a payload or no-payload case index."

The resilient numbering strategy used here is that the getEnumTag
and destructiveInjectEnumTag value witness functions now take a
tag index in the range [-ElementsWithPayload..ElementsWithNoPayload-1].

Payload elements are numbered in *reverse* declaration order, so
adding new payload cases yields decreasing tag indices, and adding
new no-payload cases yields increasing tag indices, allowing use
sites to be resilient.

This adds the adjustment between 'fragile' and 'resilient' tag
indices in a somewhat unsatisfying manner, because the calculation
could be pushed down further into EnumImplStrategy, simplifying
both the IRGen code and the generated IR. I'll clean this up later.

In the meantime, clean up some other stuff in GenEnum.cpp, mostly
abstracting code that walks cases.
2016-01-21 12:10:57 -08:00
John McCall
1d3916e6ad Add virtual methods to TypeInfo to do all the buffer operations.
Use them to generate value witnesses when the type has dynamic packing.
Regularize the interface for calling value witnesses.

Not a huge difference yet, although we do re-use local type data
a little more effectively now.
2016-01-14 20:05:44 -08:00
John McCall
7dd9f5f037 Improve IRGen's infrastructure for caching local type data.
There are several interesting new features here.

The first is that, when emitting a SILFunction, we're now able to
cache type data according to the full dominance structure of the
original function.  For example, if we ask for type metadata, and
we've already computed it in a dominating position, we're now able
to re-use that value; previously, we were limited to only doing this
if the value was from the entry block or the LLVM basic block
matched exactly.  Since this tracks the SIL dominance relationship,
things in IRGen which add their own control flow must be careful
to suppress caching within blocks that may not dominate the
fallthrough; this mechanism is currently very crude, but could be
made to allow a limited amount of caching within the
conditionally-executed blocks.

This query is done using a proper dominator tree analysis, even at -O0.
I do not expect that we will frequently need to actually build the
tree, and I expect that the code-size benefits of doing a real
analysis will be significant, especially as we move towards making
more metadata lazily computed.

The second feature is that this adds support for "abstract"
cache entries, which indicate that we know how to derive the metadata
but haven't actually done so.  This code isn't yet tested, but
it's going to be the basis of making a lot of things much lazier.
2016-01-05 17:55:51 -08:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
Slava Pestov
11b8bcfa70 IRGen: Actually construct resilient enums using the new destructiveInjectEnumTag() value witness
This completes the ResilientEnumImplStrategy implementation in IRGen.
2015-12-10 21:04:04 -08:00
Slava Pestov
65a5a03f26 IRGen: Add a new destructiveInjectEnumTag value witness function
This value witness function takes an address of an enum value where the
payload has already been initialized, together with a case index, and
forms the enum value.

The formal behavior can be thought of as satisfying an identity in
relation to the existing two enum value witnesses. For any enum
value, the following is to leave the value unchanged:

  tag = getEnumTag(value)
  destructiveProjectEnumData(value)
  destructiveInjectEnumData(value, tag)

This is the last missing piece for the inject_enum_addr SIL instruction
to handle resilient enums, allowing the implementation of an enum to be
decoupled from its uses. Also, it should be useful for dynamically
constructing enum cases with write reflection, once we get around to
doing such a thing.

The body of the value witness is emitted by a new emitStoreTag() method
on EnumImplStrategy. This is similar to the existing storeTag(), except
the case index is a value instead of a contant.

This is implemented as follows for the different enum strategies:

1) For enums consisting of a single case, this is trivial.

2) For enums where all cases are empty, stores the case index into the
   payload area.

3) For enums with a single payload case, emits a call to a runtime
   function. Note that for non-generic single payload enums, this could
   be open-coded more efficiently, but the function still has the
   correct behavior since it supports extra inhabitants and so on.
   A follow-up patch will make this more efficient.

4) For multi-payload enums, there are two cases:

   a) If one of the payloads is generic or resilient, the enum is
      dynamically-sized, and a call to a runtime function is emitted.

   b) If the entire enum is fixed-size, the value witness checks if
      the case is empty or not.

      If the case has a payload, the case index is swizzled into
      spare bits of the payload, if any, with remaining bits going
      into the extra tag area.

      If the case is empty, the case index is swizzled into the
      spare bits of the payload, the remaining bits of the payload,
      and the extra tag area.

The implementations of emitStoreTag() duplicate existing logic in the
enum strategies, in particular case 4)b) is rather complicated.

Code cleanups are welcome here!
2015-12-08 15:43:55 -08:00
Slava Pestov
ca7254c53d IRGen: Preliminary support for resilient enums
Resilient enums are manipulated as opaque values.

Clients are still allowed to assume physical case indices and case
payload types for now -- we might add a level of indirection here,
which would require designing a new case dispatch mechanism.

Resilient enums are never constructed directly, only by calling
case constructor functions. Case constructors already get emitted,
however they're [transparent] -- this will change in a subsequent
patch.

We could save on code size by emitting an InjectEnumTag value
witness function that can construct any case given a physical case
number, rather than emitting constructors for each case, but for
now going through case constructor functions will suffice.
2015-11-30 13:32:55 -08:00
Slava Pestov
9ee10e7d39 IRGen: destructiveProjectEnumData() value witness doesn't need a return value
The rest of the runtime assumes the payload starts at the beginning
of the enum, so simplify some code by removing the return value here.
2015-11-30 13:32:55 -08:00
Slava Pestov
cdd5a4121c IRGen: Generate value witnesses to get enum tag and project payload
These will be used for reflection, and eventually to speed up generic
operations on single payload enums as well.

Progress on <rdar://problem/21739870>.

Swift SVN r30214
2015-07-15 06:03:18 +00:00
Joe Groff
feebd56bf4 IRGen: Reorder the extra inhabitant value witnesses so that the count and flags go first.
This nicely gathers all the layout information together in one contiguous bundle we can potentially emit independently for use in generic type layout. A step on the way to rdar://problem/19898165.

Swift SVN r30128
2015-07-12 01:06:15 +00:00
Dmitri Hrybenko
2fc1cbe8c1 Adjust to the new IRBuilder APIs
Swift SVN r29692
2015-06-25 22:01:24 +00:00
Joe Groff
2852a3951f IRGen: Mark metadata loads as invariant.
And mark loads of the value witness table as dereferenceable, so that LLVM is able to better optimize metadata accesses.

Swift SVN r29372
2015-06-13 20:44:05 +00:00
Joe Groff
a321938d34 IRGen: Peephole (copy_addr to [initialization] (alloc_stack)) operations to use initializeBuffer value witnesses.
This saves a value witness call in the common case where a generic local variable or temporary is initialized from another value.

Swift SVN r29366
2015-06-12 16:59:14 +00:00
Joe Groff
2d3eba9e0d IRGen: Reuse value witness table projections.
Don't project every value witness from the metadata every time we need one; this wastes code size in a way LLVM can't really optimize since it doesn't know the metadata is immutable. The code size wins on the standard library are disappointingly small (stdlib only shrinks by 4KB), but this makes generic IR a lot more compact and easier to read.

Swift SVN r28095
2015-05-03 05:00:40 +00:00
Joe Groff
8e1e6665a7 IRGen: Start a type verifier to fuzz static type info against runtime type info.
We've had a rash of bugs due to inconsistencies between how IRGen and the runtime think types are laid out. Add a '-verify-type-layout' mode to the frontend that causes IRGen to emit a bunch of code that compares its static assumptions against what the runtime value witness does.

Swift SVN r24918
2015-02-03 16:47:25 +00:00
John McCall
584795e505 Replace the typeOf value witness with an
initializeBufferWithTakeOfBuffer value witness.

Attempt to use initializeBufferWithTakeOfBuffer in
some appropriate places.

There are some changes enabled by this which are
coming in a follow-up patch.

Swift SVN r20741
2014-07-30 08:24:12 +00:00
John McCall
934527a029 Eliminate all uses of the typeof value witness.
Swift SVN r20734
2014-07-30 04:40:58 +00:00
Joe Groff
caff7b62d9 IRGen: Expose the array value witnesses as builtins.
Add Builtin.destroyArray, .copyArray, .takeArrayFrontToBack, and .takeArrayBackToFront, which perform bulk destroy/copy/take operations using memcpy/memmove, a loop, or a generic value witness.

Swift SVN r17009
2014-04-29 03:46:58 +00:00
Joe Groff
f29a156e83 IRGen/Runtime: Add value witness slots for array witnesses.
Add value witnesses for destroyArray, initializeArrayWithCopy, and initializeArrayWithTake{FrontToBack,BackToFront}, and fill out the runtime value witness table implementations. Stub out the IRGen ones for now.

Swift SVN r16772
2014-04-24 22:25:26 +00:00
Joe Groff
e109124186 Replace 'union' keyword with 'enum'.
This only touches the compiler and tests. Doc updates to follow.

Swift SVN r8478
2013-09-20 01:33:14 +00:00