Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/SIL/FunctionAttributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,11 @@ Specifies that the optimizer and IRGen must not add runtime calls which
are not in the function originally. This attribute is set for functions
with performance constraints or functions which are called from
functions with performance constraints.

### Naming

```
sil-function-attribute :: '[' asmname "' identifier '" ']'
```

Specifies that the SIL function should be lowered to LLVM IR with the given function name.
9 changes: 9 additions & 0 deletions include/swift/SIL/SILFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,11 @@ class SILFunction
/// The function's remaining set of specialize attributes.
std::vector<SILSpecializeAttr*> SpecializeAttrSet;

/// The name that this function should have when it is lowered to LLVM IR.
///
/// If empty, use the SIL function's name directly.
StringRef AsmName;

/// Name of a section if @_section attribute was used, otherwise empty.
StringRef Section;

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

/// Return custom assembler name, otherwise empty.
StringRef asmName() const { return AsmName; }
void setAsmName(StringRef value) { AsmName = value; }

/// Return custom section name if @_section was used, otherwise empty
StringRef section() const { return Section; }
void setSection(StringRef value) { Section = value; }
Expand Down
26 changes: 16 additions & 10 deletions include/swift/SIL/SILGlobalVariable.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ class SILGlobalVariable
/// binary. A pointer into the module's lookup table.
StringRef Name;

/// The name that this variable should have when lowered to LLVM IR. If empty,
/// the mangled name of the variable will be used instead.
StringRef AsmName;

/// Name of a section if @_section attribute was used, otherwise empty.
StringRef Section;

/// The lowered type of the variable.
SILType LoweredType;

Expand Down Expand Up @@ -150,7 +157,15 @@ class SILGlobalVariable
}

StringRef getName() const { return Name; }


/// Return custom assembler name, otherwise empty.
StringRef asmName() const { return AsmName; }
void setAsmName(StringRef value) { AsmName = value; }

/// Return custom section name if @_section was used, otherwise empty
StringRef section() const { return Section; }
void setSection(StringRef value) { Section = value; }

void setDeclaration(bool isD) { IsDeclaration = isD; }

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

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

/// Returns a SectionAttr if this global variable has `@_section` attribute.
SectionAttr *getSectionAttr() const {
auto *V = getDecl();
if (!V)
return nullptr;

return V->getAttrs().getAttribute<SectionAttr>();
}

