Commit Graph

940 Commits

Author SHA1 Message Date
Michael Gottesman
925a211ed8 Merge pull request #60989 from gottesmm/pr-d5933fd70a08a0acd36e29c39312cf34cc50f904
[move-only] Fix a few small issues around mark must check.
2022-09-08 13:19:53 -07:00
Erik Eckstein
b2b44c0d83 Swift Optimizer: add the StackProtection optimization
It decides which functions need stack protection.

It sets the `needStackProtection` flags on all function which contain stack-allocated values for which an buffer overflow could occur.

Within safe swift code there shouldn't be any buffer overflows.
But if the address of a stack variable is converted to an unsafe pointer, it's not in the control of the compiler anymore.
This means, if there is any `address_to_pointer` instruction for an `alloc_stack`, such a function is marked for stack protection.
Another case is `index_addr` for non-tail allocated memory.
This pattern appears if pointer arithmetic is done with unsafe pointers in swift code.

If the origin of an unsafe pointer can only be tracked to a function argument, the pass tries to find the root stack allocation for such an argument by doing an inter-procedural analysis.
If this is not possible, the fallback is to move the argument into a temporary `alloc_stack` and do the unsafe pointer operations on the temporary.

rdar://93677524
2022-09-08 08:42:25 +02:00
Erik Eckstein
0eddce0dca Swift SIL: add BuiltinInst.ID.stackAlloc
And make all the case identifiers lowercase.
2022-09-08 08:42:25 +02:00
Erik Eckstein
3e1ff0a5b7 IRGen: move the EnableStackProtector option from IRGenOptions to SILOptions.
... because we need it in the SIL pass pipeline, too.
Also, add Swift bridging for that option.
2022-09-08 08:42:24 +02:00
Erik Eckstein
fdca208335 SIL: add the SILFunction.needsStackProtection flag
Indicates that stack protectors are inserted into this function to detect stack related buffer overflows.
2022-09-08 08:37:21 +02:00
Erik Eckstein
78e171303c Swift AccessUtils: improve ergonomics of getAccessPathWithScope
It doesn't make sense to let getAccessPathWithScope return an `EnclosingScope` as the second tuple element, because in case it's a `base`, it duplicates the `AccessBase` (which is returned in the first tuple element).
Instead just return an optional `BeginAccessInst` which is not nil if such an "scope" is found.
2022-09-08 08:37:21 +02:00
Michael Gottesman
03986db44f [mem-access] Teach mem-access about mark_must_check. 2022-09-07 18:20:33 -07:00
Erik Eckstein
275861f832 FunctionUses: don't eagerly reserve array capacities in the initializer
Instead do it in `collect`. This allows creating a `FunctionUses` with zero cost - in case `collect` is never called.
2022-09-02 07:11:49 +02:00
Erik Eckstein
9795f4b944 Swift Optimizer: add bridging for command line options 2022-09-02 07:11:49 +02:00
Erik Eckstein
2a2c009532 Swift AccessUtils: add convenient properties to get the AccessBase and AccessScope of a Value 2022-09-02 07:11:49 +02:00
Erik Eckstein
607268371b Swift AccessUtils: add an AccessBase.unidentified case
Now that `AccessBase` is an enum, it makes sense to add an `unidentified` case. This avoids dealing with optional AccessBases in several place.
Clients don't need to make both, an optional check and a switch, but can check for unidentified access bases just in a single switch statement.
2022-09-02 07:11:49 +02:00
Erik Eckstein
082aec0990 Swift SIL: add var FunctionArgument.convention
Also:
* move the `ArgumentConvention` enum from Function.swift to Argument.swift.
* `FunctionArgument.isExclusiveIndirectParameter` -> `ArgumentConvention.isExclusiveIndirect`
* add `ArgumentConvention.isInout`
2022-09-02 07:11:49 +02:00
Erik Eckstein
f6e6b2ecf3 Swift SIL: add the possibility to pass a custom location to Builder initializers.
And add the static property `Location.autoGeneratedLocation`
2022-08-26 18:00:11 +02:00
Erik Eckstein
a12e33e9e9 Swift Optimizer: add the FunctionUses utility
Provides a list of instructions, which reference a function.

A function "use" is an instruction in another (or the same) function which references the function.
In most cases those are `function_ref` instructions, but can also be e.g. `keypath` instructions.

