[Dependency Scanning] Make GlobalModuleDependenciesCache aware of the current scanning action's target triple

And only resolve cached dependencies that came from scanning actions with the same target triple.

This change means that the `GlobalModuleDependenciesCache` must be configured with a specific target triple for every scannig action, and it will only resolve previously-found dependencies from previous scannig actions using the exact same triple.

Furthermore, the `GlobalModuleDependenciesCache` separately tracks source-file-based module dependencies as those represent main Swift modules of previous scanning actions, and we must be able to resolve those regardless of the target triple.

Resolves rdar://83105455
This commit is contained in:
Artem Chikin
2021-09-14 19:01:14 -07:00
parent e64a40451b
commit 709676c20c
8 changed files with 580 additions and 389 deletions

View File

@@ -38,7 +38,6 @@ class Identifier;
enum class ModuleDependenciesKind : int8_t {
FirstKind,
SwiftInterface = FirstKind,
SwiftSource,
SwiftBinary,
// Placeholder dependencies are a kind of dependencies used only by the
// dependency scanner. They are swift modules that the scanner will not be
@@ -64,7 +63,8 @@ enum class ModuleDependenciesKind : int8_t {
// of all targets, individually, have been computed.
SwiftPlaceholder,
Clang,
LastKind = Clang + 1
SwiftSource,
LastKind = SwiftSource + 1
};
struct ModuleDependenciesKindHash {
@@ -98,6 +98,25 @@ public:
std::vector<std::string> moduleDependencies;
};
struct CommonSwiftTextualModuleDependencyDetails {
CommonSwiftTextualModuleDependencyDetails(ArrayRef<StringRef> extraPCMArgs)
: extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()) {}
/// To build a PCM to be used by this Swift module, we need to append these
/// arguments to the generic PCM build arguments reported from the dependency
/// graph.
const std::vector<std::string> extraPCMArgs;
/// Bridging header file, if there is one.
Optional<std::string> bridgingHeaderFile;
/// Source files on which the bridging header depends.
std::vector<std::string> bridgingSourceFiles;
/// (Clang) modules on which the bridging header depends.
std::vector<std::string> bridgingModuleDependencies;
};
/// Describes the dependencies of a Swift module described by an Swift interface file.
///
/// This class is mostly an implementation detail for \c ModuleDependencies.
@@ -114,28 +133,14 @@ public:
/// interface.
const std::vector<std::string> buildCommandLine;
/// To build a PCM to be used by this Swift module, we need to append these
/// arguments to the generic PCM build arguments reported from the dependency
/// graph.
const std::vector<std::string> extraPCMArgs;
/// The hash value that will be used for the generated module
const std::string contextHash;
/// A flag that indicates this dependency is a framework
const bool isFramework;
/// Bridging header file, if there is one.
Optional<std::string> bridgingHeaderFile;
/// Swift source files that are part of the Swift module, when known.
std::vector<std::string> sourceFiles;
/// Source files on which the bridging header depends.
std::vector<std::string> bridgingSourceFiles;
/// (Clang) modules on which the bridging header depends.
std::vector<std::string> bridgingModuleDependencies;
/// Details common to Swift textual (interface or source) modules
CommonSwiftTextualModuleDependencyDetails textualModuleDetails;
SwiftInterfaceModuleDependenciesStorage(
const std::string swiftInterfaceFile,
@@ -149,8 +154,9 @@ public:
compiledModuleCandidates(compiledModuleCandidates.begin(),
compiledModuleCandidates.end()),
buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()),
extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()),
contextHash(contextHash), isFramework(isFramework) { }
contextHash(contextHash), isFramework(isFramework),
textualModuleDetails(extraPCMArgs)
{}
ModuleDependenciesStorageBase *clone() const override {
return new SwiftInterfaceModuleDependenciesStorage(*this);
@@ -167,27 +173,17 @@ public:
class SwiftSourceModuleDependenciesStorage :
public ModuleDependenciesStorageBase {
public:
/// To build a PCM to be used by this Swift module, we need to append these
/// arguments to the generic PCM build arguments reported from the dependency
/// graph.
const std::vector<std::string> extraPCMArgs;
/// Bridging header file, if there is one.
Optional<std::string> bridgingHeaderFile;
/// Swift source files that are part of the Swift module, when known.
std::vector<std::string> sourceFiles;
/// Source files on which the bridging header depends.
std::vector<std::string> bridgingSourceFiles;
/// (Clang) modules on which the bridging header depends.
std::vector<std::string> bridgingModuleDependencies;
/// Details common to Swift textual (interface or source) modules
CommonSwiftTextualModuleDependencyDetails textualModuleDetails;
SwiftSourceModuleDependenciesStorage(
ArrayRef<StringRef> extraPCMArgs
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftSource),
extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()) {}
textualModuleDetails(extraPCMArgs) {}
ModuleDependenciesStorageBase *clone() const override {
return new SwiftSourceModuleDependenciesStorage(*this);
@@ -196,7 +192,7 @@ public:
static bool classof(const ModuleDependenciesStorageBase *base) {
return base->dependencyKind == ModuleDependenciesKind::SwiftSource;
}
};
};
/// Describes the dependencies of a pre-built Swift module (with no .swiftinterface).
///
@@ -462,6 +458,14 @@ public:
using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
using ModuleDependenciesKindMap =
std::unordered_map<ModuleDependenciesKind,
llvm::StringMap<ModuleDependenciesVector>,
ModuleDependenciesKindHash>;
using ModuleDependenciesKindRefMap =
std::unordered_map<ModuleDependenciesKind,
llvm::StringMap<const ModuleDependencies *>,
ModuleDependenciesKindHash>;
/// A cache describing the set of module dependencies that has been queried
/// thus far. This cache records/stores the actual Dependency values and can be
@@ -473,6 +477,8 @@ using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
/// ensure that the returned cached dependency was one that can be found in the
/// current scanning action's filesystem view.
class GlobalModuleDependenciesCache {
/// Global cache contents specific to a target-triple specified on a scanner invocation
struct TargetSpecificGlobalCacheState {
/// All cached module dependencies, in the order in which they were
/// encountered.
std::vector<ModuleDependencyID> AllModules;
@@ -481,10 +487,25 @@ class GlobalModuleDependenciesCache {
/// This maps a dependency kind to a map of a module's name to a vector of Dependency objects,
/// which correspond to instances of the same module that may have been found
/// in different sets of search paths.
std::unordered_map<ModuleDependenciesKind,
llvm::StringMap<ModuleDependenciesVector>,
ModuleDependenciesKindHash>
ModuleDependenciesKindMap;
ModuleDependenciesKindMap ModuleDependenciesMap;
};
/// All cached Swift source module dependencies, in the order in which they were encountered
std::vector<ModuleDependencyID> AllSourceModules;
/// Dependencies for all Swift source-based modules discovered. Each one is the main
/// module of a prior invocation of the scanner.
llvm::StringMap<ModuleDependencies> SwiftSourceModuleDependenciesMap;
/// A map from a String representing the target triple of a scanner invocation to the corresponding
/// cached dependencies discovered so far when using this triple.
llvm::StringMap<std::unique_ptr<TargetSpecificGlobalCacheState>> TargetSpecificCacheMap;
/// The current target triple cache configuration
Optional<std::string> CurrentTriple;
/// The triples used by scanners using this cache, in the order in which they were used
std::vector<std::string> AllTriples;
/// Additional information needed for Clang dependency scanning.
ClangModuleDependenciesCacheImpl *clangImpl = nullptr;
@@ -506,13 +527,19 @@ class GlobalModuleDependenciesCache {
getDependenciesMap(ModuleDependenciesKind kind) const;
public:
GlobalModuleDependenciesCache();
GlobalModuleDependenciesCache() {};
GlobalModuleDependenciesCache(const GlobalModuleDependenciesCache &) = delete;
GlobalModuleDependenciesCache &
operator=(const GlobalModuleDependenciesCache &) = delete;
virtual ~GlobalModuleDependenciesCache() { destroyClangImpl(); }
void configureForTriple(std::string triple);
const std::vector<std::string>& getAllTriples() const {
return AllTriples;
}
private:
/// Enforce clients not being allowed to query this cache directly, it must be
/// wrapped in an instance of `ModuleDependenciesCache`.
@@ -542,6 +569,12 @@ private:
Optional<ModuleDependencies>
findDependencies(StringRef moduleName, ModuleLookupSpecifics details) const;
/// Return a pointer to the target-specific cache state of the current triple configuration.
TargetSpecificGlobalCacheState* getCurrentCache() const;
/// Return a pointer to the target-specific cache state of the specified triple configuration.
TargetSpecificGlobalCacheState* getCacheForTriple(StringRef triple) const;
public:
/// Look for module dependencies for a module with the given name.
/// This method has a deliberately-obtuse name to indicate that it is not to
@@ -552,6 +585,10 @@ public:
findAllDependenciesIrrespectiveOfSearchPaths(
StringRef moduleName, Optional<ModuleDependenciesKind> kind) const;
/// Look for source-based module dependency details
Optional<ModuleDependencies>
findSourceModuleDependency(StringRef moduleName) const;
/// Record dependencies for the given module.
const ModuleDependencies *recordDependencies(StringRef moduleName,
ModuleDependencies dependencies);
@@ -560,9 +597,16 @@ public:
const ModuleDependencies *updateDependencies(ModuleDependencyID moduleID,
ModuleDependencies dependencies);
/// Reference the list of all module dependencies.
const std::vector<ModuleDependencyID> &getAllModules() const {
return AllModules;
/// Reference the list of all module dependencies that are not source-based modules
/// (i.e. interface dependencies, binary dependencies, clang dependencies).
const std::vector<ModuleDependencyID> &getAllNonSourceModules(StringRef triple) const {
auto targetSpecificCache = getCacheForTriple(triple);
return targetSpecificCache->AllModules;
}
/// Return the list of all source-based modules discovered by this cache
const std::vector<ModuleDependencyID> &getAllSourceModules() const {
return AllSourceModules;
}
};
@@ -578,10 +622,7 @@ private:
/// References to data in `globalCache` for dependencies accimulated during
/// the current scanning action.
std::unordered_map<ModuleDependenciesKind,
llvm::StringMap<const ModuleDependencies *>,
ModuleDependenciesKindHash>
ModuleDependenciesKindMap;
ModuleDependenciesKindRefMap ModuleDependenciesMap;
/// Retrieve the dependencies map that corresponds to the given dependency
/// kind.
@@ -651,9 +692,8 @@ public:
void updateDependencies(ModuleDependencyID moduleID,
ModuleDependencies dependencies);
/// Reference the list of all module dependencies.
const std::vector<ModuleDependencyID> &getAllModules() const {
return globalCache.getAllModules();
const std::vector<ModuleDependencyID> &getAllSourceModules() const {
return globalCache.getAllSourceModules();
}
};

View File

@@ -57,6 +57,7 @@ using IdentifierIDArryField = llvm::BCArray<IdentifierIDField>;
/// Identifiers used to refer to the above arrays
using FileIDArrayIDField = IdentifierIDField;
using TripleIDField = IdentifierIDField;
using DependencyIDArrayIDField = IdentifierIDField;
using FlagIDArrayIDField = IdentifierIDField;
@@ -118,6 +119,7 @@ using IdentifierArrayLayout =
using ModuleInfoLayout =
BCRecordLayout<MODULE_NODE, // ID
IdentifierIDField, // module name
TripleIDField, // target triple
DependencyIDArrayIDField // directDependencies
>;

View File

@@ -18,20 +18,20 @@
#include "swift/AST/SourceFile.h"
using namespace swift;
ModuleDependenciesStorageBase::~ModuleDependenciesStorageBase() { }
ModuleDependenciesStorageBase::~ModuleDependenciesStorageBase() {}
bool ModuleDependencies::isSwiftModule() const {
return isSwiftInterfaceModule() ||
isSwiftSourceModule() ||
isSwiftBinaryModule() ||
isSwiftPlaceholderModule();
return isSwiftInterfaceModule() || isSwiftSourceModule() ||
isSwiftBinaryModule() || isSwiftPlaceholderModule();
}
ModuleDependenciesKind& operator++(ModuleDependenciesKind& e) {
ModuleDependenciesKind &operator++(ModuleDependenciesKind &e) {
if (e == ModuleDependenciesKind::LastKind) {
llvm_unreachable("Attempting to increment last enum value on ModuleDependenciesKind");
llvm_unreachable(
"Attempting to increment last enum value on ModuleDependenciesKind");
}
e = ModuleDependenciesKind(static_cast<std::underlying_type<ModuleDependenciesKind>::type>(e) + 1);
e = ModuleDependenciesKind(
static_cast<std::underlying_type<ModuleDependenciesKind>::type>(e) + 1);
return e;
}
@@ -111,13 +111,15 @@ void ModuleDependencies::addModuleDependencies(
case swift::ModuleDependenciesKind::SwiftInterface: {
// If the storage is for an interface file, the only source file we
// should see is that interface file.
auto swiftInterfaceStorage = cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
auto swiftInterfaceStorage =
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
assert(fileName == swiftInterfaceStorage->swiftInterfaceFile);
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
// Otherwise, record the source file.
auto swiftSourceStorage = cast<SwiftSourceModuleDependenciesStorage>(storage.get());
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
swiftSourceStorage->sourceFiles.push_back(fileName.str());
break;
}
@@ -129,12 +131,14 @@ void ModuleDependencies::addModuleDependencies(
Optional<std::string> ModuleDependencies::getBridgingHeader() const {
switch (getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
auto swiftInterfaceStorage = cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
return swiftInterfaceStorage->bridgingHeaderFile;
auto swiftInterfaceStorage =
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
return swiftInterfaceStorage->textualModuleDetails.bridgingHeaderFile;
}
case swift::ModuleDependenciesKind::SwiftSource: {
auto swiftSourceStorage = cast<SwiftSourceModuleDependenciesStorage>(storage.get());
return swiftSourceStorage->bridgingHeaderFile;
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
return swiftSourceStorage->textualModuleDetails.bridgingHeaderFile;
}
default:
llvm_unreachable("Unexpected dependency kind");
@@ -144,15 +148,17 @@ Optional<std::string> ModuleDependencies::getBridgingHeader() const {
void ModuleDependencies::addBridgingHeader(StringRef bridgingHeader) {
switch (getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
auto swiftInterfaceStorage = cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
assert(!swiftInterfaceStorage->bridgingHeaderFile);
swiftInterfaceStorage->bridgingHeaderFile = bridgingHeader.str();
auto swiftInterfaceStorage =
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
assert(!swiftInterfaceStorage->textualModuleDetails.bridgingHeaderFile);
swiftInterfaceStorage->textualModuleDetails.bridgingHeaderFile = bridgingHeader.str();
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
auto swiftSourceStorage = cast<SwiftSourceModuleDependenciesStorage>(storage.get());
assert(!swiftSourceStorage->bridgingHeaderFile);
swiftSourceStorage->bridgingHeaderFile = bridgingHeader.str();
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
assert(!swiftSourceStorage->textualModuleDetails.bridgingHeaderFile);
swiftSourceStorage->textualModuleDetails.bridgingHeaderFile = bridgingHeader.str();
break;
}
default:
@@ -164,13 +170,16 @@ void ModuleDependencies::addBridgingHeader(StringRef bridgingHeader) {
void ModuleDependencies::addBridgingSourceFile(StringRef bridgingSourceFile) {
switch (getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
auto swiftInterfaceStorage = cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
swiftInterfaceStorage->bridgingSourceFiles.push_back(bridgingSourceFile.str());
auto swiftInterfaceStorage =
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
swiftInterfaceStorage->textualModuleDetails.bridgingSourceFiles.push_back(
bridgingSourceFile.str());
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
auto swiftSourceStorage = cast<SwiftSourceModuleDependenciesStorage>(storage.get());
swiftSourceStorage->bridgingSourceFiles.push_back(bridgingSourceFile.str());
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
swiftSourceStorage->textualModuleDetails.bridgingSourceFiles.push_back(bridgingSourceFile.str());
break;
}
default:
@@ -180,13 +189,9 @@ void ModuleDependencies::addBridgingSourceFile(StringRef bridgingSourceFile) {
void ModuleDependencies::addSourceFile(StringRef sourceFile) {
switch (getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
auto swiftInterfaceStorage = cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
swiftInterfaceStorage->sourceFiles.push_back(sourceFile.str());
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
auto swiftSourceStorage = cast<SwiftSourceModuleDependenciesStorage>(storage.get());
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
swiftSourceStorage->sourceFiles.push_back(sourceFile.str());
break;
}
@@ -200,15 +205,17 @@ void ModuleDependencies::addBridgingModuleDependency(
StringRef module, llvm::StringSet<> &alreadyAddedModules) {
switch (getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
auto swiftInterfaceStorage = cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
auto swiftInterfaceStorage =
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get());
if (alreadyAddedModules.insert(module).second)
swiftInterfaceStorage->bridgingModuleDependencies.push_back(module.str());
swiftInterfaceStorage->textualModuleDetails.bridgingModuleDependencies.push_back(module.str());
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
auto swiftSourceStorage = cast<SwiftSourceModuleDependenciesStorage>(storage.get());
auto swiftSourceStorage =
cast<SwiftSourceModuleDependenciesStorage>(storage.get());
if (alreadyAddedModules.insert(module).second)
swiftSourceStorage->bridgingModuleDependencies.push_back(module.str());
swiftSourceStorage->textualModuleDetails.bridgingModuleDependencies.push_back(module.str());
break;
}
default:
@@ -216,17 +223,38 @@ void ModuleDependencies::addBridgingModuleDependency(
}
}
GlobalModuleDependenciesCache::TargetSpecificGlobalCacheState *
GlobalModuleDependenciesCache::getCurrentCache() const {
assert(CurrentTriple.hasValue() &&
"Global Module Dependencies Cache not configured with Triple.");
return getCacheForTriple(CurrentTriple.getValue());
}
GlobalModuleDependenciesCache::TargetSpecificGlobalCacheState *
GlobalModuleDependenciesCache::getCacheForTriple(StringRef triple) const {
auto targetSpecificCache = TargetSpecificCacheMap.find(triple);
assert(targetSpecificCache != TargetSpecificCacheMap.end() &&
"Global Module Dependencies Cache not configured with Triple-specific "
"state.");
return targetSpecificCache->getValue().get();
}
llvm::StringMap<ModuleDependenciesVector> &
GlobalModuleDependenciesCache::getDependenciesMap(ModuleDependenciesKind kind) {
auto it = ModuleDependenciesKindMap.find(kind);
assert(it != ModuleDependenciesKindMap.end() && "invalid dependency kind");
auto targetSpecificCache = getCurrentCache();
auto it = targetSpecificCache->ModuleDependenciesMap.find(kind);
assert(it != targetSpecificCache->ModuleDependenciesMap.end() &&
"invalid dependency kind");
return it->second;
}
const llvm::StringMap<ModuleDependenciesVector> &
GlobalModuleDependenciesCache::getDependenciesMap(ModuleDependenciesKind kind) const {
auto it = ModuleDependenciesKindMap.find(kind);
assert(it != ModuleDependenciesKindMap.end() && "invalid dependency kind");
GlobalModuleDependenciesCache::getDependenciesMap(
ModuleDependenciesKind kind) const {
auto targetSpecificCache = getCurrentCache();
auto it = targetSpecificCache->ModuleDependenciesMap.find(kind);
assert(it != targetSpecificCache->ModuleDependenciesMap.end() &&
"invalid dependency kind");
return it->second;
}
@@ -238,7 +266,8 @@ static std::string moduleBasePath(const StringRef modulePath) {
parent = llvm::sys::path::parent_path(parent);
}
// If the module is a part of a framework, disambiguate to the framework's parent
// If the module is a part of a framework, disambiguate to the framework's
// parent
if (llvm::sys::path::filename(parent) == "Modules") {
auto grandParent = llvm::sys::path::parent_path(parent);
if (llvm::sys::path::extension(grandParent) == ".framework") {
@@ -249,15 +278,15 @@ static std::string moduleBasePath(const StringRef modulePath) {
return parent.str();
}
static bool moduleContainedInImportPathSet(const StringRef modulePath,
const llvm::StringSet<> &importPaths)
{
static bool
moduleContainedInImportPathSet(const StringRef modulePath,
const llvm::StringSet<> &importPaths) {
return importPaths.contains(moduleBasePath(modulePath));
}
static bool moduleContainedInImportPathSet(const ModuleDependencies &module,
const llvm::StringSet<> &importPaths)
{
static bool
moduleContainedInImportPathSet(const ModuleDependencies &module,
const llvm::StringSet<> &importPaths) {
std::string modulePath = "";
switch (module.getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
@@ -293,37 +322,45 @@ static bool moduleContainedInImportPathSet(const ModuleDependencies &module,
return false;
}
GlobalModuleDependenciesCache::GlobalModuleDependenciesCache() {
void GlobalModuleDependenciesCache::configureForTriple(std::string triple) {
auto knownTriple = TargetSpecificCacheMap.find(triple);
if (knownTriple != TargetSpecificCacheMap.end()) {
// Set the current triple and leave the rest as-is
CurrentTriple = triple;
} else {
// First time scanning with this triple, initialize target-specific state.
std::unique_ptr<TargetSpecificGlobalCacheState> targetSpecificCache =
std::make_unique<TargetSpecificGlobalCacheState>();
for (auto kind = ModuleDependenciesKind::FirstKind;
kind != ModuleDependenciesKind::LastKind; ++kind) {
ModuleDependenciesKindMap.insert(
targetSpecificCache->ModuleDependenciesMap.insert(
{kind, llvm::StringMap<ModuleDependenciesVector>()});
}
ModuleDependenciesKindMap.insert(
{ModuleDependenciesKind::SwiftBinary,
llvm::StringMap<ModuleDependenciesVector>()});
ModuleDependenciesKindMap.insert(
{ModuleDependenciesKind::SwiftPlaceholder,
llvm::StringMap<ModuleDependenciesVector>()});
ModuleDependenciesKindMap.insert(
{ModuleDependenciesKind::Clang,
llvm::StringMap<ModuleDependenciesVector>()});
TargetSpecificCacheMap.insert({triple, std::move(targetSpecificCache)});
CurrentTriple = triple;
AllTriples.push_back(triple);
}
}
Optional<ModuleDependencies> GlobalModuleDependenciesCache::findDependencies(
StringRef moduleName,
ModuleLookupSpecifics details) const {
StringRef moduleName, ModuleLookupSpecifics details) const {
if (!details.kind) {
for (auto kind = ModuleDependenciesKind::FirstKind;
kind != ModuleDependenciesKind::LastKind; ++kind) {
auto dep = findDependencies(moduleName, {kind, details.currentSearchPaths});
auto dep =
findDependencies(moduleName, {kind, details.currentSearchPaths});
if (dep.hasValue())
return dep.getValue();
}
return None;
}
assert(details.kind.hasValue() && "Expected dependencies kind for lookup.");
if (details.kind.getValue() == swift::ModuleDependenciesKind::SwiftSource) {
return findSourceModuleDependency(moduleName);
}
const auto &map = getDependenciesMap(*details.kind);
auto known = map.find(moduleName);
if (known != map.end()) {
@@ -337,9 +374,18 @@ Optional<ModuleDependencies> GlobalModuleDependenciesCache::findDependencies(
return None;
}
Optional<ModuleDependencies>
GlobalModuleDependenciesCache::findSourceModuleDependency(
StringRef moduleName) const {
auto known = SwiftSourceModuleDependenciesMap.find(moduleName);
if (known != SwiftSourceModuleDependenciesMap.end())
return known->second;
else
return None;
}
bool GlobalModuleDependenciesCache::hasDependencies(
StringRef moduleName,
ModuleLookupSpecifics details) const {
StringRef moduleName, ModuleLookupSpecifics details) const {
return findDependencies(moduleName, details).hasValue();
}
@@ -349,13 +395,17 @@ GlobalModuleDependenciesCache::findAllDependenciesIrrespectiveOfSearchPaths(
if (!kind) {
for (auto kind = ModuleDependenciesKind::FirstKind;
kind != ModuleDependenciesKind::LastKind; ++kind) {
auto deps = findAllDependenciesIrrespectiveOfSearchPaths(moduleName, kind);
auto deps =
findAllDependenciesIrrespectiveOfSearchPaths(moduleName, kind);
if (deps.hasValue())
return deps.getValue();
}
return None;
}
assert(kind.hasValue() && "Expected dependencies kind for lookup.");
assert(kind.getValue() != swift::ModuleDependenciesKind::SwiftSource);
const auto &map = getDependenciesMap(*kind);
auto known = map.find(moduleName);
if (known != map.end()) {
@@ -391,10 +441,22 @@ static std::string modulePathForVerification(const ModuleDependencies &module) {
return existingModulePath;
}
const ModuleDependencies* GlobalModuleDependenciesCache::recordDependencies(
StringRef moduleName,
ModuleDependencies dependencies) {
const ModuleDependencies *GlobalModuleDependenciesCache::recordDependencies(
StringRef moduleName, ModuleDependencies dependencies) {
auto kind = dependencies.getKind();
// Source-based dependencies are recorded independently of the invocation's
// target triple.
if (kind == swift::ModuleDependenciesKind::SwiftSource) {
assert(SwiftSourceModuleDependenciesMap.count(moduleName) == 0 &&
"Attempting to record duplicate SwiftSource dependency.");
SwiftSourceModuleDependenciesMap.insert(
{moduleName, std::move(dependencies)});
AllSourceModules.push_back({moduleName.str(), kind});
return &(SwiftSourceModuleDependenciesMap.find(moduleName)->second);
}
// All other dependencies are recorded according to the target triple of the
// scanning invocation that discovers them.
auto &map = getDependenciesMap(kind);
// Cache may already have a dependency for this module
if (map.count(moduleName) != 0) {
@@ -407,16 +469,26 @@ const ModuleDependencies* GlobalModuleDependenciesCache::recordDependencies(
}
map[moduleName].emplace_back(std::move(dependencies));
return map[moduleName].end()-1;
return map[moduleName].end() - 1;
} else {
map.insert({moduleName, ModuleDependenciesVector{std::move(dependencies)}});
AllModules.push_back({moduleName.str(), kind});
getCurrentCache()->AllModules.push_back({moduleName.str(), kind});
return &(map[moduleName].front());
}
}
const ModuleDependencies* GlobalModuleDependenciesCache::updateDependencies(
const ModuleDependencies *GlobalModuleDependenciesCache::updateDependencies(
ModuleDependencyID moduleID, ModuleDependencies dependencies) {
auto kind = dependencies.getKind();
// Source-based dependencies
if (kind == swift::ModuleDependenciesKind::SwiftSource) {
assert(SwiftSourceModuleDependenciesMap.count(moduleID.first) == 1 &&
"Attempting to update non-existing Swift Source dependency.");
auto known = SwiftSourceModuleDependenciesMap.find(moduleID.first);
known->second = std::move(dependencies);
return &(known->second);
}
auto &map = getDependenciesMap(moduleID.second);
auto known = map.find(moduleID.first);
assert(known != map.end() && "Not yet added to map");
@@ -426,30 +498,33 @@ const ModuleDependencies* GlobalModuleDependenciesCache::updateDependencies(
return &(known->second[0]);
}
llvm::StringMap<const ModuleDependencies*> &
ModuleDependenciesCache::getDependencyReferencesMap(ModuleDependenciesKind kind) {
auto it = ModuleDependenciesKindMap.find(kind);
assert(it != ModuleDependenciesKindMap.end() && "invalid dependency kind");
llvm::StringMap<const ModuleDependencies *> &
ModuleDependenciesCache::getDependencyReferencesMap(
ModuleDependenciesKind kind) {
auto it = ModuleDependenciesMap.find(kind);
assert(it != ModuleDependenciesMap.end() && "invalid dependency kind");
return it->second;
}
const llvm::StringMap<const ModuleDependencies*> &
ModuleDependenciesCache::getDependencyReferencesMap(ModuleDependenciesKind kind) const {
auto it = ModuleDependenciesKindMap.find(kind);
assert(it != ModuleDependenciesKindMap.end() && "invalid dependency kind");
const llvm::StringMap<const ModuleDependencies *> &
ModuleDependenciesCache::getDependencyReferencesMap(
ModuleDependenciesKind kind) const {
auto it = ModuleDependenciesMap.find(kind);
assert(it != ModuleDependenciesMap.end() && "invalid dependency kind");
return it->second;
}
ModuleDependenciesCache::ModuleDependenciesCache(GlobalModuleDependenciesCache &globalCache)
: globalCache(globalCache) {
ModuleDependenciesCache::ModuleDependenciesCache(
GlobalModuleDependenciesCache &globalCache)
: globalCache(globalCache) {
for (auto kind = ModuleDependenciesKind::FirstKind;
kind != ModuleDependenciesKind::LastKind; ++kind) {
ModuleDependenciesKindMap.insert(
ModuleDependenciesMap.insert(
{kind, llvm::StringMap<const ModuleDependencies *>()});
}
}
Optional<const ModuleDependencies*> ModuleDependenciesCache::findDependencies(
Optional<const ModuleDependencies *> ModuleDependenciesCache::findDependencies(
StringRef moduleName, Optional<ModuleDependenciesKind> kind) const {
if (!kind) {
for (auto kind = ModuleDependenciesKind::FirstKind;

View File

@@ -363,12 +363,12 @@ bool ClangImporter::addBridgingHeaderDependencies(
// If we've already recorded bridging header dependencies, we're done.
if (auto swiftInterfaceDeps = targetModule.getAsSwiftInterfaceModule()) {
if (!swiftInterfaceDeps->bridgingSourceFiles.empty() ||
!swiftInterfaceDeps->bridgingModuleDependencies.empty())
if (!swiftInterfaceDeps->textualModuleDetails.bridgingSourceFiles.empty() ||
!swiftInterfaceDeps->textualModuleDetails.bridgingModuleDependencies.empty())
return false;
} else if (auto swiftSourceDeps = targetModule.getAsSwiftSourceModule()) {
if (!swiftSourceDeps->bridgingSourceFiles.empty() ||
!swiftSourceDeps->bridgingModuleDependencies.empty())
if (!swiftSourceDeps->textualModuleDetails.bridgingSourceFiles.empty() ||
!swiftSourceDeps->textualModuleDetails.bridgingModuleDependencies.empty())
return false;
} else {
llvm_unreachable("Unexpected module dependency kind");

View File

@@ -118,7 +118,12 @@ void DependencyScanningTool::resetCache() {
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>
DependencyScanningTool::initScannerForAction(
ArrayRef<const char *> Command) {
return initCompilerInstanceForScan(Command);
auto instanceOrErr = initCompilerInstanceForScan(Command);
if (instanceOrErr.getError())
return instanceOrErr;
SharedCache->configureForTriple((*instanceOrErr)->getInvocation()
.getLangOptions().Target.str());
return instanceOrErr;
}
llvm::ErrorOr<std::unique_ptr<CompilerInstance>>

View File

@@ -151,8 +151,18 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
bool hasCurrentModule = false;
std::string currentModuleName;
unsigned currentTripleID;
llvm::Optional<std::vector<std::string>> currentModuleDependencies;
auto getTriple = [&]() {
assert(currentTripleID &&
"Expected target triple ID for a MODULE_DETAILS_NODE record");
auto triple = getIdentifier(currentTripleID);
if (!triple.hasValue())
llvm::report_fatal_error("Unexpected MODULE_DETAILS_NODE record");
return triple.getValue();
};
while (!Cursor.AtEndOfStream()) {
auto entry = cantFail(Cursor.advance(), "Advance bitstream cursor");
@@ -198,14 +208,14 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
case MODULE_NODE: {
hasCurrentModule = true;
unsigned moduleNameID, moduleDependenciesArrayID;
ModuleInfoLayout::readRecord(Scratch, moduleNameID,
unsigned moduleNameID, tripleID, moduleDependenciesArrayID;
ModuleInfoLayout::readRecord(Scratch, moduleNameID, tripleID,
moduleDependenciesArrayID);
auto moduleName = getIdentifier(moduleNameID);
if (!moduleName)
llvm::report_fatal_error("Bad module name");
currentModuleName = *moduleName;
currentTripleID = tripleID;
currentModuleDependencies = getArray(moduleDependenciesArrayID);
if (!currentModuleDependencies)
llvm::report_fatal_error("Bad direct dependencies");
@@ -216,6 +226,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_TEXTUAL_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned interfaceFileID, compiledModuleCandidatesArrayID,
buildCommandLineArrayID, extraPCMArgsArrayID, contextHashID,
isFramework, bridgingHeaderFileID, sourceFilesArrayID,
@@ -303,11 +314,17 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_SOURCE_MODULE_DETAILS_NODE record");
// Expected triple ID is 0
if (currentTripleID)
llvm::report_fatal_error(
"Unexpected target triple on MODULE_NODE corresponding to a "
"SWIFT_SOURCE_MODULE_DETAILS_NODE record");
unsigned extraPCMArgsArrayID, bridgingHeaderFileID, sourceFilesArrayID,
bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID;
SwiftSourceModuleDetailsLayout::readRecord(
Scratch, extraPCMArgsArrayID, bridgingHeaderFileID, sourceFilesArrayID,
bridgingSourceFilesArrayID, bridgingModuleDependenciesArrayID);
Scratch, extraPCMArgsArrayID, bridgingHeaderFileID,
sourceFilesArrayID, bridgingSourceFilesArrayID,
bridgingModuleDependenciesArrayID);
auto extraPCMArgs = getArray(extraPCMArgsArrayID);
if (!extraPCMArgs)
@@ -363,6 +380,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_BINARY_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned compiledModulePathID, moduleDocPathID, moduleSourceInfoPathID,
isFramework;
SwiftBinaryModuleDetailsLayout::readRecord(
@@ -396,6 +414,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
if (!hasCurrentModule)
llvm::report_fatal_error(
"Unexpected SWIFT_PLACEHOLDER_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned compiledModulePathID, moduleDocPathID, moduleSourceInfoPathID;
SwiftPlaceholderModuleDetailsLayout::readRecord(
Scratch, compiledModulePathID, moduleDocPathID,
@@ -426,6 +445,7 @@ bool Deserializer::readGraph(GlobalModuleDependenciesCache &cache) {
case CLANG_MODULE_DETAILS_NODE: {
if (!hasCurrentModule)
llvm::report_fatal_error("Unexpected CLANG_MODULE_DETAILS_NODE record");
cache.configureForTriple(getTriple());
unsigned moduleMapPathID, contextHashID, commandLineArrayID,
fileDependenciesArrayID;
ClangModuleDetailsLayout::readRecord(Scratch, moduleMapPathID,
@@ -647,13 +667,15 @@ class Serializer {
void writeArraysOfIdentifiers();
void writeModuleInfo(ModuleDependencyID moduleID,
Optional<std::string> triple,
const ModuleDependencies &dependencyInfo);
public:
Serializer(llvm::BitstreamWriter &ExistingOut) : Out(ExistingOut) {}
public:
void writeInterModuleDependenciesCache(const GlobalModuleDependenciesCache &cache);
void
writeInterModuleDependenciesCache(const GlobalModuleDependenciesCache &cache);
};
} // end namespace
@@ -735,22 +757,27 @@ void Serializer::writeArraysOfIdentifiers() {
}
void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
Optional<std::string> triple,
const ModuleDependencies &dependencyInfo) {
using namespace graph_block;
auto tripleStrID = triple.hasValue() ? getIdentifier(triple.getValue()) : 0;
ModuleInfoLayout::emitRecord(
Out, ScratchRecord, AbbrCodes[ModuleInfoLayout::Code],
getIdentifier(moduleID.first),
getIdentifier(moduleID.first), tripleStrID,
getArray(moduleID, ModuleIdentifierArrayKind::DirectDependencies));
switch (dependencyInfo.getKind()) {
case swift::ModuleDependenciesKind::SwiftInterface: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto swiftTextDeps = dependencyInfo.getAsSwiftInterfaceModule();
assert(swiftTextDeps);
unsigned swiftInterfaceFileId = getIdentifier(swiftTextDeps->swiftInterfaceFile);
unsigned swiftInterfaceFileId =
getIdentifier(swiftTextDeps->swiftInterfaceFile);
unsigned bridgingHeaderFileId =
swiftTextDeps->bridgingHeaderFile
? getIdentifier(swiftTextDeps->bridgingHeaderFile.getValue())
swiftTextDeps->textualModuleDetails.bridgingHeaderFile
? getIdentifier(swiftTextDeps->textualModuleDetails
.bridgingHeaderFile.getValue())
: 0;
SwiftInterfaceModuleDetailsLayout::emitRecord(
Out, ScratchRecord, AbbrCodes[SwiftInterfaceModuleDetailsLayout::Code],
@@ -767,11 +794,14 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
assert(!triple.hasValue() &&
"Did not expecte triple for serializing MODULE_NODE");
auto swiftSourceDeps = dependencyInfo.getAsSwiftSourceModule();
assert(swiftSourceDeps);
unsigned bridgingHeaderFileId =
swiftSourceDeps->bridgingHeaderFile
? getIdentifier(swiftSourceDeps->bridgingHeaderFile.getValue())
swiftSourceDeps->textualModuleDetails.bridgingHeaderFile
? getIdentifier(swiftSourceDeps->textualModuleDetails
.bridgingHeaderFile.getValue())
: 0;
SwiftSourceModuleDetailsLayout::emitRecord(
Out, ScratchRecord, AbbrCodes[SwiftSourceModuleDetailsLayout::Code],
@@ -784,6 +814,7 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::SwiftBinary: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto swiftBinDeps = dependencyInfo.getAsSwiftBinaryModule();
assert(swiftBinDeps);
SwiftBinaryModuleDetailsLayout::emitRecord(
@@ -795,6 +826,7 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::SwiftPlaceholder: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto swiftPHDeps = dependencyInfo.getAsPlaceholderDependencyModule();
assert(swiftPHDeps);
SwiftPlaceholderModuleDetailsLayout::emitRecord(
@@ -806,6 +838,7 @@ void Serializer::writeModuleInfo(ModuleDependencyID moduleID,
break;
}
case swift::ModuleDependenciesKind::Clang: {
assert(triple.hasValue() && "Expected triple for serializing MODULE_NODE");
auto clangDeps = dependencyInfo.getAsClangModule();
assert(clangDeps);
ClangModuleDetailsLayout::emitRecord(
@@ -889,8 +922,38 @@ unsigned Serializer::getArray(ModuleDependencyID moduleID,
return arrayIter->second;
}
void Serializer::collectStringsAndArrays(const GlobalModuleDependenciesCache &cache) {
for (auto &moduleID : cache.getAllModules()) {
void Serializer::collectStringsAndArrays(
const GlobalModuleDependenciesCache &cache) {
for (auto &moduleID : cache.getAllSourceModules()) {
assert(moduleID.second == ModuleDependenciesKind::SwiftSource &&
"Expected source-based dependency");
auto optionalDependencyInfo =
cache.findSourceModuleDependency(moduleID.first);
assert(optionalDependencyInfo.hasValue() && "Expected dependency info.");
auto dependencyInfo = optionalDependencyInfo.getValue();
// Add the module's name
addIdentifier(moduleID.first);
// Add the module's dependencies
addArray(moduleID, ModuleIdentifierArrayKind::DirectDependencies,
dependencyInfo.getModuleDependencies());
auto swiftSourceDeps = dependencyInfo.getAsSwiftSourceModule();
assert(swiftSourceDeps);
addArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs,
swiftSourceDeps->textualModuleDetails.extraPCMArgs);
if (swiftSourceDeps->textualModuleDetails.bridgingHeaderFile.hasValue())
addIdentifier(
swiftSourceDeps->textualModuleDetails.bridgingHeaderFile.getValue());
addArray(moduleID, ModuleIdentifierArrayKind::SourceFiles,
swiftSourceDeps->sourceFiles);
addArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles,
swiftSourceDeps->textualModuleDetails.bridgingSourceFiles);
addArray(moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftSourceDeps->textualModuleDetails.bridgingModuleDependencies);
}
for (auto &triple : cache.getAllTriples()) {
addIdentifier(triple);
for (auto &moduleID : cache.getAllNonSourceModules(triple)) {
auto dependencyInfos = cache.findAllDependenciesIrrespectiveOfSearchPaths(
moduleID.first, moduleID.second);
assert(dependencyInfos.hasValue() && "Expected dependency info.");
@@ -907,38 +970,24 @@ void Serializer::collectStringsAndArrays(const GlobalModuleDependenciesCache &ca
auto swiftTextDeps = dependencyInfo.getAsSwiftInterfaceModule();
assert(swiftTextDeps);
addIdentifier(swiftTextDeps->swiftInterfaceFile);
addArray(moduleID, ModuleIdentifierArrayKind::CompiledModuleCandidates,
addArray(moduleID,
ModuleIdentifierArrayKind::CompiledModuleCandidates,
swiftTextDeps->compiledModuleCandidates);
addArray(moduleID, ModuleIdentifierArrayKind::BuildCommandLine,
swiftTextDeps->buildCommandLine);
addArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs,
swiftTextDeps->extraPCMArgs);
swiftTextDeps->textualModuleDetails.extraPCMArgs);
addIdentifier(swiftTextDeps->contextHash);
if (swiftTextDeps->bridgingHeaderFile)
addIdentifier(swiftTextDeps->bridgingHeaderFile.getValue());
if (swiftTextDeps->textualModuleDetails.bridgingHeaderFile.hasValue())
addIdentifier(swiftTextDeps->textualModuleDetails.bridgingHeaderFile
.getValue());
addArray(moduleID, ModuleIdentifierArrayKind::SourceFiles,
swiftTextDeps->sourceFiles);
std::vector<std::string>());
addArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles,
swiftTextDeps->bridgingSourceFiles);
addArray(moduleID,
ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftTextDeps->bridgingModuleDependencies);
break;
}
case swift::ModuleDependenciesKind::SwiftSource: {
auto swiftSourceDeps = dependencyInfo.getAsSwiftSourceModule();
assert(swiftSourceDeps);
addArray(moduleID, ModuleIdentifierArrayKind::ExtraPCMArgs,
swiftSourceDeps->extraPCMArgs);
if (swiftSourceDeps->bridgingHeaderFile)
addIdentifier(swiftSourceDeps->bridgingHeaderFile.getValue());
addArray(moduleID, ModuleIdentifierArrayKind::SourceFiles,
swiftSourceDeps->sourceFiles);
addArray(moduleID, ModuleIdentifierArrayKind::BridgingSourceFiles,
swiftSourceDeps->bridgingSourceFiles);
addArray(moduleID,
ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftSourceDeps->bridgingModuleDependencies);
swiftTextDeps->textualModuleDetails.bridgingSourceFiles);
addArray(
moduleID, ModuleIdentifierArrayKind::BridgingModuleDependencies,
swiftTextDeps->textualModuleDetails.bridgingModuleDependencies);
break;
}
case swift::ModuleDependenciesKind::SwiftBinary: {
@@ -973,6 +1022,7 @@ void Serializer::collectStringsAndArrays(const GlobalModuleDependenciesCache &ca
}
}
}
}
}
void Serializer::writeInterModuleDependenciesCache(
@@ -1011,12 +1061,24 @@ void Serializer::writeInterModuleDependenciesCache(
writeArraysOfIdentifiers();
// Write the core graph
for (auto &moduleID : cache.getAllModules()) {
// First, write the source modules we've encountered
for (auto &moduleID : cache.getAllSourceModules()) {
auto dependencyInfo = cache.findSourceModuleDependency(moduleID.first);
assert(dependencyInfo.hasValue() && "Expected dependency info.");
writeModuleInfo(moduleID, llvm::Optional<std::string>(),
dependencyInfo.getValue());
}
// Write all non-source modules, for each of the target triples this scanner
// has been used with
for (auto &triple : cache.getAllTriples()) {
for (auto &moduleID : cache.getAllNonSourceModules(triple)) {
auto dependencyInfos = cache.findAllDependenciesIrrespectiveOfSearchPaths(
moduleID.first, moduleID.second);
assert(dependencyInfos.hasValue() && "Expected dependency info.");
for (auto &dependencyInfo : *dependencyInfos) {
writeModuleInfo(moduleID, dependencyInfo);
writeModuleInfo(moduleID, triple, dependencyInfo);
}
}
}
@@ -1024,14 +1086,16 @@ void Serializer::writeInterModuleDependenciesCache(
}
void swift::dependencies::module_dependency_cache_serialization::
writeInterModuleDependenciesCache(llvm::BitstreamWriter &Out,
writeInterModuleDependenciesCache(
llvm::BitstreamWriter &Out,
const GlobalModuleDependenciesCache &cache) {
Serializer serializer{Out};
serializer.writeInterModuleDependenciesCache(cache);
}
bool swift::dependencies::module_dependency_cache_serialization::
writeInterModuleDependenciesCache(DiagnosticEngine &diags, StringRef path,
writeInterModuleDependenciesCache(
DiagnosticEngine &diags, StringRef path,
const GlobalModuleDependenciesCache &cache) {
PrettyStackTraceStringAction stackTrace(
"saving inter-module dependency graph", path);

View File

@@ -199,17 +199,17 @@ resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
// Add the Clang modules referenced from the bridging header to the
// set of Clang modules we know about.
if (auto swiftDeps = knownDependencies.getAsSwiftInterfaceModule()) {
for (const auto &clangDep : swiftDeps->bridgingModuleDependencies) {
const std::vector<std::string> *bridgingModuleDependencies = nullptr;
if (auto swiftDeps = knownDependencies.getAsSwiftInterfaceModule())
bridgingModuleDependencies = &(swiftDeps->textualModuleDetails.bridgingModuleDependencies);
else if (auto sourceDeps = knownDependencies.getAsSwiftSourceModule())
bridgingModuleDependencies = &(sourceDeps->textualModuleDetails.bridgingModuleDependencies);
assert(bridgingModuleDependencies);
for (const auto &clangDep : *bridgingModuleDependencies) {
findAllImportedClangModules(ctx, clangDep, cache, allClangModules,
knownModules);
}
} else if (auto sourceDeps = knownDependencies.getAsSwiftSourceModule()) {
for (const auto &clangDep : sourceDeps->bridgingModuleDependencies) {
findAllImportedClangModules(ctx, clangDep, cache, allClangModules,
knownModules);
}
}
}
}
@@ -376,20 +376,16 @@ void writeEncodedModuleIdJSONValue(llvm::raw_ostream &out,
swiftscan_string_ref_t value,
unsigned indentLevel) {
out << "{\n";
static const std::string interfacePrefix("swiftInterface");
static const std::string sourcePrefix("swiftSource");
static const std::string textualPrefix("swiftTextual");
static const std::string binaryPrefix("swiftBinary");
static const std::string placeholderPrefix("swiftPlaceholder");
static const std::string clangPrefix("clang");
std::string valueStr = get_C_string(value);
std::string moduleKind;
std::string moduleName;
if (!valueStr.compare(0, interfacePrefix.size(), interfacePrefix)) {
if (!valueStr.compare(0, textualPrefix.size(), textualPrefix)) {
moduleKind = "swift";
moduleName = valueStr.substr(interfacePrefix.size() + 1);
} else if (!valueStr.compare(0, sourcePrefix.size(), sourcePrefix)) {
moduleKind = "swiftSource";
moduleName = valueStr.substr(sourcePrefix.size() + 1);
moduleName = valueStr.substr(textualPrefix.size() + 1);
} else if (!valueStr.compare(0, binaryPrefix.size(), binaryPrefix)) {
// FIXME: rename to be consistent in the clients (swift-driver)
moduleKind = "swiftPrebuiltExternal";
@@ -800,9 +796,7 @@ generateFullDependencyGraph(CompilerInstance &instance,
// SourceFiles
std::vector<std::string> sourceFiles;
if (swiftTextualDeps) {
sourceFiles = swiftTextualDeps->sourceFiles;
} else if (swiftSourceDeps) {
if (swiftSourceDeps) {
sourceFiles = swiftSourceDeps->sourceFiles;
} else if (clangDeps) {
sourceFiles = clangDeps->fileDependencies;
@@ -820,9 +814,9 @@ generateFullDependencyGraph(CompilerInstance &instance,
swiftscan_string_ref_t moduleInterfacePath =
create_clone(swiftTextualDeps->swiftInterfaceFile.c_str());
swiftscan_string_ref_t bridgingHeaderPath =
swiftTextualDeps->bridgingHeaderFile.hasValue()
swiftTextualDeps->textualModuleDetails.bridgingHeaderFile.hasValue()
? create_clone(
swiftTextualDeps->bridgingHeaderFile.getValue().c_str())
swiftTextualDeps->textualModuleDetails.bridgingHeaderFile.getValue().c_str())
: create_null();
details->kind = SWIFTSCAN_DEPENDENCY_INFO_SWIFT_TEXTUAL;
@@ -831,18 +825,18 @@ generateFullDependencyGraph(CompilerInstance &instance,
moduleInterfacePath,
create_set(swiftTextualDeps->compiledModuleCandidates),
bridgingHeaderPath,
create_set(swiftTextualDeps->bridgingSourceFiles),
create_set(swiftTextualDeps->bridgingModuleDependencies),
create_set(swiftTextualDeps->textualModuleDetails.bridgingSourceFiles),
create_set(swiftTextualDeps->textualModuleDetails.bridgingModuleDependencies),
create_set(swiftTextualDeps->buildCommandLine),
create_set(swiftTextualDeps->extraPCMArgs),
create_set(swiftTextualDeps->textualModuleDetails.extraPCMArgs),
create_clone(swiftTextualDeps->contextHash.c_str()),
swiftTextualDeps->isFramework};
} else if (swiftSourceDeps) {
swiftscan_string_ref_t moduleInterfacePath = create_null();
swiftscan_string_ref_t bridgingHeaderPath =
swiftSourceDeps->bridgingHeaderFile.hasValue()
swiftSourceDeps->textualModuleDetails.bridgingHeaderFile.hasValue()
? create_clone(
swiftSourceDeps->bridgingHeaderFile.getValue().c_str())
swiftSourceDeps->textualModuleDetails.bridgingHeaderFile.getValue().c_str())
: create_null();
// TODO: Once the clients are taught about the new dependency kind,
// switch to using a bespoke kind here.
@@ -852,10 +846,10 @@ generateFullDependencyGraph(CompilerInstance &instance,
moduleInterfacePath,
create_empty_set(),
bridgingHeaderPath,
create_set(swiftSourceDeps->bridgingSourceFiles),
create_set(swiftSourceDeps->bridgingModuleDependencies),
create_set(swiftSourceDeps->textualModuleDetails.bridgingSourceFiles),
create_set(swiftSourceDeps->textualModuleDetails.bridgingModuleDependencies),
create_empty_set(),
create_set(swiftSourceDeps->extraPCMArgs),
create_set(swiftSourceDeps->textualModuleDetails.extraPCMArgs),
/*contextHash*/create_null(),
/*isFramework*/false};
} else if (swiftPlaceholderDeps) {
@@ -1063,6 +1057,7 @@ forEachBatchEntry(CompilerInstance &invocationInstance,
std::make_unique<ModuleDependenciesCache>(*newGlobalCache))});
pInstance = std::get<0>((*subInstanceMap)[entry.arguments]).get();
auto globalCache = std::get<1>((*subInstanceMap)[entry.arguments]).get();
pCache = std::get<2>((*subInstanceMap)[entry.arguments]).get();
SmallVector<const char *, 4> args;
llvm::cl::TokenizeGNUCommandLine(entry.arguments, saver, args);
@@ -1078,6 +1073,8 @@ forEachBatchEntry(CompilerInstance &invocationInstance,
SourceLoc(), diag::scanner_arguments_invalid, entry.arguments);
return true;
}
globalCache->configureForTriple(pInstance->getInvocation()
.getLangOptions().Target.str());
}
assert(pInstance);
assert(pCache);
@@ -1209,6 +1206,9 @@ bool swift::dependencies::scanDependencies(CompilerInstance &instance) {
// `-scan-dependencies` invocations use a single new instance
// of a module cache
GlobalModuleDependenciesCache globalCache;
globalCache.configureForTriple(instance.getInvocation()
.getLangOptions().Target.str());
if (opts.ReuseDependencyScannerCache)
deserializeDependencyCache(instance, globalCache);
@@ -1245,6 +1245,8 @@ bool swift::dependencies::prescanDependencies(CompilerInstance &instance) {
// `-scan-dependencies` invocations use a single new instance
// of a module cache
GlobalModuleDependenciesCache singleUseGlobalCache;
singleUseGlobalCache.configureForTriple(instance.getInvocation()
.getLangOptions().Target.str());
ModuleDependenciesCache cache(singleUseGlobalCache);
if (out.has_error() || EC) {
Context.Diags.diagnose(SourceLoc(), diag::error_opening_output, path,
@@ -1274,6 +1276,8 @@ bool swift::dependencies::batchScanDependencies(
// The primary cache used for scans carried out with the compiler instance
// we have created
GlobalModuleDependenciesCache singleUseGlobalCache;
singleUseGlobalCache.configureForTriple(instance.getInvocation()
.getLangOptions().Target.str());
ModuleDependenciesCache cache(singleUseGlobalCache);
(void)instance.getMainModule();
llvm::BumpPtrAllocator alloc;
@@ -1307,6 +1311,8 @@ bool swift::dependencies::batchPrescanDependencies(
// The primary cache used for scans carried out with the compiler instance
// we have created
GlobalModuleDependenciesCache singleUseGlobalCache;
singleUseGlobalCache.configureForTriple(instance.getInvocation()
.getLangOptions().Target.str());
ModuleDependenciesCache cache(singleUseGlobalCache);
(void)instance.getMainModule();
llvm::BumpPtrAllocator alloc;
@@ -1412,14 +1418,12 @@ swift::dependencies::performModuleScan(CompilerInstance &instance,
if (auto swiftDeps = deps->getAsSwiftInterfaceModule()) {
depTracker->addDependency(swiftDeps->swiftInterfaceFile, /*IsSystem=*/false);
for (const auto &sourceFile : swiftDeps->sourceFiles)
depTracker->addDependency(sourceFile, /*IsSystem=*/false);
for (const auto &bridgingSourceFile : swiftDeps->bridgingSourceFiles)
for (const auto &bridgingSourceFile : swiftDeps->textualModuleDetails.bridgingSourceFiles)
depTracker->addDependency(bridgingSourceFile, /*IsSystem=*/false);
} else if (auto swiftSourceDeps = deps->getAsSwiftSourceModule()) {
for (const auto &sourceFile : swiftSourceDeps->sourceFiles)
depTracker->addDependency(sourceFile, /*IsSystem=*/false);
for (const auto &bridgingSourceFile : swiftSourceDeps->bridgingSourceFiles)
for (const auto &bridgingSourceFile : swiftSourceDeps->textualModuleDetails.bridgingSourceFiles)
depTracker->addDependency(bridgingSourceFile, /*IsSystem=*/false);
} else if (auto clangDeps = deps->getAsClangModule()) {
if (!clangDeps->moduleMapFile.empty())

View File

@@ -438,6 +438,7 @@ swiftscan_scan_invocation_get_argv(swiftscan_scan_invocation_t invocation) {
void swiftscan_string_set_dispose(swiftscan_string_set_t *set) {
for (unsigned SI = 0, SE = set->count; SI < SE; ++SI)
swiftscan_string_dispose(set->strings[SI]);
if (set->count > 0)
delete[] set->strings;
delete set;
}