From c4e60a7f6045efc317087f964341f74a3f1b6446 Mon Sep 17 00:00:00 2001 From: Maksim Panchenko Date: Mon, 12 Jun 2023 13:16:09 -0700 Subject: [PATCH] [BOLT] Fix --max-funcs= option Fix off-by-one error while handling of the --max-funcs= option. We used to process N+1 functions when N was requested. Reviewed By: Amir Differential Revision: https://reviews.llvm.org/D152751 --- bolt/lib/Rewrite/RewriteInstance.cpp | 26 +++++++++----------------- bolt/test/max-funcs.test | 13 +++++++++++++ 2 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 bolt/test/max-funcs.test diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 1c0c68c..3481787 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -2917,7 +2917,8 @@ void RewriteInstance::selectFunctionsToProcess() { uint64_t NumFunctionsToProcess = 0; auto mustSkip = [&](const BinaryFunction &Function) { - if (opts::MaxFunctions && NumFunctionsToProcess > opts::MaxFunctions) + if (opts::MaxFunctions.getNumOccurrences() && + NumFunctionsToProcess >= opts::MaxFunctions) return true; for (std::string &Name : opts::SkipFunctionNames) if (Function.hasNameRegex(Name)) @@ -2992,7 +2993,8 @@ void RewriteInstance::selectFunctionsToProcess() { Function.setIgnored(); } else { ++NumFunctionsToProcess; - if (opts::MaxFunctions && NumFunctionsToProcess == opts::MaxFunctions) + if (opts::MaxFunctions.getNumOccurrences() && + NumFunctionsToProcess == opts::MaxFunctions) outs() << "BOLT-INFO: processing ending on " << Function << '\n'; } } @@ -5787,6 +5789,8 @@ void RewriteInstance::rewriteFile() { } OverwrittenScore += Function->getFunctionScore(); + ++CountOverwrittenFunctions; + // Overwrite function in the output file. if (opts::Verbosity >= 2) outs() << "BOLT: rewriting function \"" << *Function << "\"\n"; @@ -5804,32 +5808,20 @@ void RewriteInstance::rewriteFile() { OS.seek(Pos); } - if (!Function->isSplit()) { - ++CountOverwrittenFunctions; - if (opts::MaxFunctions && - CountOverwrittenFunctions == opts::MaxFunctions) { - outs() << "BOLT: maximum number of functions reached\n"; - break; - } + if (!Function->isSplit()) continue; - } // Write cold part - if (opts::Verbosity >= 2) + if (opts::Verbosity >= 2) { outs() << formatv("BOLT: rewriting function \"{0}\" (split parts)\n", *Function); + } for (const FunctionFragment &FF : Function->getLayout().getSplitFragments()) { OS.pwrite(reinterpret_cast(FF.getImageAddress()), FF.getImageSize(), FF.getFileOffset()); } - - ++CountOverwrittenFunctions; - if (opts::MaxFunctions && CountOverwrittenFunctions == opts::MaxFunctions) { - outs() << "BOLT: maximum number of functions reached\n"; - break; - } } // Print function statistics for non-relocation mode. diff --git a/bolt/test/max-funcs.test b/bolt/test/max-funcs.test new file mode 100644 index 0000000..c7cd7be --- /dev/null +++ b/bolt/test/max-funcs.test @@ -0,0 +1,13 @@ +## Check that --max-funcs= option works properly in llvm-bolt, +## resulting in processing of no more than N functions in the binary. + +REQUIRES: system-linux + +RUN: %clangxx %p/Inputs/bolt_icf.cpp -g -Wl,-q -o %t.exe +RUN: llvm-bolt %t.exe --relocs -o %t --max-funcs=2 +RUN: llvm-objdump -d -j .text %t | FileCheck %s + +## Check that there are only two functions in the dump of .text +CHECK: <{{.*}}>: +CHECK: <{{.*}}>: +CHECK-NOT: <{{.*}}>: -- 2.7.4