static Timer &getNamedRegionTimer(const std::string &Name) { sys::SmartScopedLock<true> L(*TimerLock); Name2Timer::iterator I = NamedTimers->find(Name); if (I != NamedTimers->end()) return I->second; return NamedTimers->insert(I, std::make_pair(Name, Timer(Name)))->second; }
GenericValue Interpreter::callExternalFunction(Function *F, ArrayRef<GenericValue> ArgVals) { TheInterpreter = this; unique_lock<sys::Mutex> Guard(*FunctionsLock); // Do a lookup to see if the function is in our cache... this should just be a // deferred annotation! std::map<const Function *, ExFunc>::iterator FI = ExportedFunctions->find(F); if (ExFunc Fn = (FI == ExportedFunctions->end()) ? lookupFunction(F) : FI->second) { Guard.unlock(); return Fn(F->getFunctionType(), ArgVals); } #ifdef USE_LIBFFI std::map<const Function *, RawFunc>::iterator RF = RawFunctions->find(F); RawFunc RawFn; if (RF == RawFunctions->end()) { RawFn = (RawFunc)(intptr_t) sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName()); if (!RawFn) RawFn = (RawFunc)(intptr_t)getPointerToGlobalIfAvailable(F); if (RawFn != 0) RawFunctions->insert(std::make_pair(F, RawFn)); // Cache for later } else { RawFn = RF->second; } Guard.unlock(); GenericValue Result; if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getDataLayout(), Result)) return Result; #endif // USE_LIBFFI if (F->getName() == "__main") errs() << "Tried to execute an unknown external function: " << *F->getType() << " __main\n"; else report_fatal_error("Tried to execute an unknown external function: " + F->getName()); #ifndef USE_LIBFFI errs() << "Recompiling LLVM with --enable-libffi might help.\n"; #endif return GenericValue(); }
// Try to find address of external function given a Function object. // Please note, that interpreter doesn't know how to assemble a // real call in general case (this is JIT job), that's why it assumes, // that all external functions has the same (and pretty "general") signature. // The typical example of such functions are "lle_X_" ones. static ExFunc lookupFunction(const Function *F) { // Function not found, look it up... start by figuring out what the // composite function name should be. std::string ExtName = "lle_"; const FunctionType *FT = F->getFunctionType(); for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i) ExtName += getTypeID(FT->getContainedType(i)); ExtName + "_" + F->getNameStr(); sys::ScopedLock Writer(*FunctionsLock); ExFunc FnPtr = FuncNames[ExtName]; if (FnPtr == 0) FnPtr = FuncNames["lle_X_" + F->getNameStr()]; if (FnPtr == 0) // Try calling a generic function... if it exists... FnPtr = (ExFunc)(intptr_t) sys::DynamicLibrary::SearchForAddressOfSymbol("lle_X_"+F->getNameStr()); if (FnPtr != 0) ExportedFunctions->insert(std::make_pair(F, FnPtr)); // Cache for later return FnPtr; }
static Timer &getNamedRegionTimer(const std::string &Name, const std::string &GroupName) { sys::SmartScopedLock<true> L(*TimerLock); Name2Pair::iterator I = NamedGroupedTimers->find(GroupName); if (I == NamedGroupedTimers->end()) { TimerGroup TG(GroupName); std::pair<TimerGroup, Name2Timer> Pair(TG, Name2Timer()); I = NamedGroupedTimers->insert(I, std::make_pair(GroupName, Pair)); } Name2Timer::iterator J = I->second.second.find(Name); if (J == I->second.second.end()) J = I->second.second.insert(J, std::make_pair(Name, Timer(Name, I->second.first))); return J->second; }
// Try to find address of external function given a Function object. // Please note, that interpreter doesn't know how to assemble a // real call in general case (this is JIT job), that's why it assumes, // that all external functions has the same (and pretty "general") signature. // The typical example of such functions are "lle_X_" ones. static ExFunc lookupFunction(const Function *F) { // Function not found, look it up... start by figuring out what the // composite function name should be. std::string ExtName = "lle_"; FunctionType *FT = F->getFunctionType(); ExtName += getTypeID(FT->getReturnType()); for (Type *T : FT->params()) ExtName += getTypeID(T); ExtName += ("_" + F->getName()).str(); sys::ScopedLock Writer(*FunctionsLock); ExFunc FnPtr = (*FuncNames)[ExtName]; if (!FnPtr) FnPtr = (*FuncNames)[("lle_X_" + F->getName()).str()]; if (!FnPtr) // Try calling a generic function... if it exists... FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol( ("lle_X_" + F->getName()).str()); if (FnPtr) ExportedFunctions->insert(std::make_pair(F, FnPtr)); // Cache for later return FnPtr; }