Skip to content

Commit 4c33e75

Browse files
authored
Merge pull request #84939 from DougGregor/sil-asmname-and-section
[SIL] Add asmname attribute to SIL functions and global variables
2 parents 2fceb9a + 081b5cd commit 4c33e75

File tree

19 files changed

+265
-36
lines changed

19 files changed

+265
-36
lines changed

docs/SIL/FunctionAttributes.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,11 @@ Specifies that the optimizer and IRGen must not add runtime calls which
228228
are not in the function originally. This attribute is set for functions
229229
with performance constraints or functions which are called from
230230
functions with performance constraints.
231+
232+
### Naming
233+
234+
```
235+
sil-function-attribute :: '[' asmname "' identifier '" ']'
236+
```
237+
238+
Specifies that the SIL function should be lowered to LLVM IR with the given function name.

include/swift/SIL/SILFunction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,11 @@ class SILFunction
320320
/// The function's remaining set of specialize attributes.
321321
std::vector<SILSpecializeAttr*> SpecializeAttrSet;
322322

323+
/// The name that this function should have when it is lowered to LLVM IR.
324+
///
325+
/// If empty, use the SIL function's name directly.
326+
StringRef AsmName;
327+
323328
/// Name of a section if @_section attribute was used, otherwise empty.
324329
StringRef Section;
325330

@@ -1423,6 +1428,10 @@ class SILFunction
14231428
bool markedAsUsed() const { return MarkedAsUsed; }
14241429
void setMarkedAsUsed(bool value) { MarkedAsUsed = value; }
14251430

1431+
/// Return custom assembler name, otherwise empty.
1432+
StringRef asmName() const { return AsmName; }
1433+
void setAsmName(StringRef value) { AsmName = value; }
1434+
14261435
/// Return custom section name if @_section was used, otherwise empty
14271436
StringRef section() const { return Section; }
14281437
void setSection(StringRef value) { Section = value; }

include/swift/SIL/SILGlobalVariable.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ class SILGlobalVariable
6060
/// binary. A pointer into the module's lookup table.
6161
StringRef Name;
6262

63+
/// The name that this variable should have when lowered to LLVM IR. If empty,
64+
/// the mangled name of the variable will be used instead.
65+
StringRef AsmName;
66+
67+
/// Name of a section if @_section attribute was used, otherwise empty.
68+
StringRef Section;
69+
6370
/// The lowered type of the variable.
6471
SILType LoweredType;
6572

@@ -150,7 +157,15 @@ class SILGlobalVariable
150157
}
151158

152159
StringRef getName() const { return Name; }
153-
160+
161+
/// Return custom assembler name, otherwise empty.
162+
StringRef asmName() const { return AsmName; }
163+
void setAsmName(StringRef value) { AsmName = value; }
164+
165+
/// Return custom section name if @_section was used, otherwise empty
166+
StringRef section() const { return Section; }
167+
void setSection(StringRef value) { Section = value; }
168+
154169
void setDeclaration(bool isD) { IsDeclaration = isD; }
155170

156171
/// True if this is a definition of the variable.
@@ -232,15 +247,6 @@ class SILGlobalVariable
232247

233248
void setMarkedAsUsed(bool used) { IsUsed = used; }
234249

235-
/// Returns a SectionAttr if this global variable has `@_section` attribute.
236-
SectionAttr *getSectionAttr() const {
237-
auto *V = getDecl();
238-
if (!V)
239-
return nullptr;
240-
241-
return V->getAttrs().getAttribute<SectionAttr>();
242-
}
243-
244250
/// Return whether this variable corresponds to a Clang node.
245251
bool hasClangNode() const;
246252

