Commit Graph

32 Commits

Author SHA1 Message Date
Nate Chandler
469c3ec3bd [ObjectOutliner] See through move_value insts.
Enables the outlining of the ContiguousArrayStorage<StaticString> used
when initializing a RawRepresentable enum whose RawValue is String into
a global value to continue even when ContiguousArrayStorage has a
lexical lifetime.

Addresses the following regressions

StringEnumRawValueInitialization    400     7680    +1820.0%   **0.05x**
ArrayLiteral2                       78      647     +729.5%    **0.12x**
DataCreateSmallArray                1750    8850    +405.7%    **0.20x**

seen when enabling lexical lifetimes in the standard library.
2023-01-25 11:39:42 -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
Arnold Schwaighofer
9f2b6a4ebb Reuse _ContiguousArrayStorage<AnyObject> metadata for any class or objc generic type
Reduces the number of _ContiguousArrayStorage metadata.

In order to support constant time bridging we do need to set the correct
metadata when we bridge to Objective-C. This is so that the type check
succeeds when bridging back from Objective-C to reuse the storage
instance rather than bridging the elements.

To support dynamically setting the `_ContiguousArrayStorage` element
type i needed to add support for optimizing `alloc_ref_dynamic`
throughout the optimizer.

Possible future improvements:
* Use different metadata such that we can disambiguate native Swift
  classes during destruction -- allowing native release rather then unknown
  release usage.
* Optimize the newly added semantic function
  getContiguousArrayStorageType

rdar://86171143
2022-02-16 07:55:34 -08:00
Erik Eckstein
383c52aa35 SIL: rename dealloc_ref [stack] -> dealloc_stack_ref
Introduce a new instruction `dealloc_stack_ref ` and remove the `stack` flag from `dealloc_ref`.

The `dealloc_ref [stack]` was confusing, because all it does is to mark the deallocation of the stack space for a stack promoted object.
2022-01-07 16:20:27 +01: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
Slava Pestov
7ccc41a7b7 SIL: Preliminary support for 'apply [noasync]' calls
Refactor SILGen's ApplyOptions into an OptionSet, add a
DoesNotAwait flag to go with DoesNotThrow, and sink it
all down into SILInstruction.h.

Then, replace the isNonThrowing() flag in ApplyInst and
BeginApplyInst with getApplyOptions(), and plumb it
through to TryApplyInst as well.

Set the flag when SILGen emits a sync call to a reasync
function.

When set, this disables the SIL verifier check against
calling async functions from sync functions.

Finally, this allows us to add end-to-end tests for
rdar://problem/71098795.
2021-03-04 22:41:46 -05:00
Andrew Trick
5ae231eaab Rename getFieldNo() to getFieldIndex().
Do I really need to justify this?
2020-09-24 22:44:13 -07:00
Erik Eckstein
71a642e51b stdlib, SIL optimizer: use the SIL copy-on-write representation in the Array types.
Use the new builtins for COW representation in Array, ContiguousArray and ArraySlice.
The basic idea is to strictly separate code which mutates an array buffer from code which reads from an array.
The concept is explained in more detail in docs/SIL.rst, section "Copy-on-Write Representation".

The main change is to use beginCOWMutation() instead of isUniquelyReferenced() and insert endCOWMutation() at the end of all mutating functions. Also, reading from the array buffer must be done differently, depending on if the buffer is in a mutable or immutable state.

All the required invariants are enforced by runtime checks - but only in an assert-build of the library: a bit in the buffer object side-table indicates if the buffer is mutable or not.

Along with the library changes, also two optimizations needed to be updated: COWArrayOpt and ObjectOutliner.
2020-06-08 15:02:22 +02:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Arnold Schwaighofer
147144baa6 SIL: Thread type expansion context through to function convention apis
This became necessary after recent function type changes that keep
substituted generic function types abstract even after substitution to
correctly handle automatic opaque result type substitution.

Instead of performing the opaque result type substitution as part of
substituting the generic args the underlying type will now be reified as
part of looking at the parameter/return types which happens as part of
the function convention apis.

