Skip to content

Commit 1d25b89

Browse files
authored
Merge pull request #39374 from artemcm/55MultiTargetScan
[5.5][Dependency Scanning] Make dependency scanner cache specific to a given target triple.
2 parents 5e0d32b + fdd9125 commit 1d25b89

17 files changed

+877
-371
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ typedef struct {
4949
} swiftscan_string_set_t;
5050

5151
typedef enum {
52+
// This dependency info encodes two ModuleDependencyKind types:
53+
// SwiftInterface and SwiftSource.
5254
SWIFTSCAN_DEPENDENCY_INFO_SWIFT_TEXTUAL = 0,
5355
SWIFTSCAN_DEPENDENCY_INFO_SWIFT_BINARY = 1,
5456
SWIFTSCAN_DEPENDENCY_INFO_SWIFT_PLACEHOLDER = 2,

include/swift/AST/ModuleDependencies.h

Lines changed: 144 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Identifier;
3737
/// Which kind of module dependencies we are looking for.
3838
enum class ModuleDependenciesKind : int8_t {
3939
FirstKind,
40-
SwiftTextual = FirstKind,
40+
SwiftInterface = FirstKind,
4141
SwiftBinary,
4242
// Placeholder dependencies are a kind of dependencies used only by the
4343
// dependency scanner. They are swift modules that the scanner will not be
@@ -63,7 +63,8 @@ enum class ModuleDependenciesKind : int8_t {
6363
// of all targets, individually, have been computed.
6464
SwiftPlaceholder,
6565
Clang,
66-
LastKind = Clang + 1
66+
SwiftSource,
67+
LastKind = SwiftSource + 1
6768
};
6869

6970
struct ModuleDependenciesKindHash {
@@ -97,14 +98,33 @@ class ModuleDependenciesStorageBase {
9798
std::vector<std::string> moduleDependencies;
9899
};
99100

100-
/// Describes the dependencies of a Swift module.
101+
struct CommonSwiftTextualModuleDependencyDetails {
102+
CommonSwiftTextualModuleDependencyDetails(ArrayRef<StringRef> extraPCMArgs)
103+
: extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()) {}
104+
105+
/// To build a PCM to be used by this Swift module, we need to append these
106+
/// arguments to the generic PCM build arguments reported from the dependency
107+
/// graph.
108+
const std::vector<std::string> extraPCMArgs;
109+
110+
/// Bridging header file, if there is one.
111+
Optional<std::string> bridgingHeaderFile;
112+
113+
/// Source files on which the bridging header depends.
114+
std::vector<std::string> bridgingSourceFiles;
115+
116+
/// (Clang) modules on which the bridging header depends.
117+
std::vector<std::string> bridgingModuleDependencies;
118+
};
119+
120+
/// Describes the dependencies of a Swift module described by an Swift interface file.
101121
///
102122
/// This class is mostly an implementation detail for \c ModuleDependencies.
103-
class SwiftTextualModuleDependenciesStorage :
123+
class SwiftInterfaceModuleDependenciesStorage :
104124
public ModuleDependenciesStorageBase {
105125
public:
106-
/// The Swift interface file, if it can be used to generate the module file.
107-
const Optional<std::string> swiftInterfaceFile;
126+
/// The Swift interface file to be used to generate the module file.
127+
const std::string swiftInterfaceFile;
108128

109129
/// Potentially ready-to-use compiled modules for the interface file.
110130
const std::vector<std::string> compiledModuleCandidates;
@@ -113,50 +133,64 @@ class SwiftTextualModuleDependenciesStorage :
113133
/// interface.
114134
const std::vector<std::string> buildCommandLine;
115135

116-
/// To build a PCM to be used by this Swift module, we need to append these
117-
/// arguments to the generic PCM build arguments reported from the dependency
118-
/// graph.
119-
const std::vector<std::string> extraPCMArgs;
120-
121136
/// The hash value that will be used for the generated module
122137
const std::string contextHash;
123138

124139
/// A flag that indicates this dependency is a framework
125140
const bool isFramework;
126141

127-
/// Bridging header file, if there is one.
128-
Optional<std::string> bridgingHeaderFile;
129-
130-
/// Swift source files that are part of the Swift module, when known.
131-
std::vector<std::string> sourceFiles;
142+
/// Details common to Swift textual (interface or source) modules
143+
CommonSwiftTextualModuleDependencyDetails textualModuleDetails;
132144

133-
/// Source files on which the bridging header depends.
134-
std::vector<std::string> bridgingSourceFiles;
135-
136-
/// (Clang) modules on which the bridging header depends.
137-
std::vector<std::string> bridgingModuleDependencies;
138-
139-
SwiftTextualModuleDependenciesStorage(
140-
const Optional<std::string> &swiftInterfaceFile,
145+
SwiftInterfaceModuleDependenciesStorage(
146+
const std::string swiftInterfaceFile,
141147
ArrayRef<std::string> compiledModuleCandidates,
142148
ArrayRef<StringRef> buildCommandLine,
143149
ArrayRef<StringRef> extraPCMArgs,
144150
StringRef contextHash,
145151
bool isFramework
146-
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftTextual),
152+
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftInterface),
147153
swiftInterfaceFile(swiftInterfaceFile),
148154
compiledModuleCandidates(compiledModuleCandidates.begin(),
149155
compiledModuleCandidates.end()),
150156
buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()),
151-
extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()),
152-
contextHash(contextHash), isFramework(isFramework) { }
157+
contextHash(contextHash), isFramework(isFramework),
158+
textualModuleDetails(extraPCMArgs)
159+
{}
153160

154161
ModuleDependenciesStorageBase *clone() const override {
155-
return new SwiftTextualModuleDependenciesStorage(*this);
162+
return new SwiftInterfaceModuleDependenciesStorage(*this);
156163
}
157164

158165
static bool classof(const ModuleDependenciesStorageBase *base) {
159-
return base->dependencyKind == ModuleDependenciesKind::SwiftTextual;
166+
return base->dependencyKind == ModuleDependenciesKind::SwiftInterface;
167+
}
168+
};
169+
170+
/// Describes the dependencies of a Swift module
171+
///
172+
/// This class is mostly an implementation detail for \c ModuleDependencies.
173+
class SwiftSourceModuleDependenciesStorage :
174+
public ModuleDependenciesStorageBase {
175+
public:
176+
177+
/// Swift source files that are part of the Swift module, when known.
178+
std::vector<std::string> sourceFiles;
179+
180+
/// Details common to Swift textual (interface or source) modules
181+
CommonSwiftTextualModuleDependencyDetails textualModuleDetails;
182+
183+
SwiftSourceModuleDependenciesStorage(
184+
ArrayRef<StringRef> extraPCMArgs
185+
) : ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftSource),
186+
textualModuleDetails(extraPCMArgs) {}
187+
188+
ModuleDependenciesStorageBase *clone() const override {
189+
return new SwiftSourceModuleDependenciesStorage(*this);
190+
}
191+
192+
static bool classof(const ModuleDependenciesStorageBase *base) {
193+
return base->dependencyKind == ModuleDependenciesKind::SwiftSource;
160194
}
161195
};
162196

