[Serialization] Improve module loading performance

When looking for a Swift module on disk, we were scanning all module search paths if they contain the module we are searching for. In a setup where each module is contained in its own framework search path, this scaled quadratically with the number of modules being imported. E.g. a setup with 100 modules being imported form 100 module search paths could cause on the order of 10,000 checks of `FileSystem::exists`. While these checks are fairly fast (~10µs), they add up to ~100ms.

To improve this, perform a first scan of all module search paths and list the files they contain. From this, create a lookup map that maps filenames to the search paths they can be found in. E.g. for
```
searchPath1/
  Module1.framework

searchPath2/
  Module1.framework
  Module2.swiftmodule
```
we create the following lookup table
```
Module1.framework -> [searchPath1, searchPath2]
Module2.swiftmodule -> [searchPath2]
```
This commit is contained in:
Alex Hoppen
2021-12-08 22:54:38 +01:00
parent 5a6341bd65
commit fe7878ecce
24 changed files with 581 additions and 212 deletions

View File

@@ -74,7 +74,7 @@ bool ModuleInterfaceBuilder::collectDepsForSerialization(
llvm::vfs::FileSystem &fs = *sourceMgr.getFileSystem();
auto &Opts = SubInstance.getASTContext().SearchPathOpts;
SmallString<128> SDKPath(Opts.SDKPath);
SmallString<128> SDKPath(Opts.getSDKPath());
path::native(SDKPath);
SmallString<128> ResourcePath(Opts.RuntimeResourcePath);
path::native(ResourcePath);
@@ -287,7 +287,7 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
SerializationOpts.UserModuleVersion = FEOpts.UserModuleVersion;
// Record any non-SDK module interface files for the debug info.
StringRef SDKPath = SubInstance.getASTContext().SearchPathOpts.SDKPath;
StringRef SDKPath = SubInstance.getASTContext().SearchPathOpts.getSDKPath();
if (!getRelativeDepPath(InPath, SDKPath))
SerializationOpts.ModuleInterface = InPath;