/// Return whether this variable corresponds to a Clang node.
bool hasClangNode() const;

Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2865,8 +2865,8 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
addUsedGlobal(gvar);
else if (var->shouldBePreservedForDebugger() && forDefinition)
addUsedGlobal(gvar);
if (auto *sectionAttr = var->getSectionAttr())
gvar->setSection(sectionAttr->Name);
if (!var->section().empty())
gvar->setSection(var->section());
}
if (forDefinition && !gvar->hasInitializer()) {
if (initVal) {
Expand Down
11 changes: 10 additions & 1 deletion lib/IRGen/Linking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ std::string LinkEntity::mangleAsString(ASTContext &Ctx) const {
}

case Kind::SILFunction: {
auto asmName = getSILFunction()->asmName();
if (!asmName.empty())
return asmName.str();

std::string Result(getSILFunction()->getName());
if (isDynamicallyReplaceable()) {
Result.append("TI");
Expand Down Expand Up @@ -465,8 +469,13 @@ std::string LinkEntity::mangleAsString(ASTContext &Ctx) const {
return Result;
}

case Kind::SILGlobalVariable:
case Kind::SILGlobalVariable: {
auto asmName = getSILGlobalVariable()->asmName();
if (!asmName.empty())
return asmName.str();

return getSILGlobalVariable()->getName().str();
}

case Kind::ReadOnlyGlobalObject:
return getSILGlobalVariable()->getName().str() + "r";
Expand Down
4 changes: 2 additions & 2 deletions lib/SIL/IR/SILGlobalVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ bool SILGlobalVariable::isPossiblyUsedExternally() const {
if (markedAsUsed())
return true;

if (getSectionAttr())
if (!section().empty())
return true;

SILLinkage linkage = getLinkage();
Expand Down Expand Up @@ -151,7 +151,7 @@ SILInstruction *SILGlobalVariable::getStaticInitializerValue() {
}

bool SILGlobalVariable::mustBeInitializedStatically() const {
if (getSectionAttr())
if (!section().empty())
return true;

auto *decl = getDecl();
Expand Down
9 changes: 9 additions & 0 deletions lib/SIL/IR/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3709,6 +3709,9 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
if (!section().empty())
OS << "[section \"" << section() << "\"] ";

if (!asmName().empty())
OS << "[asmname \"" << asmName() << "\"] ";

// TODO: Handle clang node owners which don't have a name.
if (hasClangNode() && getClangNodeOwner()->hasName()) {
OS << "[clang ";
Expand Down Expand Up @@ -3777,6 +3780,12 @@ void SILGlobalVariable::print(llvm::raw_ostream &OS, bool Verbose) const {
if (markedAsUsed())
OS << "[used] ";

if (!asmName().empty())
OS << "[asmname \"" << asmName() << "\"] ";

if (!section().empty())
OS << "[section \"" << section() << "\"] ";

printName(OS);
OS << " : " << LoweredType;

Expand Down
48 changes: 37 additions & 11 deletions lib/SIL/Parser/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,8 @@ static bool parseDeclSILOptional(
SILFunction **usedAdHocRequirementWitness, Identifier *objCReplacementFor,
SILFunction::Purpose *specialPurpose, Inline_t *inlineStrategy,
OptimizationMode *optimizationMode, PerformanceConstraints *perfConstraints,
bool *isPerformanceConstraint, bool *markedAsUsed, StringRef *section,
bool *isPerformanceConstraint, bool *markedAsUsed, StringRef *asmName,
StringRef *section,
bool *isLet, bool *isWeakImported, bool *needStackProtection,
bool *isSpecialized, AvailabilityRange *availability,
bool *isWithoutActuallyEscapingThunk,
Expand Down Expand Up @@ -807,6 +808,20 @@ static bool parseDeclSILOptional(
}
*actorIsolation = *optIsolation;
SP.P.consumeToken(tok::string_literal);
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
continue;
} else if (asmName && SP.P.Tok.getText() == "asmname") {
SP.P.consumeToken(tok::identifier);
if (SP.P.Tok.getKind() != tok::string_literal) {
SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
return true;
}

// Drop the double quotes.
StringRef rawString = SP.P.Tok.getText().drop_front().drop_back();
*asmName = SP.P.Context.getIdentifier(rawString).str();
SP.P.consumeToken(tok::string_literal);

SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
continue;
} else if (section && SP.P.Tok.getText() == "section") {
Expand Down Expand Up @@ -7288,6 +7303,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
PerformanceConstraints perfConstr = PerformanceConstraints::None;
bool isPerformanceConstraint = false;
bool markedAsUsed = false;
StringRef asmName;
StringRef section;
SmallVector<std::string, 1> Semantics;
SmallVector<ParsedSpecAttr, 4> SpecAttrs;
Expand All @@ -7306,7 +7322,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
&DynamicallyReplacedFunction, &AdHocWitnessFunction,
&objCReplacementFor, &specialPurpose, &inlineStrategy,
&optimizationMode, &perfConstr, &isPerformanceConstraint,
&markedAsUsed, &section, nullptr, &isWeakImported,
&markedAsUsed, &asmName, &section, nullptr, &isWeakImported,
&needStackProtection, nullptr, &availability,
&isWithoutActuallyEscapingThunk, &Semantics, &SpecAttrs, &ClangDecl,
&MRK, &actorIsolation, FunctionState, M) ||
Expand Down Expand Up @@ -7363,6 +7379,9 @@ bool SILParserState::parseDeclSIL(Parser &P) {
FunctionState.F->setPerfConstraints(perfConstr);
FunctionState.F->setIsPerformanceConstraint(isPerformanceConstraint);
FunctionState.F->setEffectsKind(MRK);
FunctionState.F->setMarkedAsUsed(markedAsUsed);
FunctionState.F->setAsmName(asmName);
FunctionState.F->setSection(section);

if (ClangDecl)
FunctionState.F->setClangNodeOwner(ClangDecl);
Expand Down Expand Up @@ -7557,17 +7576,19 @@ bool SILParserState::parseSILGlobal(Parser &P) {
SourceLoc NameLoc;
SerializedKind_t isSerialized = IsNotSerialized;
bool isMarkedAsUsed = false;
StringRef asmName;
StringRef section;
bool isLet = false;

SILParser State(P);
if (parseSILLinkage(GlobalLinkage, P) ||
parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, &isMarkedAsUsed, nullptr,
&isLet, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, State,
M) ||
nullptr, nullptr, nullptr, &isMarkedAsUsed, &asmName,
&section, &isLet, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
State, M) ||
P.parseToken(tok::at_sign, diag::expected_sil_value_name) ||
P.parseIdentifier(GlobalName, NameLoc, /*diagnoseDollarPrefix=*/false,
diag::expected_sil_value_name) ||
Expand All @@ -7594,6 +7615,9 @@ bool SILParserState::parseSILGlobal(Parser &P) {

GV->setLet(isLet);
GV->setMarkedAsUsed(isMarkedAsUsed);
GV->setAsmName(asmName);
GV->setSection(section);

// Parse static initializer if exists.
if (State.P.consumeIf(tok::equal) && State.P.consumeIf(tok::l_brace)) {
SILBuilder B(GV);
Expand Down Expand Up @@ -7621,7 +7645,7 @@ bool SILParserState::parseSILProperty(Parser &P) {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, SP, M))
nullptr, nullptr, nullptr, nullptr, nullptr, SP, M))
return true;

ValueDecl *VD;
Expand Down Expand Up @@ -7691,7 +7715,8 @@ bool SILParserState::parseSILVTable(Parser &P) {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, VTableState, M))
nullptr, nullptr, nullptr, nullptr, nullptr,
VTableState, M))
return true;


Expand Down Expand Up @@ -7814,7 +7839,7 @@ bool SILParserState::parseSILMoveOnlyDeinit(Parser &parser) {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr,
moveOnlyDeinitTableState, M))
return true;

Expand Down Expand Up @@ -8359,8 +8384,9 @@ bool SILParserState::parseSILWitnessTable(Parser &P) {
nullptr, &isSerialized, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, &isSpecialized, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, WitnessState, M))
nullptr, nullptr, nullptr, nullptr, nullptr, &isSpecialized,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
WitnessState, M))
return true;

// Parse the protocol conformance.
Expand Down
3 changes: 3 additions & 0 deletions lib/SILGen/SILGenGlobalVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl,
M, silLinkage, IsNotSerialized, mangledName, silTy, std::nullopt, gDecl);
silGlobal->setDeclaration(!forDef);

if (auto sectionAttr = gDecl->getAttrs().getAttribute<SectionAttr>())
silGlobal->setSection(sectionAttr->Name);

return silGlobal;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ class PerformanceDiagnosticsPass : public SILModuleTransform {
"global inst", &g);

auto *decl = g.getDecl();
if (g.getSectionAttr()) {
if (!g.section().empty()) {
module->getASTContext().Diags.diagnose(
g.getDecl()->getLoc(), diag::bad_attr_on_non_const_global,
"@_section");
Expand Down
Loading