Adding oprofile support for MCJIT.

Patch by Dmitry Stogov



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192809 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Kaylor 2013-10-16 16:32:47 +00:00
parent 8225b23c6a
commit 8a75384361
2 changed files with 72 additions and 1 deletions

View File

@ -20,7 +20,9 @@
#include "llvm/IR/Function.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/ExecutionEngine/OProfileWrapper.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Errno.h"
@ -52,6 +54,10 @@ public:
const JITEvent_EmittedFunctionDetails &Details);
virtual void NotifyFreeingMachineCode(void *OldPtr);
virtual void NotifyObjectEmitted(const ObjectImage &Obj);
virtual void NotifyFreeingObject(const ObjectImage &Obj);
};
void OProfileJITEventListener::initialize() {
@ -159,6 +165,66 @@ void OProfileJITEventListener::NotifyFreeingMachineCode(void *FnStart) {
}
}
void OProfileJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) {
if (!Wrapper.isAgentAvailable()) {
return;
}
// Use symbol info to iterate functions in the object.
error_code ec;
for (object::symbol_iterator I = Obj.begin_symbols(),
E = Obj.end_symbols();
I != E && !ec;
I.increment(ec)) {
object::SymbolRef::Type SymType;
if (I->getType(SymType)) continue;
if (SymType == object::SymbolRef::ST_Function) {
StringRef Name;
uint64_t Addr;
uint64_t Size;
if (I->getName(Name)) continue;
if (I->getAddress(Addr)) continue;
if (I->getSize(Size)) continue;
if (Wrapper.op_write_native_code(Name.data(), Addr, (void*)Addr, Size)
== -1) {
DEBUG(dbgs() << "Failed to tell OProfile about native function "
<< Name << " at ["
<< (void*)Addr << "-" << ((char*)Addr + Size) << "]\n");
continue;
}
// TODO: support line number info (similar to IntelJITEventListener.cpp)
}
}
}
void OProfileJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) {
if (!Wrapper.isAgentAvailable()) {
return;
}
// Use symbol info to iterate functions in the object.
error_code ec;
for (object::symbol_iterator I = Obj.begin_symbols(),
E = Obj.end_symbols();
I != E && !ec;
I.increment(ec)) {
object::SymbolRef::Type SymType;
if (I->getType(SymType)) continue;
if (SymType == object::SymbolRef::ST_Function) {
uint64_t Addr;
if (I->getAddress(Addr)) continue;
if (Wrapper.op_unload_native_code(Addr) == -1) {
DEBUG(dbgs()
<< "Failed to tell OProfile about unload of native function at "
<< (void*)Addr << "\n");
continue;
}
}
}
}
} // anonymous namespace.
namespace llvm {

View File

@ -141,6 +141,10 @@ bool OProfileWrapper::checkForOProfileProcEntry() {
close(CmdLineFD);
ssize_t Idx = 0;
if (ExeName[0] != '/') {
BaseName = ExeName;
}
// Find the terminator for the first string
while (Idx < NumRead-1 && ExeName[Idx] != 0) {
Idx++;
@ -159,7 +163,8 @@ bool OProfileWrapper::checkForOProfileProcEntry() {
}
// Test this to see if it is the oprofile daemon
if (BaseName != 0 && !strcmp("oprofiled", BaseName)) {
if (BaseName != 0 && (!strcmp("oprofiled", BaseName) ||
!strcmp("operf", BaseName))) {
// If it is, we're done
closedir(ProcDir);
return true;