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