Commit Graph

106 Commits

Author SHA1 Message Date
Andrew Trick
85317c6e8f [move-only] Fix dead code elimination to preserve value deinits. 2023-06-06 09:17:53 -07:00
Erik Eckstein
f381e422ca DeadFunctionElimination: an alloc_global instruction keeps the referenced global alive
Fixes a crash caused by a deleted global variable which is still referenced by an `alloc_global` instruction.

rdar://109093730
2023-05-09 16:24:21 +02:00
Ellie Shin
1c66d02f92 Add package access level to enum AccessLevel
Resolves rdar://104198440
2023-01-19 15:54:18 -08:00
Allan Shortlidge
3da18b6e68 SIL: Serialize and deserialize has_symbol instructions. 2022-11-16 16:07:59 -08:00
Josh Soref
730b16c569 Spelling siloptimizer
* access
* accessed
* accesses
* accessor
* acquiring
* across
* activated
* additive
* address
* addresses'
* aggregated
* analysis
* and
* appropriately
* archetype
* argument
* associated
* availability
* barriers
* because
* been
* beginning
* belongs
* beneficial
* blocks
* borrow
* builtin
* cannot
* canonical
* canonicalize
* clazz
* cleanup
* coalesceable
* coalesced
* comparisons
* completely
* component
* computed
* concrete
* conjunction
* conservatively
* constituent
* construct
* consuming
* containing
* covered
* creates
* critical
* dataflow
* declaration
* defined
* defining
* definition
* deinitialization
* deliberately
* dependencies
* dependent
* deserialized
* destroy
* deterministic
* deterministically
* devirtualizes
* diagnostic
* diagnostics
* differentiation
* disable
* discipline
* dominate
* dominates
* don't
* element
* eliminate
* eliminating
* elimination
* embedded
* encounter
* epilogue
* epsilon
* escape
* escaping
* essential
* evaluating
* evaluation
* evaluator
* executing
* existential
* existentials
* explicit
* expression
* extended
* extension
* extract
* for
* from
* function
* generic
* guarantee
* guaranteed
* happened
* heuristic
* however
* identifiable
* immediately
* implementation
* improper
* include
* infinite
* initialize
* initialized
* initializer
* inside
* instruction
* interference
* interferes
* interleaved
* internal
* intersection
* intractable
* intrinsic
* invalidates
* irreducible
* irrelevant
* language
* lifetime
* literal
* looks
* materialize
* meaning
* mergeable
* might
* mimics
* modification
* modifies
* multiple
* mutating
* necessarily
* necessary
* needsmultiplecopies
* nonetheless
* nothing
* occurred
* occurs
* optimization
* optimizing
* original
* outside
* overflow
* overlapping
* overridden
* owned
* ownership
* parallel
* parameter
* paths
* patterns
* pipeline
* plottable
* possible
* potentially
* practically
* preamble
* precede
* preceding
* predecessor
* preferable
* preparation
* probably
* projection
* properties
* property
* protocol
* reabstraction
* reachable
* recognized
* recursive
* recursively
* redundant
* reentrancy
* referenced
* registry
* reinitialization
* reload
* represent
* requires
* response
* responsible
* retrieving
* returned
* returning
* returns
* rewriting
* rewritten
* sample
* scenarios
* scope
* should
* sideeffects
* similar
* simplify
* simplifycfg
* somewhat
* spaghetti
* specialization
* specializations
* specialized
* specially
* statistically
* substitute
* substitution
* succeeds
* successful
* successfully
* successor
* superfluous
* surprisingly
* suspension
* swift
* targeted
* that
* that our
* the
* therefore
* this
* those
* threshold
* through
* transform
* transformation
* truncated
* ultimate
* unchecked
* uninitialized
* unlikely
* unmanaged
* unoptimized key
* updataflow
* usefulness
* utilities
* villain
* whenever
* writes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2022-10-03 18:31:33 -04:00
Pavel Yaskevich
d36822e742 [SILOpt] Make sure that dynamically replaced function is kept alive 2022-04-19 11:37:42 -07:00
Pavel Yaskevich
41a4ceae15 [Distributed] SILOpt: Make sure that ad-hoc function does not get eliminated as unused 2022-04-18 16:53:47 -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
Erik Eckstein
9f616e5e37 DeadFunctionElimination: rename the pass and some other refactoring
The main change is to rename DeadFunctionElimination -> DeadFunctionAndGlobalElimination, because the pass is now also doing dead-global elimination.
A second change is to remove the FunctionLivenessComputation base class. It’s not used anywhere else.
2021-02-09 19:56:43 +01:00
Erik Eckstein
ee8cdac501 DeadFunctionElimination: Also eliminate dead global variables.
It makes sense to to this in a single pass, because there might be dead cycles for globals and functions, e.g. if a global references a function in its static initializer and the function references that global.

