#include "bolt/Passes/Instrumentation.h"
#include "bolt/Core/ParallelUtilities.h"
#include "bolt/RuntimeLibs/InstrumentationRuntimeLibrary.h"
#include "bolt/Utils/CommandLineOpts.h"
#include "bolt/Utils/Utils.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/RWMutex.h"
#include <queue>
#include <stack>
#include <unordered_set>
#define DEBUG_TYPE …
usingnamespacellvm;
namespace opts {
extern cl::OptionCategory BoltInstrCategory;
cl::opt<std::string> InstrumentationFilename(
"instrumentation-file",
cl::desc("file name where instrumented profile will be saved (default: "
"/tmp/prof.fdata)"),
cl::init("/tmp/prof.fdata"), cl::Optional, cl::cat(BoltInstrCategory));
cl::opt<std::string> InstrumentationBinpath(
"instrumentation-binpath",
cl::desc("path to instrumented binary in case if /proc/self/map_files "
"is not accessible due to access restriction issues"),
cl::Optional, cl::cat(BoltInstrCategory));
cl::opt<bool> InstrumentationFileAppendPID(
"instrumentation-file-append-pid",
cl::desc("append PID to saved profile file name (default: false)"),
cl::init(false), cl::Optional, cl::cat(BoltInstrCategory));
cl::opt<bool> ConservativeInstrumentation(
"conservative-instrumentation",
cl::desc("disable instrumentation optimizations that sacrifice profile "
"accuracy (for debugging, default: false)"),
cl::init(false), cl::Optional, cl::cat(BoltInstrCategory));
cl::opt<uint32_t> InstrumentationSleepTime(
"instrumentation-sleep-time",
cl::desc("interval between profile writes (default: 0 = write only at "
"program end). This is useful for service workloads when you "
"want to dump profile every X minutes or if you are killing the "
"program and the profile is not being dumped at the end."),
cl::init(0), cl::Optional, cl::cat(BoltInstrCategory));
cl::opt<bool> InstrumentationNoCountersClear(
"instrumentation-no-counters-clear",
cl::desc("Don't clear counters across dumps "
"(use with instrumentation-sleep-time option)"),
cl::init(false), cl::Optional, cl::cat(BoltInstrCategory));
cl::opt<bool> InstrumentationWaitForks(
"instrumentation-wait-forks",
cl::desc("Wait until all forks of instrumented process will finish "
"(use with instrumentation-sleep-time option)"),
cl::init(false), cl::Optional, cl::cat(BoltInstrCategory));
cl::opt<bool>
InstrumentHotOnly("instrument-hot-only",
cl::desc("only insert instrumentation on hot functions "
"(needs profile, default: false)"),
cl::init(false), cl::Optional,
cl::cat(BoltInstrCategory));
cl::opt<bool> InstrumentCalls("instrument-calls",
cl::desc("record profile for inter-function "
"control flow activity (default: true)"),
cl::init(true), cl::Optional,
cl::cat(BoltInstrCategory));
}
namespace llvm {
namespace bolt {
static bool hasAArch64ExclusiveMemop(
BinaryFunction &Function,
std::unordered_set<const BinaryBasicBlock *> &BBToSkip) { … }
uint32_t Instrumentation::getFunctionNameIndex(const BinaryFunction &Function) { … }
bool Instrumentation::createCallDescription(FunctionDescription &FuncDesc,
const BinaryFunction &FromFunction,
uint32_t From, uint32_t FromNodeID,
const BinaryFunction &ToFunction,
uint32_t To, bool IsInvoke) { … }
void Instrumentation::createIndCallDescription(
const BinaryFunction &FromFunction, uint32_t From) { … }
void Instrumentation::createIndCallTargetDescription(
const BinaryFunction &ToFunction, uint32_t To) { … }
bool Instrumentation::createEdgeDescription(FunctionDescription &FuncDesc,
const BinaryFunction &FromFunction,
uint32_t From, uint32_t FromNodeID,
const BinaryFunction &ToFunction,
uint32_t To, uint32_t ToNodeID,
bool Instrumented) { … }
void Instrumentation::createLeafNodeDescription(FunctionDescription &FuncDesc,
uint32_t Node) { … }
InstructionListType
Instrumentation::createInstrumentationSnippet(BinaryContext &BC, bool IsLeaf) { … }
static BinaryBasicBlock::iterator
insertInstructions(InstructionListType &Instrs, BinaryBasicBlock &BB,
BinaryBasicBlock::iterator Iter) { … }
void Instrumentation::instrumentLeafNode(BinaryBasicBlock &BB,
BinaryBasicBlock::iterator Iter,
bool IsLeaf,
FunctionDescription &FuncDesc,
uint32_t Node) { … }
void Instrumentation::instrumentIndirectTarget(BinaryBasicBlock &BB,
BinaryBasicBlock::iterator &Iter,
BinaryFunction &FromFunction,
uint32_t From) { … }
bool Instrumentation::instrumentOneTarget(
SplitWorklistTy &SplitWorklist, SplitInstrsTy &SplitInstrs,
BinaryBasicBlock::iterator &Iter, BinaryFunction &FromFunction,
BinaryBasicBlock &FromBB, uint32_t From, BinaryFunction &ToFunc,
BinaryBasicBlock *TargetBB, uint32_t ToOffset, bool IsLeaf, bool IsInvoke,
FunctionDescription *FuncDesc, uint32_t FromNodeID, uint32_t ToNodeID) { … }
void Instrumentation::instrumentFunction(BinaryFunction &Function,
MCPlusBuilder::AllocatorIdTy AllocId) { … }
Error Instrumentation::runOnFunctions(BinaryContext &BC) { … }
void Instrumentation::createAuxiliaryFunctions(BinaryContext &BC) { … }
void Instrumentation::setupRuntimeLibrary(BinaryContext &BC) { … }
}
}