@@ -291,15 +325,15 @@ class ModuleDependencies {
291325

292326
/// Describe the module dependencies for a Swift module that can be
293327
/// built from a Swift interface file (\c .swiftinterface).
294-
static ModuleDependencies forSwiftTextualModule(
295-
const Optional<std::string> &swiftInterfaceFile,
328+
static ModuleDependencies forSwiftInterfaceModule(
329+
std::string swiftInterfaceFile,
296330
ArrayRef<std::string> compiledCandidates,
297331
ArrayRef<StringRef> buildCommands,
298332
ArrayRef<StringRef> extraPCMArgs,
299333
StringRef contextHash,
300334
bool isFramework) {
301335
return ModuleDependencies(
302-
std::make_unique<SwiftTextualModuleDependenciesStorage>(
336+
std::make_unique<SwiftInterfaceModuleDependenciesStorage>(
303337
swiftInterfaceFile, compiledCandidates, buildCommands,
304338
extraPCMArgs, contextHash, isFramework));
305339
}
@@ -316,11 +350,9 @@ class ModuleDependencies {
316350
}
317351

318352
/// Describe the main Swift module.
319-
static ModuleDependencies forMainSwiftModule(ArrayRef<StringRef> extraPCMArgs) {
353+
static ModuleDependencies forSwiftSourceModule(ArrayRef<StringRef> extraPCMArgs) {
320354
return ModuleDependencies(
321-
std::make_unique<SwiftTextualModuleDependenciesStorage>(
322-
None, ArrayRef<std::string>(), ArrayRef<StringRef>(),
323-
extraPCMArgs, StringRef(), false));
355+
std::make_unique<SwiftSourceModuleDependenciesStorage>(extraPCMArgs));
324356
}
325357

326358
/// Describe the module dependencies for a Clang module that can be
@@ -350,11 +382,14 @@ class ModuleDependencies {
350382
return storage->moduleDependencies;
351383
}
352384

353-
/// Whether the dependencies are for a Swift module: either Textual, Binary, or Placeholder.
385+
/// Whether the dependencies are for a Swift module: either Textual, Source, Binary, or Placeholder.
354386
bool isSwiftModule() const;
355387

356388
/// Whether the dependencies are for a textual Swift module.
357-
bool isSwiftTextualModule() const;
389+
bool isSwiftInterfaceModule() const;
390+
391+
/// Whether the dependencies are for a textual Swift module.
392+
bool isSwiftSourceModule() const;
358393

359394
/// Whether the dependencies are for a binary Swift module.
360395
bool isSwiftBinaryModule() const;
@@ -368,8 +403,11 @@ class ModuleDependencies {
368403
ModuleDependenciesKind getKind() const {
369404
return storage->dependencyKind;
370405
}
406+
/// Retrieve the dependencies for a Swift textual-interface module.
407+
const SwiftInterfaceModuleDependenciesStorage *getAsSwiftInterfaceModule() const;
408+
371409
/// Retrieve the dependencies for a Swift module.
372-
const SwiftTextualModuleDependenciesStorage *getAsSwiftTextualModule() const;
410+
const SwiftSourceModuleDependenciesStorage *getAsSwiftSourceModule() const;
373411

374412
/// Retrieve the dependencies for a binary Swift module.
375413
const SwiftBinaryModuleDependencyStorage *getAsSwiftBinaryModule() const;
@@ -420,6 +458,14 @@ class ModuleDependencies {
420458

421459
using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
422460
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
461+
using ModuleDependenciesKindMap =
462+
std::unordered_map<ModuleDependenciesKind,
463+
llvm::StringMap<ModuleDependenciesVector>,
464+
ModuleDependenciesKindHash>;
465+
using ModuleDependenciesKindRefMap =
466+
std::unordered_map<ModuleDependenciesKind,
467+
llvm::StringMap<const ModuleDependencies *>,
468+
ModuleDependenciesKindHash>;
423469

424470
/// A cache describing the set of module dependencies that has been queried
425471
/// thus far. This cache records/stores the actual Dependency values and can be
@@ -431,18 +477,35 @@ using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1>;
431477
/// ensure that the returned cached dependency was one that can be found in the
432478
/// current scanning action's filesystem view.
433479
class GlobalModuleDependenciesCache {
434-
/// All cached module dependencies, in the order in which they were
435-
/// encountered.
436-
std::vector<ModuleDependencyID> AllModules;
437-
438-
/// Dependencies for modules that have already been computed.
439-
/// This maps a dependency kind to a map of a module's name to a vector of Dependency objects,
440-
/// which correspond to instances of the same module that may have been found
441-
/// in different sets of search paths.
442-
std::unordered_map<ModuleDependenciesKind,
443-
llvm::StringMap<ModuleDependenciesVector>,
444-
ModuleDependenciesKindHash>
445-
ModuleDependenciesKindMap;
480+
/// Global cache contents specific to a target-triple specified on a scanner invocation
481+
struct TargetSpecificGlobalCacheState {
482+
/// All cached module dependencies, in the order in which they were
483+
/// encountered.
484+
std::vector<ModuleDependencyID> AllModules;
485+
486+
/// Dependencies for modules that have already been computed.
487+
/// This maps a dependency kind to a map of a module's name to a vector of Dependency objects,
488+
/// which correspond to instances of the same module that may have been found
489+
/// in different sets of search paths.
490+
ModuleDependenciesKindMap ModuleDependenciesMap;
491+
};
492+
493+
/// All cached Swift source module dependencies, in the order in which they were encountered
494+
std::vector<ModuleDependencyID> AllSourceModules;
495+
496+
/// Dependencies for all Swift source-based modules discovered. Each one is the main
497+
/// module of a prior invocation of the scanner.
498+
llvm::StringMap<ModuleDependencies> SwiftSourceModuleDependenciesMap;
499+
500+
/// A map from a String representing the target triple of a scanner invocation to the corresponding
501+
/// cached dependencies discovered so far when using this triple.
502+
llvm::StringMap<std::unique_ptr<TargetSpecificGlobalCacheState>> TargetSpecificCacheMap;
503+
504+
/// The current target triple cache configuration
505+
Optional<std::string> CurrentTriple;
506+
507+
/// The triples used by scanners using this cache, in the order in which they were used
508+
std::vector<std::string> AllTriples;
446509

447510
/// Additional information needed for Clang dependency scanning.
448511
ClangModuleDependenciesCacheImpl *clangImpl = nullptr;
@@ -464,13 +527,19 @@ class GlobalModuleDependenciesCache {
464527
getDependenciesMap(ModuleDependenciesKind kind) const;
465528

466529
public:
467-
GlobalModuleDependenciesCache();
530+
GlobalModuleDependenciesCache() {};
468531
GlobalModuleDependenciesCache(const GlobalModuleDependenciesCache &) = delete;
469532
GlobalModuleDependenciesCache &
470533
operator=(const GlobalModuleDependenciesCache &) = delete;
471534

472535
virtual ~GlobalModuleDependenciesCache() { destroyClangImpl(); }
473536

537+
void configureForTriple(std::string triple);
538+
539+
const std::vector<std::string>& getAllTriples() const {
540+
return AllTriples;
541+
}
542+
474543
private:
475544
/// Enforce clients not being allowed to query this cache directly, it must be
476545
/// wrapped in an instance of `ModuleDependenciesCache`.
@@ -500,6 +569,12 @@ class GlobalModuleDependenciesCache {
500569
Optional<ModuleDependencies>
501570
findDependencies(StringRef moduleName, ModuleLookupSpecifics details) const;
502571

572+
/// Return a pointer to the target-specific cache state of the current triple configuration.
573+
TargetSpecificGlobalCacheState* getCurrentCache() const;
574+
575+
/// Return a pointer to the target-specific cache state of the specified triple configuration.
576+
TargetSpecificGlobalCacheState* getCacheForTriple(StringRef triple) const;
577+
503578
public:
504579
/// Look for module dependencies for a module with the given name.
505580
/// This method has a deliberately-obtuse name to indicate that it is not to
@@ -510,6 +585,10 @@ class GlobalModuleDependenciesCache {
510585
findAllDependenciesIrrespectiveOfSearchPaths(
511586
StringRef moduleName, Optional<ModuleDependenciesKind> kind) const;
512587

588+
/// Look for source-based module dependency details
589+
Optional<ModuleDependencies>
590+
findSourceModuleDependency(StringRef moduleName) const;
591+
513592
/// Record dependencies for the given module.
514593
const ModuleDependencies *recordDependencies(StringRef moduleName,
515594
ModuleDependencies dependencies);
@@ -518,9 +597,16 @@ class GlobalModuleDependenciesCache {
518597
const ModuleDependencies *updateDependencies(ModuleDependencyID moduleID,
519598
ModuleDependencies dependencies);
520599

521-
/// Reference the list of all module dependencies.
522-
const std::vector<ModuleDependencyID> &getAllModules() const {
523-
return AllModules;
600+
/// Reference the list of all module dependencies that are not source-based modules
601+
/// (i.e. interface dependencies, binary dependencies, clang dependencies).
602+
const std::vector<ModuleDependencyID> &getAllNonSourceModules(StringRef triple) const {
603+
auto targetSpecificCache = getCacheForTriple(triple);
604+
return targetSpecificCache->AllModules;
605+
}
606+
607+
/// Return the list of all source-based modules discovered by this cache
608+
const std::vector<ModuleDependencyID> &getAllSourceModules() const {
609+
return AllSourceModules;
524610
}
525611
};
526612

@@ -536,10 +622,7 @@ class ModuleDependenciesCache {
536622

537623
/// References to data in `globalCache` for dependencies accimulated during
538624
/// the current scanning action.
539-
std::unordered_map<ModuleDependenciesKind,
540-
llvm::StringMap<const ModuleDependencies *>,
541-
ModuleDependenciesKindHash>
542-
ModuleDependenciesKindMap;
625+
ModuleDependenciesKindRefMap ModuleDependenciesMap;
543626

544627
/// Retrieve the dependencies map that corresponds to the given dependency
545628
/// kind.
@@ -609,9 +692,8 @@ class ModuleDependenciesCache {
609692
void updateDependencies(ModuleDependencyID moduleID,
610693
ModuleDependencies dependencies);
611694

612-
/// Reference the list of all module dependencies.
613-
const std::vector<ModuleDependencyID> &getAllModules() const {
614-
return globalCache.getAllModules();
695+
const std::vector<ModuleDependencyID> &getAllSourceModules() const {
696+
return globalCache.getAllSourceModules();
615697
}
616698
};
617699

include/swift/ClangImporter/ClangImporter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,9 @@ class ClangImporter final : public ClangModuleLoader {
409409
///
410410
/// \returns \c true if an error occurred, \c false otherwise
411411
bool addBridgingHeaderDependencies(
412-
StringRef moduleName, ModuleDependenciesCache &cache);
412+
StringRef moduleName,
413+
ModuleDependenciesKind moduleKind,
414+
ModuleDependenciesCache &cache);
413415

414416
clang::TargetInfo &getTargetInfo() const override;
415417
clang::ASTContext &getClangASTContext() const override;

include/swift/DependencyScan/DependencyScanImpl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ struct swiftscan_dependency_info_s {
3737
/// The format is:
3838
/// `<module-kind>:<module-name>`
3939
/// where `module-kind` is one of:
40-
/// "swiftTextual"
40+
/// "swiftInterface"
41+
/// "swiftSource"
4142
/// "swiftBinary"
4243
/// "swiftPlaceholder"
4344
/// "clang""

0 commit comments

Comments
 (0)