lib/IRGen/GenDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2865,8 +2865,8 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
28652865
addUsedGlobal(gvar);
28662866
else if (var->shouldBePreservedForDebugger() && forDefinition)
28672867
addUsedGlobal(gvar);
2868-
if (auto *sectionAttr = var->getSectionAttr())
2869-
gvar->setSection(sectionAttr->Name);
2868+
if (!var->section().empty())
2869+
gvar->setSection(var->section());
28702870
}
28712871
if (forDefinition && !gvar->hasInitializer()) {
28722872
if (initVal) {

lib/IRGen/Linking.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,10 @@ std::string LinkEntity::mangleAsString(ASTContext &Ctx) const {
408408
}
409409

410410
case Kind::SILFunction: {
411+
auto asmName = getSILFunction()->asmName();
412+
if (!asmName.empty())
413+
return asmName.str();
414+
411415
std::string Result(getSILFunction()->getName());
412416
if (isDynamicallyReplaceable()) {
413417
Result.append("TI");
@@ -465,8 +469,13 @@ std::string LinkEntity::mangleAsString(ASTContext &Ctx) const {
465469
return Result;
466470
}
467471

468-
case Kind::SILGlobalVariable:
472+
case Kind::SILGlobalVariable: {
473+
auto asmName = getSILGlobalVariable()->asmName();
474+
if (!asmName.empty())
475+
return asmName.str();
476+
469477
return getSILGlobalVariable()->getName().str();
478+
}
470479

471480
case Kind::ReadOnlyGlobalObject:
472481
return getSILGlobalVariable()->getName().str() + "r";

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ bool SILGlobalVariable::isPossiblyUsedExternally() const {
9191
if (markedAsUsed())
9292
return true;
9393

94-
if (getSectionAttr())
94+
if (!section().empty())
9595
return true;
9696

9797
SILLinkage linkage = getLinkage();
@@ -151,7 +151,7 @@ SILInstruction *SILGlobalVariable::getStaticInitializerValue() {
151151
}
152152

153153
bool SILGlobalVariable::mustBeInitializedStatically() const {
154-
if (getSectionAttr())
154+
if (!section().empty())
155155
return true;
156156

157157
auto *decl = getDecl();

lib/SIL/IR/SILPrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3709,6 +3709,9 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
37093709
if (!section().empty())
37103710
OS << "[section \"" << section() << "\"] ";
37113711

3712+
if (!asmName().empty())
3713+
OS << "[asmname \"" << asmName() << "\"] ";
3714+
37123715
// TODO: Handle clang node owners which don't have a name.
37133716
if (hasClangNode() && getClangNodeOwner()->hasName()) {
37143717
OS << "[clang ";
@@ -3777,6 +3780,12 @@ void SILGlobalVariable::print(llvm::raw_ostream &OS, bool Verbose) const {
37773780
if (markedAsUsed())
37783781
OS << "[used] ";
37793782

3783+
if (!asmName().empty())
3784+
OS << "[asmname \"" << asmName() << "\"] ";
3785+
3786+
if (!section().empty())
3787+
OS << "[section \"" << section() << "\"] ";
3788+
37803789
printName(OS);
37813790
OS << " : " << LoweredType;
37823791

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,8 @@ static bool parseDeclSILOptional(
679679
SILFunction **usedAdHocRequirementWitness, Identifier *objCReplacementFor,
680680
SILFunction::Purpose *specialPurpose, Inline_t *inlineStrategy,
681681
OptimizationMode *optimizationMode, PerformanceConstraints *perfConstraints,
682-
bool *isPerformanceConstraint, bool *markedAsUsed, StringRef *section,
682+
bool *isPerformanceConstraint, bool *markedAsUsed, StringRef *asmName,
683+
StringRef *section,
683684
bool *isLet, bool *isWeakImported, bool *needStackProtection,
684685
bool *isSpecialized, AvailabilityRange *availability,
685686
bool *isWithoutActuallyEscapingThunk,
@@ -807,6 +808,20 @@ static bool parseDeclSILOptional(
807808
}
808809
*actorIsolation = *optIsolation;
809810
SP.P.consumeToken(tok::string_literal);
811+
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
812+
continue;
813+
} else if (asmName && SP.P.Tok.getText() == "asmname") {
814+
SP.P.consumeToken(tok::identifier);
815+
if (SP.P.Tok.getKind() != tok::string_literal) {
816+
SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
817+
return true;
818+
}
819+
820+
// Drop the double quotes.
821+
StringRef rawString = SP.P.Tok.getText().drop_front().drop_back();
822+
*asmName = SP.P.Context.getIdentifier(rawString).str();
823+
SP.P.consumeToken(tok::string_literal);
824+
810825
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
811826
continue;
812827
} else if (section && SP.P.Tok.getText() == "section") {
@@ -7288,6 +7303,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
72887303
PerformanceConstraints perfConstr = PerformanceConstraints::None;
72897304
bool isPerformanceConstraint = false;
72907305
bool markedAsUsed = false;
7306+
StringRef asmName;
72917307
StringRef section;
72927308
SmallVector<std::string, 1> Semantics;
72937309
SmallVector<ParsedSpecAttr, 4> SpecAttrs;
@@ -7306,7 +7322,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
73067322
&DynamicallyReplacedFunction, &AdHocWitnessFunction,
73077323
&objCReplacementFor, &specialPurpose, &inlineStrategy,
73087324
&optimizationMode, &perfConstr, &isPerformanceConstraint,
7309-
&markedAsUsed, &section, nullptr, &isWeakImported,
7325+
&markedAsUsed, &asmName, &section, nullptr, &isWeakImported,
73107326
&needStackProtection, nullptr, &availability,
73117327
&isWithoutActuallyEscapingThunk, &Semantics, &SpecAttrs, &ClangDecl,
73127328
&MRK, &actorIsolation, FunctionState, M) ||
@@ -7363,6 +7379,9 @@ bool SILParserState::parseDeclSIL(Parser &P) {
73637379
FunctionState.F->setPerfConstraints(perfConstr);
73647380
FunctionState.F->setIsPerformanceConstraint(isPerformanceConstraint);
73657381
FunctionState.F->setEffectsKind(MRK);
7382+
FunctionState.F->setMarkedAsUsed(markedAsUsed);
7383+
FunctionState.F->setAsmName(asmName);
7384+
FunctionState.F->setSection(section);
73667385

73677386
if (ClangDecl)
73687387
FunctionState.F->setClangNodeOwner(ClangDecl);
@@ -7557,17 +7576,19 @@ bool SILParserState::parseSILGlobal(Parser &P) {
75577576
SourceLoc NameLoc;
75587577
SerializedKind_t isSerialized = IsNotSerialized;
75597578
bool isMarkedAsUsed = false;
7579+
StringRef asmName;
7580+
StringRef section;
75607581
bool isLet = false;
75617582

75627583
SILParser State(P);
75637584
if (parseSILLinkage(GlobalLinkage, P) ||
75647585
parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
75657586
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
75667587
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7567-
nullptr, nullptr, nullptr, &isMarkedAsUsed, nullptr,
7568-
&isLet, nullptr, nullptr, nullptr, nullptr, nullptr,
7569-
nullptr, nullptr, nullptr, nullptr, nullptr, State,
7570-
M) ||
7588+
nullptr, nullptr, nullptr, &isMarkedAsUsed, &asmName,
7589+
&section, &isLet, nullptr, nullptr, nullptr, nullptr,
7590+
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7591+
State, M) ||
75717592
P.parseToken(tok::at_sign, diag::expected_sil_value_name) ||
75727593
P.parseIdentifier(GlobalName, NameLoc, /*diagnoseDollarPrefix=*/false,
75737594
diag::expected_sil_value_name) ||
@@ -7594,6 +7615,9 @@ bool SILParserState::parseSILGlobal(Parser &P) {
75947615

75957616
GV->setLet(isLet);
75967617
GV->setMarkedAsUsed(isMarkedAsUsed);
7618+
GV->setAsmName(asmName);
7619+
GV->setSection(section);
7620+
75977621
// Parse static initializer if exists.
75987622
if (State.P.consumeIf(tok::equal) && State.P.consumeIf(tok::l_brace)) {
75997623
SILBuilder B(GV);
@@ -7621,7 +7645,7 @@ bool SILParserState::parseSILProperty(Parser &P) {
76217645
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
76227646
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
76237647
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7624-
nullptr, nullptr, nullptr, nullptr, SP, M))
7648+
nullptr, nullptr, nullptr, nullptr, nullptr, SP, M))
76257649
return true;
76267650

76277651
ValueDecl *VD;
@@ -7691,7 +7715,8 @@ bool SILParserState::parseSILVTable(Parser &P) {
76917715
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
76927716
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
76937717
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7694-
nullptr, nullptr, nullptr, nullptr, VTableState, M))
7718+
nullptr, nullptr, nullptr, nullptr, nullptr,
7719+
VTableState, M))
76957720
return true;
76967721

76977722

@@ -7814,7 +7839,7 @@ bool SILParserState::parseSILMoveOnlyDeinit(Parser &parser) {
78147839
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
78157840
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
78167841
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7817-
nullptr, nullptr, nullptr, nullptr,
7842+
nullptr, nullptr, nullptr, nullptr, nullptr,
78187843
moveOnlyDeinitTableState, M))
78197844
return true;
78207845

@@ -8359,8 +8384,9 @@ bool SILParserState::parseSILWitnessTable(Parser &P) {
83598384
nullptr, &isSerialized, nullptr, nullptr, nullptr, nullptr, nullptr,
83608385
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
83618386
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
8362-
nullptr, nullptr, nullptr, nullptr, &isSpecialized, nullptr, nullptr,
8363-
nullptr, nullptr, nullptr, nullptr, nullptr, WitnessState, M))
8387+
nullptr, nullptr, nullptr, nullptr, nullptr, &isSpecialized,
8388+
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
8389+
WitnessState, M))
83648390
return true;
83658391

83668392
// Parse the protocol conformance.

lib/SILGen/SILGenGlobalVariable.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl,
7474
M, silLinkage, IsNotSerialized, mangledName, silTy, std::nullopt, gDecl);
7575
silGlobal->setDeclaration(!forDef);
7676

77+
if (auto sectionAttr = gDecl->getAttrs().getAttribute<SectionAttr>())
78+
silGlobal->setSection(sectionAttr->Name);
79+
7780
return silGlobal;
7881
}
7982

lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ class PerformanceDiagnosticsPass : public SILModuleTransform {
730730
"global inst", &g);
731731

732732
auto *decl = g.getDecl();
733-
if (g.getSectionAttr()) {
733+
if (!g.section().empty()) {
734734
module->getASTContext().Diags.diagnose(
735735
g.getDecl()->getLoc(), diag::bad_attr_on_non_const_global,
736736
"@_section");

0 commit comments

Comments
 (0)