'FunctionUses' performs an analysis of all functions in the module and collects instructions which reference other functions.
This utility can be used to do inter-procedural caller-analysis.
2022-08-24 17:55:02 +02:00
Erik Eckstein
2fe1ee5533 Swift SIL: add a few Builder functions
* add `createAllocStack`
* add `createDeallocStack`
* add `createCopyAddr`
* add `@discardableResult` to the existing `createDeallocStackRef`
2022-08-24 17:55:02 +02:00
Erik Eckstein
90c83be7a6 Swift Optimizer: make the Stack data structure also work with a ModulePassContext 2022-08-24 17:55:02 +02:00
Erik Eckstein
fbb694bcde Swift SIL: add bridging for witness and default witness tables 2022-08-24 17:55:02 +02:00
Erik Eckstein
7816513f0d Swift SIL: add bridging for vTables 2022-08-24 17:55:02 +02:00
Erik Eckstein
87f2f41d51 Swift Optimizer: add infrastructure for module passes.
To add a module pass in `Passes.def` use the new `SWIFT_MODULE_PASS` macro.
On the swift side, create a `ModulePass`.
It’s run function receives a `ModulePassContext`, which provides access to all functions of a module.
But it doesn't provide any APIs to modify functions.
In order to modify a function, a module pass must use `ModulePassContext.transform(function:)`.
2022-08-24 17:55:02 +02:00
Erik Eckstein
de6e539a0a Swift Optimizer: make the set's insert functions return a Bool.
Returning true if the element was not contained in the set before inserting
2022-08-24 17:54:46 +02:00
Erik Eckstein
c2ef10661a Swift Optimizer: move function passes which are only used for unit testing to their own TestPasses directory. 2022-08-24 17:54:46 +02:00
Erik Eckstein
beebd5a920 PassManager: add a invalidation kind for non-body function data
E.g. used if function effects are changed. This tells the passmanager that something changed, but no SIL-specific analysis have to be invalidated.
2022-08-24 17:54:46 +02:00
Erik Eckstein
3bba7caacc Swift SIL: add var Function.instructions
To be used to iterate over all instructions in a function without the need of two loops - one for blocks and one for instructions.
2022-08-24 17:54:46 +02:00
Erik Eckstein
20a8f450dd Swift AccessUtils: improvements and bug fixes
While I was using the new AccessUtils for a new optimization pass I discovered some areas for improvements. Also I found some bugs.

Changes:

* AccessBase: remove the unhealthy redundancy between `kind` and `baseAddress` types. Now AccessBase is single enum with the relevant base objects/addresses as payloads.

* AccessBase: for `global`, store the `GlobalValue` and not a `global_address` instruction, which is more accurate (because there can be multiple `global_addr`s for a single global variable)

* AccessBase: drop the support for function argument "pointers". The `pointer` is now always a `pointer_to_address` instruction. This also simplifies `PointerIdentification`: either it finds a matching `address_to_pointer` or it bails.

* AccessBase: improve `func isDistinct(from:)`. There are more possibilities to prove that two access bases do not alias.

* AccessBase: replace `var isUniquelyIdentified` with `var hasKnownStorageKind` which is more useful for aliasing checking.

* AccessPath: fix `func isDistinct(from:)`. `SmallProjectionPath.matches` is the wrong way to check if two expression paths may overlap. Instead use the new `SmallProjectionPath.mayOverlap`.

* AccessStoragePathWalker: rename `getAccessStorage` -> `visitAccessStorageRoots` and let it return false if it's not a class/reference AccessBase.

* add tests for `AccessPath.isDistinct(from:)`
2022-08-22 13:22:14 +02:00
Anxhelo Xhebraj
7a20bc3ea6 Swift Optimizer: add AccessUtils
This set of utilities introduce concepts such as `AccessBase`,
`AccessPath` and `AccessStoragePath` useful to analyze memory accesses.
2022-08-12 09:42:13 -07:00
Anxhelo Xhebraj
b8b8f1ac88 Swift Optimizer: add SmallProjectionWalkingPaths in WalkUtils
- This protocol with its default implementations simplifies
  writing walkers, requiring only `merge` for conformance
