Skip to content

Commit c91a482

Browse files
committed
Serialize the "markedAsUsed" bit for SILGlobalVariable
1 parent b5e61cc commit c91a482

File tree

14 files changed

+46
-17
lines changed

14 files changed

+46
-17
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjectOutliner.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ private func optimizeObjectAllocation(allocRef: AllocRefInstBase, _ context: Fun
109109
type: allocRef.type, linkage: .private,
110110
// Only if it's a COW object we can be sure that the object allocated in the global is not mutated.
111111
// If someone wants to mutate it, it has to be copied first.
112-
isLet: endOfInitInst is EndCOWMutationInst)
112+
isLet: endOfInitInst is EndCOWMutationInst,
113+
markedAsUsed: false)
113114

114115
constructObject(of: allocRef, inInitializerOf: outlinedGlobal, storesToClassFields, storesToTailElements, context)
115116
context.erase(instructions: storesToClassFields)
@@ -555,7 +556,7 @@ private func replace(findStringCall: ApplyInst,
555556

556557
// Create an "opaque" global variable which is passed as inout to
557558
// _findStringSwitchCaseWithCache and into which the function stores the "cache".
558-
let cacheVar = context.createGlobalVariable(name: name, type: cacheType, linkage: .private, isLet: false)
559+
let cacheVar = context.createGlobalVariable(name: name, type: cacheType, linkage: .private, isLet: false, markedAsUsed: false)
559560

560561
let varBuilder = Builder(staticInitializerOf: cacheVar, context)
561562
let zero = varBuilder.createIntegerLiteral(0, type: wordTy)

SwiftCompilerSources/Sources/SIL/Context.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,10 @@ extension MutatingContext {
114114
_bridged.notifyChanges(.Effects)
115115
}
116116

117-
public func createGlobalVariable(name: String, type: Type, linkage: Linkage, isLet: Bool) -> GlobalVariable {
117+
public func createGlobalVariable(name: String, type: Type, linkage: Linkage, isLet: Bool, markedAsUsed: Bool) -> GlobalVariable {
118118
let gv = name._withBridgedStringRef {
119-
_bridged.createGlobalVariable($0, type.bridged, linkage.bridged, isLet)
119+
_bridged.createGlobalVariable($0, type.bridged, linkage.bridged, isLet,
120+
markedAsUsed)
120121
}
121122
return gv.globalVar
122123
}

include/swift/SIL/SILBridging.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,8 @@ struct BridgedGlobalVar {
596596
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedStringRef getName() const;
597597
BRIDGED_INLINE bool isLet() const;
598598
BRIDGED_INLINE void setLet(bool value) const;
599+
BRIDGED_INLINE bool markedAsUsed() const;
600+
BRIDGED_INLINE void setMarkedAsUsed(bool value) const;
599601
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedType getType() const;
600602
BRIDGED_INLINE BridgedLinkage getLinkage() const;
601603
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE swift::SourceLoc getSourceLocation() const;
@@ -1449,7 +1451,8 @@ struct BridgedContext {
14491451
bool hasSelfParam,
14501452
BridgedFunction fromFunc) const;
14511453
SWIFT_IMPORT_UNSAFE BridgedGlobalVar createGlobalVariable(BridgedStringRef name, BridgedType type,
1452-
BridgedLinkage linkage, bool isLet) const;
1454+
BridgedLinkage linkage, bool isLet,
1455+
bool markedAsUsed) const;
14531456
void moveFunctionBody(BridgedFunction sourceFunc, BridgedFunction destFunc) const;
14541457

14551458
// Function-local SIL modifications

include/swift/SIL/SILBridgingImpl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,14 @@ bool BridgedGlobalVar::isLet() const { return getGlobal()->isLet(); }
932932

933933
void BridgedGlobalVar::setLet(bool value) const { getGlobal()->setLet(value); }
934934

935+
bool BridgedGlobalVar::markedAsUsed() const {
936+
return getGlobal()->markedAsUsed();
937+
}
938+
939+
void BridgedGlobalVar::setMarkedAsUsed(bool value) const {
940+
getGlobal()->setMarkedAsUsed(value);
941+
}
942+
935943
BridgedType BridgedGlobalVar::getType() const {
936944
return getGlobal()->getLoweredType();
937945
}

include/swift/SIL/SILGlobalVariable.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ class SILGlobalVariable
7575
/// once (either in its declaration, or once later), making it immutable.
7676
unsigned IsLet : 1;
7777

78+
/// Whether this declaration was marked `@_used`, meaning that it should be
79+
/// added to the llvm.used list.
80+
unsigned IsUsed : 1;
81+
7882
/// Whether or not this is a declaration.
7983
unsigned IsDeclaration : 1;
8084

@@ -207,10 +211,9 @@ class SILGlobalVariable
207211
}
208212

209213
/// Returns true if this global variable has `@_used` attribute.
210-
bool markedAsUsed() const {
211-
auto *V = getDecl();
212-
return V && V->getAttrs().hasAttribute<UsedAttr>();
213-
}
214+
bool markedAsUsed() const { return IsUsed; }
215+
216+
void setMarkedAsUsed(bool used) { IsUsed = used; }
214217

215218
/// Returns a SectionAttr if this global variable has `@_section` attribute.
216219
SectionAttr *getSectionAttr() const {

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage,
7272
setSerializedKind(serializedKind);
7373
IsDeclaration = isAvailableExternally(Linkage);
7474
setLet(isGlobalLet(Module, Decl, LoweredType));
75+
setMarkedAsUsed(Decl && Decl->getAttrs().hasAttribute<UsedAttr>());
7576
Module.silGlobals.push_back(this);
7677
}
7778

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3775,6 +3775,9 @@ void SILGlobalVariable::print(llvm::raw_ostream &OS, bool Verbose) const {
37753775
if (isLet())
37763776
OS << "[let] ";
37773777

3778+
if (markedAsUsed())
3779+
OS << "[used] ";
3780+
37783781
printName(OS);
37793782
OS << " : " << LoweredType;
37803783

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7601,16 +7601,18 @@ bool SILParserState::parseSILGlobal(Parser &P) {
76017601
SILType GlobalType;
76027602
SourceLoc NameLoc;
76037603
SerializedKind_t isSerialized = IsNotSerialized;
7604+
bool isMarkedAsUsed = false;
76047605
bool isLet = false;
76057606

76067607
SILParser State(P);
76077608
if (parseSILLinkage(GlobalLinkage, P) ||
76087609
parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
76097610
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
76107611
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7611-
nullptr, nullptr, nullptr, nullptr, nullptr, &isLet,
7612-
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
7613-
nullptr, nullptr, nullptr, nullptr, State, M) ||
7612+
nullptr, nullptr, nullptr, &isMarkedAsUsed, nullptr,
7613+
&isLet, nullptr, nullptr, nullptr, nullptr, nullptr,
7614+
nullptr, nullptr, nullptr, nullptr, nullptr, State,
7615+
M) ||
76147616
P.parseToken(tok::at_sign, diag::expected_sil_value_name) ||
76157617
P.parseIdentifier(GlobalName, NameLoc, /*diagnoseDollarPrefix=*/false,
76167618
diag::expected_sil_value_name) ||
@@ -7636,6 +7638,7 @@ bool SILParserState::parseSILGlobal(Parser &P) {
76367638
RegularLocation(NameLoc), VD.value());
76377639

76387640
GV->setLet(isLet);
7641+
GV->setMarkedAsUsed(isMarkedAsUsed);
76397642
// Parse static initializer if exists.
76407643
if (State.P.consumeIf(tok::equal) && State.P.consumeIf(tok::l_brace)) {
76417644
SILBuilder B(GV);

lib/SIL/Utils/SILBridging.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,13 +654,16 @@ createEmptyFunction(BridgedStringRef name,
654654
}
655655

656656
BridgedGlobalVar BridgedContext::createGlobalVariable(BridgedStringRef name, BridgedType type,
657-
BridgedLinkage linkage, bool isLet) const {
657+
BridgedLinkage linkage,
658+
bool isLet,
659+
bool markedAsUsed) const {
658660
auto *global = SILGlobalVariable::create(
659661
*context->getModule(),
660662
(swift::SILLinkage)linkage, IsNotSerialized,
661663
name.unbridged(), type.unbridged());
662664
if (isLet)
663665
global->setLet(true);
666+
global->setMarkedAsUsed(markedAsUsed);
664667
return {global};
665668
}
666669

lib/Serialization/DeserializeSIL.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4079,9 +4079,9 @@ SILGlobalVariable *SILDeserializer::readGlobalVar(StringRef Name) {
40794079

40804080
TypeID TyID;
40814081
DeclID dID;
4082-
unsigned rawLinkage, serializedKind, IsDeclaration, IsLet;
4082+
unsigned rawLinkage, serializedKind, IsDeclaration, IsLet, IsUsed;
40834083
SILGlobalVarLayout::readRecord(scratch, rawLinkage, serializedKind,
4084-
IsDeclaration, IsLet, TyID, dID);
4084+
IsDeclaration, IsLet, IsUsed, TyID, dID);
40854085
if (TyID == 0) {
40864086
LLVM_DEBUG(llvm::dbgs() << "SILGlobalVariable typeID is 0.\n");
40874087
return nullptr;
@@ -4112,6 +4112,7 @@ SILGlobalVariable *SILDeserializer::readGlobalVar(StringRef Name) {
41124112
Name.str(), getSILType(Ty, SILValueCategory::Object, nullptr),
41134113
std::nullopt, globalDecl);
41144114
v->setLet(IsLet);
4115+
v->setMarkedAsUsed(IsUsed);
41154116
globalVarOrOffset.set(v, true /*isFullyDeserialized*/);
41164117
v->setDeclaration(IsDeclaration);
41174118

0 commit comments

Comments
 (0)