Skip to content
This repository has been archived by the owner on Jul 1, 2023. It is now read-only.

Commit

Permalink
Add support for reading profile on Mach-O
Browse files Browse the repository at this point in the history
Summary: Add support for reading profile on Mach-O.

Reviewed By: rafaelauler

Differential Revision: D25777049

fbshipit-source-id: ce9bf5616ca
  • Loading branch information
Alexander Shaposhnikov authored and facebook-github-bot committed Jan 30, 2021
1 parent db02a9b commit 125a226
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/MachORewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "BinaryEmitter.h"
#include "BinaryFunction.h"
#include "BinaryPassManager.h"
#include "DataReader.h"
#include "ExecutableFileMemoryManager.h"
#include "JumpTable.h"
#include "Passes/Instrumentation.h"
Expand Down Expand Up @@ -64,6 +65,42 @@ MachORewriteInstance::MachORewriteInstance(object::MachOObjectFile *InputFile,
DWARFContext::defaultErrorHandler, "",
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() {
for (const auto &Section : InputFile->sections()) {
StringRef SectionName;
Expand Down Expand Up @@ -252,6 +289,14 @@ void MachORewriteInstance::disassembleFunctions() {
Function.disassemble();
if (opts::PrintDisasm)
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)) {
errs() << "BOLT-WARNING: failed to build CFG for the function "
<< Function << "\n";
Expand Down Expand Up @@ -522,12 +567,27 @@ void MachORewriteInstance::adjustCommandLineOptions() {

void MachORewriteInstance::run() {
adjustCommandLineOptions();

readSpecialSections();

discoverFileObjects();

preprocessProfileData();

disassembleFunctions();

processProfileDataPreCFG();

buildFunctionsCFG();

processProfileData();

postProcessFunctions();

runOptimizationPasses();

emitAndLink();

rewriteFile();
}

Expand Down
9 changes: 9 additions & 0 deletions src/MachORewriteInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_TOOLS_LLVM_BOLT_MACHO_REWRITE_INSTANCE_H

#include "NameResolver.h"
#include "ProfileReaderBase.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/Object/MachO.h"
#include <memory>
Expand Down Expand Up @@ -48,6 +49,11 @@ class MachORewriteInstance {

std::unique_ptr<ToolOutputFile> Out;

std::unique_ptr<ProfileReaderBase> ProfileReader;
void preprocessProfileData();
void processProfileDataPreCFG();
void processProfileData();

static StringRef getOrgSecPrefix() { return ".bolt.org"; }

void mapInstrumentationSection(orc::VModuleKey Key, StringRef SectionName);
Expand All @@ -57,6 +63,7 @@ class MachORewriteInstance {
void readSpecialSections();
void discoverFileObjects();
void disassembleFunctions();
void buildFunctionsCFG();
void postProcessFunctions();
void runOptimizationPasses();
void emitAndLink();
Expand All @@ -68,6 +75,8 @@ class MachORewriteInstance {
MachORewriteInstance(object::MachOObjectFile *InputFile, StringRef ToolPath);
~MachORewriteInstance();

Error setProfile(StringRef FileName);

/// Run all the necessary steps to read, optimize and rewrite the binary.
void run();
};
Expand Down
5 changes: 5 additions & 0 deletions src/llvm-bolt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,11 @@ int main(int argc, char **argv) {
RI.run();
} else if (auto *O = dyn_cast<MachOObjectFile>(&Binary)) {
MachORewriteInstance MachORI(O, ToolPath);

if (!opts::InputDataFilename.empty())
if (auto E = MachORI.setProfile(opts::InputDataFilename))
report_error(opts::InputDataFilename, std::move(E));

MachORI.run();
} else {
report_error(opts::InputFilename, object_error::invalid_file_type);
Expand Down

0 comments on commit 125a226

Please sign in to comment.