Skip to content

Commit 2d1a948

Browse files
committed
Initial commit for Debug Scope serialization/deserialization
This patch adds code for serializing and deserializing debug scopes. During serialization, declarations of functions only referred to by debug scopes are serialization. During deserialization, these declarations are deserialized as zombie functions. The deserializer refuses to deserialize these functions when referred to by the optimizer, such as during Generic Specialization.
1 parent 844d103 commit 2d1a948

24 files changed

+456
-46
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class FrontendOptions {
125125
/// Include local definitions/references in the index data.
126126
bool IndexIncludeLocals = false;
127127

128+
bool SerializeDebugInfo = false;
128129
/// If building a module from interface, ignore compiler flags
129130
/// specified in the swiftinterface.
130131
bool ExplicitInterfaceBuild = false;

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,10 @@ def experimental_package_interface_load:
805805
Flags<[FrontendOption, HelpHidden]>,
806806
HelpText<"Enables loading a package interface if in the same package specified with package-name">;
807807

808+
def experimental_serialize_debug_info:
809+
Flag<["-"], "experimental-serialize-debug-info">,
810+
Flags<[FrontendOption, HelpHidden]>,
811+
HelpText<"Enables seriailzation/deserialization of debug scopes">;
808812
// Diagnostic control options
809813
def suppress_warnings : Flag<["-"], "suppress-warnings">,
810814
Flags<[FrontendOption]>,

include/swift/SIL/SILFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ class SILFunction
524524
SILFunction *InsertBefore = nullptr,
525525
const SILDebugScope *DebugScope = nullptr);
526526

527+
static SILFunction *resurrectFunction(SILModule &M, StringRef name);
527528
void init(SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType,
528529
GenericEnvironment *genericEnv, IsBare_t isBareSILFunction,
529530
IsTransparent_t isTrans, SerializedKind_t serializedKind,

include/swift/SIL/SILFunctionBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class SILFunctionBuilder {
120120
static void setHasOwnership(SILFunction *F, bool newValue) {
121121
F->setHasOwnership(newValue);
122122
}
123+
124+
SILFunction *resurrectFunction(StringRef name);
123125
};
124126

125127
} // namespace swift

include/swift/Serialization/SerializationOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ namespace swift {
151151

152152
bool AutolinkForceLoad = false;
153153
bool SerializeAllSIL = false;
154+
bool SerializeDebugInfo = false;
154155
bool SerializeOptionsForDebugging = false;
155156
bool IsSIB = false;
156157
bool DisableCrossModuleIncrementalInfo = false;

lib/Driver/ToolChains.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
204204
arguments.push_back("-disable-objc-interop");
205205
}
206206

