Skip to content

Commit c187c8a

Browse files
committed
SIL: Replace uses of getReferencedFunction() by getReferencedFunctionOrNull() and getInitialReferencedFunction()
With the advent of dynamic_function_ref the actual callee of such a ref my vary. Optimizations should not assume to know the content of a function referenced by dynamic_function_ref. Introduce getReferencedFunctionOrNull which will return null for such function refs. And getInitialReferencedFunction to return the referenced function. Use as appropriate. rdar://50959798
1 parent 036e74a commit c187c8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+223
-157
lines changed

include/swift/SIL/ApplySite.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,17 @@ class ApplySite {
143143

144144
/// Return the referenced function if the callee is a function_ref
145145
/// instruction.
146-
SILFunction *getReferencedFunction() const {
147-
FOREACH_IMPL_RETURN(getReferencedFunction());
146+
SILFunction *getReferencedFunctionOrNull() const {
147+
FOREACH_IMPL_RETURN(getReferencedFunctionOrNull());
148+
}
149+
150+
/// Return the referenced function if the callee is a function_ref like
151+
/// instruction.
152+
/// WARNING: This not necessarily the function that will be called at runtime.
153+
/// If the callee is a (prev_)dynamic_function_ref the actuall function called
154+
/// might be different.
155+
SILFunction *getInitiallyReferencedFunction() const {
156+
FOREACH_IMPL_RETURN(getInitiallyReferencedFunction());
148157
}
149158

150159
/// Should we optimize this call.

include/swift/SIL/PatternMatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ struct Callee_match<SILFunction &> {
518518
if (!AI)
519519
return false;
520520

521-
return AI->getReferencedFunction() == &Fun;
521+
return AI->getReferencedFunctionOrNull() == &Fun;
522522
}
523523
};
524524

include/swift/SIL/SILCloner.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ SILCloner<ImplClass>::visitEndApplyInst(EndApplyInst *Inst) {
950950
template<typename ImplClass>
951951
void
952952
SILCloner<ImplClass>::visitFunctionRefInst(FunctionRefInst *Inst) {
953-
SILFunction *OpFunction = getOpFunction(Inst->getReferencedFunction());
953+
SILFunction *OpFunction =
954+
getOpFunction(Inst->getInitiallyReferencedFunction());
954955
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
955956
recordClonedInstruction(Inst, getBuilder().createFunctionRef(
956957
getOpLocation(Inst->getLoc()), OpFunction));
@@ -959,7 +960,8 @@ SILCloner<ImplClass>::visitFunctionRefInst(FunctionRefInst *Inst) {
959960
template<typename ImplClass>
960961
void
961962
SILCloner<ImplClass>::visitDynamicFunctionRefInst(DynamicFunctionRefInst *Inst) {
962-
SILFunction *OpFunction = getOpFunction(Inst->getReferencedFunction());
963+
SILFunction *OpFunction =
964+
getOpFunction(Inst->getInitiallyReferencedFunction());
963965
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
964966
recordClonedInstruction(Inst, getBuilder().createDynamicFunctionRef(
965967
getOpLocation(Inst->getLoc()), OpFunction));
@@ -968,7 +970,8 @@ SILCloner<ImplClass>::visitDynamicFunctionRefInst(DynamicFunctionRefInst *Inst)
968970
template <typename ImplClass>
969971
void SILCloner<ImplClass>::visitPreviousDynamicFunctionRefInst(
970972
PreviousDynamicFunctionRefInst *Inst) {
971-
SILFunction *OpFunction = getOpFunction(Inst->getReferencedFunction());
973+
SILFunction *OpFunction =
974+
getOpFunction(Inst->getInitiallyReferencedFunction());
972975
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
973976
recordClonedInstruction(Inst, getBuilder().createPreviousDynamicFunctionRef(
974977
getOpLocation(Inst->getLoc()), OpFunction));

include/swift/SIL/SILInstruction.h

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,9 +1844,22 @@ class ApplyInstBase<Impl, Base, false> : public Base {
18441844
bool isCalleeDynamicallyReplaceable() const;
18451845

18461846
/// Gets the referenced function if the callee is a function_ref instruction.
1847-
SILFunction *getReferencedFunction() const {
1847+
/// Returns null if the callee is dynamic or a (prev_)dynamic_function_ref
1848+
/// instruction.
1849+
SILFunction *getReferencedFunctionOrNull() const {
18481850
if (auto *FRI = dyn_cast<FunctionRefBaseInst>(getCallee()))
1849-
return FRI->getReferencedFunction();
1851+
return FRI->getReferencedFunctionOrNull();
1852+
return nullptr;
1853+
}
1854+
1855+
/// Return the referenced function if the callee is a function_ref like
1856+
/// instruction.
1857+
/// WARNING: This not necessarily the function that will be called at runtime.
1858+
/// If this is a (prev_)dynamic_function_ref the actuall function called might
1859+
/// be different.
1860+
SILFunction *getInitiallyReferencedFunction() const {
1861+
if (auto *FRI = dyn_cast<FunctionRefBaseInst>(getCallee()))
1862+
return FRI->getInitiallyReferencedFunction();
18501863
return nullptr;
18511864
}
18521865

@@ -2294,8 +2307,23 @@ class FunctionRefBaseInst : public LiteralInst {
22942307
public:
22952308
~FunctionRefBaseInst();
22962309

2310+
/// Return the referenced function if this is a function_ref instruction and
2311+
/// therefore a client can rely on the dynamically called function being equal
2312+
/// to the returned value and null otherwise.
2313+
SILFunction *getReferencedFunctionOrNull() const {
2314+
auto kind = getKind();
2315+
if (kind == SILInstructionKind::FunctionRefInst)
2316+
return f;
2317+
assert(kind == SILInstructionKind::DynamicFunctionRefInst ||
2318+
kind == SILInstructionKind::PreviousDynamicFunctionRefInst);
2319+
return nullptr;
2320+
}
2321+
22972322
/// Return the referenced function.
2298-
SILFunction *getReferencedFunction() const { return f; }
2323+
/// WARNING: This not necessarily the function that will be called at runtime.
2324+
/// If this is a (prev_)dynamic_function_ref the actuall function called might
2325+
/// be different.
2326+
SILFunction *getInitiallyReferencedFunction() const { return f; }
22992327

23002328
void dropReferencedFunction();
23012329

@@ -7805,7 +7833,7 @@ SILFunction *ApplyInstBase<Impl, Base, false>::getCalleeFunction() const {
78057833
// previous_dynamic_function_ref as the target of those functions is not
78067834
// statically known.
78077835
if (auto *FRI = dyn_cast<FunctionRefInst>(Callee))
7808-
return FRI->getReferencedFunction();
7836+
return FRI->getReferencedFunctionOrNull();
78097837

78107838
if (auto *PAI = dyn_cast<PartialApplyInst>(Callee)) {
78117839
Callee = PAI->getCalleeOrigin();

include/swift/SIL/TypeSubstCloner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
6969

7070
if (!Cloner.Inlining) {
7171
FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(AI.getCallee());
72-
if (FRI && FRI->getReferencedFunction() == AI.getFunction() &&
72+
if (FRI && FRI->getInitiallyReferencedFunction() == AI.getFunction() &&
7373
Subs == Cloner.SubsMap) {
7474
// Handle recursions by replacing the apply to the callee with an
7575
// apply to the newly specialized function, but only if substitutions

lib/IRGen/AllocStackHoisting.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ bool indicatesDynamicAvailabilityCheckUse(SILInstruction *I) {
352352
return false;
353353
if (Apply->hasSemantics("availability.osversion"))
354354
return true;
355-
auto *FunRef = Apply->getReferencedFunction();
355+
auto *FunRef = Apply->getReferencedFunctionOrNull();
356356
if (!FunRef)
357357
return false;
358358
if (FunRef->getName().equals("_swift_stdlib_operatingSystemVersion"))

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1842,7 +1842,7 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) {
18421842
}
18431843

18441844
void IRGenSILFunction::visitFunctionRefBaseInst(FunctionRefBaseInst *i) {
1845-
auto fn = i->getReferencedFunction();
1845+
auto fn = i->getInitiallyReferencedFunction();
18461846

18471847
llvm::Constant *fnPtr = IGM.getAddrOfSILFunction(
18481848
fn, NotForDefinition, false /*isDynamicallyReplaceableImplementation*/,

lib/IRGen/LoadableByAddress.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2790,7 +2790,7 @@ void LoadableByAddress::run() {
27902790
for (SILBasicBlock &BB : CurrF) {
27912791
for (SILInstruction &I : BB) {
27922792
if (auto *FRI = dyn_cast<FunctionRefBaseInst>(&I)) {
2793-
SILFunction *RefF = FRI->getReferencedFunction();
2793+
SILFunction *RefF = FRI->getInitiallyReferencedFunction();
27942794
if (modFuncs.count(RefF) != 0) {
27952795
// Go over the uses and add them to lists to modify
27962796
//
@@ -2895,7 +2895,7 @@ void LoadableByAddress::run() {
28952895
// They just contain a pointer to the function
28962896
// The pointer does not change
28972897
for (auto *instr : funcRefs) {
2898-
SILFunction *F = instr->getReferencedFunction();
2898+
SILFunction *F = instr->getInitiallyReferencedFunction();
28992899
SILBuilderWithScope refBuilder(instr);
29002900
SingleValueInstruction *newInstr =
29012901
refBuilder.createFunctionRef(instr->getLoc(), F, instr->getKind());

lib/SIL/InstructionUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ SILValue swift::isPartialApplyOfReabstractionThunk(PartialApplyInst *PAI) {
358358
PAI->getNumArguments() != 2)
359359
return SILValue();
360360

361-
auto *Fun = PAI->getReferencedFunction();
361+
auto *Fun = PAI->getReferencedFunctionOrNull();
362362
if (!Fun)
363363
return SILValue();
364364

lib/SIL/Linker.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,17 +170,17 @@ void SILLinkerVisitor::visitPartialApplyInst(PartialApplyInst *PAI) {
170170
}
171171

172172
void SILLinkerVisitor::visitFunctionRefInst(FunctionRefInst *FRI) {
173-
maybeAddFunctionToWorklist(FRI->getReferencedFunction());
173+
maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction());
174174
}
175175

176176
void SILLinkerVisitor::visitDynamicFunctionRefInst(
177177
DynamicFunctionRefInst *FRI) {
178-
maybeAddFunctionToWorklist(FRI->getReferencedFunction());
178+
maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction());
179179
}
180180

181181
void SILLinkerVisitor::visitPreviousDynamicFunctionRefInst(
182182
PreviousDynamicFunctionRefInst *FRI) {
183-
maybeAddFunctionToWorklist(FRI->getReferencedFunction());
183+
maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction());
184184
}
185185

186186
// Eagerly visiting all used conformances leads to a large blowup

0 commit comments

Comments
 (0)