rdar://62560867
2020-05-04 13:53:30 -07:00
Slava Pestov
291364b2f1 Merge pull request #28037 from zoecarver/semantics-def
Semantics attribute definition file
2019-11-20 16:42:29 -05:00
Arnold Schwaighofer
8aaa7b4dc1 SILOptimizer: Pipe through TypeExpansionContext 2019-11-11 14:21:52 -08:00
zoecarver
2ca448b23d Address review comments
* add namespace
* fix block comment style
* SEMA_ATTR -> SEMANTICS_ATTR
* error when SEMANTICS_ATTR isn't defined
2019-11-02 21:58:26 -07:00
zoecarver
9c1a614efb Fix based on review comments 2019-11-02 13:07:20 -07:00
zoecarver
d4129d8659 Add def file for semantics attributes and use constants instead of cstring literals 2019-11-02 11:36:13 -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
Erik Eckstein
a402544588 SILOptimizer: support for Dictionary literals generated in the data section.
Actually: generate the array of (key, value) tuples in the data section, which is then passed to Dictionary.init(dictionaryLiteral:)
We already do this for simple arrays, e.g. arrays with trivial element types.
The only change needed for dictionary literals is to support tuple types in the ObjectOutliner.

The effect of this optimization is a significant reduction in code size for dictionary literals - and an increase in data size.
But in most cases there is a considerable net win for code+data size in total.
2019-04-23 09:02:53 -07:00
Slava Pestov
5c72a3691c SILOptimizer: Add some FIXMEs and a cleanup 2019-03-13 02:12:29 -04:00
Michael Gottesman
f35a2a3cf8 [sil-opt] Only notify the pass manager of newly added functions in SILOptFunctionBuilder.
To do so this commit does a few different things:

1. I changed SILOptFunctionBuilder to notify the pass manager's logging
functionality when new functions are added to the module and to notify analyses
as well. NOTE: This on purpose does not put the new function on the pass manager
worklist since we do not want to by mistake introduce a large amount of
re-optimizations. Such a thing should be explicit.

2. I eliminated SILModuleTransform::notifyAddFunction. This just performed the
operations from 1. Now that SILOptFunctionBuilder performs this operation for
us, it is not needed.

3. I changed SILFunctionTransform::notifyAddFunction to just add the function to
the passmanager worklist. It does not need to notify the pass manager's logging
or analyses that a new function was added to the module since
SILOptFunctionBuilder now performs that operation. Given its reduced
functionality, I changed the name to addFunctionToPassManagerWorklist(...). The
name is a little long/verbose, but this is a feature since one should think
before getting the pass manager to rerun transforms on a function. Also, giving
it a longer name calls out the operation in the code visually, giving this
operation more prominance when reading code. NOTE: I did the rename using
Xcode's refactoring functionality!

rdar://42301529
2018-08-06 18:27:24 -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
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
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
Doug Gregor
4b5abbddbc [SIL] Teach *ApplyInst to traffic in SubstitutionMap.
Push SubstitutionMaps through most of SILGen and the SIL optimizers
that involve the various *ApplyInsts.
2018-05-11 13:18:06 -07:00
Erik Eckstein
c408468210 ObjectOutliner: restrict object outlining to tail allocated arrays.
SR-7146, rdar://problem/38302248
2018-03-09 16:25:16 -08:00
Sho Ikeda
cea6c03eb2 [gardening] Use !empty() over size() > 0 2018-03-08 09:21:09 +09:00
Erik Eckstein
3afd9c8eb4 ObjectOutliner: fix for handling set_deallocating instruction correctly.
rdar://problem/36692828
2018-01-23 18:21:33 -08:00
Erik Eckstein
e081392672 ObjectOutliner: handle set_deallocating instruction correctly.
rdar://problem/36692828
2018-01-22 17:04:56 -08:00
Erik Eckstein
bf87035a36 GlobalOpt: Move the object outlining from GlobalOpt into a separate pass "ObjectOutliner"
We run GlobalOpt multiple times in the pass pipeline but in some cases object outlining shouldn't be done too early.
Having it done in a separate pass enables to run it independently from GlobalOpt.
2018-01-19 11:32:36 -08:00
eeckstein
b126b62256 Revert "Optimization changes to completely fold OptionSet literals" 2018-01-18 22:05:07 -08:00
Erik Eckstein
1f511ab846 GlobalOpt: Move the object outlining from GlobalOpt into a separate pass "ObjectOutliner"
We run GlobalOpt multiple times in the pass pipeline but in some cases object outlining shouldn't be done too early.
Having it done in a separate pass enables to run it independently from GlobalOpt.
2018-01-18 18:27:17 -08:00