Commit Graph

68 Commits

Author SHA1 Message Date
Pavel Yaskevich
3fb69b3c3c [SIL] SILFunction: Add runtime accessible function attribute
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
2022-12-20 09:33:44 -08:00
Meghana Gupta
6ee4c17abe Merge pull request #62573 from meg-gupta/sbiverify
Update store_borrow checking in MemoryLifetimeVerifier and fix ForEachLoopUnroll and GenericCloner
2022-12-15 09:53:00 -08:00
Michael Gottesman
9e44011e4d [sil] Add a new attribute called @closureCaptured to SILFunctionArguments that are closure capture arguments.
I am adding this to make it easy to determine if a SILFunction that is not inout
aliasable is captured. This is useful when emitting certain types of
diagnostics like I need to emit with move only.
2022-12-14 15:16:43 -08:00
Meghana Gupta
7ad1a183f4 Fix store_borrow's end_borrows in GenericCloner when lifetime boundary cannot be found
Make sure end_borrows are inserted before dealloc_stack. Instead of inserting them at
function exits. Insert before dealloc_stack of destination.
2022-12-14 02:08:38 -08:00
Andrew Trick
619a638e34 ScopedAddressUtils - clarify the API used for transitive liveness.
Begin to distnguish logic that relies on complete OSSA lifetimes from
the logic that computes transitive uses.
2022-10-04 13:27:47 -07:00
Andrew Trick
464e353028 Fix ScopedAddressValue::computeLiveness.
Return the AddressUseKind.

Fixes a bug in extendStoreBorrow where it was looking at an
uninitialized liveness result whenever a pointer escape was present.
2022-10-04 13:27:47 -07:00
Andrew Trick
ca503b54b7 Redesign PrunedLiveness APIs, introducing live ranges
First restore the basic PrunedLiveness abstraction to its original
intention. Move code outside of the basic abstraction that polutes the
abstraction and is fundamentally wrong from the perspective of the
liveness abstraction.

Most clients need to reason about live ranges, including the def
points, not just liveness based on use points. Add a PrunedLiveRange
layer of types that understand where the live range is
defined. Knowing where the live range is defined (the kill set) helps
reliably check that arbitrary points are within the boundary. This
way, the client doesn't need to be manage this on its own. We can also
support holes in the live range for non-SSA liveness. This makes it
safe and correct for the way liveness is now being used. This layer
safety handles:

- multiple defs
- instructions that are both uses and defs
- dead values
- unreachable code
- self-loops

So it's no longer the client's responsibility to check these things!

Add SSAPrunedLiveness and MultiDefPrunedLiveness to safely handle each
situation.

Split code that I can't figure out into
DiagnosticPrunedLiveness. Hopefully it will be deleted soon.
2022-10-04 13:27:44 -07:00
nate-chandler
5cf1cb368d Merge pull request #61304 from nate-chandler/transfer-sil-function-argument-attrs
[SILOptimizer] Preserve arg attrs at cloning.
2022-09-27 08:05:19 -07:00
Nate Chandler
5d14610043 [SILOptimizer] Preserve arg attrs at cloning.
Arguments are copied into new cloned functions in a number of places.
Wherever that happens, be sure to transfer the attributes as well.
2022-09-26 16:55:50 -07:00
Meghana Gupta
7c4d4b0671 Fix an edge case in GenericCloner which was not generating end_borrows for store_borrow
Generic Cloner creates store_borrow for in_guaranteed args in OSSA. We use PrunedLiveness
to compute the boundary of store_borrow for inserting end_borrows. However, if there is an escape
boundary cannot be found, and we insert end_borrows at function exits. FunctionExists are populated while cloning.
There is an edgecase, where the Generic Cloner is explicitly creating return instructions, these were not inserted
in FunctionExits, thereby missing an end_borrow on that path. This PR fixes it.

rdar://99874076
2022-09-23 11:38:07 -07:00
Meghana Gupta
46bdf131d7 Fix store_borrow generation in GenericCloner 2022-08-16 15:08:23 -07:00
Erik Eckstein
c3de7c1317 MandatoryGenericSpecializer: drop metatype arguments in specialized functions
And replace them with explicit `metatype` instruction in the entry block.
This allows such metatype instructions to be deleted if they are dead.

