Skip to content

Commit 8055c1d

Browse files
committed
Initial commit of InterfaceModuleNameExpander implmentation. All tests pass, and the unused vfs overlay is optimized.
1 parent da02cd0 commit 8055c1d

File tree

4 files changed

+178
-3
lines changed

4 files changed

+178
-3
lines changed

include/swift/AST/ModuleDependencies.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,14 @@ class SwiftInterfaceModuleDependenciesStorage
320320
void updateCommandLine(const std::vector<std::string> &newCommandLine) {
321321
textualModuleDetails.buildCommandLine = newCommandLine;
322322
}
323+
324+
void updateModuleOutputPath(const std::string &newPath) {
325+
const_cast<std::string &>(moduleOutputPath) = newPath;
326+
}
327+
328+
void updateContextHash(const std::string &newContextHash) {
329+
const_cast<std::string &>(contextHash) = newContextHash;
330+
}
323331
};
324332

325333
/// Describes the dependencies of a Swift module
@@ -876,6 +884,20 @@ class ModuleDependencyInfo {
876884
llvm_unreachable("Unexpected type");
877885
}
878886

887+
void updateModuleOutputPath(const std::string &newPath) {
888+
if (isSwiftInterfaceModule())
889+
return cast<SwiftInterfaceModuleDependenciesStorage>(storage.get())
890+
->updateModuleOutputPath(newPath);
891+
llvm_unreachable("Unexpected type");
892+
}
893+
894+
void updateContextHash(const std::string &newContextHash) {
895+
if (isSwiftInterfaceModule())
896+
return cast<SwiftInterfaceModuleDependenciesStorage>(storage.get())
897+
->updateContextHash(newContextHash);
898+
llvm_unreachable("Unexpected type");
899+
}
900+
879901
/// Whether explicit input paths of all the module dependencies
880902
/// have been specified on the command-line recipe for this module.
881903
bool isFinalized() const { return storage->finalized; }

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,41 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
710710
StringRef &CacheHash);
711711
std::string getCacheHash(StringRef useInterfacePath, StringRef sdkPath);
712712
};
713+
714+
class InterfaceModuleNameExpander {
715+
public:
716+
using ArgListTy = std::vector<std::string>;
717+
struct ResultTy {
718+
llvm::SmallString<256> outputPath;
719+
720+
// Hash points to a segment of outputPath.
721+
StringRef hash;
722+
};
723+
724+
private:
725+
const StringRef moduleName;
726+
const StringRef interfacePath;
727+
const StringRef sdkPath;
728+
const CompilerInvocation &CI;
729+
ArgListTy extraArgs;
730+
731+
ResultTy expandedName;
732+
733+
bool expanded = false;
734+
735+
std::string getHash();
736+
737+
public:
738+
InterfaceModuleNameExpander(const StringRef moduleName,
739+
const StringRef interfacePath,
740+
const StringRef sdkPath,
741+
const CompilerInvocation &CI)
742+
: moduleName(moduleName), interfacePath(interfacePath), sdkPath(sdkPath),
743+
CI(CI), extraArgs(CI.getClangImporterOptions()
744+
.getReducedExtraArgsForSwiftModuleDependency()) {}
745+
ResultTy getExpandedName();
746+
void pruneExtraArgs(std::function<void(ArgListTy &)> filter);
747+
};
713748
}
714749

715750
#endif

