1df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//===- JITEventListener.h - Exposes events from JIT compilation -*- C++ -*-===//
2df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//
3df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//                     The LLVM Compiler Infrastructure
4df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//
5df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin// This file is distributed under the University of Illinois Open Source
6df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin// License. See LICENSE.TXT for details.
7df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//
8df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//===----------------------------------------------------------------------===//
9df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//
10df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin// This file defines the JITEventListener interface, which lets users get
11df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin// callbacks when significant events happen during the JIT compilation process.
12df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//
13df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin//===----------------------------------------------------------------------===//
14df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
15674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
16674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
17df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
180069b55b8a70e450fa612534bc13f28b2be28c7eNAKAMURA Takumi#include "llvm/Config/llvm-config.h"
191f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h"
2032360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin#include "llvm/Support/DebugLoc.h"
2132360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin#include <vector>
22df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
23df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinnamespace llvm {
24df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinclass Function;
2532360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskinclass MachineFunction;
2661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyclass OProfileWrapper;
2761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Benderskyclass IntelJITEventsWrapper;
28776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorclass ObjectImage;
29df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
30f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar/// JITEvent_EmittedFunctionDetails - Helper struct for containing information
31f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar/// about a generated machine code function.
32df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinstruct JITEvent_EmittedFunctionDetails {
3332360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin  struct LineStart {
34f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar    /// The address at which the current line changes.
3532360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin    uintptr_t Address;
36f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar
37f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar    /// The new location information.  These can be translated to DebugLocTuples
38f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar    /// using MF->getDebugLocTuple().
3932360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin    DebugLoc Loc;
4032360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin  };
41f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar
42f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// The machine function the struct contains information for.
43f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  const MachineFunction *MF;
44f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar
45f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// The list of line boundary information, sorted by address.
4632360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin  std::vector<LineStart> LineStarts;
47df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin};
48df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
49f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar/// JITEventListener - Abstract interface for use by the JIT to notify clients
50f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar/// about significant events during compilation. For example, to notify
51f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar/// profilers and debuggers that need to know where functions have been emitted.
52df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin///
53f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar/// The default implementation of each method does nothing.
54df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinclass JITEventListener {
55df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinpublic:
56f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails;
57f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar
58f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbarpublic:
59df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin  JITEventListener() {}
60f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  virtual ~JITEventListener();
61df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
62df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin  /// NotifyFunctionEmitted - Called after a function has been successfully
63df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin  /// emitted to memory.  The function still has its MachineFunction attached,
64df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin  /// if you should happen to need that.
65b39e25ef2c8d8c840ec4155e57c737ac7bd4f167Eli Friedman  virtual void NotifyFunctionEmitted(const Function &,
66b39e25ef2c8d8c840ec4155e57c737ac7bd4f167Eli Friedman                                     void *, size_t,
67b39e25ef2c8d8c840ec4155e57c737ac7bd4f167Eli Friedman                                     const EmittedFunctionDetails &) {}
68df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
69f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// NotifyFreeingMachineCode - Called from freeMachineCodeForFunction(), after
70f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// the global mapping is removed, but before the machine code is returned to
71f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// the allocator.
72f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  ///
73f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// OldPtr is the address of the machine code and will be the same as the Code
74f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// parameter to a previous NotifyFunctionEmitted call.  The Function passed
75f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// to NotifyFunctionEmitted may have been destroyed by the time of the
76f47a7b2699a6d0dcda4aac8b9a6de19c9b5a4219Daniel Dunbar  /// matching NotifyFreeingMachineCode call.
77b39e25ef2c8d8c840ec4155e57c737ac7bd4f167Eli Friedman  virtual void NotifyFreeingMachineCode(void *) {}
78df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
79776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// NotifyObjectEmitted - Called after an object has been successfully
80776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// emitted to memory.  NotifyFunctionEmitted will not be called for
81776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// individual functions in the object.
82776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  ///
83776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// ELF-specific information
84776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// The ObjectImage contains the generated object image
85776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// with section headers updated to reflect the address at which sections
86776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// were loaded and with relocations performed in-place on debug sections.
87776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  virtual void NotifyObjectEmitted(const ObjectImage &Obj) {}
88776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor
89776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// NotifyFreeingObject - Called just before the memory associated with
90776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  /// a previously emitted object is released.
91776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  virtual void NotifyFreeingObject(const ObjectImage &Obj) {}
92776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor
9361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#if LLVM_USE_INTEL_JITEVENTS
9461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Construct an IntelJITEventListener
9561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createIntelJITEventListener();
9661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
9761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Construct an IntelJITEventListener with a test Intel JIT API implementation
9861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createIntelJITEventListener(
9961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                      IntelJITEventsWrapper* AlternativeImpl);
10061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#else
10161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createIntelJITEventListener() { return 0; }
10261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
10361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createIntelJITEventListener(
10461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                      IntelJITEventsWrapper* AlternativeImpl) {
10561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    return 0;
10661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  }
10761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#endif // USE_INTEL_JITEVENTS
10861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
10961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#if LLVM_USE_OPROFILE
11061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Construct an OProfileJITEventListener
11161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createOProfileJITEventListener();
11261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
11361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  // Construct an OProfileJITEventListener with a test opagent implementation
11461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createOProfileJITEventListener(
11561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                      OProfileWrapper* AlternativeImpl);
11661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#else
11761b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
11861b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createOProfileJITEventListener() { return 0; }
11961b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
12061b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  static JITEventListener *createOProfileJITEventListener(
12161b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky                                      OProfileWrapper* AlternativeImpl) {
12261b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky    return 0;
12361b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky  }
12461b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky#endif // USE_OPROFILE
12561b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky
12661b1851a205cb8dd29c1d3d4231efb8f8f7da283Eli Bendersky};
127df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
128df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin} // end namespace llvm.
129df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin
130674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#endif // defined LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
131