rdar://94388453
2022-07-07 08:34:54 +02:00
Erik Eckstein
e41c237686 GenericCloner: copy effects from the original function to the generic specialization 2022-05-02 12:00:06 +02:00
Arnold Schwaighofer
2bc8ad27e3 GenericCloner: Generate a valid debug location if no decl is available for a SILArgument
Without this we used to crash in a test case in IRGen trying to generate code
for an invalid debug location.

rdar://87565600
2022-01-18 14:04:56 -08:00
Pavel Yaskevich
4860f90fd7 [SIL] Add new flag to SILFunction - IsDistributed
Determines whether given SILFunction represents a distributed
method or its thunk.
2021-12-17 10:52:52 -08:00
Meghana Gupta
2658cbec9b Fix begin_apply inlining when there are no yields
In this PR, preFixUp function in SILCloner is added which can be
overidden by implementations so that the SIL is cleaned for `commonFixup` processing.
For begin_apply inlining, blocks split due to end_apply and abort_apply
are fixed when no yields are found.
2021-10-08 14:45:08 -07:00
Min-Yih Hsu
343d842394 [SIL][DebugInfo] PATCH 3/3: Deprecate debug_value_addr SIL instruciton
This patch removes all references to DebugValueAddrInst class and
debug_value_addr instruction in textual SIL files.
2021-08-31 12:01:04 -07:00
Min-Yih Hsu
e1023bc323 [DebugInfo] PATCH 2/3: Duplicate logics regarding debug_value_addr
This patch replace all in-memory objects of DebugValueAddrInst with
DebugValueInst + op_deref, and duplicates logics that handles
DebugValueAddrInst with the latter. All related check in the tests
have been updated as well.

Note that this patch neither remove the DebugValueAddrInst class nor
remove `debug_value_addr` syntax in the test inputs.
2021-08-31 11:57:56 -07: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
Michael Gottesman
1b97c0393c [ownership] Loosen restrictions around what we specialize and add generic specialization tests behind a flag.
The idea is that this will let me remove these assertions that were in place to
make sure we were really conservative around specializing ownership code. For me
to remove that I need to be able to actually test out this code (since I think
there are some code paths where this will trigger in other parts of the compiler
now).

So to work out the kinks, I added a flag that allows for the generic specializer
to process ownership code and translated most of the .sil test cases/fixed any
bugs that I found. This hopefully will expose anything that is missing.

NOTE: I have not enabled the generic specializer running in ownership in the
pipeline. This is just a step in that direction by adding tests/etc.
2020-07-03 02:54:19 -07:00
Joe Groff
03c7919b4a SIL: Add fields to SILFunctionType for substituted function types.
https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711

This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:

- A substitution map, accessed by `getSubstitutions()`, which maps the generic signature
  of the function to its concrete implementation. This will allow, for instance, a protocol
  witness for a requirement of type `<Self: P> (Self, ...) -> ...` for a concrete conforming
  type `Foo` to express its type as `<Self: P> (Self, ...) -> ... for <Foo>`, preserving the relation
  to the protocol interface without relying on the pile of hacks that is the `witness_method`
  protocol.

- A bool for whether the generic signature of the function is "implied" by the substitutions.
  If true, the generic signature isn't really part of the calling convention of the function.
  This will allow closure types to distinguish a closure being passed to a generic function, like
  `<T, U> in (*T, *U) -> T for <Int, String>`, from the concrete type `(*Int, *String) -> Int`,
  which will make it easier for us to differentiate the representation of those as types, for
  instance by giving them different pointer authentication discriminators to harden arm64e
  code.

This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.

This does bifurcate some existing APIs:

- SILFunctionType now has two accessors to get its generic signature.
  `getSubstGenericSignature` gets the generic signature that is used to apply its
  substitution map, if any. `getInvocationGenericSignature` gets the generic signature
  used to invoke the function at apply sites. These differ if the generic signature is
  implied.
- SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
  and results of the function. They now have two APIs to get that type. `getInterfaceType`
  returns the unsubstituted type of the generic interface, and
  `getArgumentType`/`getReturnValueType` produce the substituted type that is used at
  apply sites.
2019-10-25 13:38:51 -07: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
Adrian Prantl
5b92814a0e Debug Info: Add missing debug info propagation to SILCloner.
While tightening the requirements of the debug info generator in
IRGenSIL I noticed that SILCloner didn't correctly transfer variable
debug info on alloc_box and alloc_stack instructions. In order to make
these mistakes easier to find I added an assertion to SILBuilder and
fixed all issues uncovered by that assertion, too.

The result is a moderate increase in debug info coverage in optimized code.

On stdlib/public/core/OSX/x86_64/Swift.o "variables with location"
increases from 60134 to 60299.
2019-09-24 14:10:25 -07:00
Arnold Schwaighofer
a5036a97df Fix generic specialization that can result in noreturn apply without unreachable
rdar://50393169
2019-05-02 16:12:21 -07:00
Slava Pestov
00b4662ab9 SILOptimizer: Clean up the generic specializer a bit 2019-03-12 01:16:04 -04:00
Michael Gottesman
23378cc16f [sil] Rename QualifiedOwnership => Ownership.
Done using Xcode's refactoring engine.
2018-12-16 15:21:52 -08:00
Arnold Schwaighofer
5f4e183302 Add [dynamically_replacable] to SILFunctions
'dynamic' functions are marked as [dynamically_replaceable].
2018-11-06 09:53:21 -08:00
Andrew Trick
bd28b0ea1b SILCloner and SILInliner rewrite.
Mostly functionally neutral:
- may fix latent bugs.
- may reduce useless basic blocks after inlining.

This rewrite encapsulates the cloner's internal state, providing a
clean API for the CRTP subclasses. The subclasses are rewritten to use
the exposed API and extension points. This makes it much easier to
understand, work with, and extend SIL cloners, which are central to
many optimization passes. Basic SIL invariants are now clearly
expressed and enforced. There is no longer a intricate dance between
multiple levels of subclasses operating on underlying low-level data
structures. All of the logic needed to keep the original SIL in a
consistent state is contained within the SILCloner itself. Subclasses
only need to be responsible for their own modifications.

The immediate motiviation is to make CFG updates self-contained so
that SIL remains in a valid state. This will allow the removal of
critical edge splitting hacks and will allow general SIL utilities to
take advantage of the fact that we don't allow critical edges.

This rewrite establishes a simple principal that should be followed
everywhere: aside from the primitive mutation APIs on SIL data types,
each SIL utility is responsibile for leaving SIL in a valid state and
the logic for doing so should exist in one central location.

This includes, for example:
- Generating a valid CFG, splitting edges if needed.
- Returning a valid instruction iterator if any instructions are removed.
- Updating dominance.
- Updating SSA (block arguments).

(Dominance info and SSA properties are fundamental to SIL verification).

LoopInfo is also somewhat fundamental to SIL, and should generally be
updated, but it isn't required.

This also fixes some latent bugs related to iterator invalidation in
recursivelyDeleteTriviallyDeadInstructions and SILInliner. Note that
the SILModule deletion callback should be avoided. It can be useful as
a simple cache invalidation mechanism, but it is otherwise bug prone,
too limited to be very useful, and basically bad design. Utilities
that mutate should return a valid instruction iterator and provide
their own deletion callbacks.
2018-10-08 19:30:09 -07:00
John McCall
348fda2c2f More optimizer fixes for coroutines. 2018-08-24 15:19:14 -04:00
Michael Gottesman
f500f007f8 [sil] Add a template parameter to TypeSubstCloner so that subclasses can inject a SILFunctionBuilder composition class.
This works around a potential circular dependence issue where TypeSubstCloner
needs access to SILOptFunctionBuilder but is in libswiftSIL.

rdar://42301529
2018-08-06 13:40:25 -07:00
Michael Gottesman
b72304415d [passmanager] Change the optimizer to use SILOptFunctionBuilder.
I am going to add the code in a bit that does the notifications. I tried to pass
down the builder instead of the pass manager. I also tried not to change the
formatting.