Another improvement: eliminate dead global-initializers. Before we had an explicit SIL representation of statically initialized globals, we had to keep them alive.

rdar://32956923
2021-02-09 19:56:43 +01:00
Erik Eckstein
542a378436 SIL: add FunctionRefInst::getReferencedFunction()
If we know that we have a FunctionRefInst (and not another variant of FunctionRefBaseInst), we know that getting the referenced function will not be null (in contrast to FunctionRefBaseInst::getReferencedFunctionOrNull).

NFC
2021-02-09 19:56:43 +01:00
Arnold Schwaighofer
b994bf3191 Add support for _specialize(exported: true, ...)
This attribute allows to define a pre-specialized entry point of a
generic function in a library.

The following definition provides a pre-specialized entry point for
`genericFunc(_:)` for the parameter type `Int` that clients of the
library can call.

```
@_specialize(exported: true, where T == Int)
public func genericFunc<T>(_ t: T) { ... }
```

Pre-specializations of internal `@inlinable` functions are allowed.

```
@usableFromInline
internal struct GenericThing<T> {
  @_specialize(exported: true, where T == Int)
  @inlinable
  internal func genericMethod(_ t: T) {
  }
}
```

There is syntax to pre-specialize a method from a different module.

```
import ModuleDefiningGenericFunc

@_specialize(exported: true, target: genericFunc(_:), where T == Double)
func prespecialize_genericFunc(_ t: T) { fatalError("dont call") }

```

Specially marked extensions allow for pre-specialization of internal
methods accross module boundries (respecting `@inlinable` and
`@usableFromInline`).

```
import ModuleDefiningGenericThing
public struct Something {}

@_specializeExtension
extension GenericThing {
  @_specialize(exported: true, target: genericMethod(_:), where T == Something)
  func prespecialize_genericMethod(_ t: T) { fatalError("dont call") }
}
```

rdar://64993425
2020-10-12 09:19:29 -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
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Dan Zheng
aa66cce808 [AutoDiff upstream] Add differentiation transform.
The differentiation transform does the following:
- Canonicalizes differentiability witnesses by filling in missing derivative
  function entries.
- Canonicalizes `differentiable_function` instructions by filling in missing
  derivative function operands.
- If necessary, performs automatic differentiation: generating derivative
  functions for original functions.
  - When encountering non-differentiability code, produces a diagnostic and
    errors out.

Partially resolves TF-1211: add the main canonicalization loop.

To incrementally stage changes, derivative functions are currently created
with empty bodies that fatal error with a nice message.

Derivative emitters will be upstreamed separately.
2020-04-02 15:43:57 -07:00
Hamish Knight
13217b600c [SILOptimizer] Add pipeline execution request
Add ExecuteSILPipelineRequest which executes a
pipeline plan on a given SIL (and possibly IRGen)
module. This serves as a top-level request for
the SILOptimizer that we'll be able to hang
dependencies off.
2020-02-14 09:58:32 -08:00
Erik Eckstein
03b0a6c148 DeadFunctionElimination: remove externally available witness tables at the end of the pipeline
... including all SIL functions with are transitively referenced from such witness tables.

After the last devirtualizer run witness tables are not needed in the optimizer anymore.
We can delete witness tables with an available-externally linkage. IRGen does not emit such witness tables anyway.
This can save a little bit of compile time, because it reduces the amount of SIL at the end of the optimizer pipeline.
It also reduces the size of the SIL output after the optimizer, which makes debugging the SIL output easier.
2020-01-27 14:45:10 +01:00
Erik Eckstein
0b6e3bf6f6 DeadFunctionElimination: factor out function/method visiting of keypath components into a general utility.
This is a NFC
2019-12-03 14:37:01 +01:00
Erik Eckstein
402e228b39 SIL: add a table in SILModule to mark method declarations as externally visible.
This is needed for cross-module-optimization: CMO marks functions as inlinable. If a private or internal method is referenced from such an inlinable function, it must not be eliminated by dead function elimination after serialization (a method is basically an AbstractFunctionDecl).
For SILFunctions we can do this by simply setting the linkage, but for methods we need another mechanism.
2019-12-03 14:37:01 +01:00
Andrew Trick
bddc69c8a6 Organize SILOptimizer/Utils headers. Remove Local.h.
The XXOptUtils.h convention is already established and parallels
the SIL/XXUtils convention.

New:
- InstOptUtils.h
- CFGOptUtils.h
- BasicBlockOptUtils.h
- ValueLifetime.h

