Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
ded9b78
Warn on redundant comparison to 'Optional.none', like we already do f…
calda Sep 1, 2022
88b65f4
Update tests
calda Sep 1, 2022
2e76562
Combine the two diagnostics
calda Sep 1, 2022
1b224bd
Add a test that verifyies comparing to a .none case that isn't Option…
calda Sep 1, 2022
568549f
Update comment
calda Sep 1, 2022
c2bf0f9
Revert "Combine the two diagnostics"
calda Sep 1, 2022
c3e74e0
Use a single warning, but dynamically specify 'nil' or 'Optional.none'
calda Sep 1, 2022
992a9d3
remove warning test case that doesn't actually compile
calda Sep 1, 2022
7cbadf2
[stdlib] _modify: Ensure cleanup is always executed
lorentey Sep 7, 2022
6061516
[Dependency Scanner] Add API to query emitted diagnostics during a scan
artemcm Sep 7, 2022
1d52c9c
AST: Move some #available parsing diagnostics to the right section of…
tshortli Aug 29, 2022
f5f1d3c
AST: Parse `#_hasSymbol`
tshortli Aug 27, 2022
d9be4a7
Update check for Optional.none
calda Sep 9, 2022
6d9b82b
[Sema] Error on aliases desugaring to a reference SPI only imported
xymus Sep 6, 2022
bc4efe5
[Sema] Always error on public uses of conformance from @_spiOnly import
xymus Sep 8, 2022
ebc2162
[Sema] @_spiOnly isn't a public import that triggers the diagnostic
xymus Aug 27, 2022
03136e0
[Dependency Scanner] Ensure the Clang dependency scanner working dire…
artemcm Sep 9, 2022
467b742
[move-only] Update the non-address move checker part of the optimizer…
gottesmm Aug 2, 2022
0583457
[sil] Add a try_emplace/simple failable get method to BasicBlockData.
gottesmm Aug 31, 2022
8232270
[TypeLowering] Correct assertion.
nate-chandler Sep 7, 2022
f3cc081
[NFC] Fix verification in TypeLowering.
nate-chandler Sep 7, 2022
af6749e
[TypeLowering] Mark lexical when marking non-trivial.
nate-chandler Sep 9, 2022
b4d7a0c
[interop][SwiftToCxx] bridge returned C++ record types back to C++ fr…
hyp Sep 9, 2022
0a16cc3
[move-only] Implement an initial version of the move only address che…
gottesmm Aug 31, 2022
e327848
Workaround MSVC overload resolution.
nate-chandler Sep 12, 2022
8f0dd56
Merge pull request #60889 from gottesmm/initial-move-only-address-che…
gottesmm Sep 12, 2022
e1ff0aa
SmallProjectionPath: allow parsing an empty path
eeckstein Sep 12, 2022
8e2e7a7
SIL: make argument effects more readable in textual SIL
eeckstein Sep 12, 2022
149e57a
Merge pull request #60893 from calda/cal--warn-redundant-comparison-t…
xedin Sep 12, 2022
9ab055a
Merge pull request #61044 from eeckstein/sil-effect-syntax
eeckstein Sep 12, 2022
0db1457
[interop][SwiftToCxx] pass C++ value types into Swift correctly
hyp Sep 12, 2022
f53e88b
Workaround MSVC more.
nate-chandler Sep 12, 2022
5642a46
Renamed _noEagerMove attribute.
nate-chandler Sep 12, 2022
9a28ae0
Merge pull request #61025 from artemcm/ClangScannerWorkDir
artemcm Sep 12, 2022
06595f6
Merge pull request #60852 from tshortli/parse-has-symbol
tshortli Sep 12, 2022
d8f77c6
[Dependency Scanner] Use Clang scanner's module name query API instea…
artemcm Aug 26, 2022
3211b93
Merge pull request #60999 from artemcm/LibSwiftScanDiagnostics
artemcm Sep 12, 2022
5d0c6e6
Merge pull request #60973 from lorentey/fix-modify-implementations
lorentey Sep 12, 2022
d5f6b12
Avoid generating address phis in LoopUnroll
meg-gupta Sep 12, 2022
035f062
Ban address phis in non-OSSA SIL
meg-gupta Sep 12, 2022
26e5742
[interop][SwiftToCxx] emit generic type traits for C++ types bridged …
hyp Sep 12, 2022
21adff9
Merge pull request #61047 from hyp/eng/cxx-types-to-cxx
hyp Sep 12, 2022
0dcb8b5
[interop][SwiftToCxx] use C++ types bridged to Swift in Swift generic…
hyp Sep 12, 2022
5372177
Merge pull request #61042 from nate-chandler/fix-lexical-recursive-pr…
nate-chandler Sep 12, 2022
6075af2
Merge pull request #61048 from nate-chandler/no_eager_move_attr
nate-chandler Sep 12, 2022
d20e00e
[NFC] Improve deserialization errors for wrong record kind
beccadax Sep 12, 2022
ea27698
Merge pull request #61023 from xymus/spi-only-and-apis
xymus Sep 12, 2022
fa82a6e
Merge pull request #60807 from artemcm/NoHackScanning
artemcm Sep 12, 2022
fd8d7af
[Parse] Fix variable identifier parsing including code on newline as …
theblixguy Sep 12, 2022
a190855
Merge pull request #61051 from meg-gupta/loopunrolladdressphi
meg-gupta Sep 13, 2022
6ed6290
Merge pull request #61053 from hyp/i/cxx-type-in-generic-ctx
hyp Sep 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 79 additions & 39 deletions SwiftCompilerSources/Sources/SIL/Effects.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ public struct ArgumentEffect : CustomStringConvertible, CustomReflectable {
public typealias Path = SmallProjectionPath

public enum Kind {
/// The selected argument value does not escape.
/// The argument value does not escape.
///
/// Syntax examples:
/// !%0 // argument 0 does not escape
/// !%0.** // argument 0 and all transitively contained values do not escape
/// [%0: noescape] // argument 0 does not escape
/// [%0: noescape **] // argument 0 and all transitively contained values do not escape
///
case notEscaping

/// The selected argument value escapes to the specified selection (= first payload).
/// The argument value escapes to the function return value.
///
/// Syntax examples:
/// %0.s1 => %r // field 2 of argument 0 exclusively escapes via return.
/// %0.s1 -> %1 // field 2 of argument 0 - and other values - escape to argument 1.
/// [%0: escape s1 => %r] // field 2 of argument 0 exclusively escapes via return.
/// [%0: escape s1 -> %r] // field 2 of argument 0 - and other values - escape via return
///
/// The "exclusive" flag (= second payload) is true if only the selected argument escapes
/// to the specified selection, but nothing else escapes to it.
/// The "exclusive" flag (= second payload) is true if only the argument escapes,
/// but nothing else escapes to the return value.
/// For example, "exclusive" is true for the following function:
///
/// @_effect(escaping c => return)
Expand All @@ -46,6 +46,14 @@ public struct ArgumentEffect : CustomStringConvertible, CustomReflectable {
///
case escapingToReturn(Path, Bool) // toPath, exclusive

/// Like `escapingToReturn`, but the argument escapes to another argument.
///
/// Example: The argument effects of
/// func argToArgEscape(_ r: inout Class, _ c: Class) { r = c }
///
/// would be
/// [%1: escape => %0] // Argument 1 escapes to argument 0
///
case escapingToArgument(Int, Path, Bool) // toArgumentIndex, toPath, exclusive
}

Expand Down Expand Up @@ -111,21 +119,28 @@ public struct ArgumentEffect : CustomStringConvertible, CustomReflectable {
return argumentIndex == rhsArgIdx && rhsPath.matches(pattern: pathPattern)
}

public var description: String {
let selectedArg = "%\(argumentIndex)" + (pathPattern.isEmpty ? "" : ".\(pathPattern)")
public var headerDescription: String {
"%\(argumentIndex)\(isDerived ? "" : "!"): "
}

public var bodyDescription: String {
let patternStr = pathPattern.isEmpty ? "" : " \(pathPattern)"
switch kind {
case .notEscaping:
return "!\(selectedArg)"
return "noescape\(patternStr)"
case .escapingToReturn(let toPath, let exclusive):
let pathStr = (toPath.isEmpty ? "" : ".\(toPath)")
return "\(selectedArg) \(exclusive ? "=>" : "->") %r\(pathStr)"
let toPathStr = (toPath.isEmpty ? "" : ".\(toPath)")
return "escape\(patternStr) \(exclusive ? "=>" : "->") %r\(toPathStr)"
case .escapingToArgument(let toArgIdx, let toPath, let exclusive):
let pathStr = (toPath.isEmpty ? "" : ".\(toPath)")
return "\(selectedArg) \(exclusive ? "=>" : "->") %\(toArgIdx)\(pathStr)"
let toPathStr = (toPath.isEmpty ? "" : ".\(toPath)")
return "escape\(patternStr) \(exclusive ? "=>" : "->") %\(toArgIdx)\(toPathStr)"
}
}

public var description: String {
headerDescription + bodyDescription
}

public var customMirror: Mirror { Mirror(self, children: []) }
}

Expand Down Expand Up @@ -164,8 +179,27 @@ public struct FunctionEffects : CustomStringConvertible, CustomReflectable {
argumentEffects = argumentEffects.filter { !$0.isDerived }
}

public var argumentEffectsDescription: String {
var currentArgIdx = -1
var currentIsDerived = false
var result = ""
for effect in argumentEffects {
if effect.argumentIndex != currentArgIdx || effect.isDerived != currentIsDerived {
if currentArgIdx >= 0 { result += "]\n" }
result += "[\(effect.headerDescription)"
currentArgIdx = effect.argumentIndex
currentIsDerived = effect.isDerived
} else {
result += ", "
}
result += effect.bodyDescription
}
if currentArgIdx >= 0 { result += "]\n" }
return result
}

public var description: String {
return "[" + argumentEffects.map { $0.description }.joined(separator: ", ") + "]"
return argumentEffectsDescription
}

public var customMirror: Mirror { Mirror(self, children: []) }
Expand Down Expand Up @@ -237,24 +271,37 @@ extension StringParser {
return ArgumentEffect.Path()
}

mutating func parseEffectFromSIL(for function: Function, isDerived: Bool) throws -> ArgumentEffect {
if consume("!") {
let argIdx = try parseArgumentIndexFromSIL()
let path = try parsePathPatternFromSIL()
return ArgumentEffect(.notEscaping, argumentIndex: argIdx, pathPattern: path, isDerived: isDerived)
mutating func parseEffectsFromSIL(to effects: inout FunctionEffects) throws {
let argumentIndex = try parseArgumentIndexFromSIL()
let isDerived = !consume("!")
if !consume(":") {
try throwError("expected ':'")
}
let fromArgIdx = try parseArgumentIndexFromSIL()
let fromPath = try parsePathPatternFromSIL()
let exclusive = try parseEscapingArrow()
if consume("%r") {
let toPath = try parsePathPatternFromSIL()
return ArgumentEffect(.escapingToReturn(toPath, exclusive),
argumentIndex: fromArgIdx, pathPattern: fromPath, isDerived: isDerived)
repeat {
let effect = try parseEffectFromSIL(argumentIndex: argumentIndex, isDerived: isDerived)
effects.argumentEffects.append(effect)
} while consume(",")
}

mutating func parseEffectFromSIL(argumentIndex: Int, isDerived: Bool) throws -> ArgumentEffect {
if consume("noescape") {
let path = try parseProjectionPathFromSIL()
return ArgumentEffect(.notEscaping, argumentIndex: argumentIndex, pathPattern: path, isDerived: isDerived)
}
if consume("escape") {
let fromPath = try parseProjectionPathFromSIL()
let exclusive = try parseEscapingArrow()
if consume("%r") {
let toPath = consume(".") ? try parseProjectionPathFromSIL() : ArgumentEffect.Path()
return ArgumentEffect(.escapingToReturn(toPath, exclusive),
argumentIndex: argumentIndex, pathPattern: fromPath, isDerived: isDerived)
}
let toArgIdx = try parseArgumentIndexFromSIL()
let toPath = consume(".") ? try parseProjectionPathFromSIL() : ArgumentEffect.Path()
return ArgumentEffect(.escapingToArgument(toArgIdx, toPath, exclusive),
argumentIndex: argumentIndex, pathPattern: fromPath, isDerived: isDerived)
}
let toArgIdx = try parseArgumentIndexFromSIL()
let toPath = try parsePathPatternFromSIL()
return ArgumentEffect(.escapingToArgument(toArgIdx, toPath, exclusive),
argumentIndex: fromArgIdx, pathPattern: fromPath, isDerived: isDerived)
try throwError("unknown effect")
}

mutating func parseArgumentIndexFromSIL() throws -> Int {
Expand All @@ -267,13 +314,6 @@ extension StringParser {
try throwError("expected parameter")
}

mutating func parsePathPatternFromSIL() throws -> ArgumentEffect.Path {
if consume(".") {
return try parseProjectionPathFromSIL()
}
return ArgumentEffect.Path()
}

private mutating func parseEscapingArrow() throws -> Bool {
if consume("=>") { return true }
if consume("->") { return false }
Expand Down
51 changes: 27 additions & 24 deletions SwiftCompilerSources/Sources/SIL/Function.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,27 +133,36 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
},
// writeFn
{ (f: BridgedFunction, os: BridgedOStream, idx: Int) in
let s = f.function.effects.argumentEffects[idx].description
let s: String
if idx >= 0 {
s = f.function.effects.argumentEffects[idx].bodyDescription
} else {
s = f.function.effects.argumentEffectsDescription
}
s._withStringRef { OStream_write(os, $0) }
},
// parseFn:
{ (f: BridgedFunction, str: llvm.StringRef, fromSIL: Int, isDerived: Int, paramNames: BridgedArrayRef) -> BridgedParsingError in
{ (f: BridgedFunction, str: llvm.StringRef, fromSIL: Int, argumentIndex: Int, isDerived: Int, paramNames: BridgedArrayRef) -> BridgedParsingError in
do {
var parser = StringParser(str.string)
let effect: ArgumentEffect
if fromSIL != 0 {
effect = try parser.parseEffectFromSIL(for: f.function, isDerived: isDerived != 0)

if fromSIL != 0 && argumentIndex < 0 {
try parser.parseEffectsFromSIL(to: &f.function.effects)
} else {
let paramToIdx = paramNames.withElements(ofType: llvm.StringRef.self) {
(buffer: UnsafeBufferPointer<llvm.StringRef>) -> Dictionary<String, Int> in
let keyValPairs = buffer.enumerated().lazy.map { ($0.1.string, $0.0) }
return Dictionary(uniqueKeysWithValues: keyValPairs)
let effect: ArgumentEffect
if fromSIL != 0 {
effect = try parser.parseEffectFromSIL(argumentIndex: argumentIndex, isDerived: isDerived != 0)
} else {
let paramToIdx = paramNames.withElements(ofType: llvm.StringRef.self) {
(buffer: UnsafeBufferPointer<llvm.StringRef>) -> Dictionary<String, Int> in
let keyValPairs = buffer.enumerated().lazy.map { ($0.1.string, $0.0) }
return Dictionary(uniqueKeysWithValues: keyValPairs)
}
effect = try parser.parseEffectFromSource(for: f.function, params: paramToIdx)
}
effect = try parser.parseEffectFromSource(for: f.function, params: paramToIdx)
f.function.effects.argumentEffects.append(effect)
}
if !parser.isEmpty() { try parser.throwError("syntax error") }

f.function.effects.argumentEffects.append(effect)
} catch let error as ParsingError {
return BridgedParsingError(message: error.message.utf8Start, position: error.position)
} catch {
Expand All @@ -179,20 +188,14 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
resultArgDelta: destResultArgs - srcResultArgs)
return 1
},
// getEffectFlags
{ (f: BridgedFunction, idx: Int) -> Int in
// getEffectInfo
{ (f: BridgedFunction, idx: Int) -> BridgedEffectInfo in
let argEffects = f.function.effects.argumentEffects
if idx >= argEffects.count { return 0 }
let effect = argEffects[idx]
var flags = 0
switch effect.kind {
case .notEscaping, .escapingToArgument, .escapingToReturn:
flags |= Int(EffectsFlagEscape)
}
if effect.isDerived {
flags |= Int(EffectsFlagDerived)
if idx >= argEffects.count {
return BridgedEffectInfo(argumentIndex: -1, isDerived: false)
}
return flags
let effect = argEffects[idx]
return BridgedEffectInfo(argumentIndex: effect.argumentIndex, isDerived: effect.isDerived)
}
)
}
Expand Down
10 changes: 4 additions & 6 deletions SwiftCompilerSources/Sources/SIL/SmallProjectionPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ extension StringParser {

mutating func parseProjectionPathFromSIL() throws -> SmallProjectionPath {
var entries: [(SmallProjectionPath.FieldKind, Int)] = []
repeat {
while true {
if consume("**") {
entries.append((.anything, 0))
} else if consume("c*") {
Expand All @@ -497,12 +497,10 @@ extension StringParser {
entries.append((.structField, idx))
} else if let tupleElemIdx = consumeInt() {
entries.append((.tupleField, tupleElemIdx))
} else {
try throwError("expected selection path component")
} else if !consume(".") {
return try createPath(from: entries)
}
} while consume(".")

return try createPath(from: entries)
}
}

private func createPath(from entries: [(SmallProjectionPath.FieldKind, Int)]) throws -> SmallProjectionPath {
Expand Down
6 changes: 3 additions & 3 deletions docs/ReferenceGuides/UnderscoredAttributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ that releases of the value may be hoisted without respect to deinit barriers.

When applied to a type, indicates that all values which are _statically_
instances of that type are themselves `@_eagerMove` as above, unless overridden
with `@_lexical`.
with `@_noEagerMove`.

Aggregates all of whose fields are `@_eagerMove` or trivial are inferred to be
`@_eagerMove`.
Expand Down Expand Up @@ -534,7 +534,7 @@ initializers from its superclass. This implies that all designated initializers
overridden. This attribute is often printed alongside
`@_hasMissingDesignatedInitializers` in this case.

## `@_lexical`
## `@_noEagerMove`

When applied to a value, indicates that the value's lifetime is lexical, that
releases of the value may not be hoisted over deinit barriers.
Expand All @@ -544,7 +544,7 @@ This is the default behavior, unless the value's type is annotated
annotation.

When applied to a type, indicates that all values which are instances of that
type are themselves `@_lexical` as above.
type are themselves `@_noEagerMove` as above.

This is the default behavior, unless the type annotated is an aggregate that
consists entirely of `@_eagerMove` or trivial values, in which case the
Expand Down
Loading