@@ -1213,9 +1213,51 @@ static void rewriteApplySites(AllocBoxToStackState &pass) {
12131213 auto *FRI = cast<FunctionRefInst>(Apply.getCallee ());
12141214 Apply.getInstruction ()->eraseFromParent ();
12151215
1216- // TODO: Erase from module if there are no more uses.
1217- if ( FRI->use_empty ())
1216+ if (FRI-> use_empty ()) {
1217+ auto referencedFn = FRI->getReferencedFunction ();
12181218 FRI->eraseFromParent ();
1219+
1220+ // TODO: Erase from module if there are no more uses.
1221+ // If the function has no remaining references, it should eventually
1222+ // be deleted. We can't do that from a function pass, since the function
1223+ // is still queued up for other passes to run after this one, but we
1224+ // can at least gut the implementation, since subsequent passes that
1225+ // rely on stack promotion to occur (particularly closure lifetime
1226+ // fixup and move-only checking) may not be able to proceed in a
1227+ // sensible way on the now non-canonical original implementation.
1228+ if (referencedFn->getRefCount () == 0
1229+ && !isPossiblyUsedExternally (referencedFn->getLinkage (),
1230+ referencedFn->getModule ().isWholeModule ())) {
1231+ LLVM_DEBUG (llvm::dbgs () << " *** Deleting original function " << referencedFn->getName () << " 's body since it is unused" );
1232+ // Remove all non-entry blocks.
1233+ auto entryBB = referencedFn->begin ();
1234+ auto nextBB = std::next (entryBB);
1235+
1236+ while (nextBB != referencedFn->end ()) {
1237+ auto thisBB = nextBB;
1238+ ++nextBB;
1239+ thisBB->eraseFromParent ();
1240+ }
1241+
1242+ // Rewrite the entry block to only contain an unreachable.
1243+ auto loc = entryBB->begin ()->getLoc ();
1244+ entryBB->eraseAllInstructions (referencedFn->getModule ());
1245+ {
1246+ SILBuilder b (&*entryBB);
1247+ b.createUnreachable (loc);
1248+ }
1249+
1250+ // Refresh the CFG in case we removed any function calls.
1251+ pass.CFGChanged = true ;
1252+
1253+ // If the function has shared linkage, reduce this version to private
1254+ // linkage, because we don't want the deleted-body form to win in any
1255+ // ODR shootouts.
1256+ if (referencedFn->getLinkage () == SILLinkage::Shared) {
1257+ referencedFn->setLinkage (SILLinkage::Private);
1258+ }
1259+ }
1260+ }
12191261 }
12201262}
12211263
0 commit comments