lib/DependencyScan/ScanDependencies.cpp

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,22 @@ namespace {
8181
class ExplicitModuleDependencyResolver {
8282
public:
8383
ExplicitModuleDependencyResolver(
84-
ModuleDependencyID moduleID, ModuleDependenciesCache &cache,
84+
const ModuleDependencyID &moduleID, ModuleDependenciesCache &cache,
8585
CompilerInstance &instance, std::optional<SwiftDependencyTracker> tracker)
8686
: moduleID(moduleID), cache(cache), instance(instance),
8787
resolvingDepInfo(cache.findKnownDependency(moduleID)),
8888
tracker(std::move(tracker)) {
8989
// Copy commandline.
9090
commandline = resolvingDepInfo.getCommandline();
91+
92+
if (resolvingDepInfo.isSwiftInterfaceModule()) {
93+
auto swiftTextualDeps = resolvingDepInfo.getAsSwiftInterfaceModule();
94+
auto &interfacePath = swiftTextualDeps->swiftInterfaceFile;
95+
auto SDKPath = instance.getASTContext().SearchPathOpts.getSDKPath();
96+
nameExpander = std::make_unique<InterfaceModuleNameExpander>(
97+
moduleID.ModuleName, interfacePath, SDKPath,
98+
instance.getInvocation());
99+
}
91100
}
92101

93102
llvm::Error
@@ -171,6 +180,9 @@ class ExplicitModuleDependencyResolver {
171180

172181
pruneUnusedVFSOverlay();
173182

183+
if (resolvingDepInfo.isSwiftInterfaceModule())
184+
updateSwiftInterfaceCommandLine();
185+
174186
// Update the dependency in the cache with the modified command-line.
175187
if (resolvingDepInfo.isSwiftInterfaceModule() ||
176188
resolvingDepInfo.isClangModule()) {
@@ -221,6 +233,12 @@ class ExplicitModuleDependencyResolver {
221233
return err;
222234
}
223235

236+
if (nameExpander) {
237+
auto expandedName = nameExpander->getExpandedName();
238+
depInfo.updateModuleOutputPath(expandedName.outputPath.c_str());
239+
depInfo.updateContextHash(expandedName.hash.str());
240+
}
241+
224242
return llvm::Error::success();
225243
}
226244

@@ -402,9 +420,62 @@ class ExplicitModuleDependencyResolver {
402420
}
403421
resolvedCommandLine.push_back(*it);
404422
}
423+
424+
// Filter the extra args that we use to calculate the hash of the module.
425+
// The key assumption is that these args are clang importer args, so we
426+
// do not need to check for -Xcc.
427+
auto extraArgsFilter = [&](InterfaceModuleNameExpander::ArgListTy &args) {
428+
bool skip = false;
429+
InterfaceModuleNameExpander::ArgListTy newArgs;
430+
for (auto it = args.begin(), end = args.end(); it != end; it++) {
431+
if (skip) {
432+
skip = false;
433+
continue;
434+
}
435+
436+
if ((it + 1) != end && isVFSOverlayFlag(*it)) {
437+
if (!usedVFSOverlayPaths.contains(*(it + 1))) {
438+
skip = true;
439+
continue;
440+
}
441+
}
442+
443+
newArgs.push_back(*it);
444+
}
445+
args = newArgs;
446+
return;
447+
};
448+
449+
if (nameExpander)
450+
nameExpander->pruneExtraArgs(extraArgsFilter);
451+
405452
commandline = std::move(resolvedCommandLine);
406453
}
407454

455+
void updateSwiftInterfaceCommandLine() {
456+
// The command line needs upadte once we prune the unused VFS overlays.
457+
// The update consists of two steps.
458+
// 1. Recompute the output path, which includes the module hash.
459+
// 2. Update `-o `'s value on the command line with the new output path.
460+
461+
assert(nameExpander && "Can only update if we hae a nameExpander.");
462+
auto expandedName = nameExpander->getExpandedName();
463+
464+
StringRef outputName = expandedName.outputPath.str();
465+
466+
bool isOutputPath = false;
467+
for (auto &A : commandline) {
468+
if (isOutputPath) {
469+
A = outputName.str();
470+
break;
471+
} else if (A == "-o") {
472+
isOutputPath = true;
473+
}
474+
}
475+
476+
return;
477+
}
478+
408479
llvm::Error collectCASDependencies(ModuleDependencyInfo &dependencyInfoCopy) {
409480
if (!instance.getInvocation().getCASOptions().EnableCaching)
410481
return llvm::Error::success();
@@ -524,10 +595,11 @@ class ExplicitModuleDependencyResolver {
524595
}
525596

526597
private:
527-
ModuleDependencyID moduleID;
598+
const ModuleDependencyID &moduleID;
528599
ModuleDependenciesCache &cache;
529600
CompilerInstance &instance;
530601
const ModuleDependencyInfo &resolvingDepInfo;
602+
std::unique_ptr<InterfaceModuleNameExpander> nameExpander;
531603

532604
std::optional<SwiftDependencyTracker> tracker;
533605
std::vector<std::string> rootIDs;
@@ -540,7 +612,7 @@ class ExplicitModuleDependencyResolver {
540612
};
541613

542614
static llvm::Error resolveExplicitModuleInputs(
543-
ModuleDependencyID moduleID,
615+
const ModuleDependencyID &moduleID,
544616
const std::set<ModuleDependencyID> &dependencies,
545617
ModuleDependenciesCache &cache, CompilerInstance &instance,
546618
std::optional<std::set<ModuleDependencyID>> bridgingHeaderDeps,

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2843,3 +2843,49 @@ std::unique_ptr<ExplicitCASModuleLoader> ExplicitCASModuleLoader::create(
28432843

28442844
return result;
28452845
}
2846+
2847+
InterfaceModuleNameExpander::ResultTy
2848+
InterfaceModuleNameExpander::getExpandedName() {
2849+
// Expand the name once, and reuse later.
2850+
if (!expanded) {
2851+
auto &outputPath = expandedName.outputPath;
2852+
outputPath = CI.getClangModuleCachePath();
2853+
llvm::sys::path::append(outputPath, moduleName);
2854+
outputPath.append("-");
2855+
auto hashStart = outputPath.size();
2856+
outputPath.append(getHash());
2857+
expandedName.hash = outputPath.str().substr(hashStart);
2858+
outputPath.append(".");
2859+
auto outExt = file_types::getExtension(file_types::TY_SwiftModuleFile);
2860+
outputPath.append(outExt);
2861+
expanded = true;
2862+
}
2863+
return expandedName;
2864+
}
2865+
2866+
std::string InterfaceModuleNameExpander::getHash() {
2867+
bool useStrictCacheHash = CI.getFrontendOptions().RequestedAction ==
2868+
FrontendOptions::ActionType::ScanDependencies;
2869+
auto targetToHash =
2870+
useStrictCacheHash
2871+
? CI.getLangOptions().Target
2872+
: getTargetSpecificModuleTriple(CI.getLangOptions().Target);
2873+
2874+
std::string sdkBuildVersion = getSDKBuildVersion(sdkPath);
2875+
2876+
llvm::hash_code H = llvm::hash_combine(
2877+
swift::version::getSwiftFullVersion(), interfacePath, targetToHash.str(),
2878+
CI.getSDKPath(), sdkBuildVersion, version::getCurrentCompilerChannel(),
2879+
CI.getFrontendOptions().shouldTrackSystemDependencies(),
2880+
CI.getCASOptions().getModuleScanningHashComponents(),
2881+
llvm::hash_combine_range(extraArgs.begin(), extraArgs.end()),
2882+
unsigned(CI.getLangOptions().EnableAppExtensionRestrictions),
2883+
unsigned(CI.getSILOptions().EnableOSSAModules));
2884+
2885+
return llvm::toString(llvm::APInt(64, H), 36, /*Signed=*/false);
2886+
}
2887+
2888+
void InterfaceModuleNameExpander::pruneExtraArgs(
2889+
std::function<void(ArgListTy &)> filter) {
2890+
filter(extraArgs);
2891+
}

0 commit comments

Comments
 (0)