rdar://42301529
2018-08-05 21:21:55 -07:00
Adrian Prantl
58475ef1ad Add debug info support for inlined and specialized generic variables.
This patch adds SIL-level debug info support for variables whose
static type is rewritten by an optimizer transformation. When a
function is (generic-)specialized or inlined, the static types of
inlined variables my change as they are remapped into the generic
environment of the inlined call site. With this patch all inlined
SILDebugScopes that point to functions with a generic signature are
recursively rewritten to point to clones of the original function with
new unique mangled names. The new mangled names consist of the old
mangled names plus the new substituions, similar (or exactly,
respectively) to how generic specialization is handled.

On libSwiftCore.dylib (x86_64), this yields a 17% increase in unique
source vars and a ~24% increase in variables with a debug location.

rdar://problem/28859432
rdar://problem/34526036
2018-07-31 16:59:56 -07:00
Michael Gottesman
11b24415c1 [sil-module] Create SILFunctionBuilder and hide creation/erasing functions on SILModule.
This commit does not modify those APIs or their usage. It just:

1. Moves the APIs onto SILFunctionBuilder and makes SILFunctionBuilder a friend
   of SILModule.
2. Hides the APIs on SILModule so all users need to use SILFunctionBuilder to
   create/destroy functions.

I am doing this in order to allow for adding/removing function notifications to
be enforced via the type system in the SILOptimizer. In the process of finishing
off CallerAnalysis for FSO, I discovered that we were not doing this everywhere
we need to. After considering various other options such as:

1. Verifying after all passes that the notifications were sent correctly and
   asserting. Turned out to be expensive.
2. Putting a callback in SILModule. This would add an unnecessary virtual call.

I realized that by using a builder we can:

1. Enforce that users of SILFunctionBuilder can only construct composed function
   builders by making the composed function builder's friends of
   SILFunctionBuilder (notice I did not use the word subclass, I am talking
   about a pure composition).
2. Refactor a huge amount of code in SILOpt/SILGen that involve function
   creation onto a SILGenFunctionBuilder/SILOptFunctionBuilder struct. Many of
   the SILFunction creation code in question are straight up copies of each
   other with small variations. A builder would be a great way to simplify that
   code.
3. Reduce the size of SILModule.cpp by 25% from ~30k -> ~23k making the whole
   file easier to read.

NOTE: In this commit, I do not hide the constructor of SILFunctionBuilder since
I have not created the derived builder structs yet. Once I have created those in
a subsequent commit, I will hide that constructor.

rdar://42301529
2018-07-31 10:04:03 -07:00
Adrian Prantl
fdad9076f2 Revert "Add debug info support for inlined and specialized generic variables."
There is an assertion failure building the source compatibility suite that
needs to be investigated.

This reverts commit 91f6f34119.
2018-07-07 13:01:01 -07:00
Adrian Prantl
91f6f34119 Add debug info support for inlined and specialized generic variables.
This patch adds SIL-level debug info support for variables whose
static type is rewritten by an optimizer transformation. When a
function is (generic-)specialized or inlined, the static types of
inlined variables my change as they are remapped into the generic
environment of the inlined call site. With this patch all inlined
SILDebugScopes that point to functions with a generic signature are
recursively rewritten to point to clones of the original function with
new unique mangled names. The new mangled names consist of the old
mangled names plus the new substituions, similar (or exactly,
respectively) to how generic specialization is handled.

On libSwiftCore.dylib (x86_64), this yields a 17% increase in unique
source vars and a ~24% increase in variables with a debug location.

rdar://problem/28859432
rdar://problem/34526036
2018-07-06 22:06:48 -07:00
Adrian Prantl
9b6a9946ec Be explicit about whether a DebugInfo-carying SILInstruction has debug info.
This patch both makes debug variable information it optional on
alloc_stack and alloc_box instructions, and forced variable
information on debug_value and debug_value_addr instructions. The
change of the interface uncovered a plethora of bugs in SILGen,
SILTransform, and IRGen's LoadableByAddress pass.

Most importantly this fixes the previously commented part of the
DebugInfo/local-vars.swift.gyb testcase.