Removed:
- Local.h
- Two conflicting CFG.h files

This reorganization is helpful before I introduce more
utilities for block cloning similar to SinkAddressProjections.

Move the control flow utilies out of Local.h, which was an
unreadable, unprincipled mess. Rename it to InstOptUtils.h, and
confine it to small APIs for working with individual instructions.
These are the optimizer's additions to /SIL/InstUtils.h.

Rename CFG.h to CFGOptUtils.h and remove the one in /Analysis. Now
there is only SIL/CFG.h, resolving the naming conflict within the
swift project (this has always been a problem for source tools). Limit
this header to low-level APIs for working with branches and CFG edges.

Add BasicBlockOptUtils.h for block level transforms (it makes me sad
that I can't use BBOptUtils.h, but SIL already has
BasicBlockUtils.h). These are larger APIs for cloning or removing
whole blocks.
2019-10-02 11:34:54 -07:00
Slava Pestov
866f316e07 SILOptimizer: Simplify dead method elimination
We used to look at the vtable entry's linkage to determine if the
vtable entry was dead, in case the vtable entry linkage was more
visible than the method being overridden.

This hack is no longer needed now that a method override more
visible than its base introduces a new vtable entry.
2019-06-09 15:54:05 -07:00
Arnold Schwaighofer
c187c8ac13 SIL: Replace uses of getReferencedFunction() by getReferencedFunctionOrNull() and getInitialReferencedFunction()
With the advent of dynamic_function_ref the actual callee of such a ref
my vary. Optimizations should not assume to know the content of a
function referenced by dynamic_function_ref. Introduce
getReferencedFunctionOrNull which will return null for such function
refs. And getInitialReferencedFunction to return the referenced
function.
Use as appropriate.

rdar://50959798
2019-05-26 08:58:14 -07:00
Slava Pestov
1864f6f679 AST: Introduce ClassDecl::isSuperclassOf() 2019-03-26 18:42:59 -04:00
Joe Groff
bb67cf815c Merge pull request #21355 from technicated/tuple-keypaths-2
Tuple KeyPaths
2019-02-25 12:56:05 -08:00
Andrea Tomarelli
aab138dcea Barebone implementation of TupleElement in SIL 2019-02-18 09:04:42 +01:00
Michael Gottesman
fccd75e5ce [sil-passmanager] Stash a SILOptions reference in SILPassPipeline.
This normalizes the creation of pass pipelines by ensuring that all pass
pipelines take a SILOption instead of only some. It also makes it so that we do
not need to propagate options through various pipeline creation helpers.
2019-02-02 22:57:05 -08:00
John McCall
5553224fd4 Support the explicit representation of self-conformances.
Big, but actually NFC because we're never actually creating them.
2018-11-15 16:42:03 -05:00
Arnold Schwaighofer
7e32c68e1d Add new SIL instruction for calling dynamically_replaceable funtions
%0 = dynamic_function_ref @dynamically_replaceable_function
  apply %0()
  Calls a [dynamically_replaceable] function.

  %0 = prev_dynamic_function_ref @dynamic_replacement_function
  apply %0
  Calls the previous implementation that dynamic_replacement_function
  replaced.
2018-11-06 09:53:22 -08:00
Doug Gregor
4ed973329a [SIL] Unify default witness table entries with witness table entries.
SILWitnessTable::Entry already contains a superset of what was supported
by SILDefaultWitnessTable::Entry, the latter of which only had “no entry”
and “method” states. Make SILDefaultWitnessTable::Entry an alias for
SILWitnessTable::Entry, and unify all of the parsing/printing/
(de)serialization logic.
2018-09-15 22:04:46 -07:00
Doug Gregor
c7152f3576 [SIL] Don’t create witness table entries for overriding requirements.
SIL will not generate calls to protocol requirements that override
other protocol requirements, so all of the witness table entries for
the overriding arguments are dynamically dead. Remove them from the
witness tables entirely.

Implements rdar://problem/43870489, reducing the size of the standard
library binary by 196k.
2018-09-05 13:51:26 -07:00
Doug Gregor
0972111c60 [Type checker] Start tracking overrides of protocol requirements.
When a protocol that inherits another protocol restates a requirement
from its inherited protocol, track that as an override in the AST.
2018-09-04 16:42:06 -07:00
Doug Gregor
d07fa5ab69 Switch many callers of ClassDecl::getSuperclass() to ClassDecl::getSuperclassDecl().
ClassDecl::getSuperclass() produces a complete interface type describing the
superclass of a class, including any generic arguments (for a generic type).
Most callers only need the referenced ClassDecl, which is (now) cheaper
to compute: switch those callers over to ClassDecl::getSuperclassDecl().

