void *ExecutionEngine::LazyFunctionCreator( std::string const &functionName ) { if ( functionName == "report" ) return (void *)&ExecutionEngine::Report; else { void *result = 0; if ( !result ) result = KL::LookupExternalSymbol( functionName ); if ( !result ) result = Plug::Manager::Instance()->llvmResolveExternalFunction( functionName ); #if defined(FABRIC_MODULE_OPENCL) if ( !result ) result = OCL::llvmResolveExternalFunction( functionName ); #endif if ( !result ) { RC::ConstHandle<Context> context = s_currentContext; result = context->getCGManager()->llvmResolveExternalFunction( functionName ); } // We should *always* return a valid symbol. Otherwise something's // wrong in the KL compiler/support. if( !result ) throw Exception( "LLVM lookup failed for symbol: " + functionName ); return result; } }
ArrayOutputOperator::ArrayOutputOperator( RC::ConstHandle<Executable> const &executable, RC::ConstHandle<AST::Operator> const &astOperator, void (*functionPtr)(...) ) : m_executable( executable ) { if ( astOperator ) { RC::Handle<CG::Manager> cgManager = executable->getCGManager(); RC::ConstHandle<AST::ParamVector> params = astOperator->getParams( cgManager ); size_t numParams = params->size(); if ( numParams < 1 || numParams > 4 ) throw GetPrototypeException(); RC::ConstHandle<AST::Param> valueParam = params->get(0); if ( valueParam->getUsage() != CG::USAGE_LVALUE ) throw GetPrototypeException(); RC::ConstHandle<RT::Desc> valueDesc = valueParam->getAdapter( cgManager )->getDesc(); RC::ConstHandle<RT::Desc> sharedDesc; if ( numParams >= 2 ) { RC::ConstHandle<AST::Param> indexParam = params->get(1); if ( indexParam->getUsage() != CG::USAGE_RVALUE || !indexParam->getAdapter( cgManager )->isEquivalentTo( cgManager->getSizeAdapter() ) ) throw GetPrototypeException(); if ( numParams >= 3 ) { RC::ConstHandle<AST::Param> countParam = params->get(2); if ( countParam->getUsage() != CG::USAGE_RVALUE || !countParam->getAdapter( cgManager )->isEquivalentTo( cgManager->getSizeAdapter() ) ) throw GetPrototypeException(); if ( numParams >= 4 ) { RC::ConstHandle<AST::Param> sharedParam = params->get(3); if ( sharedParam->getUsage() != CG::USAGE_RVALUE ) throw GetPrototypeException(); sharedDesc = sharedParam->getAdapter( cgManager )->getDesc(); } } } init( functionPtr, numParams, valueDesc, sharedDesc ); } }
ExecutionEngine::ExecutionEngine( RC::ConstHandle<Context> const &context, RC::Handle<CG::Context> const &cgContext, llvm::Module *llvmModule ) : m_contextWeakRef( context ) , m_cgContext( cgContext ) { std::string errStr; m_llvmExecutionEngine.reset( llvm::EngineBuilder(llvmModule) .setErrorStr(&errStr) .setEngineKind(llvm::EngineKind::JIT) .create() ); if ( !m_llvmExecutionEngine ) throw Exception( "Failed to construct ExecutionEngine: " + errStr ); m_llvmExecutionEngine->InstallLazyFunctionCreator( &LazyFunctionCreator ); // Make sure we don't search loaded libraries for missing symbols. // Only symbols *we* provide should be available as calling functions. m_llvmExecutionEngine->DisableSymbolSearching(); context->getCGManager()->llvmAddGlobalMappingsToExecutionEngine( m_llvmExecutionEngine.get(), *llvmModule ); }