2022-08-11 10:16:12 -07:00
Egor Zhdan
0e2d438c5b [cxx-interop][SwiftCompilerSources] Use llvm::StringRef instead of BridgedStringRef
rdar://83361000
2022-07-21 16:32:16 +01:00
Erik Eckstein
872ded9341 ReleaseDevirtualizer: use the ValueUseDefWalker instead of the manual use-def walking implementation 2022-07-20 13:50:18 +02:00
Erik Eckstein
b52297bb79 Swift SIL: some improvements for WalkUtils and EscapeInfo
* "merge" the `Path` and `State` in WalkUtils into a single `WalkingPath`. This makes it simpler for clients to configure a path and additional state variables. EscapeInfo now defines `EscapePath` which includes the projection path and EscapeInfo's specific state variables.
* Make the `WalkerCache` part of the WalkUtils, so that not all clients have to re-implement it.
* Rename `walkDownResults` -> `walkDownAllResults` and `walkUpOperands` -> `walkUpAllOperands` and make these functions client configurable.
2022-07-20 13:50:18 +02:00
Erik Eckstein
ce5e2fb637 Swift SIL: use InstructionSet (instead of Set<Instruction>) in InstructionRange 2022-07-13 14:27:50 +02:00
Erik Eckstein
49a5b3ebdc Swift SIL: add ValueSet and InstructionSet utilities.
These sets are _much_ more efficient than `Set<Value>` and `Set<Instruction>` because they bridge to the efficient `NodeSet`.
Insertions/deletions are just bit operations.
2022-07-13 14:27:50 +02:00
Erik Eckstein
6760dc420c SIL: add a utility which can manage per-value and per-instruction bitfields and flags efficiently.
It's used to implement `InstructionSet` and `ValueSet`: sets of SILValues and SILInstructions.
Just like `BasicBlockSet` for basic blocks, the set is implemented by setting bits directly in SILNode.
This is super efficient because insertion and deletion to/from the set are basic bit operations.

The cost is an additional word in SILNode. But this is basically negligible: it just adds ~0.7% of memory used for SILInstructions.
In my experiments, I didn't see any relevant changes in memory consumption or compile time.
2022-07-13 14:27:50 +02:00
Anxhelo Xhebraj
c3ccbde52b Swift Optimizer: update EscapeInfo to use the generic walker utilities
`EscapeInfo` now conforms to the generic protocols defined in `WalkUtils`.
This simplifies the implementation a bit, since trivial instructions are handled
by `WalkUtils` and `EscapeInfo` only has to handle a subset of instructions
inherent to escape information.
Passes using `EscapeInfo` are updated accordingly to become visitors that
customize the `EscapeInfo` walk.
2022-07-05 11:28:49 -07:00
Anxhelo Xhebraj
50a7e25e31 Swift Optimizer: add projection path DefUse/UseDef walkers
Introduces a set of protocols useful to perform def-use and use-def
traversals to find uses and definitions of values.

This logic was originally baked into `EscapeInfo` directly.
Here we extract it into general utilities, namely:
- `ValueDefUseWalker`: visit uses of a value walking down value-value projections/constructions.
- `AddressDefUseWalker`: visit uses of an address walking down addr-addr projections/constructions.
- `ValueUseDefWalker`: visit definitions of a value walking up value-value projections/constructions.
- `AddressUseDefWalker`: visit definitions of an address walking up addr-addr projections/constructions.

These utilities can then be used in other passes or to create
new utilities by composing them. For example to find a definition
passing through both address projections and value extractions,
it's enough to implement a visitor conforming to both
`AddressUseDefWalker` and `ValueUseDefWalker`.
2022-07-05 11:26:13 -07:00
eeckstein
b3d9b873a9 Merge pull request #58888 from eeckstein/objc-string-opt
Optimizer: add the ObjCBridgingOptimization to optimize ObjectiveC bridging operations.
2022-06-09 06:48:36 +02:00
Erik Eckstein
ec3d9dd9c7 Optimizer: add the ObjCBridgingOptimization to optimize ObjectiveC bridging operations.
Removes redundant ObjectiveC <-> Swift bridging calls.
Basically, if a value is bridged from ObjectiveC to Swift an then back to ObjectiveC again, then just re-use the original ObjectiveC value.

Also in this commit: add an additional DCE pass before ownership elimination. It can cleanup dead code which is left behind by the ObjCBridgingOptimization.

rdar://89987440
2022-06-08 22:51:57 +02:00
Rintaro Ishizaki
9f4ce612a2 [SwiftCompilerModules] Link lib_InternalSwiftSyntaxParser to libswift
To use _RegexParser from SwiftSyntax.

* Create 'libswiftCompilerModules_SwiftSyntax.a' which is a subset of
  'libswiftCompilerModules.a'
