mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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:
@@ -263,8 +263,8 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
|
||||
/// %addr = struct_element_addr/ref_element_addr %root_object
|
||||
/// ...
|
||||
/// load/store %addr
|
||||
bool SILCombiner::tryOptimizeKeypathApplication(ApplyInst *AI,
|
||||
SILFunction *callee) {
|
||||
bool swift::tryOptimizeKeypathApplication(ApplyInst *AI,
|
||||
SILFunction *callee, SILBuilder Builder) {
|
||||
if (AI->getNumArguments() != 3)
|
||||
return false;
|
||||
|
||||
@@ -303,7 +303,6 @@ bool SILCombiner::tryOptimizeKeypathApplication(ApplyInst *AI,
|
||||
}
|
||||
});
|
||||
|
||||
eraseInstFromFunction(*AI);
|
||||
++NumOptimizedKeypaths;
|
||||
return true;
|
||||
}
|
||||
@@ -329,9 +328,9 @@ bool SILCombiner::tryOptimizeKeypathApplication(ApplyInst *AI,
|
||||
/// %offset_builtin_int = unchecked_trivial_bit_cast %offset_ptr
|
||||
/// %offset_int = struct $Int (%offset_builtin_int)
|
||||
/// %offset = enum $Optional<Int>, #Optional.some!enumelt, %offset_int
|
||||
bool SILCombiner::tryOptimizeKeypathOffsetOf(ApplyInst *AI,
|
||||
bool swift::tryOptimizeKeypathOffsetOf(ApplyInst *AI,
|
||||
FuncDecl *calleeFn,
|
||||
KeyPathInst *kp) {
|
||||
KeyPathInst *kp, SILBuilder Builder) {
|
||||
auto *accessor = dyn_cast<AccessorDecl>(calleeFn);
|
||||
if (!accessor || !accessor->isGetter())
|
||||
return false;
|
||||
@@ -432,7 +431,6 @@ bool SILCombiner::tryOptimizeKeypathOffsetOf(ApplyInst *AI,
|
||||
result = Builder.createOptionalNone(loc, AI->getType());
|
||||
}
|
||||
AI->replaceAllUsesWith(result);
|
||||
eraseInstFromFunction(*AI);
|
||||
++NumOptimizedKeypaths;
|
||||
return true;
|
||||
}
|
||||
@@ -444,9 +442,9 @@ bool SILCombiner::tryOptimizeKeypathOffsetOf(ApplyInst *AI,
|
||||
/// %string = apply %keypath_kvcString_method(%kp)
|
||||
/// With:
|
||||
/// %string = string_literal "blah"
|
||||
bool SILCombiner::tryOptimizeKeypathKVCString(ApplyInst *AI,
|
||||
bool swift::tryOptimizeKeypathKVCString(ApplyInst *AI,
|
||||
FuncDecl *calleeFn,
|
||||
KeyPathInst *kp) {
|
||||
KeyPathInst *kp, SILBuilder Builder) {
|
||||
if (!calleeFn->getAttrs()
|
||||
.hasSemanticsAttr(semantics::KEYPATH_KVC_KEY_PATH_STRING))
|
||||
return false;
|
||||
@@ -499,14 +497,13 @@ bool SILCombiner::tryOptimizeKeypathKVCString(ApplyInst *AI,
|
||||
}
|
||||
|
||||
AI->replaceAllUsesWith(literalValue);
|
||||
eraseInstFromFunction(*AI);
|
||||
++NumOptimizedKeypaths;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SILCombiner::tryOptimizeKeypath(ApplyInst *AI) {
|
||||
bool swift::tryOptimizeKeypath(ApplyInst *AI, SILBuilder Builder) {
|
||||
if (SILFunction *callee = AI->getReferencedFunctionOrNull()) {
|
||||
return tryOptimizeKeypathApplication(AI, callee);
|
||||
return tryOptimizeKeypathApplication(AI, callee, Builder);
|
||||
}
|
||||
|
||||
// Try optimize keypath method calls.
|
||||
@@ -530,10 +527,10 @@ bool SILCombiner::tryOptimizeKeypath(ApplyInst *AI) {
|
||||
if (!kp || !kp->hasPattern())
|
||||
return false;
|
||||
|
||||
if (tryOptimizeKeypathOffsetOf(AI, calleeFn, kp))
|
||||
if (tryOptimizeKeypathOffsetOf(AI, calleeFn, kp, Builder))
|
||||
return true;
|
||||
|
||||
if (tryOptimizeKeypathKVCString(AI, calleeFn, kp))
|
||||
if (tryOptimizeKeypathKVCString(AI, calleeFn, kp, Builder))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1465,8 +1462,10 @@ SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
|
||||
if (auto *CFI = dyn_cast<ConvertFunctionInst>(callee))
|
||||
return optimizeApplyOfConvertFunctionInst(AI, CFI);
|
||||
|
||||
if (tryOptimizeKeypath(AI))
|
||||
if (tryOptimizeKeypath(AI, Builder)) {
|
||||
eraseInstFromFunction(*AI);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Optimize readonly functions with no meaningful users.
|
||||
SILFunction *SF = AI->getReferencedFunctionOrNull();
|
||||
|
||||
Reference in New Issue
Block a user