Skip to content

Commit 23fe168

Browse files
authored
Merge pull request #61886 from tshortli/silgen-has-symbol-forward-decls
SILGen: Forward declare SIL functions referenced by `#_hasSymbol` query helpers
2 parents 56665d5 + 38779f3 commit 23fe168

File tree

12 files changed

+214
-27
lines changed

12 files changed

+214
-27
lines changed

include/swift/IRGen/IRSymbolVisitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ class IRSymbolVisitor {
5858
const IRSymbolVisitorContext &ctx);
5959

6060
/// Override to prepare for enumeration of the symbols for a specific decl.
61-
virtual void willVisitDecl(Decl *D) {}
61+
/// Return \c true to proceed with visiting the decl or \c false to skip it.
62+
virtual bool willVisitDecl(Decl *D) { return true; }
6263

6364
/// Override to clean up after enumeration of the symbols for a specific decl.
6465
virtual void didVisitDecl(Decl *D) {}

include/swift/SIL/SILLinkage.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ enum class SILLinkage : uint8_t {
7474
///
7575
/// This linkage is used e.g. for thunks and for specialized functions.
7676
///
77-
/// Public functions must be definitions, i.e. must have a body, except the
77+
/// Shared functions must be definitions, i.e. must have a body, except the
7878
/// body is emitted by clang.
7979
Shared,
8080

include/swift/SIL/SILModule.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ class SILModule {
279279
llvm::DenseMap<const NominalTypeDecl *, SILMoveOnlyDeinit *>
280280
MoveOnlyDeinitMap;
281281

282-
/// The list of SILVTables in the module.
282+
/// The list of move only deinits in the module.
283283
std::vector<SILMoveOnlyDeinit *> moveOnlyDeinits;
284284

285285
/// Declarations which are externally visible.
@@ -315,6 +315,9 @@ class SILModule {
315315
/// This is the set of undef values we've created, for uniquing purposes.
316316
llvm::DenseMap<SILType, SILUndef *> UndefValues;
317317

318+
/// The list of decls that require query functions for #_hasSymbol conditions.
319+
llvm::SetVector<ValueDecl *> hasSymbolDecls;
320+
318321
llvm::DenseMap<std::pair<Decl *, VarDecl *>, unsigned> fieldIndices;
319322
llvm::DenseMap<EnumElementDecl *, unsigned> enumCaseIndices;
320323

@@ -700,6 +703,12 @@ class SILModule {
700703
return externallyVisible.count(decl) != 0;
701704
}
702705

706+
void addHasSymbolDecl(ValueDecl *decl) { hasSymbolDecls.insert(decl); }
707+
708+
ArrayRef<ValueDecl *> getHasSymbolDecls() {
709+
return hasSymbolDecls.getArrayRef();
710+
}
711+
703712
using sil_global_iterator = GlobalListType::iterator;
704713
using sil_global_const_iterator = GlobalListType::const_iterator;
705714
GlobalListType &getSILGlobalList() { return silGlobals; }

include/swift/SIL/SILSymbolVisitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ class SILSymbolVisitor {
7676
const SILSymbolVisitorContext &ctx);
7777

7878
/// Override to prepare for enumeration of the symbols for a specific decl.
79-
virtual void willVisitDecl(Decl *D) {}
79+
/// Return \c true to proceed with visiting the decl or \c false to skip it.
80+
virtual bool willVisitDecl(Decl *D) { return true; }
8081

8182
/// Override to clean up after enumeration of the symbols for a specific decl.
8283
virtual void didVisitDecl(Decl *D) {}

lib/IRGen/IRGenModule.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,6 @@ static llvm::StructType *createStructType(IRGenModule &IGM,
8585
name, packed);
8686
}
8787

88-
/// A helper for creating pointer-to-struct types.
89-
static llvm::PointerType *createStructPointerType(IRGenModule &IGM,
90-
StringRef name,
91-
std::initializer_list<llvm::Type*> types) {
92-
return createStructType(IGM, name, types)->getPointerTo(DefaultAS);
93-
}
94-
9588
static clang::CodeGenerator *createClangCodeGenerator(ASTContext &Context,
9689
llvm::LLVMContext &LLVMContext,
9790
const IRGenOptions &Opts,

lib/IRGen/IRSymbolVisitor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ class IRSymbolVisitorImpl : public SILSymbolVisitor {
7272
: Visitor{Visitor}, Ctx{Ctx},
7373
PublicSymbolsOnly{Ctx.getSILCtx().getOpts().PublicSymbolsOnly} {}
7474

75-
void willVisitDecl(Decl *D) override {
76-
Visitor.willVisitDecl(D);
75+
bool willVisitDecl(Decl *D) override {
76+
return Visitor.willVisitDecl(D);
7777
}
7878

7979
void didVisitDecl(Decl *D) override {

lib/IRGen/TBDGen.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,15 @@ void TBDGenVisitor::addSymbol(StringRef name, SymbolSource source,
400400
}
401401
}
402402

403-
void TBDGenVisitor::willVisitDecl(Decl *D) {
403+
bool TBDGenVisitor::willVisitDecl(Decl *D) {
404+
// A @_silgen_name("...") function without a body only exists to
405+
// forward-declare a symbol from another library.
406+
if (auto AFD = dyn_cast<AbstractFunctionDecl>(D))
407+
if (!AFD->hasBody() && AFD->getAttrs().hasAttribute<SILGenNameAttr>())
408+
return false;
409+
404410
DeclStack.push_back(D);
411+
return true;
405412
}
406413

407414
void TBDGenVisitor::didVisitDecl(Decl *D) {

lib/IRGen/TBDGenVisitor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class TBDGenVisitor : public IRSymbolVisitor {
139139

140140
// --- IRSymbolVisitor ---
141141

142-
void willVisitDecl(Decl *D) override;
142+
bool willVisitDecl(Decl *D) override;
143143
void didVisitDecl(Decl *D) override;
144144

145145
void addFunction(SILDeclRef declRef) override;

lib/SIL/IR/SILSymbolVisitor.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,8 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
362362
: Visitor{Visitor}, Ctx{Ctx} {}
363363

364364
void visit(Decl *D) {
365-
Visitor.willVisitDecl(D);
365+
if (!Visitor.willVisitDecl(D))
366+
return;
366367
ASTVisitor::visit(D);
367368
Visitor.didVisitDecl(D);
368369
}
@@ -408,12 +409,6 @@ class SILSymbolVisitorImpl : public ASTVisitor<SILSymbolVisitorImpl> {
408409
}
409410

410411
void visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
411-
// A @_silgen_name("...") function without a body only exists to
412-
// forward-declare a symbol from another library.
413-
if (!AFD->hasBody() && AFD->getAttrs().hasAttribute<SILGenNameAttr>()) {
414-
return;
415-
}
416-
417412
// Add exported prespecialized symbols.
418413
for (auto *attr : AFD->getAttrs().getAttributes<SpecializeAttr>()) {
419414
if (!attr->isExported())

lib/SILGen/SILGenDecl.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/SIL/SILArgument.h"
3131
#include "swift/SIL/SILDebuggerClient.h"
3232
#include "swift/SIL/SILInstruction.h"
33+
#include "swift/SIL/SILSymbolVisitor.h"
3334
#include "swift/SIL/SILType.h"
3435
#include "swift/SIL/TypeLowering.h"
3536
#include "llvm/ADT/SmallString.h"
@@ -1601,21 +1602,57 @@ void SILGenFunction::emitStmtCondition(StmtCondition Cond, JumpDest FalseDest,
16011602

16021603
case StmtConditionElement::CK_HasSymbol: {
16031604
auto info = elt.getHasSymbolInfo();
1604-
assert(!info->isInvalid());
1605+
if (info->isInvalid()) {
1606+
// This condition may have referenced a decl that isn't valid in some
1607+
// way but for developer convenience wasn't treated as an error. Just
1608+
// emit a 'true' condition value.
1609+
SILType i1 = SILType::getBuiltinIntegerType(1, getASTContext());
1610+
booleanTestValue = B.createIntegerLiteral(loc, i1, 1);
1611+
break;
1612+
}
1613+
16051614
auto expr = info->getSymbolExpr();
16061615
auto declRef = info->getReferencedDecl();
16071616
assert(declRef);
16081617

1609-
auto queryFunc = declRef.getDecl()->getHasSymbolQueryDecl();
1618+
auto decl = declRef.getDecl();
1619+
getModule().addHasSymbolDecl(decl);
1620+
16101621
SILFunction *silFn = SGM.getFunction(
1611-
SILDeclRef(queryFunc, SILDeclRef::Kind::Func), NotForDefinition);
1622+
SILDeclRef(decl->getHasSymbolQueryDecl(), SILDeclRef::Kind::Func),
1623+
NotForDefinition);
16121624
SILValue fnRef = B.createFunctionRefFor(loc, silFn);
16131625
booleanTestValue = B.createApply(loc, fnRef, {}, {});
16141626
booleanTestValue = emitUnwrapIntegerResult(expr, booleanTestValue);
16151627
booleanTestLoc = expr;
16161628

1617-
// FIXME: Add decl to list of decls that need a has symbol query
1618-
// function to be emitted during IRGen.
1629+
// Ensure that function declarations for each function associated with
1630+
// the decl are emitted so that they can be referenced during IRGen.
1631+
class SymbolVisitor : public SILSymbolVisitor {
1632+
SILGenModule &SGM;
1633+
1634+
public:
1635+
SymbolVisitor(SILGenModule &SGM) : SGM{SGM} {};
1636+
1637+
void addFunction(SILDeclRef declRef) override {
1638+
(void)SGM.getFunction(declRef, NotForDefinition);
1639+
}
1640+
1641+
virtual void addFunction(StringRef name, SILDeclRef declRef) override {
1642+
// The kinds of functions which go through this callback (e.g.
1643+
// differentiability witnesses) can't be forward declared with a
1644+
// SILDeclRef alone. For now, just ignore them.
1645+
//
1646+
// Ideally, this callback will be removed entirely in favor of
1647+
// SILDeclRef being able to represent all function variants.
1648+
}
1649+
};
1650+
1651+
SILSymbolVisitorOptions opts;
1652+
opts.VisitMembers = false;
1653+
auto visitorCtx =
1654+
SILSymbolVisitorContext(getModule().getSwiftModule(), opts);
1655+
SymbolVisitor(SGM).visitDecl(decl, visitorCtx);
16191656
break;
16201657
}
16211658
}

0 commit comments

Comments
 (0)