* Link 'lib_InternalSwiftSyntaxParser' to
  'libswiftCompilerModules_SwiftSyntax.a'
* Factor out swift runtime linking logic in CMake so that dynamic
  libraries can link to Swift runtime, in addition to executables
* Link 'lib_InternalSwiftSyntaxParser' to swift runtime
2022-06-02 12:23:03 -07:00
Erik Eckstein
4011e086f0 Swift optimizer: add Value.makeAvailable and `Value.copy(at:andMakeAvailableIn:)
Utilities to make a value available to be used in another basic block.
Inserts required `copy_value` and `destroy_value` operations in case the destination block is in a different control region than the value.
For example, if the destination block is in a loop while the value is not in that loop, the value has to be copied for each loop iteration.
2022-05-12 21:48:37 +02:00
Erik Eckstein
ad9dafc9bf Swift SIL: add Value.definingBlock
and re-factor `Value.definingInstruction`
2022-05-12 21:48:37 +02:00
Erik Eckstein
3b43da9637 Swift Optimizer: improve ergonomics of Builder and PassContext
* split the PassUtils.swift file into PassContext.swift and Passes.swift
* rework `Builder` bridging allowing more insertion point variations, e.g. inserting at the end of a block.
* add Builder.create functions for more instructions
* add `PassContext.splitBlock`
* move SIL modification functions from PassContext to extensions of the relevant types (e.g. instructions).
* rename `Location.bridgedLocation` -> `Location.bridged`
2022-05-12 21:48:37 +02:00
Erik Eckstein
cd456fa792 Swift SIL: make Function.name and GlobalVariable.name return a StringRef and not a String
and introduce the StringRef struct.
It's more efficient.

Also, rename the `HasName` protocol to `HasShortDescription`, which introduces the new requirement `shortDescription`. This is need because `name` now has `StringRef` type and not `String` anymore
2022-05-12 21:48:37 +02:00
Erik Eckstein
cad646b283 re-implement the StackPromotion pass in swift
It uses the new EscapeInfo.
2022-05-02 14:22:27 +02:00
Josh Soref
1b0aa6d7f1 Spelling swiftcompilersources (#42617)
* spelling: diagnose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnostic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intentionally

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: optimization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: target

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unbalanced

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-25 09:01:23 -07:00
Rintaro Ishizaki
30a53fed05 Merge pull request #42583 from rintaro/regex_diagnostics
[SwiftCompiler/Regex] Use bridged DiagnosticEngine for error reporting
2022-04-25 08:26:38 -07:00
eeckstein
4a5db44e8a Merge pull request #52196 from eeckstein/subpass-bisect
Swift SIL: support for sub-pass bisecting: add `PassContext.continueWithNextSubpassRun`
2022-04-25 14:05:07 +02:00
Erik Eckstein
f98a6655eb ReleaseDevirtualizer: support sub-pass bisecting for debugging 2022-04-25 11:57:12 +02:00
Erik Eckstein
5d3339e9a3 Swift SIL: support for sub-pass bisecting: add PassContext.continueWithNextSubpassRun 2022-04-25 11:57:02 +02:00
Erik Eckstein
1c4ba46c3b EscapeInfo: fix a bug and some refactoring
Add a flag `analyzeAddresses` for distinguishing address vs value escape analysis. This is simpler than handling that in the visitUse/visitDef closures.
Also, fix a related bug, which let an address, which is escaping to a function, get unnoticed.
2022-04-25 08:56:24 +02:00
Rintaro Ishizaki
d292a95296 [SwiftCompiler/Regex] Use bridged DiagnosticEngine for error reporting
This fixes:
 * An issue where the diagnostic messages were leaked
 * Diagnose at correct position inside the regex literal

To do this:
 * Introduce 'Parse' SwiftCompiler module that is a bridging layer
   between '_CompilerRegexParser' and C++ libParse
 * Move libswiftParseRegexLiteral and libswiftLexRegexLiteral to 'Parse'

Also this change makes 'SwiftCompilerSources/Package.swift' be configured
by CMake so it can actually be built with 'swift-build'.

rdar://92187284
2022-04-22 22:53:46 -07:00
Erik Eckstein
eea471fe99 add the ComputeEffects pass
The ComputeEffects pass derives escape information for function arguments and adds those effects in the function.
This needs a lot of changes in check-lines in the tests, because the effects are printed in SIL
2022-04-22 09:50:07 +02:00