207+
if (const Arg *arg = inputArgs.getLastArg(
208+
options::OPT_experimental_serialize_debug_info)) {
209+
arguments.push_back(
210+
inputArgs.MakeArgString(Twine("-experimental-serialize-debug-info")));
211+
}
212+
207213
if (inputArgs.hasArg(options::OPT_experimental_hermetic_seal_at_link)) {
208214
arguments.push_back("-enable-llvm-vfe");
209215
arguments.push_back("-enable-llvm-wme");

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ bool ArgsToFrontendOptionsConverter::convert(
8989
Opts.IndexSystemModules |= Args.hasArg(OPT_index_system_modules);
9090
Opts.IndexIgnoreStdlib |= Args.hasArg(OPT_index_ignore_stdlib);
9191
Opts.IndexIncludeLocals |= Args.hasArg(OPT_index_include_locals);
92+
Opts.SerializeDebugInfo |= Args.hasArg(OPT_experimental_serialize_debug_info);
9293

9394
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
9495
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);

lib/Frontend/Frontend.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
200200
serializationOpts.ModuleLinkName = opts.ModuleLinkName;
201201
serializationOpts.UserModuleVersion = opts.UserModuleVersion;
202202
serializationOpts.AllowableClients = opts.AllowableClients;
203+
serializationOpts.SerializeDebugInfo = opts.SerializeDebugInfo;
203204

204205
serializationOpts.PublicDependentLibraries =
205206
getIRGenOptions().PublicLinkLibraries;

lib/SIL/IR/Linker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) {
8383
Mod.getSILLoader()->lookupSILFunction(F, /*onlyUpdateLinkage*/ false);
8484
ASSERT(!NewF || NewF == F);
8585
if (!NewF || F->isExternalDeclaration()) {
86-
ASSERT((!hasSharedVisibility(F->getLinkage()) || F->hasForeignBody()) &&
86+
ASSERT((!hasSharedVisibility(F->getLinkage()) || F->hasForeignBody() || F->isZombie()) &&
8787
"cannot deserialize shared function");
8888
return;
8989
}

lib/SIL/IR/SILFunction.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,34 @@ SILFunction::SILFunction(
231231
initFunction({this}, &libswiftSpecificData, sizeof(libswiftSpecificData));
232232
}
233233

234+
SILFunction *SILFunction::resurrectFunction(SILModule &M, StringRef name) {
235+
llvm::StringMapEntry<SILFunction *> *entry = nullptr;
236+
if (!name.empty()) {
237+
entry = &*M.FunctionTable.insert(std::make_pair(name, nullptr)).first;
238+
PrettyStackTraceSILFunction trace("creating", entry->getValue());
239+
assert(!entry->getValue() && "function already exists");
240+
name = entry->getKey();
241+
}
242+
243+
SILFunction *fn = M.removeFromZombieList(name);
244+
assert(fn);
245+
246+
assert(fn->empty());
247+
fn->init(fn->getLinkage(), name, fn->getLoweredFunctionType(),
248+
fn->getGenericEnvironment(), fn->isBare(), fn->isTransparent(),
249+
fn->getSerializedKind(), fn->getEntryCount(), fn->isThunk(),
250+
fn->getClassSubclassScope(), fn->getInlineStrategy(),
251+
fn->getEffectsKind(), fn->getDebugScope(),
252+
fn->isDynamicallyReplaceable(), fn->isExactSelfClass(),
253+
fn->isDistributed(), fn->isRuntimeAccessible());
254+
255+
if (entry)
256+
entry->setValue(fn);
257+
258+
M.functions.push_back(fn);
259+
260+
return fn;
261+
}
234262
void SILFunction::init(
235263
SILLinkage Linkage, StringRef Name, CanSILFunctionType LoweredType,
236264
GenericEnvironment *genericEnv, IsBare_t isBareSILFunction,

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,8 @@ SILFunction *SILFunctionBuilder::createFunction(
431431
subclassScope, inlineStrategy, EK, InsertBefore,
432432
DebugScope);
433433
}
434+
435+
SILFunction *SILFunctionBuilder::resurrectFunction(
436+
StringRef name) {
437+
return SILFunction::resurrectFunction(mod, name);
438+
}

lib/SIL/IR/SILModule.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ SILFunction *SILModule::lookUpFunction(SILDeclRef fnRef) {
350350
bool SILModule::loadFunction(SILFunction *F, LinkingMode LinkMode) {
351351
SILFunction *NewF =
352352
getSILLoader()->lookupSILFunction(F, /*onlyUpdateLinkage*/ false);
353-
if (!NewF)
353+
if (!NewF || NewF->isZombie())
354354
return false;
355355

356356
linkFunction(NewF, LinkMode);
@@ -364,7 +364,7 @@ SILFunction *SILModule::loadFunction(StringRef name, LinkingMode LinkMode,
364364
SILFunction *func = lookUpFunction(name);
365365
if (!func)
366366
func = getSILLoader()->lookupSILFunction(name, linkage);
367-
if (!func)
367+
if (!func || func->isZombie())
368368
return nullptr;
369369

370370
linkFunction(func, LinkMode);

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,16 @@ SILParserState::~SILParserState() {
8787
}
8888

8989
// Turn any debug-info-only function declarations into zombies.
90-
for (auto *Fn : PotentialZombieFns)
91-
if (Fn->isExternalDeclaration()) {
90+
markZombies();
91+
}
92+
93+
void SILParserState::markZombies() {
94+
for (auto *Fn : PotentialZombieFns) {
95+
if (Fn->isExternalDeclaration() && !Fn->isZombie()) {
9296
Fn->setInlined();
9397
M.eraseFunction(Fn);
9498
}
99+
}
95100
}
96101

97102
std::unique_ptr<SILModule>
@@ -125,6 +130,11 @@ ParseSILModuleRequest::evaluate(Evaluator &evaluator,
125130
"Failed to parse SIL but did not emit any errors!");
126131
return SILModule::createEmptyModule(desc.context, desc.conv, desc.opts);
127132
}
133+
134+
//mark functions as zombies before calling SILVerifier as functions referred
135+
//to by debug scopes only can fail verifier checks
136+
parserState.markZombies();
137+
128138
// If SIL parsing succeeded, verify the generated SIL.
129139
if (!parser.Diags.hadAnyError() && !DisableInputVerify) {
130140
silMod->verify(/*SingleFunction=*/true, !ParseIncompleteOSSA);

lib/SIL/Parser/SILParserState.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ class SILParserState : public SILParserStateBase {
6262
bool parseSILCoverageMap(Parser &P) override;
6363
bool parseSILProperty(Parser &P) override;
6464
bool parseSILScope(Parser &P) override;
65+
66+
void markZombies();
6567
};
6668

6769
} // end namespace swift

0 commit comments

Comments
 (0)