Fixes an existing test for SR-5993.
2018-07-31 10:14:44 -07:00
Bob Wilson
8e330ee344 NFC: Fix indentation around the newly renamed LLVM_DEBUG macro.
Jordan used a sed command to rename DEBUG to LLVM_DEBUG. That caused some
lines to wrap and messed up indentiation for multi-line arguments.
2018-07-21 00:56:18 -07:00
Jordan Rose
cefb0b62ba Replace old DEBUG macro with new LLVM_DEBUG
...using a sed command provided by Vedant:

$ find . -name \*.cpp -print -exec sed -i "" -E "s/ DEBUG\(/ LLVM_DEBUG(/g" {} \;
2018-07-20 14:37:26 -07:00
Michael Gottesman
fe97efcdbd [pass-manager] Missed one. notifyDeleteFunction => notifyWillDeleteFunction. 2018-07-17 10:00:27 -07:00
Joe Groff
849d9397d6 SIL: Generate external key path references with local candidate components.
The other side of #17404. Since we don't want to generate up front key path metadata for properties/subscripts with no withheld implementation details, the client should generate a key path component that can be used to represent a key path component based on its public interface.
2018-07-06 14:24:07 -07:00
Andrew Trick
7c4d15f96a SILModule::isVisibleExternally utility for VarDecls. (#16834)
* SILModule::isVisibleExternally utility for VarDecls.

* Fix the SIL parser so it doesn't drop global variable decls.

This information was getting lost in SIL printing/parsing.
Some passes rely on it. Regardless of whether passes should rely on it,
it is totally unacceptable for the SIL passes to have subtle differences
in behavior depending on the frontend mode. So, if we don't want passes
to rely on global variable decls, that needs to be enforced by the API
independent of how the frontend is invoked or how SIL is serialized.

* Use custom DemangleOptions to lookup global variable identifiers.
2018-06-26 12:27:26 -07:00
Michael Gottesman
27c5366f70 [dfe] Change Impl to be a stongly typed PointerUnion instead of a union. 2018-06-23 20:43:32 -07:00
Joe Groff
3e4e00c163 SILGen: Emit "trivial" property descriptors for properties that withhold no information about their implementation.
Client code can make a best effort at emitting a key path referencing a property with its publicly exposed API, which in the common case will match what the defining module would produce as the canonical key path component representation of the declaration. We can reduce the code size impact of these descriptors by not emitting them when there's no hidden or possibly-resiliently-changed-in-the-past information about a storage declaration, having the property descriptor symbol reference a sentinel value telling client key paths to use their definition of the key path component.
2018-06-21 15:18:24 -07:00
Slava Pestov
c35d1f5fc7 SIL: Remove unused code for optional (non-@objc) protocol requirements 2018-03-23 18:59:06 -06:00
Joe Groff
a84f7f175a SIL: Consider accessors from property descriptors to be used. 2018-03-22 13:46:50 -07:00
Joe Groff
d4e03f2ba3 SIL: Add an 'external' KeyPathPatternComponent kind.
This will allow key paths to resiliently reference public properties from other binaries by referencing a descriptor vended by the originating binary. NFC yet, this just provides printing/parsing/verification of the new component.
2018-02-14 10:48:24 -08:00
Slava Pestov
48d0407f43 SIL: Remove SILFunction::{is,set}KeepAsPublic() 2018-01-12 22:08:00 -08:00
Slava Pestov
8027e8108e DeadFunctionElimination: Serialized functions are not anchors 2018-01-12 21:56:17 -08:00
Slava Pestov
6c055652b6 DeadFunctionElimination: Fold shouldBeSerializedOrEmitted() into isAnchorFunction() 2018-01-12 21:56:17 -08:00
Slava Pestov
7f84ae5449 SILOptimizer: Remove special handling of transparent functions from dead function elimination
This is no longer sound after https://github.com/apple/swift/pull/12903.
We no longer special-case the linkage of transparent functions at all.
2017-11-20 00:21:49 -05:00
Joe Shajrawi
4d5949942d Merge branch 'master' into sil-serialization-before-optimizations5 2017-11-17 16:17:16 -08:00
Huon Wilson
99c4cddfca [SILGen] Store conditional conformances in SILWitnessTables. 2017-11-08 17:02:50 -08:00
Greg Parker
d6e1866344 [SIL] Make @_silgen_name and @_cdecl functions immune to some optimizations (#12696)
@_silgen_name and @_cdecl functions are assumed to be referenced from
C code. Public and internal functions marked as such must not be deleted
by the optimizer, and their C symbols must be public or hidden respectively.

rdar://33924873, SR-6209
2017-11-01 01:41:05 -07:00