Skip to content

Commit bb6852e

Browse files
[InterfaceFile] Improve flag extraction from interface file
Improve the version/flags extract from interface file by moving away from using Regex and limiting the search to the beginning of the file. Switch away from Regex will give 5-10% improvement in time and instruction counts, and limiting the search lines can save a lot of time if the swiftinterface is large. For example, the extract time for Swift stdlib is 10x faster after the patch.
1 parent 52ad460 commit bb6852e

File tree

1 file changed

+30
-21
lines changed

1 file changed

+30
-21
lines changed

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,16 +1267,31 @@ void swift::serialization::diagnoseSerializedASTLoadFailureTransitive(
12671267
}
12681268
}
12691269

1270+
static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef buffer,
1271+
StringRef prefix) {
1272+
StringRef line;
1273+
unsigned lineCount = 0;
1274+
const unsigned maxLine = 10;
1275+
while (!buffer.empty()) {
1276+
std::tie(line, buffer) = buffer.split('\n');
1277+
if (line.consume_front(prefix))
1278+
return line;
1279+
1280+
if (++lineCount > maxLine)
1281+
return std::nullopt;
1282+
}
1283+
1284+
return std::nullopt;
1285+
}
1286+
12701287
bool swift::extractCompilerFlagsFromInterface(StringRef interfacePath,
12711288
StringRef buffer,
12721289
llvm::StringSaver &ArgSaver,
12731290
SmallVectorImpl<const char *> &SubArgs) {
1274-
SmallVector<StringRef, 1> FlagMatches;
1275-
auto FlagRe = llvm::Regex("^// swift-module-flags:(.*)$", llvm::Regex::Newline);
1276-
if (!FlagRe.match(buffer, &FlagMatches))
1291+
auto FlagMatch = getFlagsFromInterfaceFile(buffer, "// swift-module-flags:");
1292+
if (!FlagMatch)
12771293
return true;
1278-
assert(FlagMatches.size() == 2);
1279-
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], ArgSaver, SubArgs);
1294+
llvm::cl::TokenizeGNUCommandLine(*FlagMatch, ArgSaver, SubArgs);
12801295

12811296
auto intFileName = llvm::sys::path::filename(interfacePath);
12821297

@@ -1300,28 +1315,22 @@ bool swift::extractCompilerFlagsFromInterface(StringRef interfacePath,
13001315
}
13011316
}
13021317

1303-
SmallVector<StringRef, 1> IgnFlagMatches;
1304-
// Cherry-pick supported options from the ignorable list.
1305-
auto IgnFlagRe = llvm::Regex("^// swift-module-flags-ignorable:(.*)$",
1306-
llvm::Regex::Newline);
1307-
auto hasIgnorableFlags = IgnFlagRe.match(buffer, &IgnFlagMatches);
1308-
1309-
// Check for ignorable-private flags
1310-
SmallVector<StringRef, 1> IgnPrivateFlagMatches;
1311-
auto IgnPrivateFlagRe = llvm::Regex("^// swift-module-flags-ignorable-private:(.*)$",
1312-
llvm::Regex::Newline);
1313-
auto hasIgnorablePrivateFlags = IgnPrivateFlagRe.match(buffer, &IgnPrivateFlagMatches);
1318+
auto IgnFlagMatch =
1319+
getFlagsFromInterfaceFile(buffer, "// swift-module-flags-ignorable:");
1320+
auto IgnPrivateFlagMatch = getFlagsFromInterfaceFile(
1321+
buffer, "// swift-module-flags-ignorable-private:");
13141322

13151323
// It's OK the interface doesn't have the ignorable list (private or not), we just
13161324
// ignore them all.
1317-
if (!hasIgnorableFlags && !hasIgnorablePrivateFlags)
1325+
if (!IgnFlagMatch && !IgnPrivateFlagMatch)
13181326
return false;
13191327

13201328
SmallVector<const char *, 8> IgnSubArgs;
1321-
if (hasIgnorableFlags)
1322-
llvm::cl::TokenizeGNUCommandLine(IgnFlagMatches[1], ArgSaver, IgnSubArgs);
1323-
if (hasIgnorablePrivateFlags)
1324-
llvm::cl::TokenizeGNUCommandLine(IgnPrivateFlagMatches[1], ArgSaver, IgnSubArgs);
1329+
if (IgnFlagMatch)
1330+
llvm::cl::TokenizeGNUCommandLine(*IgnFlagMatch, ArgSaver, IgnSubArgs);
1331+
if (IgnPrivateFlagMatch)
1332+
llvm::cl::TokenizeGNUCommandLine(*IgnPrivateFlagMatch, ArgSaver,
1333+
IgnSubArgs);
13251334

13261335
std::unique_ptr<llvm::opt::OptTable> table = swift::createSwiftOptTable();
13271336
unsigned missingArgIdx = 0;

0 commit comments

Comments
 (0)