Skip to content

Commit f9a25ba

Browse files
Merge pull request swiftlang#35516 from aschwaighofer/constant_fold_availability
Constant fold known availability checks
2 parents 13ffb8b + 30ac6e6 commit f9a25ba

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,38 @@ static bool isApplyOfBuiltin(SILInstruction &I, BuiltinValueKind kind) {
14961496
return false;
14971497
}
14981498

1499+
static bool isApplyOfKnownAvailability(SILInstruction &I) {
1500+
auto apply = FullApplySite::isa(&I);
1501+
if (!apply)
1502+
return false;
1503+
auto callee = apply.getReferencedFunctionOrNull();
1504+
if (!callee)
1505+
return false;
1506+
if (!callee->hasSemanticsAttr("availability.osversion"))
1507+
return false;
1508+
auto &context = I.getFunction()->getASTContext();
1509+
auto deploymentAvailability =
1510+
AvailabilityContext::forDeploymentTarget(context);
1511+
if (apply.getNumArguments() != 3)
1512+
return false;
1513+
auto arg0 = dyn_cast<IntegerLiteralInst>(apply.getArgument(0));
1514+
if (!arg0)
1515+
return false;
1516+
auto arg1 = dyn_cast<IntegerLiteralInst>(apply.getArgument(1));
1517+
if (!arg1)
1518+
return false;
1519+
auto arg2 = dyn_cast<IntegerLiteralInst>(apply.getArgument(2));
1520+
if (!arg2)
1521+
return false;
1522+
1523+
auto version = VersionRange::allGTE(llvm::VersionTuple(
1524+
arg0->getValue().getLimitedValue(), arg1->getValue().getLimitedValue(),
1525+
arg2->getValue().getLimitedValue()));
1526+
1527+
auto callAvailability = AvailabilityContext(version);
1528+
return deploymentAvailability.isContainedIn(callAvailability);
1529+
}
1530+
14991531
static bool isApplyOfStringConcat(SILInstruction &I) {
15001532
if (auto *AI = dyn_cast<ApplyInst>(&I))
15011533
if (auto *Fn = AI->getReferencedFunctionOrNull())
@@ -1590,6 +1622,11 @@ void ConstantFolder::initializeWorklist(SILFunction &f) {
15901622
continue;
15911623
}
15921624

1625+
if (isApplyOfKnownAvailability(*inst)) {
1626+
WorkList.insert(inst);
1627+
continue;
1628+
}
1629+
15931630
if (isa<CheckedCastBranchInst>(inst) ||
15941631
isa<CheckedCastAddrBranchInst>(inst) ||
15951632
isa<UnconditionalCheckedCastInst>(inst) ||
@@ -1731,6 +1768,19 @@ ConstantFolder::processWorkList() {
17311768
continue;
17321769
}
17331770
}
1771+
// Replace a known availability.version semantic call.
1772+
if (isApplyOfKnownAvailability(*I)) {
1773+
if (auto apply = dyn_cast<ApplyInst>(I)) {
1774+
SILBuilderWithScope B(I);
1775+
auto tru = B.createIntegerLiteral(apply->getLoc(), apply->getType(), 1);
1776+
apply->replaceAllUsesWith(tru);
1777+
eliminateDeadInstruction(
1778+
I, [&](SILInstruction *DeadI) { WorkList.remove(DeadI); });
1779+
WorkList.insert(tru);
1780+
InvalidateInstructions = true;
1781+
}
1782+
continue;
1783+
}
17341784

17351785
// If we have a cast instruction, try to optimize it.
17361786
if (isa<CheckedCastBranchInst>(I) || isa<CheckedCastAddrBranchInst>(I) ||
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %target-swift-frontend -target x86_64-apple-macos10.15 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_15 %s
2+
// RUN: %target-swift-frontend -target x86_64-apple-macos10.14 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_14 %s
3+
// RUN: %target-swift-frontend -O -target x86_64-apple-macos10.15 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_15 %s
4+
// RUN: %target-swift-frontend -O -target x86_64-apple-macos10.14 -emit-sil %s | %FileCheck --check-prefix=CHECK-macosx10_14 %s
5+
6+
// REQUIRES: OS=macosx
7+
8+
@available(macOS 10.15, *)
9+
@inline(never)
10+
public func newFunction() -> Int {
11+
return 0
12+
}
13+
14+
@inline(never)
15+
public func oldFunction() -> Int {
16+
return 1
17+
}
18+
19+
public func testAvailabilityPropagation() -> Int {
20+
if #available(macOS 10.15, *) {
21+
return newFunction()
22+
} else {
23+
return oldFunction()
24+
}
25+
}
26+
27+
// CHECK-macosx10_15-LABEL: sil @$s33constant_propagation_availability27testAvailabilityPropagationSiyF : $@convention(thin) () -> Int {
28+
// CHECK-macosx10_15-NOT: apply
29+
// CHECK-macosx10_15: [[F:%.*]] = function_ref @$s33constant_propagation_availability11newFunctionSiyF
30+
// CHECK-macosx10_15: apply [[F]]() : $@convention(thin) () -> Int
31+
// CHECK-macosx10_15-NOT: apply
32+
// CHECK-macosx10_15: } // end sil function '$s33constant_propagation_availability27testAvailabilityPropagationSiyF'
33+
34+
// CHECK-macosx10_14-LABEL: sil @$s33constant_propagation_availability27testAvailabilityPropagationSiyF : $@convention(thin) () -> Int {
35+
// CHECK-macosx10_14: [[F:%.*]] = function_ref @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF
36+
// CHECK-macosx10_14: apply [[F]]
37+
// CHECK-macosx10_14: [[F:%.*]] = function_ref @$s33constant_propagation_availability11newFunctionSiyF
38+
// CHECK-macosx10_14: apply [[F]]() : $@convention(thin) () -> Int
39+
// CHECK-macosx10_14: [[F:%.*]] = function_ref @$s33constant_propagation_availability11oldFunctionSiyF
40+
// CHECK-macosx10_14: apply [[F]]
41+
// CHECK-macosx10_14: } // end sil function '$s33constant_propagation_availability27testAvailabilityPropagationSiyF'
42+
43+
// CHECK-macosx10_14: sil [readnone] [_semantics "availability.osversion"] @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF

0 commit comments

Comments
 (0)