LEFT | RIGHT |
1 //===-- OProfileJITEventListener.cpp - Tell OProfile about JITted code ----===// | 1 //===-- OProfileJITEventListener.cpp - Tell OProfile about JITted code ----===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines a JITEventListener object that calls into OProfile to tell | 10 // This file defines a JITEventListener object that calls into OProfile to tell |
11 // it about JITted functions. For now, we only record function names and sizes, | 11 // it about JITted functions. For now, we only record function names and sizes, |
12 // but eventually we'll also record line number information. | 12 // but eventually we'll also record line number information. |
13 // | 13 // |
14 // See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the | 14 // See http://oprofile.sourceforge.net/doc/devel/jit-interface.html for the |
15 // definition of the interface we're using. | 15 // definition of the interface we're using. |
16 // | 16 // |
17 //===----------------------------------------------------------------------===// | 17 //===----------------------------------------------------------------------===// |
18 | 18 |
19 #define DEBUG_TYPE "oprofile-jit-event-listener" | 19 #define DEBUG_TYPE "oprofile-jit-event-listener" |
20 #include "llvm/Function.h" | 20 #include "llvm/Function.h" |
21 #include "llvm/Analysis/DebugInfo.h" | 21 #include "llvm/Analysis/DebugInfo.h" |
| 22 #include "llvm/CodeGen/MachineFunction.h" |
22 #include "llvm/ExecutionEngine/JITEventListener.h" | 23 #include "llvm/ExecutionEngine/JITEventListener.h" |
23 #include "llvm/Support/Debug.h" | 24 #include "llvm/Support/Debug.h" |
24 #include "llvm/System/Errno.h" | 25 #include "llvm/System/Errno.h" |
25 #include "llvm/Config/config.h" | 26 #include "llvm/Config/config.h" |
26 #include <stddef.h> | 27 #include <stddef.h> |
27 using namespace llvm; | 28 using namespace llvm; |
28 | 29 |
29 #if USE_OPROFILE | 30 #if USE_OPROFILE |
30 | 31 |
31 #include <opagent.h> | 32 #include <opagent.h> |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 return Filename; | 83 return Filename; |
83 } | 84 } |
84 ~FilenameCache() { | 85 ~FilenameCache() { |
85 for (DenseMap<GlobalVariable*, char*>::iterator | 86 for (DenseMap<GlobalVariable*, char*>::iterator |
86 I = Filenames.begin(), E = Filenames.end(); I != E;++I) { | 87 I = Filenames.begin(), E = Filenames.end(); I != E;++I) { |
87 free(I->second); | 88 free(I->second); |
88 } | 89 } |
89 } | 90 } |
90 }; | 91 }; |
91 | 92 |
| 93 static debug_line_info LineStartToOProfileFormat( |
| 94 const MachineFunction &MF, FilenameCache &Filenames, |
| 95 uintptr_t Address, DebugLoc Loc) { |
| 96 debug_line_info Result; |
| 97 Result.vma = Address; |
| 98 const DebugLocTuple& tuple = MF.getDebugLocTuple(Loc); |
| 99 Result.lineno = tuple.Line; |
| 100 Result.filename = Filenames.getFilename(tuple.CompileUnit); |
| 101 DOUT << "Mapping " << reinterpret_cast<void*>(Result.vma) << " to " |
| 102 << Result.filename << ":" << Result.lineno << "\n"; |
| 103 return Result; |
| 104 } |
| 105 |
92 // Adds the just-emitted function to the symbol table. | 106 // Adds the just-emitted function to the symbol table. |
93 void OProfileJITEventListener::NotifyFunctionEmitted( | 107 void OProfileJITEventListener::NotifyFunctionEmitted( |
94 const Function &F, void *FnStart, size_t FnSize, | 108 const Function &F, void *FnStart, size_t FnSize, |
95 const EmittedFunctionDetails &Details) { | 109 const EmittedFunctionDetails &Details) { |
96 const char *const FnName = F.getNameStart(); | 110 const char *const FnName = F.getNameStart(); |
97 assert(FnName != 0 && FnStart != 0 && "Bad symbol to add"); | 111 assert(FnName != 0 && FnStart != 0 && "Bad symbol to add"); |
98 if (op_write_native_code(Agent, FnName, | 112 if (op_write_native_code(Agent, FnName, |
99 reinterpret_cast<uint64_t>(FnStart), | 113 reinterpret_cast<uint64_t>(FnStart), |
100 FnStart, FnSize) == -1) { | 114 FnStart, FnSize) == -1) { |
101 DOUT << "Failed to tell OProfile about native function " << FnName | 115 DOUT << "Failed to tell OProfile about native function " << FnName |
102 << " at [" << FnStart << "-" << ((char*)FnStart + FnSize) << "]\n"; | 116 << " at [" << FnStart << "-" << ((char*)FnStart + FnSize) << "]\n"; |
103 return; | 117 return; |
104 } | 118 } |
105 | 119 |
| 120 // Now we convert the line number information from the address/DebugLoc format |
| 121 // in Details to the address/filename/lineno format that OProfile expects. |
| 122 // OProfile 0.9.4 (and maybe later versions) has a bug that causes it to |
| 123 // ignore line numbers for addresses above 4G. |
106 FilenameCache Filenames; | 124 FilenameCache Filenames; |
107 std::vector<debug_line_info> LineInfo; | 125 std::vector<debug_line_info> LineInfo; |
108 LineInfo.reserve(1 + Details.LineStarts.size()); | 126 LineInfo.reserve(1 + Details.LineStarts.size()); |
109 debug_line_info Line; | 127 if (!Details.MF->getDefaultDebugLoc().isUnknown()) { |
110 Line.vma = reinterpret_cast<uintptr_t>(FnStart); | 128 LineInfo.push_back(LineStartToOProfileFormat( |
111 //const DebugLocTuple& tuple = Details.MF->getDebugLocTuple(Details.MF->getDef
aultDebugLoc()); | 129 *Details.MF, Filenames, |
112 Line.lineno = 15; | 130 reinterpret_cast<uintptr_t>(FnStart), |
113 Line.filename = "Hello world"; | 131 Details.MF->getDefaultDebugLoc())); |
114 DOUT << "Mapping " << std::hex << Line.vma << " to " | 132 } |
115 << std::dec << Line.filename << ":" << Line.lineno << "\n"; | 133 for (std::vector<EmittedFunctionDetails::LineStart>::const_iterator |
116 LineInfo.push_back(Line); | |
117 for (std::vector<EmittedFunctionDetails::LineStartsT>::const_iterator | |
118 I = Details.LineStarts.begin(), E = Details.LineStarts.end(); | 134 I = Details.LineStarts.begin(), E = Details.LineStarts.end(); |
119 I != E; ++I) { | 135 I != E; ++I) { |
120 debug_line_info Line; | 136 LineInfo.push_back(LineStartToOProfileFormat( |
121 Line.vma = I->Address; | 137 *Details.MF, Filenames, I->Address, I->Loc)); |
122 const DebugLocTuple& tuple = Details.MF->getDebugLocTuple(I->Loc); | |
123 Line.lineno = tuple.Line; | |
124 Line.filename = Filenames.getFilename(tuple.CompileUnit); | |
125 DOUT << "Mapping " << std::hex << Line.vma << " to " | |
126 << std::dec << Line.filename << ":" << Line.lineno << "\n"; | |
127 LineInfo.push_back(Line); | |
128 } | 138 } |
129 if (!LineInfo.empty()) { | 139 if (!LineInfo.empty()) { |
130 if (op_write_debug_line_info(Agent, FnStart, | 140 if (op_write_debug_line_info(Agent, FnStart, |
131 LineInfo.size(), &*LineInfo.begin()) == -1) { | 141 LineInfo.size(), &*LineInfo.begin()) == -1) { |
132 DOUT << "Failed to tell OProfile about line numbers for native function " | 142 DOUT << "Failed to tell OProfile about line numbers for native function " |
133 << FnName << " at [" << FnStart << "-" << ((char*)FnStart + FnSize) | 143 << FnName << " at [" << FnStart << "-" << ((char*)FnStart + FnSize) |
134 << "]\n"; | 144 << "]\n"; |
135 } | 145 } |
136 } | 146 } |
137 } | 147 } |
(...skipping 20 matching lines...) Expand all Loading... |
158 | 168 |
159 namespace llvm { | 169 namespace llvm { |
160 // By defining this to return NULL, we can let clients call it unconditionally, | 170 // By defining this to return NULL, we can let clients call it unconditionally, |
161 // even if they haven't configured with the OProfile libraries. | 171 // even if they haven't configured with the OProfile libraries. |
162 JITEventListener *createOProfileJITEventListener() { | 172 JITEventListener *createOProfileJITEventListener() { |
163 return NULL; | 173 return NULL; |
164 } | 174 } |
165 } // namespace llvm | 175 } // namespace llvm |
166 | 176 |
167 #endif // USE_OPROFILE | 177 #endif // USE_OPROFILE |
LEFT | RIGHT |