[BOLT] Add support for reading profile on Mach-O
Summary: Add support for reading profile on Mach-O. (cherry picked from FBD25777049)
This commit is contained in:
parent
a0dd5b05dc
commit
0a8aaf56bb
@ -14,6 +14,7 @@
|
|||||||
#include "BinaryEmitter.h"
|
#include "BinaryEmitter.h"
|
||||||
#include "BinaryFunction.h"
|
#include "BinaryFunction.h"
|
||||||
#include "BinaryPassManager.h"
|
#include "BinaryPassManager.h"
|
||||||
|
#include "DataReader.h"
|
||||||
#include "ExecutableFileMemoryManager.h"
|
#include "ExecutableFileMemoryManager.h"
|
||||||
#include "JumpTable.h"
|
#include "JumpTable.h"
|
||||||
#include "Passes/Instrumentation.h"
|
#include "Passes/Instrumentation.h"
|
||||||
@ -64,6 +65,42 @@ MachORewriteInstance::MachORewriteInstance(object::MachOObjectFile *InputFile,
|
|||||||
DWARFContext::defaultErrorHandler, "",
|
DWARFContext::defaultErrorHandler, "",
|
||||||
false))) {}
|
false))) {}
|
||||||
|
|
||||||
|
Error MachORewriteInstance::setProfile(StringRef Filename) {
|
||||||
|
if (!sys::fs::exists(Filename))
|
||||||
|
return errorCodeToError(make_error_code(errc::no_such_file_or_directory));
|
||||||
|
|
||||||
|
if (ProfileReader) {
|
||||||
|
// Already exists
|
||||||
|
return make_error<StringError>(
|
||||||
|
Twine("multiple profiles specified: ") + ProfileReader->getFilename() +
|
||||||
|
" and " + Filename, inconvertibleErrorCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileReader = llvm::make_unique<DataReader>(Filename);
|
||||||
|
return Error::success();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachORewriteInstance::preprocessProfileData() {
|
||||||
|
if (!ProfileReader)
|
||||||
|
return;
|
||||||
|
if (auto E = ProfileReader->preprocessProfile(*BC.get()))
|
||||||
|
report_error("cannot pre-process profile", std::move(E));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachORewriteInstance::processProfileDataPreCFG() {
|
||||||
|
if (!ProfileReader)
|
||||||
|
return;
|
||||||
|
if (auto E = ProfileReader->readProfilePreCFG(*BC.get()))
|
||||||
|
report_error("cannot read profile pre-CFG", std::move(E));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachORewriteInstance::processProfileData() {
|
||||||
|
if (!ProfileReader)
|
||||||
|
return;
|
||||||
|
if (auto E = ProfileReader->readProfile(*BC.get()))
|
||||||
|
report_error("cannot read profile", std::move(E));
|
||||||
|
}
|
||||||
|
|
||||||
void MachORewriteInstance::readSpecialSections() {
|
void MachORewriteInstance::readSpecialSections() {
|
||||||
for (const auto &Section : InputFile->sections()) {
|
for (const auto &Section : InputFile->sections()) {
|
||||||
StringRef SectionName;
|
StringRef SectionName;
|
||||||
@ -252,6 +289,14 @@ void MachORewriteInstance::disassembleFunctions() {
|
|||||||
Function.disassemble();
|
Function.disassemble();
|
||||||
if (opts::PrintDisasm)
|
if (opts::PrintDisasm)
|
||||||
Function.print(outs(), "after disassembly", true);
|
Function.print(outs(), "after disassembly", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachORewriteInstance::buildFunctionsCFG() {
|
||||||
|
for (auto &BFI : BC->getBinaryFunctions()) {
|
||||||
|
BinaryFunction &Function = BFI.second;
|
||||||
|
if (!Function.isSimple())
|
||||||
|
continue;
|
||||||
if (!Function.buildCFG(/*AllocId*/ 0)) {
|
if (!Function.buildCFG(/*AllocId*/ 0)) {
|
||||||
errs() << "BOLT-WARNING: failed to build CFG for the function "
|
errs() << "BOLT-WARNING: failed to build CFG for the function "
|
||||||
<< Function << "\n";
|
<< Function << "\n";
|
||||||
@ -522,12 +567,27 @@ void MachORewriteInstance::adjustCommandLineOptions() {
|
|||||||
|
|
||||||
void MachORewriteInstance::run() {
|
void MachORewriteInstance::run() {
|
||||||
adjustCommandLineOptions();
|
adjustCommandLineOptions();
|
||||||
|
|
||||||
readSpecialSections();
|
readSpecialSections();
|
||||||
|
|
||||||
discoverFileObjects();
|
discoverFileObjects();
|
||||||
|
|
||||||
|
preprocessProfileData();
|
||||||
|
|
||||||
disassembleFunctions();
|
disassembleFunctions();
|
||||||
|
|
||||||
|
processProfileDataPreCFG();
|
||||||
|
|
||||||
|
buildFunctionsCFG();
|
||||||
|
|
||||||
|
processProfileData();
|
||||||
|
|
||||||
postProcessFunctions();
|
postProcessFunctions();
|
||||||
|
|
||||||
runOptimizationPasses();
|
runOptimizationPasses();
|
||||||
|
|
||||||
emitAndLink();
|
emitAndLink();
|
||||||
|
|
||||||
rewriteFile();
|
rewriteFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define LLVM_TOOLS_LLVM_BOLT_MACHO_REWRITE_INSTANCE_H
|
#define LLVM_TOOLS_LLVM_BOLT_MACHO_REWRITE_INSTANCE_H
|
||||||
|
|
||||||
#include "NameResolver.h"
|
#include "NameResolver.h"
|
||||||
|
#include "ProfileReaderBase.h"
|
||||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||||
#include "llvm/Object/MachO.h"
|
#include "llvm/Object/MachO.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -48,6 +49,11 @@ class MachORewriteInstance {
|
|||||||
|
|
||||||
std::unique_ptr<ToolOutputFile> Out;
|
std::unique_ptr<ToolOutputFile> Out;
|
||||||
|
|
||||||
|
std::unique_ptr<ProfileReaderBase> ProfileReader;
|
||||||
|
void preprocessProfileData();
|
||||||
|
void processProfileDataPreCFG();
|
||||||
|
void processProfileData();
|
||||||
|
|
||||||
static StringRef getOrgSecPrefix() { return ".bolt.org"; }
|
static StringRef getOrgSecPrefix() { return ".bolt.org"; }
|
||||||
|
|
||||||
void mapInstrumentationSection(orc::VModuleKey Key, StringRef SectionName);
|
void mapInstrumentationSection(orc::VModuleKey Key, StringRef SectionName);
|
||||||
@ -57,6 +63,7 @@ class MachORewriteInstance {
|
|||||||
void readSpecialSections();
|
void readSpecialSections();
|
||||||
void discoverFileObjects();
|
void discoverFileObjects();
|
||||||
void disassembleFunctions();
|
void disassembleFunctions();
|
||||||
|
void buildFunctionsCFG();
|
||||||
void postProcessFunctions();
|
void postProcessFunctions();
|
||||||
void runOptimizationPasses();
|
void runOptimizationPasses();
|
||||||
void emitAndLink();
|
void emitAndLink();
|
||||||
@ -68,6 +75,8 @@ public:
|
|||||||
MachORewriteInstance(object::MachOObjectFile *InputFile, StringRef ToolPath);
|
MachORewriteInstance(object::MachOObjectFile *InputFile, StringRef ToolPath);
|
||||||
~MachORewriteInstance();
|
~MachORewriteInstance();
|
||||||
|
|
||||||
|
Error setProfile(StringRef FileName);
|
||||||
|
|
||||||
/// Run all the necessary steps to read, optimize and rewrite the binary.
|
/// Run all the necessary steps to read, optimize and rewrite the binary.
|
||||||
void run();
|
void run();
|
||||||
};
|
};
|
||||||
|
@ -323,6 +323,11 @@ int main(int argc, char **argv) {
|
|||||||
RI.run();
|
RI.run();
|
||||||
} else if (auto *O = dyn_cast<MachOObjectFile>(&Binary)) {
|
} else if (auto *O = dyn_cast<MachOObjectFile>(&Binary)) {
|
||||||
MachORewriteInstance MachORI(O, ToolPath);
|
MachORewriteInstance MachORI(O, ToolPath);
|
||||||
|
|
||||||
|
if (!opts::InputDataFilename.empty())
|
||||||
|
if (auto E = MachORI.setProfile(opts::InputDataFilename))
|
||||||
|
report_error(opts::InputDataFilename, std::move(E));
|
||||||
|
|
||||||
MachORI.run();
|
MachORI.run();
|
||||||
} else {
|
} else {
|
||||||
report_error(opts::InputFilename, object_error::invalid_file_type);
|
report_error(opts::InputFilename, object_error::invalid_file_type);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user