Skip to content

Commit 4fd6adb

Browse files
authored
Merge pull request #72669 from kubamracek/embedded-drop-all-sil-flag
[embedded] Add a frontend flag to drop all code from a module and emit an empty object file
2 parents 989d4ba + 00d7a3b commit 4fd6adb

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,10 @@ def enable_single_module_llvm_emission: Flag<["-"], "enable-single-module-llvm-e
580580
Flags<[FrontendOption, NoInteractiveOption]>,
581581
HelpText<"Emit LLVM IR into a single LLVM module in multithreaded mode.">;
582582

583+
def emit_empty_object_file : Flag<["-"], "emit-empty-object-file">,
584+
Flags<[FrontendOption, NoInteractiveOption]>,
585+
HelpText<"Produce a valid but dummy object file when building a library module">;
586+
583587
def stack_promotion_checks : Flag<["-"], "emit-stack-promotion-checks">,
584588
HelpText<"Emit runtime checks for correct stack promotion of objects.">;
585589

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,10 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
21822182
FEOpts.RequestedAction == FrontendOptions::ActionType::CompileModuleFromInterface)
21832183
Opts.StopOptimizationAfterSerialization = true;
21842184

2185+
if (Args.getLastArg(OPT_emit_empty_object_file)) {
2186+
Opts.StopOptimizationAfterSerialization = true;
2187+
}
2188+
21852189
// Propagate the typechecker's understanding of
21862190
// -experimental-skip-*-function-bodies to SIL.
21872191
Opts.SkipFunctionBodies = TCOpts.SkipFunctionBodies;

lib/IRGen/GenDecl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,11 @@ class PrettySynthesizedFileUnitEmission : public llvm::PrettyStackTraceEntry {
454454

455455
/// Emit all the top-level code in the source file.
456456
void IRGenModule::emitSourceFile(SourceFile &SF) {
457+
if (getSILModule().getOptions().StopOptimizationAfterSerialization) {
458+
// We're asked to emit an empty IR module
459+
return;
460+
}
461+
457462
// Type-check the file if we haven't already (this may be necessary for .sil
458463
// files, which don't get fully type-checked by parsing).
459464
performTypeChecking(SF);
@@ -1259,6 +1264,11 @@ static bool isLazilyEmittedFunction(SILFunction &f, SILModule &m) {
12591264

12601265
void IRGenerator::emitGlobalTopLevel(
12611266
const std::vector<std::string> &linkerDirectives) {
1267+
if (PrimaryIGM->getSILModule().getOptions().StopOptimizationAfterSerialization) {
1268+
// We're asked to emit an empty IR module
1269+
return;
1270+
}
1271+
12621272
// Generate order numbers for the functions in the SIL module that
12631273
// correspond to definitions in the LLVM module.
12641274
unsigned nextOrderNumber = 0;
@@ -2195,6 +2205,11 @@ void IRGenerator::emitObjCActorsNeedingSuperclassSwizzle() {
21952205
/// from other modules. This happens e.g. if a public class contains a (dead)
21962206
/// private method.
21972207
void IRGenModule::emitVTableStubs() {
2208+
if (getSILModule().getOptions().StopOptimizationAfterSerialization) {
2209+
// We're asked to emit an empty IR module
2210+
return;
2211+
}
2212+
21982213
llvm::Function *stub = nullptr;
21992214
for (auto I = getSILModule().zombies_begin();
22002215
I != getSILModule().zombies_end(); ++I) {

lib/IRGen/GenReflection.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,6 +1667,11 @@ llvm::ArrayRef<CanType> IRGenModule::getOrCreateSpecialStlibBuiltinTypes() {
16671667
}
16681668

16691669
void IRGenModule::emitBuiltinReflectionMetadata() {
1670+
if (getSILModule().getOptions().StopOptimizationAfterSerialization) {
1671+
// We're asked to emit an empty IR module
1672+
return;
1673+
}
1674+
16701675
if (getSwiftModule()->isStdlibModule()) {
16711676
auto SpecialBuiltins = getOrCreateSpecialStlibBuiltinTypes();
16721677
BuiltinTypes.insert(SpecialBuiltins.begin(), SpecialBuiltins.end());

lib/IRGen/IRGenModule.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1912,7 +1912,8 @@ void IRGenModule::cleanupClangCodeGenMetadata() {
19121912
bool IRGenModule::finalize() {
19131913
const char *ModuleHashVarName = "llvm.swift_module_hash";
19141914
if (IRGen.Opts.OutputKind == IRGenOutputKind::ObjectFile &&
1915-
!Module.getGlobalVariable(ModuleHashVarName)) {
1915+
!Module.getGlobalVariable(ModuleHashVarName) &&
1916+
!getSILModule().getOptions().StopOptimizationAfterSerialization) {
19161917
// Create a global variable into which we will store the hash of the
19171918
// module (used for incremental compilation).
19181919
// We have to create the variable now (before we emit the global lists).
@@ -1969,6 +1970,14 @@ bool IRGenModule::finalize() {
19691970
if (F.hasDLLImportStorageClass())
19701971
F.setDSOLocal(false);
19711972

1973+
if (getSILModule().getOptions().StopOptimizationAfterSerialization) {
1974+
// We're asked to emit an empty IR module, check that that's actually true
1975+
if (Module.global_size() != 0 || Module.size() != 0) {
1976+
Module.dump();
1977+
llvm::report_fatal_error("Module is not empty");
1978+
}
1979+
}
1980+
19721981
return true;
19731982
}
19741983

0 commit comments

Comments
 (0)