[embedded] Compile-time (literal) KeyPaths for Embedded Swift

Enable KeyPath/AnyKeyPath/PartialKeyPath/WritableKeyPath in Embedded Swift, but
for compile-time use only:

- Add keypath optimizations into the mandatory optimizations pipeline
- Allow keypath optimizations to look through begin_borrow, to make them work
  even in OSSA.
- If a use of a KeyPath doesn't optimize away, diagnose in PerformanceDiagnostics
- Make UnsafePointer.pointer(to:) transparent to allow the keypath optimization
  to happen in the callers of UnsafePointer.pointer(to:).
This commit is contained in:
Kuba Mracek
2024-03-20 15:35:43 -07:00
parent 4389ae2dc8
commit b642d771be
18 changed files with 272 additions and 119 deletions

View File

@@ -21,6 +21,7 @@ swift_compiler_sources(Optimizer
SimplifyDestructure.swift
SimplifyGlobalValue.swift
SimplifyInitEnumDataAddr.swift
SimplifyKeyPath.swift
SimplifyLoad.swift
SimplifyPartialApply.swift
SimplifyPointerToAddress.swift

View File

@@ -17,6 +17,10 @@ extension ApplyInst : OnoneSimplifyable {
if tryTransformThickToThinCallee(of: self, context) {
return
}
if context.tryOptimizeKeypath(apply: self) {
context.erase(instruction: self)
return
}
_ = context.tryDevirtualize(apply: self, isMandatory: false)
}
}

View File

@@ -0,0 +1,35 @@
//===--- SimplifyKeyPath.swift --------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SIL
extension KeyPathInst : OnoneSimplifyable {
func simplify(_ context: SimplifyContext) {
if allUsesRemovable(instruction: self) {
context.erase(instructionIncludingAllUsers: self)
}
}
}
fileprivate func allUsesRemovable(instruction: Instruction) -> Bool {
for result in instruction.results {
for use in result.uses {
if !(use.instruction is UpcastInst || use.instruction is DestroyValueInst || use.instruction is BeginBorrowInst || use.instruction is EndBorrowInst) {
return false
}
if !allUsesRemovable(instruction: use.instruction) {
return false
}
}
}
return true
}

View File

@@ -170,6 +170,10 @@ extension MutatingContext {
}
return nil
}
func tryOptimizeKeypath(apply: FullApplySite) -> Bool {
return _bridged.tryOptimizeKeypath(apply.bridged)
}
func inlineFunction(apply: FullApplySite, mandatoryInline: Bool) {
// This is only a best-effort attempt to notity the new cloned instructions as changed.