Merge pull request #4480 from eeckstein/partial-apply-opt2
address gottesmm's and jrose-apple's comments on the partial_apply optimization
diff --git a/include/swift/SILOptimizer/Analysis/CallerAnalysis.h b/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
index 309997f..770d55c 100644
--- a/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/CallerAnalysis.h
@@ -53,6 +53,7 @@
llvm::SmallSet<SILFunction *, 4> Callers;
/// The number of partial applied arguments of this function.
+ ///
/// Specifically, it stores the minimum number of partial applied arguments
/// of each function which contain one or multiple partial_applys of this
/// function.
@@ -67,6 +68,7 @@
}
/// Returns non zero if this function is partially applied anywhere.
+ ///
/// The return value is the minimum number of partially applied arguments.
/// Usually all partial applies of a function partially apply the same
/// number of arguments anyway.
diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp
index a60a00b..6bee0b0 100644
--- a/lib/SILOptimizer/IPO/CapturePropagation.cpp
+++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp
@@ -286,7 +286,7 @@
/// Returns true if block \p BB only contains a return or throw of the first
/// block argument and side-effect-free instructions.
-static bool isArgReturnOrThrow(SILBasicBlock *BB) {
+static bool onlyContainsReturnOrThrowOfArg(SILBasicBlock *BB) {
for (SILInstruction &I : *BB) {
if (isa<ReturnInst>(&I) || isa<ThrowInst>(&I)) {
SILValue RetVal = I.getOperand(0);
@@ -349,8 +349,8 @@
if (TryApplyInst *TAI = dyn_cast<TryApplyInst>(&I)) {
// Check the normal and throw blocks of the try_apply.
- if (isArgReturnOrThrow(TAI->getNormalBB()) &&
- isArgReturnOrThrow(TAI->getErrorBB()))
+ if (onlyContainsReturnOrThrowOfArg(TAI->getNormalBB()) &&
+ onlyContainsReturnOrThrowOfArg(TAI->getErrorBB()))
return Specialized;
return nullptr;
}
diff --git a/test/SILOptimizer/functionsigopts.sil b/test/SILOptimizer/functionsigopts.sil
index 2754a1a..37072ea 100644
--- a/test/SILOptimizer/functionsigopts.sil
+++ b/test/SILOptimizer/functionsigopts.sil
@@ -1326,6 +1326,27 @@
}
+// Check if externally available functions are optimized.
+
+sil public_external [noinline] @externally_available_with_dead_arg : $@convention(thin) (@guaranteed foo) -> () {
+bb0(%0 : $foo):
+ %r = tuple()
+ return %r : $()
+}
+
+// CHECK-LABEL: sil @call_externally_available
+// CHECK: [[F:%[0-9]+]] = function_ref @_TTSf4d__externally_available_with_dead_arg : $@convention(thin) () -> ()
+// CHECK: apply [[F]]()
+// CHECK: return
+sil @call_externally_available : $@convention(thin) (@guaranteed foo) -> () {
+bb0(%0 : $foo):
+ %f = function_ref @externally_available_with_dead_arg : $@convention(thin) (@guaranteed foo) -> ()
+ %a = apply %f(%0) : $@convention(thin) (@guaranteed foo) -> ()
+ %r = tuple()
+ return %r : $()
+}
+
+
// We should remove the array semantic from specialized calls.
// CHECK-LABEL: sil [fragile] [thunk] [always_inline] [_semantics "array.foobar"] @array_semantic : $@convention(method) (@owned Builtin.NativeObject) -> () {