rdar://problem/37720555
2018-02-21 10:50:19 -08:00
Michael Gottesman
5263e9e74e [sil] Eliminate redundant method SILFunction::hasUnqualifiedOwnership().
We can just !SILFunction::hasQualifiedOwnership(). Plus as Andy pointed out,
even ignoring the functional aspects, having APIs with names this close can
create confusion.
2017-12-02 17:42:34 -08:00
Joe Shajrawi
2c03144436 Add support for function_entry_count Profile counter 2017-09-26 11:10:52 -07:00
Huon Wilson
b59f95418c [SIL] Extract ClassVisibility from SILFunction to SubclassScope in SILLinkage. 2017-04-13 14:17:29 -07:00
Slava Pestov
8fe8b89b0f SIL: Terminology change: [fragile] => [serialized]
Also, add a third [serializable] state for functions whose bodies we
*can* serialize, but only do so if they're referenced from another
serialized function.

This will be used for bodies synthesized for imported definitions,
such as init(rawValue:), etc, and various thunks, but for now this
change is NFC.
2017-03-29 16:47:28 -07:00
Roman Levenstein
dc79034a6a [sil-generic-specializer] Set proper debug scope in the GenericCloner
Fixes a bug uncovered by enabling the inlining of generics, rdar://problem/30479945

The patch is written by @adrian-prantl
2017-02-15 15:21:21 -08:00
Roman Levenstein
26c963f27b Generic specializer API changes to prepare for the new @_specialize attribute and partial specializations. 2017-02-07 23:16:00 -08:00
Adrian Prantl
4d1ae142c6 Remove the redundant DeclCtx field in SILFunction.
In all cases the DeclCtx field was supposed to be initialized from the
SILLocation of the function, so we can save one pointer per
SILFunction.

There is one test case change where a different (more precise)
diagnostic is being generated after this change.
2017-02-06 11:07:50 -08:00
Andrew Trick
8d65b758f2 [SILOpt] support for opaque values. 2017-01-31 16:19:24 -08:00
Andrew Trick
1abeddcc5d [SILType] SILFunctionConventions API.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.

Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.

Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
2017-01-26 15:35:48 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Michael Gottesman
4e8ff35df5 [semantic-sil] Add ValueOwnershipKind field to SILPHIArgument and split Argument creation methods into one for SILPHIArgument and another for SILFunctionArgument.
We preserve the current behavior of assuming Any ownership always and use
default arguments to hide this change most of the time. There are asserts now in
the SILBasicBlock::{create,replace,insert}{PHI,Function}Argument to ensure that
the people can only create SILFunctionArguments in entry blocks and
SILPHIArguments in non-entry blocks. This will ensure that the code in tree
maintains the API distinction even if we are not using the full distinction in
between the two.

Once the verifier is finished being upstreamed, I am going to audit the
createPHIArgument cases for the proper ownership. This is b/c I will be able to
use the verifier to properly debug the code. At that point, I will also start
serializing/printing/parsing the ownershipkind of SILPHIArguments, but lets take
things one step at a time and move incrementally.

In the process, I also discovered a CSE bug. I am not sure how it ever worked.
Basically we replace an argument with a new argument type but return the uses of
the old argument to refer to the old argument instead of a new argument.

rdar://29671437
2016-12-18 14:48:35 -08:00
Michael Gottesman
96837babda Merge pull request #5920 from gottesmm/vacation_gardening
Vacation gardening
2016-11-25 09:17:21 -06:00
Michael Gottesman
0a8c54d04f [gardening] Always create new SILArguments using SILBasicBlock::createArgument instead of inline placement new.
The reasoning here is the same as in e42bf07.
2016-11-25 01:14:45 -06:00
Michael Gottesman
bf6920650c [gardening] Drop BB from all argument related code in SILBasicBlock.
Before this commit all code relating to handling arguments in SILBasicBlock had
somewhere in the name BB. This is redundant given that the class's name is
already SILBasicBlock. This commit drops those names.

Some examples:

getBBArg() => getArgument()
BBArgList => ArgumentList
bbarg_begin() => args_begin()
2016-11-25 01:14:36 -06:00