Commit Graph

40 Commits

Author SHA1 Message Date
Erik Eckstein
e0533e6125 SIL: add an API to replace all entries of a VTable
* add `ModulePassContext.replaceVTableEntries()`
* add `ModulePassContext.notifyFunctionTablesChanged()`
2024-10-14 14:43:11 +02:00
Ellie Shin
4ecfc96578 [SIL][PackageCMO] Allow optimizing [serialized_for_pkg] functions during SIL
inlining, generic/closure specialization, and devirtualization optimization passes.

SILFunction::canBeInlinedIntoCaller now exlicitly requires a caller's SerializedKind_t arg.
isAnySerialized() is added as a convenience function that checks if [serialized] or [serialized_for_pkg].

Resolves rdar://128704752
2024-05-27 23:05:56 -07:00
Ellie Shin
5ccc4cd394 SIL function can be serialized with different kinds: [serialized] or
[serialized_for_package] if Package CMO is enabled. The latter kind
allows a function to be serialized even if it contains loadable types,
if Package CMO is enabled. Renamed IsSerialized_t as SerializedKind_t.

The tri-state serialization kind requires validating inlinability
depending on the serialization kinds of callee vs caller; e.g. if the
callee is [serialized_for_package], the caller must be _not_ [serialized].
Renamed `hasValidLinkageForFragileInline` as `canBeInlinedIntoCaller`
that takes in its caller's SerializedKind as an argument. Another argument
`assumeFragileCaller` is also added to ensure that the calle sites of
this function know the caller is serialized unless it's called for SIL
inlining optimization passes.

The [serialized_for_package] attribute is allowed for SIL function, global var,
v-table, and witness-table.

Resolves rdar://128406520
2024-05-23 15:53:02 -07:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Erik Eckstein
6e8b80c791 SIL: add printing and parsing support for specialized vtables
If the vtable refers to a specialized class, a SIL type specifies the bound generic class type:
```
  sil_vtable $G<Int> {
    // ...
  }
```
2024-02-14 09:51:36 +01:00
Kuba Mracek
d0c2a4ccf8 [embedded] Initial support for generic classes in embedded Swift
- VTableSpecializer, a new pass that synthesizes a new vtable per each observed concrete type used
- Don't use full type metadata refs in embedded Swift
- Lazily emit specialized class metadata (LazySpecializedClassMetadata) in IRGen
- Don't emit regular class metadata for a class decl if it's generic (only emit the specialized metadata)
2023-09-12 09:44:54 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Erik Eckstein
6a020f8f15 Stabilize and simplify SIL linkage and serialization
The main point of this change is to make sure that a shared function always has a body: both, in the optimizer pipeline and in the swiftmodule file.
This is important because the compiler always needs to emit code for a shared function. Shared functions cannot be referenced from outside the module.
In several corner cases we missed to maintain this invariant which resulted in unresolved-symbol linker errors.

As side-effect of this change we can drop the shared_external SIL linkage and the IsSerializable flag, which simplifies the serialization and linkage concept.
2022-03-09 15:28:05 +01:00
Joe Groff
cc358ba8fb PruneVTables: Keep SILModule's vtable lookup table in sync with updates.
And add a verifier check to ensure the cache remains synced.
2020-07-23 20:40:49 -07:00
Joe Groff
04c8f0df42 IRGen: Don't reify internal vtable entries that are marked overridden.
Private and internal classes shouldn't have ABI constraints on their concrete vtable layout, so if methods
don't have overrides in practice, we can elide their vtable entries.
2020-06-12 11:59:24 -07:00
David Zarzycki
e077b6ffd9 [SIL] NFC: Make SILVTable follow C++ and LLVM best practices
1) Convert the `Entry` type to a class with getters/setters
2) Use llvm::TrailingObjects
3) Use llvm::PointerIntPair
2020-06-11 07:51:42 -04:00
David Zarzycki
017ee7bf04 [SIL] NFC: Simplify SILVTable and save 8 bytes per SILVTable
We were not using the primary benefits of an intrusive list, namely the
ability to insert or remove from the middle of the list, so let's switch
to a plain vector. This also avoids linked-list pointer chasing.
2020-06-10 07:54:23 -04:00
Joe Groff
e3ce94d97d Introduce a PruneVTables pass to mark non-overridden entries.
Start with some high-level checks of whether a declaration is formally final, or has no visible overrides
in the domain of the program visible to the SIL module.

We can eventually adopt more of the logic from the Devirtualizer pass to tell whether call sites are
"effectively final", and maybe make the Devirtualizer consume that information applied by this pass.
2020-06-05 11:03:04 -07:00
Joe Groff
564c1a5eec Add a [nonoverridden] kind for SILVTable entries.
This will let us track class methods that must exist for pass ordering, interface, or ABI reasons, but which can
be given more efficient runtime representation because they have no overrides.
2020-06-01 12:24:18 -07:00
Slava Pestov
f681cbe264 SIL: Remove SILVTable::Entry::Linkage
This field would store the linkage of the original method, if it was
distinct from the linkage of a vtable thunk. It is no longer used.
2019-06-09 15:54:05 -07:00
Bob Wilson
9dc02e67a2 master-next: Stop using ilist_default_traits
LLVM r330736 removed ilist_default_traits. Apparently it is not needed
and ilist_node_traits works just as well.
2018-04-25 22:44:58 -07:00
Sho Ikeda
03fbd4a6de [gardening][SIL] Replace typedef with using 2018-04-05 13:53:20 +09:00
Slava Pestov
1831b5471e SIL: Clean up 'early serialization' a bit
- Clear the 'serialized' flag on witness tables and vtables
  after serialization, not just functions. This fixes SIL
  verifier failures if post-serialization SIL is printed
  out and parsed back in.

