[BOLT] Use regex matching for function names passed on command line

Summary:
Options such as `-print-only`, `-skip-funcs`, etc. now take regular
expressions. Internally, the option is converted to '^funcname$' form
prior to regex matching. This ensures that names without special
symbols will match exactly, i.e. "foo" will not match "foo123".

(cherry picked from FBD15551930)
This commit is contained in:
Maksim Panchenko
2019-05-29 18:33:09 -07:00
parent c8038da36e
commit 9ef9a7b1be
4 changed files with 13 additions and 27 deletions

View File

@@ -138,14 +138,6 @@ PrintOnly("print-only",
cl::Hidden,
cl::cat(BoltCategory));
static cl::list<std::string>
PrintOnlyRegex("print-only-regex",
cl::CommaSeparated,
cl::desc("list of function regexes to print"),
cl::value_desc("func1,func2,func3,..."),
cl::Hidden,
cl::cat(BoltCategory));
static cl::opt<bool>
TimeBuild("time-build",
cl::desc("print time spent constructing binary functions"),
@@ -163,16 +155,10 @@ TrapOnAVX512("trap-avx512",
cl::cat(BoltCategory));
bool shouldPrint(const BinaryFunction &Function) {
if (PrintOnly.empty() && PrintOnlyRegex.empty())
if (PrintOnly.empty())
return true;
for (auto &Name : opts::PrintOnly) {
if (Function.hasName(Name)) {
return true;
}
}
for (auto &Name : opts::PrintOnlyRegex) {
if (Function.hasNameRegex(Name)) {
return true;
}
@@ -240,8 +226,9 @@ SMLoc findDebugLineInformationForInstructionAt(
uint64_t BinaryFunction::Count = 0;
const std::string *
BinaryFunction::hasNameRegex(const std::string &NameRegex) const {
Regex MatchName(NameRegex);
BinaryFunction::hasNameRegex(const StringRef Name) const {
const auto RegexName = (Twine("^") + StringRef(Name) + "$").str();
Regex MatchName(RegexName);
for (auto &Name : Names)
if (MatchName.match(Name))
return &Name;

View File

@@ -921,7 +921,7 @@ public:
/// Check if (possibly one out of many) function name matches the given
/// regex.
const std::string *hasNameRegex(const std::string &NameRegex) const;
const std::string *hasNameRegex(const StringRef NameRegex) const;
/// Return a vector of all possible names for the function.
const std::vector<std::string> &getNames() const {

View File

@@ -1559,8 +1559,6 @@ bool SpecializeMemcpy1::shouldOptimize(const BinaryFunction &Function) const {
for (auto &FunctionSpec : Spec) {
auto FunctionName = StringRef(FunctionSpec).split(':').first;
if (Function.hasName(FunctionName))
return true;
if (Function.hasNameRegex(FunctionName))
return true;
}
@@ -1574,8 +1572,6 @@ SpecializeMemcpy1::getCallSitesToOptimize(const BinaryFunction &Function) const{
for (auto &FunctionSpec : Spec) {
StringRef FunctionName;
std::tie(FunctionName, SitesString) = StringRef(FunctionSpec).split(':');
if (Function.hasName(FunctionName))
break;
if (Function.hasNameRegex(FunctionName))
break;
SitesString = "";

View File

@@ -452,7 +452,7 @@ bool shouldProcess(const BinaryFunction &Function) {
if (!FunctionNames.empty()) {
IsValid = false;
for (auto &Name : FunctionNames) {
if (Function.hasName(Name)) {
if (Function.hasNameRegex(Name)) {
IsValid = true;
break;
}
@@ -462,7 +462,7 @@ bool shouldProcess(const BinaryFunction &Function) {
return false;
for (auto &Name : SkipFunctionNames) {
if (Function.hasName(Name))
if (Function.hasNameRegex(Name))
return false;
}
@@ -486,7 +486,7 @@ size_t padFunction(const BinaryFunction &Function) {
for (auto &FPI : FunctionPadding) {
auto Name = FPI.first;
auto Padding = FPI.second;
if (Function.hasName(Name)) {
if (Function.hasNameRegex(Name)) {
return Padding;
}
}
@@ -1644,7 +1644,10 @@ void RewriteInstance::adjustFunctionBoundaries() {
auto &Function = BFI->second;
// Check if it's a fragment of a function.
if (auto *FragName = Function.hasNameRegex("\\.cold\\.")) {
const auto *FragName = Function.hasNameRegex(".*\\.cold\\..*");
if (!FragName)
FragName = Function.hasNameRegex(".*\\.cold");
if (FragName) {
static bool PrintedWarning = false;
if (BC->HasRelocations && !PrintedWarning) {
errs() << "BOLT-WARNING: split function detected on input : "
@@ -2757,7 +2760,7 @@ void RewriteInstance::emitFunction(MCStreamer &Streamer,
// Emit UD2 at the beginning if requested by user.
if (!opts::BreakFunctionNames.empty()) {
for (auto &Name : opts::BreakFunctionNames) {
if (Function.hasName(Name)) {
if (Function.hasNameRegex(Name)) {
Streamer.EmitIntValue(0x0B0F, 2); // UD2: 0F 0B
break;
}