ExecutionEngine.h revision 199481
1177633Sdfr//===- ExecutionEngine.h - Abstract Execution Engine Interface --*- C++ -*-===// 2177633Sdfr// 3177633Sdfr// The LLVM Compiler Infrastructure 4177633Sdfr// 5177633Sdfr// This file is distributed under the University of Illinois Open Source 6177633Sdfr// License. See LICENSE.TXT for details. 7177633Sdfr// 8177633Sdfr//===----------------------------------------------------------------------===// 9177633Sdfr// 10177633Sdfr// This file defines the abstract interface that implements execution support 11177633Sdfr// for LLVM. 12177633Sdfr// 13177633Sdfr//===----------------------------------------------------------------------===// 14177633Sdfr 15177633Sdfr#ifndef LLVM_EXECUTION_ENGINE_H 16177633Sdfr#define LLVM_EXECUTION_ENGINE_H 17177633Sdfr 18177633Sdfr#include <vector> 19177633Sdfr#include <map> 20177633Sdfr#include <string> 21177633Sdfr#include "llvm/ADT/SmallVector.h" 22177633Sdfr#include "llvm/ADT/ValueMap.h" 23177633Sdfr#include "llvm/Support/ValueHandle.h" 24177633Sdfr#include "llvm/System/Mutex.h" 25177633Sdfr#include "llvm/Target/TargetMachine.h" 26177633Sdfr 27177633Sdfrnamespace llvm { 28177633Sdfr 29177633Sdfrstruct GenericValue; 30177633Sdfrclass Constant; 31177633Sdfrclass ExecutionEngine; 32177633Sdfrclass Function; 33177633Sdfrclass GlobalVariable; 34177633Sdfrclass GlobalValue; 35177633Sdfrclass JITEventListener; 36177633Sdfrclass JITMemoryManager; 37177633Sdfrclass MachineCodeInfo; 38177633Sdfrclass Module; 39177633Sdfrclass ModuleProvider; 40177633Sdfrclass MutexGuard; 41177633Sdfrclass TargetData; 42177633Sdfrclass Type; 43177633Sdfr 44177633Sdfrclass ExecutionEngineState { 45177685Sdfrpublic: 46177633Sdfr struct AddressMapConfig : public ValueMapConfig<const GlobalValue*> { 47177633Sdfr typedef ExecutionEngineState *ExtraData; 48177633Sdfr static sys::Mutex *getMutex(ExecutionEngineState *EES); 49177633Sdfr static void onDelete(ExecutionEngineState *EES, const GlobalValue *Old); 50177633Sdfr static void onRAUW(ExecutionEngineState *, const GlobalValue *, 51177633Sdfr const GlobalValue *); 52177633Sdfr }; 53177633Sdfr 54177633Sdfr typedef ValueMap<const GlobalValue *, void *, AddressMapConfig> 55177633Sdfr GlobalAddressMapTy; 56177633Sdfr 57177633Sdfrprivate: 58177633Sdfr ExecutionEngine &EE; 59177633Sdfr 60177633Sdfr /// GlobalAddressMap - A mapping between LLVM global values and their 61177633Sdfr /// actualized version... 62177633Sdfr GlobalAddressMapTy GlobalAddressMap; 63177633Sdfr 64177633Sdfr /// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap, 65177633Sdfr /// used to convert raw addresses into the LLVM global value that is emitted 66177633Sdfr /// at the address. This map is not computed unless getGlobalValueAtAddress 67177633Sdfr /// is called at some point. 68177633Sdfr std::map<void *, AssertingVH<const GlobalValue> > GlobalAddressReverseMap; 69177633Sdfr 70177633Sdfrpublic: 71177633Sdfr ExecutionEngineState(ExecutionEngine &EE); 72177633Sdfr 73177633Sdfr GlobalAddressMapTy & 74177633Sdfr getGlobalAddressMap(const MutexGuard &) { 75177633Sdfr return GlobalAddressMap; 76177633Sdfr } 77177633Sdfr 78177633Sdfr std::map<void*, AssertingVH<const GlobalValue> > & 79177633Sdfr getGlobalAddressReverseMap(const MutexGuard &) { 80177633Sdfr return GlobalAddressReverseMap; 81177633Sdfr } 82177633Sdfr 83177633Sdfr // Returns the address ToUnmap was mapped to. 84177633Sdfr void *RemoveMapping(const MutexGuard &, const GlobalValue *ToUnmap); 85177633Sdfr}; 86177633Sdfr 87177633Sdfr 88177633Sdfrclass ExecutionEngine { 89177633Sdfr const TargetData *TD; 90177633Sdfr ExecutionEngineState EEState; 91177633Sdfr bool CompilingLazily; 92177633Sdfr bool GVCompilationDisabled; 93177633Sdfr bool SymbolSearchingDisabled; 94177633Sdfr 95177633Sdfr friend class EngineBuilder; // To allow access to JITCtor and InterpCtor. 96177633Sdfr 97177633Sdfrprotected: 98177633Sdfr /// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We 99177633Sdfr /// use a smallvector to optimize for the case where there is only one module. 100177633Sdfr SmallVector<ModuleProvider*, 1> Modules; 101177633Sdfr 102177633Sdfr void setTargetData(const TargetData *td) { 103177633Sdfr TD = td; 104177633Sdfr } 105177633Sdfr 106177633Sdfr /// getMemoryforGV - Allocate memory for a global variable. 107177633Sdfr virtual char* getMemoryForGV(const GlobalVariable* GV); 108177633Sdfr 109177633Sdfr // To avoid having libexecutionengine depend on the JIT and interpreter 110177633Sdfr // libraries, the JIT and Interpreter set these functions to ctor pointers 111177633Sdfr // at startup time if they are linked in. 112177633Sdfr static ExecutionEngine *(*JITCtor)(ModuleProvider *MP, 113177633Sdfr std::string *ErrorStr, 114177633Sdfr JITMemoryManager *JMM, 115177633Sdfr CodeGenOpt::Level OptLevel, 116177633Sdfr bool GVsWithCode, 117177633Sdfr CodeModel::Model CMM); 118177633Sdfr static ExecutionEngine *(*InterpCtor)(ModuleProvider *MP, 119177633Sdfr std::string *ErrorStr); 120177633Sdfr 121177633Sdfr /// LazyFunctionCreator - If an unknown function is needed, this function 122177633Sdfr /// pointer is invoked to create it. If this returns null, the JIT will abort. 123177633Sdfr void* (*LazyFunctionCreator)(const std::string &); 124177633Sdfr 125177633Sdfr /// ExceptionTableRegister - If Exception Handling is set, the JIT will 126177633Sdfr /// register dwarf tables with this function 127177633Sdfr typedef void (*EERegisterFn)(void*); 128177633Sdfr static EERegisterFn ExceptionTableRegister; 129177633Sdfr 130177633Sdfrpublic: 131177633Sdfr /// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and 132177633Sdfr /// JITEmitter classes. It must be held while changing the internal state of 133177633Sdfr /// any of those classes. 134177633Sdfr sys::Mutex lock; // Used to make this class and subclasses thread-safe 135177633Sdfr 136177633Sdfr //===--------------------------------------------------------------------===// 137177633Sdfr // ExecutionEngine Startup 138177633Sdfr //===--------------------------------------------------------------------===// 139177633Sdfr 140177633Sdfr virtual ~ExecutionEngine(); 141177633Sdfr 142178112Sdfr /// create - This is the factory method for creating an execution engine which 143178112Sdfr /// is appropriate for the current machine. This takes ownership of the 144178112Sdfr /// module provider. 145177633Sdfr static ExecutionEngine *create(ModuleProvider *MP, 146177633Sdfr bool ForceInterpreter = false, 147177633Sdfr std::string *ErrorStr = 0, 148177633Sdfr CodeGenOpt::Level OptLevel = 149177633Sdfr CodeGenOpt::Default, 150177633Sdfr // Allocating globals with code breaks 151177633Sdfr // freeMachineCodeForFunction and is probably 152177633Sdfr // unsafe and bad for performance. However, 153177633Sdfr // we have clients who depend on this 154177633Sdfr // behavior, so we must support it. 155177633Sdfr // Eventually, when we're willing to break 156177633Sdfr // some backwards compatability, this flag 157177633Sdfr // should be flipped to false, so that by 158177633Sdfr // default freeMachineCodeForFunction works. 159177633Sdfr bool GVsWithCode = true); 160177633Sdfr 161177633Sdfr /// create - This is the factory method for creating an execution engine which 162177633Sdfr /// is appropriate for the current machine. This takes ownership of the 163177633Sdfr /// module. 164177633Sdfr static ExecutionEngine *create(Module *M); 165177633Sdfr 166177633Sdfr /// createJIT - This is the factory method for creating a JIT for the current 167177633Sdfr /// machine, it does not fall back to the interpreter. This takes ownership 168177633Sdfr /// of the ModuleProvider and JITMemoryManager if successful. 169178112Sdfr /// 170178112Sdfr /// Clients should make sure to initialize targets prior to calling this 171178112Sdfr /// function. 172178112Sdfr static ExecutionEngine *createJIT(ModuleProvider *MP, 173178112Sdfr std::string *ErrorStr = 0, 174177633Sdfr JITMemoryManager *JMM = 0, 175177633Sdfr CodeGenOpt::Level OptLevel = 176177633Sdfr CodeGenOpt::Default, 177177633Sdfr bool GVsWithCode = true, 178177633Sdfr CodeModel::Model CMM = 179177633Sdfr CodeModel::Default); 180177633Sdfr 181177633Sdfr /// addModuleProvider - Add a ModuleProvider to the list of modules that we 182177633Sdfr /// can JIT from. Note that this takes ownership of the ModuleProvider: when 183177633Sdfr /// the ExecutionEngine is destroyed, it destroys the MP as well. 184177633Sdfr virtual void addModuleProvider(ModuleProvider *P) { 185177633Sdfr Modules.push_back(P); 186177633Sdfr } 187177633Sdfr 188177633Sdfr //===----------------------------------------------------------------------===// 189177633Sdfr 190177633Sdfr const TargetData *getTargetData() const { return TD; } 191177633Sdfr 192177633Sdfr 193177633Sdfr /// removeModuleProvider - Remove a ModuleProvider from the list of modules. 194177633Sdfr /// Relases the Module from the ModuleProvider, materializing it in the 195177633Sdfr /// process, and returns the materialized Module. 196177633Sdfr virtual Module* removeModuleProvider(ModuleProvider *P, 197177633Sdfr std::string *ErrInfo = 0); 198177633Sdfr 199177633Sdfr /// deleteModuleProvider - Remove a ModuleProvider from the list of modules, 200177633Sdfr /// and deletes the ModuleProvider and owned Module. Avoids materializing 201177633Sdfr /// the underlying module. 202177633Sdfr virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0); 203177633Sdfr 204177633Sdfr /// FindFunctionNamed - Search all of the active modules to find the one that 205177633Sdfr /// defines FnName. This is very slow operation and shouldn't be used for 206177633Sdfr /// general code. 207177633Sdfr Function *FindFunctionNamed(const char *FnName); 208177633Sdfr 209177633Sdfr /// runFunction - Execute the specified function with the specified arguments, 210177633Sdfr /// and return the result. 211177633Sdfr /// 212177633Sdfr virtual GenericValue runFunction(Function *F, 213177633Sdfr const std::vector<GenericValue> &ArgValues) = 0; 214177633Sdfr 215177633Sdfr /// runStaticConstructorsDestructors - This method is used to execute all of 216177633Sdfr /// the static constructors or destructors for a program, depending on the 217177633Sdfr /// value of isDtors. 218177633Sdfr void runStaticConstructorsDestructors(bool isDtors); 219177633Sdfr /// runStaticConstructorsDestructors - This method is used to execute all of 220177633Sdfr /// the static constructors or destructors for a module, depending on the 221177633Sdfr /// value of isDtors. 222177633Sdfr void runStaticConstructorsDestructors(Module *module, bool isDtors); 223177633Sdfr 224177633Sdfr 225177633Sdfr /// runFunctionAsMain - This is a helper function which wraps runFunction to 226177633Sdfr /// handle the common task of starting up main with the specified argc, argv, 227177633Sdfr /// and envp parameters. 228177633Sdfr int runFunctionAsMain(Function *Fn, const std::vector<std::string> &argv, 229177633Sdfr const char * const * envp); 230177633Sdfr 231177633Sdfr 232177633Sdfr /// addGlobalMapping - Tell the execution engine that the specified global is 233177633Sdfr /// at the specified location. This is used internally as functions are JIT'd 234177633Sdfr /// and as global variables are laid out in memory. It can and should also be 235177633Sdfr /// used by clients of the EE that want to have an LLVM global overlay 236177633Sdfr /// existing data in memory. Mappings are automatically removed when their 237177633Sdfr /// GlobalValue is destroyed. 238177633Sdfr void addGlobalMapping(const GlobalValue *GV, void *Addr); 239177633Sdfr 240177633Sdfr /// clearAllGlobalMappings - Clear all global mappings and start over again 241177633Sdfr /// use in dynamic compilation scenarios when you want to move globals 242177633Sdfr void clearAllGlobalMappings(); 243177633Sdfr 244177633Sdfr /// clearGlobalMappingsFromModule - Clear all global mappings that came from a 245177633Sdfr /// particular module, because it has been removed from the JIT. 246177633Sdfr void clearGlobalMappingsFromModule(Module *M); 247177633Sdfr 248177633Sdfr /// updateGlobalMapping - Replace an existing mapping for GV with a new 249177633Sdfr /// address. This updates both maps as required. If "Addr" is null, the 250177633Sdfr /// entry for the global is removed from the mappings. This returns the old 251177633Sdfr /// value of the pointer, or null if it was not in the map. 252177633Sdfr void *updateGlobalMapping(const GlobalValue *GV, void *Addr); 253177633Sdfr 254177633Sdfr /// getPointerToGlobalIfAvailable - This returns the address of the specified 255177633Sdfr /// global value if it is has already been codegen'd, otherwise it returns 256177633Sdfr /// null. 257177633Sdfr /// 258177633Sdfr void *getPointerToGlobalIfAvailable(const GlobalValue *GV); 259177633Sdfr 260177633Sdfr /// getPointerToGlobal - This returns the address of the specified global 261177633Sdfr /// value. This may involve code generation if it's a function. 262177633Sdfr /// 263177633Sdfr void *getPointerToGlobal(const GlobalValue *GV); 264177633Sdfr 265177633Sdfr /// getPointerToFunction - The different EE's represent function bodies in 266177633Sdfr /// different ways. They should each implement this to say what a function 267177633Sdfr /// pointer should look like. When F is destroyed, the ExecutionEngine will 268177633Sdfr /// remove its global mapping and free any machine code. Be sure no threads 269177633Sdfr /// are running inside F when that happens. 270177633Sdfr /// 271177633Sdfr virtual void *getPointerToFunction(Function *F) = 0; 272177633Sdfr 273177633Sdfr /// getPointerToBasicBlock - The different EE's represent basic blocks in 274177633Sdfr /// different ways. Return the representation for a blockaddress of the 275177633Sdfr /// specified block. 276177633Sdfr /// 277177633Sdfr virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0; 278177633Sdfr 279177633Sdfr /// getPointerToFunctionOrStub - If the specified function has been 280177633Sdfr /// code-gen'd, return a pointer to the function. If not, compile it, or use 281177633Sdfr /// a stub to implement lazy compilation if available. See 282177633Sdfr /// getPointerToFunction for the requirements on destroying F. 283177633Sdfr /// 284177633Sdfr virtual void *getPointerToFunctionOrStub(Function *F) { 285177633Sdfr // Default implementation, just codegen the function. 286177633Sdfr return getPointerToFunction(F); 287177633Sdfr } 288177633Sdfr 289177633Sdfr // The JIT overrides a version that actually does this. 290177633Sdfr virtual void runJITOnFunction(Function *, MachineCodeInfo * = 0) { } 291177633Sdfr 292177633Sdfr /// getGlobalValueAtAddress - Return the LLVM global value object that starts 293177633Sdfr /// at the specified address. 294177633Sdfr /// 295177633Sdfr const GlobalValue *getGlobalValueAtAddress(void *Addr); 296177633Sdfr 297177633Sdfr 298177633Sdfr void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, 299177633Sdfr const Type *Ty); 300177633Sdfr void InitializeMemory(const Constant *Init, void *Addr); 301177633Sdfr 302177633Sdfr /// recompileAndRelinkFunction - This method is used to force a function 303177633Sdfr /// which has already been compiled to be compiled again, possibly 304177633Sdfr /// after it has been modified. Then the entry to the old copy is overwritten 305177633Sdfr /// with a branch to the new copy. If there was no old copy, this acts 306177633Sdfr /// just like VM::getPointerToFunction(). 307177633Sdfr /// 308177633Sdfr virtual void *recompileAndRelinkFunction(Function *F) = 0; 309177633Sdfr 310177633Sdfr /// freeMachineCodeForFunction - Release memory in the ExecutionEngine 311177633Sdfr /// corresponding to the machine code emitted to execute this function, useful 312177633Sdfr /// for garbage-collecting generated code. 313177633Sdfr /// 314 virtual void freeMachineCodeForFunction(Function *F) = 0; 315 316 /// getOrEmitGlobalVariable - Return the address of the specified global 317 /// variable, possibly emitting it to memory if needed. This is used by the 318 /// Emitter. 319 virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) { 320 return getPointerToGlobal((GlobalValue*)GV); 321 } 322 323 /// Registers a listener to be called back on various events within 324 /// the JIT. See JITEventListener.h for more details. Does not 325 /// take ownership of the argument. The argument may be NULL, in 326 /// which case these functions do nothing. 327 virtual void RegisterJITEventListener(JITEventListener *) {} 328 virtual void UnregisterJITEventListener(JITEventListener *) {} 329 330 /// DisableLazyCompilation - When lazy compilation is off (the default), the 331 /// JIT will eagerly compile every function reachable from the argument to 332 /// getPointerToFunction. If lazy compilation is turned on, the JIT will only 333 /// compile the one function and emit stubs to compile the rest when they're 334 /// first called. If lazy compilation is turned off again while some lazy 335 /// stubs are still around, and one of those stubs is called, the program will 336 /// abort. 337 /// 338 /// In order to safely compile lazily in a threaded program, the user must 339 /// ensure that 1) only one thread at a time can call any particular lazy 340 /// stub, and 2) any thread modifying LLVM IR must hold the JIT's lock 341 /// (ExecutionEngine::lock) or otherwise ensure that no other thread calls a 342 /// lazy stub. See http://llvm.org/PR5184 for details. 343 void DisableLazyCompilation(bool Disabled = true) { 344 CompilingLazily = !Disabled; 345 } 346 bool isCompilingLazily() const { 347 return CompilingLazily; 348 } 349 // Deprecated in favor of isCompilingLazily (to reduce double-negatives). 350 // Remove this in LLVM 2.8. 351 bool isLazyCompilationDisabled() const { 352 return !CompilingLazily; 353 } 354 355 /// DisableGVCompilation - If called, the JIT will abort if it's asked to 356 /// allocate space and populate a GlobalVariable that is not internal to 357 /// the module. 358 void DisableGVCompilation(bool Disabled = true) { 359 GVCompilationDisabled = Disabled; 360 } 361 bool isGVCompilationDisabled() const { 362 return GVCompilationDisabled; 363 } 364 365 /// DisableSymbolSearching - If called, the JIT will not try to lookup unknown 366 /// symbols with dlsym. A client can still use InstallLazyFunctionCreator to 367 /// resolve symbols in a custom way. 368 void DisableSymbolSearching(bool Disabled = true) { 369 SymbolSearchingDisabled = Disabled; 370 } 371 bool isSymbolSearchingDisabled() const { 372 return SymbolSearchingDisabled; 373 } 374 375 /// InstallLazyFunctionCreator - If an unknown function is needed, the 376 /// specified function pointer is invoked to create it. If it returns null, 377 /// the JIT will abort. 378 void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { 379 LazyFunctionCreator = P; 380 } 381 382 /// InstallExceptionTableRegister - The JIT will use the given function 383 /// to register the exception tables it generates. 384 static void InstallExceptionTableRegister(void (*F)(void*)) { 385 ExceptionTableRegister = F; 386 } 387 388 /// RegisterTable - Registers the given pointer as an exception table. It uses 389 /// the ExceptionTableRegister function. 390 static void RegisterTable(void* res) { 391 if (ExceptionTableRegister) 392 ExceptionTableRegister(res); 393 } 394 395protected: 396 explicit ExecutionEngine(ModuleProvider *P); 397 398 void emitGlobals(); 399 400 // EmitGlobalVariable - This method emits the specified global variable to the 401 // address specified in GlobalAddresses, or allocates new memory if it's not 402 // already in the map. 403 void EmitGlobalVariable(const GlobalVariable *GV); 404 405 GenericValue getConstantValue(const Constant *C); 406 void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, 407 const Type *Ty); 408}; 409 410namespace EngineKind { 411 // These are actually bitmasks that get or-ed together. 412 enum Kind { 413 JIT = 0x1, 414 Interpreter = 0x2 415 }; 416 const static Kind Either = (Kind)(JIT | Interpreter); 417} 418 419/// EngineBuilder - Builder class for ExecutionEngines. Use this by 420/// stack-allocating a builder, chaining the various set* methods, and 421/// terminating it with a .create() call. 422class EngineBuilder { 423 424 private: 425 ModuleProvider *MP; 426 EngineKind::Kind WhichEngine; 427 std::string *ErrorStr; 428 CodeGenOpt::Level OptLevel; 429 JITMemoryManager *JMM; 430 bool AllocateGVsWithCode; 431 CodeModel::Model CMModel; 432 433 /// InitEngine - Does the common initialization of default options. 434 /// 435 void InitEngine() { 436 WhichEngine = EngineKind::Either; 437 ErrorStr = NULL; 438 OptLevel = CodeGenOpt::Default; 439 JMM = NULL; 440 AllocateGVsWithCode = false; 441 CMModel = CodeModel::Default; 442 } 443 444 public: 445 /// EngineBuilder - Constructor for EngineBuilder. If create() is called and 446 /// is successful, the created engine takes ownership of the module 447 /// provider. 448 EngineBuilder(ModuleProvider *mp) : MP(mp) { 449 InitEngine(); 450 } 451 452 /// EngineBuilder - Overloaded constructor that automatically creates an 453 /// ExistingModuleProvider for an existing module. 454 EngineBuilder(Module *m); 455 456 /// setEngineKind - Controls whether the user wants the interpreter, the JIT, 457 /// or whichever engine works. This option defaults to EngineKind::Either. 458 EngineBuilder &setEngineKind(EngineKind::Kind w) { 459 WhichEngine = w; 460 return *this; 461 } 462 463 /// setJITMemoryManager - Sets the memory manager to use. This allows 464 /// clients to customize their memory allocation policies. If create() is 465 /// called and is successful, the created engine takes ownership of the 466 /// memory manager. This option defaults to NULL. 467 EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) { 468 JMM = jmm; 469 return *this; 470 } 471 472 /// setErrorStr - Set the error string to write to on error. This option 473 /// defaults to NULL. 474 EngineBuilder &setErrorStr(std::string *e) { 475 ErrorStr = e; 476 return *this; 477 } 478 479 /// setOptLevel - Set the optimization level for the JIT. This option 480 /// defaults to CodeGenOpt::Default. 481 EngineBuilder &setOptLevel(CodeGenOpt::Level l) { 482 OptLevel = l; 483 return *this; 484 } 485 486 /// setCodeModel - Set the CodeModel that the ExecutionEngine target 487 /// data is using. Defaults to target specific default "CodeModel::Default". 488 EngineBuilder &setCodeModel(CodeModel::Model M) { 489 CMModel = M; 490 return *this; 491 } 492 493 /// setAllocateGVsWithCode - Sets whether global values should be allocated 494 /// into the same buffer as code. For most applications this should be set 495 /// to false. Allocating globals with code breaks freeMachineCodeForFunction 496 /// and is probably unsafe and bad for performance. However, we have clients 497 /// who depend on this behavior, so we must support it. This option defaults 498 /// to false so that users of the new API can safely use the new memory 499 /// manager and free machine code. 500 EngineBuilder &setAllocateGVsWithCode(bool a) { 501 AllocateGVsWithCode = a; 502 return *this; 503 } 504 505 ExecutionEngine *create(); 506}; 507 508} // End llvm namespace 509 510#endif 511