1//===- JITEventListener.h - Exposes events from JIT compilation -*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the JITEventListener interface, which lets users get
11// callbacks when significant events happen during the JIT compilation process.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
16#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
17
18#include "llvm/Config/llvm-config.h"
19#include "llvm/IR/DebugLoc.h"
20#include "llvm/Support/DataTypes.h"
21#include <vector>
22
23namespace llvm {
24class Function;
25class MachineFunction;
26class OProfileWrapper;
27class IntelJITEventsWrapper;
28class ObjectImage;
29
30/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
31/// about a generated machine code function.
32struct JITEvent_EmittedFunctionDetails {
33  struct LineStart {
34    /// The address at which the current line changes.
35    uintptr_t Address;
36
37    /// The new location information.  These can be translated to DebugLocTuples
38    /// using MF->getDebugLocTuple().
39    DebugLoc Loc;
40  };
41
42  /// The machine function the struct contains information for.
43  const MachineFunction *MF;
44
45  /// The list of line boundary information, sorted by address.
46  std::vector<LineStart> LineStarts;
47};
48
49/// JITEventListener - Abstract interface for use by the JIT to notify clients
50/// about significant events during compilation. For example, to notify
51/// profilers and debuggers that need to know where functions have been emitted.
52///
53/// The default implementation of each method does nothing.
54class JITEventListener {
55public:
56  typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails;
57
58public:
59  JITEventListener() {}
60  virtual ~JITEventListener();
61
62  /// NotifyFunctionEmitted - Called after a function has been successfully
63  /// emitted to memory.  The function still has its MachineFunction attached,
64  /// if you should happen to need that.
65  virtual void NotifyFunctionEmitted(const Function &,
66                                     void *, size_t,
67                                     const EmittedFunctionDetails &) {}
68
69  /// NotifyFreeingMachineCode - Called from freeMachineCodeForFunction(), after
70  /// the global mapping is removed, but before the machine code is returned to
71  /// the allocator.
72  ///
73  /// OldPtr is the address of the machine code and will be the same as the Code
74  /// parameter to a previous NotifyFunctionEmitted call.  The Function passed
75  /// to NotifyFunctionEmitted may have been destroyed by the time of the
76  /// matching NotifyFreeingMachineCode call.
77  virtual void NotifyFreeingMachineCode(void *) {}
78
79  /// NotifyObjectEmitted - Called after an object has been successfully
80  /// emitted to memory.  NotifyFunctionEmitted will not be called for
81  /// individual functions in the object.
82  ///
83  /// ELF-specific information
84  /// The ObjectImage contains the generated object image
85  /// with section headers updated to reflect the address at which sections
86  /// were loaded and with relocations performed in-place on debug sections.
87  virtual void NotifyObjectEmitted(const ObjectImage &Obj) {}
88
89  /// NotifyFreeingObject - Called just before the memory associated with
90  /// a previously emitted object is released.
91  virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
92
93#if LLVM_USE_INTEL_JITEVENTS
94  // Construct an IntelJITEventListener
95  static JITEventListener *createIntelJITEventListener();
96
97  // Construct an IntelJITEventListener with a test Intel JIT API implementation
98  static JITEventListener *createIntelJITEventListener(
99                                      IntelJITEventsWrapper* AlternativeImpl);
100#else
101  static JITEventListener *createIntelJITEventListener() { return nullptr; }
102
103  static JITEventListener *createIntelJITEventListener(
104                                      IntelJITEventsWrapper* AlternativeImpl) {
105    return nullptr;
106  }
107#endif // USE_INTEL_JITEVENTS
108
109#if LLVM_USE_OPROFILE
110  // Construct an OProfileJITEventListener
111  static JITEventListener *createOProfileJITEventListener();
112
113  // Construct an OProfileJITEventListener with a test opagent implementation
114  static JITEventListener *createOProfileJITEventListener(
115                                      OProfileWrapper* AlternativeImpl);
116#else
117
118  static JITEventListener *createOProfileJITEventListener() { return nullptr; }
119
120  static JITEventListener *createOProfileJITEventListener(
121                                      OProfileWrapper* AlternativeImpl) {
122    return nullptr;
123  }
124#endif // USE_OPROFILE
125
126};
127
128} // end namespace llvm.
129
130#endif // defined LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
131