- Clear the 'serialized' flag when deserializing functions,
  witness tables and vtables in a module that has already
  been serialized. This fixes SIL verifier failures if
  we deserialize more declarations after serializing SIL.

We were seeing SIL verifier failures on bots that run the
tests with the stdlib built with non-standard flags.

Unfortunately I don't have a reduced test case that would
fail in PR testing without these fixes.

Fixes <rdar://problem/36682929>.
2018-01-21 01:35:13 -08:00
Roman Levenstein
d86ef3b7e3 Add [serialized] flag to sil_vtables 2017-10-21 19:18:15 -07:00
Slava Pestov
a7ff2d2ddc SIL: Refactor SILVTable::getImplementation() into getEntry()
This will allow IRGen to recover the entry kind when emitting
class metadata.
2017-08-14 22:45:59 -04:00
Slava Pestov
556d35d9b1 SIL: Record whether vtable entries are inherited or overridden
Consider a class hierarchy like the following:

class Base {
  func m1() {}
  func m2() {}
}

class Derived : Base {
  override func m2() {}
  func m3() {}
}

The SIL vtable for 'Derived' now records that the entry for m1
is inherited, the entry for m2 is an override, and the entry
for m3 is a new entry:

sil_vtable Derived {
  #Base.m1!1: (Base) -> () -> () : _T01a4BaseC2m1yyF [inherited]
  #Base.m2!1: (Base) -> () -> () : _T01a7DerivedC2m2yyF [override]
  #Derived.m3!1: (Derived) -> () -> () : _T01a7DerivedC2m3yyF
}

This additional information will allow IRGen to emit the vtable
for Derived resiliently, without referencing the symbol for
the inherited method m1() directly.
2017-08-14 19:50:34 -04:00
practicalswift
a9d6d8938c [gardening] Fix recently introduced typos 2017-01-22 20:40:45 +01: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
Bob Wilson
2c21ef586d Update to match llvm r279473: remove ilist_*sentinel_traits.
(cherry picked from commit 391e7d8b60)
2016-12-01 10:46:38 -08:00
Bob Wilson
26a62b912a Update to match llvm r278513: share code for embedded sentinel traits.
Nothing at all should be changing here, this is just rearranging code.

(cherry picked from commit 9964697f22)
2016-12-01 10:42:59 -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
Joe Shajrawi
9b2c0cde5e add a sidetable cache in the module for VTable entries, replacing linear lookup 2016-09-29 11:07:43 -07:00
Zach Panzarino
e3a4147ac9 Update copyright date 2015-12-31 23:28:40 +00:00
practicalswift
6f5940e49d Fix typo: entires → entries 2015-12-14 00:11:42 +01:00
Erik Eckstein
f40f3a93a0 New implementation of dead function elimination, which includes dead method elimination.
If vtable or witness methods are never called, e.g. because they are completely devirtualized,
then they are removed from the tables and eliminated.

Another improvement of the new algorithm is that it is able to eliminate dead function cycles
(e.g. A() calls B() and vice versa).



Swift SVN r22969
2014-10-27 16:41:02 +00:00
Michael Gottesman
67351cf0a2 Since SILVTables and SILWitnessTables are bump ptr allocated, we need to call their destructor when we remove them so that the functions they reference have a decremented ref count.
Swift SVN r16171
2014-04-10 22:10:59 +00:00
Michael Gottesman
9dd5fa3fcf Add in some comments to SILVTable. NFC.
Swift SVN r15562
2014-03-27 19:49:00 +00:00
Michael Gottesman
c4f407b058 Fix whitespace errors. NFC.
Swift SVN r15548
2014-03-27 03:56:34 +00:00
Michael Gottesman
fb8b3f3649 Remove unnecessary include of std::string. NFC.
Swift SVN r15546
2014-03-27 03:52:00 +00:00
Nadav Rotem
3355cf7bfa VTables should be accessed by reference.
Swift SVN r11691
2013-12-28 09:00:12 +00:00
Joe Groff
c76548916e SIL: Have VTables and WitnessTables bump the reference counts of SILFunctions.
Fixes <rdar://problem/15725600>.

Swift SVN r11666
2013-12-27 05:59:19 +00:00
Joe Groff
0ff977d407 Add a 'WitnessMethod' enumerator to AbstractCC.
We'll use this to represent the slightly-different polymorphic calling convention used for passing Self into protocol witnesses.

Swift SVN r10898
2013-12-06 01:32:35 +00:00
Joe Groff
aca3bd52ac SILGen: Build SILVTables while visiting classes.
When we walk a ClassDecl, generate its vtable, first pulling in decls from its ancestor classes, then overlaying overridden or new decls as we discover them.

Swift SVN r8947
2013-10-06 01:02:14 +00:00
Joe Groff
b4f85653e6 SIL: Introduce SILVTables.
These will provide a SIL-level representation of class_method dispatch, mapping from dynamically-dispatched SILDeclRefs to SILFunctions so that devirtualization passes will be able to promote a class_method for a statically-known type to a function_ref without going all the way back to the AST.

Swift SVN r8943
2013-10-05 21:58:58 +00:00