[llvm-objdump] - Remove one overload of reportError. NFCI.
[llvm-complete.git] / tools / llvm-jitlistener / llvm-jitlistener.cpp
blob82a798d3f74d3c5de0c12cf4ca95e6a678659dbc
1 //===-- llvm-jitlistener.cpp - Utility for testing MCJIT event listener ---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This program is a used by lit tests to verify the MCJIT JITEventListener
10 // interface. It registers a mock JIT event listener, generates a module from
11 // an input IR file and dumps the reported event information to stdout.
13 //===----------------------------------------------------------------------===//
15 #include "../../lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/ExecutionEngine/JITEventListener.h"
18 #include "llvm/ExecutionEngine/MCJIT.h"
19 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/IRReader/IRReader.h"
23 #include "llvm/Support/CommandLine.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/Host.h"
26 #include "llvm/Support/InitLLVM.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/Support/SourceMgr.h"
29 #include "llvm/Support/TargetSelect.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include <string>
33 using namespace llvm;
35 namespace {
37 typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
38 typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
40 NativeCodeMap ReportedDebugFuncs;
42 int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
43 switch (EventType) {
44 case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
45 if (!EventSpecificData) {
46 errs() <<
47 "Error: The JIT event listener did not provide a event data.";
48 return -1;
50 iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);
52 ReportedDebugFuncs[msg->method_id];
54 outs() << "Method load [" << msg->method_id << "]: " << msg->method_name
55 << ", Size = " << msg->method_size << "\n";
57 for(unsigned int i = 0; i < msg->line_number_size; ++i) {
58 if (!msg->line_number_table) {
59 errs() << "A function with a non-zero line count had no line table.";
60 return -1;
62 std::pair<std::string, unsigned int> loc(
63 std::string(msg->source_file_name),
64 msg->line_number_table[i].LineNumber);
65 ReportedDebugFuncs[msg->method_id].push_back(loc);
66 outs() << " Line info @ " << msg->line_number_table[i].Offset
67 << ": " << msg->source_file_name
68 << ", line " << msg->line_number_table[i].LineNumber << "\n";
70 outs() << "\n";
72 break;
73 case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
74 if (!EventSpecificData) {
75 errs() <<
76 "Error: The JIT event listener did not provide a event data.";
77 return -1;
79 unsigned int UnloadId
80 = *reinterpret_cast<unsigned int*>(EventSpecificData);
81 assert(1 == ReportedDebugFuncs.erase(UnloadId));
82 outs() << "Method unload [" << UnloadId << "]\n";
84 break;
85 default:
86 break;
88 return 0;
91 iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
92 // for testing, pretend we have an Intel Parallel Amplifier XE 2011
93 // instance attached
94 return iJIT_SAMPLING_ON;
97 unsigned int GetNewMethodID(void) {
98 static unsigned int id = 0;
99 return ++id;
102 class JitEventListenerTest {
103 protected:
104 void InitEE(const std::string &IRFile) {
105 // If we have a native target, initialize it to ensure it is linked in and
106 // usable by the JIT.
107 InitializeNativeTarget();
108 InitializeNativeTargetAsmPrinter();
110 // Parse the bitcode...
111 SMDiagnostic Err;
112 std::unique_ptr<Module> TheModule(parseIRFile(IRFile, Err, Context));
113 if (!TheModule) {
114 errs() << Err.getMessage();
115 return;
118 RTDyldMemoryManager *MemMgr = new SectionMemoryManager();
119 if (!MemMgr) {
120 errs() << "Unable to create memory manager.";
121 return;
124 // Override the triple to generate ELF on Windows since that's supported
125 Triple Tuple(TheModule->getTargetTriple());
126 if (Tuple.getTriple().empty())
127 Tuple.setTriple(sys::getProcessTriple());
129 if (Tuple.isOSWindows() && !Tuple.isOSBinFormatELF()) {
130 Tuple.setObjectFormat(Triple::ELF);
131 TheModule->setTargetTriple(Tuple.getTriple());
134 // Compile the IR
135 std::string Error;
136 TheJIT.reset(EngineBuilder(std::move(TheModule))
137 .setEngineKind(EngineKind::JIT)
138 .setErrorStr(&Error)
139 .setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(MemMgr))
140 .create());
141 if (Error.empty() == false)
142 errs() << Error;
145 void DestroyEE() {
146 TheJIT.reset();
149 LLVMContext Context; // Global ownership
150 std::unique_ptr<ExecutionEngine> TheJIT;
152 public:
153 void ProcessInput(const std::string &Filename) {
154 InitEE(Filename);
156 std::unique_ptr<llvm::JITEventListener> Listener(
157 JITEventListener::createIntelJITEventListener(new IntelJITEventsWrapper(
158 NotifyEvent, 0, IsProfilingActive, 0, 0, GetNewMethodID)));
160 TheJIT->RegisterJITEventListener(Listener.get());
162 TheJIT->finalizeObject();
164 // Destroy the JIT engine instead of unregistering to get unload events.
165 DestroyEE();
171 } // end anonymous namespace
173 static cl::opt<std::string>
174 InputFilename(cl::Positional, cl::desc("<input IR file>"),
175 cl::Required);
177 int main(int argc, char **argv) {
178 InitLLVM X(argc, argv);
179 cl::ParseCommandLineOptions(argc, argv, "llvm jit event listener test utility\n");
181 JitEventListenerTest Test;
182 Test.ProcessInput(InputFilename);
183 return 0;