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
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.
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.
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.
* add `DynamicFunctionRefInst` and `PreviousDynamicFunctionRefInst`
* add a common base class to all function-referencing instructions: `FunctionRefBaseInst`
* add `KeyPathInst`
* add `IndexAddrInst.base` and `IndexAddrInst.index` getters
* add `Instruction.visitReferencedFunctions` to visit all functions which are referenced by an instruction
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:)`.
It fixes the default reflection for bridged random access collections, which usually have a `bridged` stored property.
Conforming to this protocol displays the "real" children of a bridged random access collection and not just `bridged`.
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:)`
* "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.