Skip to content

Commit

Permalink
add tracer for code gen function
Browse files Browse the repository at this point in the history
  • Loading branch information
mo-xiaoming committed Mar 21, 2023
1 parent 3a1d1fe commit 9ea374a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 6 deletions.
2 changes: 2 additions & 0 deletions include/hobbes/eval/jitcc.H
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ private:

struct IrTracer;
std::unique_ptr<IrTracer> irTracer;
struct JitFuncTracer;
std::unique_ptr<JitFuncTracer> jitFuncTracer;
};

// shorthand for compilation over a sequence of expressions
Expand Down
81 changes: 75 additions & 6 deletions lib/hobbes/eval/jitcc.C
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

#include <cstdint>
#include <hobbes/eval/func.H>
#include <hobbes/util/llvm.H>
#include <hobbes/eval/cexpr.H>
Expand All @@ -9,6 +8,7 @@
#include <llvm/IR/Constant.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Value.h>
Expand All @@ -21,10 +21,13 @@
#include <llvm/Support/raw_ostream.h>
#include <llvm/Target/TargetMachine.h>

#include <algorithm>
#include <cstdint>
#include <fstream>
#include <ostream>
#include <sstream>
#include <stdexcept>
#include <system_error>
#include <utility>

#pragma GCC diagnostic push
Expand Down Expand Up @@ -569,11 +572,72 @@ struct jitcc::IrTracer {
}

void log(const llvm::Module& m) {
if (!isEnabled()) {
if (isEnabled()) {
m.print(*out, nullptr, false, true);
}
}

private:
[[nodiscard]] bool isEnabled() const noexcept {
return !!out;
}

std::unique_ptr<llvm::raw_fd_ostream> out;
};

struct jitcc::JitFuncTracer {
JitFuncTracer() {
std::error_code ec;
const char* name = std::getenv("HOBBES_JIT_FUNC_TRACE_FILE");
if (name == nullptr) {
return;
}
out = std::make_unique<llvm::raw_fd_ostream>(name, ec, llvm::sys::fs::F_None);
if (ec != std::errc()) {
out = nullptr;
return;
}
}

private:
struct ModuleFunctions {
ModuleFunctions() = default;
explicit ModuleFunctions(const llvm::Module& m) {
funcs.reserve(m.getFunctionList().size());
for (const auto& f : m) {
if (!f.isDeclaration()) {
funcs.push_back(f.getName());
}
}
}

const std::vector<llvm::StringRef>& get() const noexcept {
return funcs;
}

private:
std::vector<llvm::StringRef> funcs;
};

m.print(*out, nullptr, false, true);
public:
ModuleFunctions getCollector(const llvm::Module& m) {
if (isEnabled()) {
return ModuleFunctions(m);
}
return {};
}

void log(const ModuleFunctions& mf, llvm::ExecutionEngine& ee) {
if (isEnabled()) {
for (const auto name : mf.get()) {
if (const auto a = ee.getFunctionAddress(name)) {
*out << name << ":0x";
out->write_hex(a);
*out << '\n';
}
}
out->flush();
}
}

private:
Expand All @@ -589,7 +653,8 @@ jitcc::jitcc(const TEnvPtr& tenv)
: tenv(tenv), vtenv(std::make_unique<VTEnv>()), ignoreLocalScope(false),
globals(std::make_unique<Globals>()), globalData(32768 /* min global page size = 32K */),
constants(std::make_unique<ConstantList>()),
irTracer(std::make_unique<IrTracer>())
irTracer(std::make_unique<IrTracer>()),
jitFuncTracer(std::make_unique<JitFuncTracer>())
{
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmParser();
Expand Down Expand Up @@ -620,7 +685,8 @@ jitcc::jitcc(const TEnvPtr& tenv) :
tenv(tenv),
ignoreLocalScope(false),
globalData(32768 /* min global page size = 32K */),
irTracer(std::make_unique<IrTracer>())
irTracer(std::make_unique<IrTracer>()),
jitFuncTracer(std::make_unique<JitFuncTracer>())
{
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmParser();
Expand Down Expand Up @@ -786,6 +852,8 @@ void* jitcc::getMachineCode(llvm::Function* f, llvm::JITEventListener* listener)
}
irTracer->log(*this->currentModule);

const auto moduleFunctions = jitFuncTracer->getCollector(*this->currentModule);

// make a new execution engine out of this module (finalizing the module)
std::string err;
llvm::ExecutionEngine* ee = makeExecutionEngine(this->currentModule, reinterpret_cast<llvm::SectionMemoryManager*>(new jitmm(this)));
Expand Down Expand Up @@ -839,6 +907,8 @@ void* jitcc::getMachineCode(llvm::Function* f, llvm::JITEventListener* listener)
// and _now_ we must be able to get machine code for this function
void* pf = ee->getPointerToFunction(f);

jitFuncTracer->log(moduleFunctions, *ee);

if (listener) {
ee->UnregisterJITEventListener(listener);
}
Expand Down Expand Up @@ -1239,7 +1309,6 @@ void jitcc::defineGlobal(const std::string& vn, const ExprPtr& ue) {
// compile and run this function, it should then perform the global variable assignment
// (make sure that any allocation happens in the global context iff we need it)
auto f = reinterpret_cast<Thunk>(getMachineCode(initfn));

if (hasPointerRep(uety)) {
size_t oldregion = pushGlobalRegion();
f();
Expand Down

0 comments on commit 9ea374a

Please sign in to comment.