std::string *ErrorStr,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel,
- bool GVsWithCode) {
- return JIT::createJIT(MP, ErrorStr, JMM, OptLevel, GVsWithCode);
+ bool GVsWithCode,
+ CodeModel::Model CMM) {
+ return JIT::createJIT(MP, ErrorStr, JMM, OptLevel, GVsWithCode, CMM);
}
ExecutionEngine *JIT::createJIT(ModuleProvider *MP,
std::string *ErrorStr,
JITMemoryManager *JMM,
CodeGenOpt::Level OptLevel,
- bool GVsWithCode) {
+ bool GVsWithCode,
+ CodeModel::Model CMM) {
// Make sure we can resolve symbols in the program as well. The zero arg
// to the function tells DynamicLibrary to load the program, not a library.
if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
// Pick a target either via -march or by guessing the native arch.
TargetMachine *TM = JIT::selectTarget(MP, ErrorStr);
if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0;
+ TM->setCodeModel(CMM);
// If the target supports JIT code generation, create a the JIT.
if (TargetJITInfo *TJ = TM->getJITInfo()) {
jitstate = new JITState(MP);
// Initialize JCE
- JCE = createEmitter(*this, JMM);
+ JCE = createEmitter(*this, JMM, TM);
// Add target data
MutexGuard locked(lock);
}
}
+/// materializeFunction - make sure the given function is fully read. If the
+/// module is corrupt, this returns true and fills in the optional string with
+/// information about the problem. If successful, this returns false.
+bool JIT::materializeFunction(Function *F, std::string *ErrInfo) {
+ // Read in the function if it exists in this Module.
+ if (F->hasNotBeenReadFromBitcode()) {
+ // Determine the module provider this function is provided by.
+ Module *M = F->getParent();
+ ModuleProvider *MP = 0;
+ for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
+ if (Modules[i]->getModule() == M) {
+ MP = Modules[i];
+ break;
+ }
+ }
+ if (MP)
+ return MP->materializeFunction(F, ErrInfo);
+
+ if (ErrInfo)
+ *ErrInfo = "Function isn't in a module we know about!";
+ return true;
+ }
+ // Succeed if the function is already read.
+ return false;
+}
+
/// run - Start execution with the specified function and arguments.
///
GenericValue JIT::runFunction(Function *F,
// Handle some common cases first. These cases correspond to common `main'
// prototypes.
- if (RetTy == Type::Int32Ty || RetTy == Type::VoidTy) {
+ if (RetTy == Type::getInt32Ty(F->getContext()) || RetTy->isVoidTy()) {
switch (ArgValues.size()) {
case 3:
- if (FTy->getParamType(0) == Type::Int32Ty &&
+ if (FTy->getParamType(0)->isInteger(32) &&
isa<PointerType>(FTy->getParamType(1)) &&
isa<PointerType>(FTy->getParamType(2))) {
int (*PF)(int, char **, const char **) =
}
break;
case 2:
- if (FTy->getParamType(0) == Type::Int32Ty &&
+ if (FTy->getParamType(0)->isInteger(32) &&
isa<PointerType>(FTy->getParamType(1))) {
int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
break;
case 1:
if (FTy->getNumParams() == 1 &&
- FTy->getParamType(0) == Type::Int32Ty) {
+ FTy->getParamType(0)->isInteger(32)) {
GenericValue rv;
int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
F->getParent());
// Insert a basic block.
- BasicBlock *StubBB = BasicBlock::Create("", Stub);
+ BasicBlock *StubBB = BasicBlock::Create(F->getContext(), "", Stub);
// Convert all of the GenericValue arguments over to constants. Note that we
// currently don't support varargs.
case Type::PointerTyID:
void *ArgPtr = GVTOP(AV);
if (sizeof(void*) == 4)
- C = ConstantInt::get(Type::Int32Ty, (int)(intptr_t)ArgPtr);
+ C = ConstantInt::get(Type::getInt32Ty(F->getContext()),
+ (int)(intptr_t)ArgPtr);
else
- C = ConstantInt::get(Type::Int64Ty, (intptr_t)ArgPtr);
+ C = ConstantInt::get(Type::getInt64Ty(F->getContext()),
+ (intptr_t)ArgPtr);
// Cast the integer to pointer
C = ConstantExpr::getIntToPtr(C, ArgTy);
break;
"", StubBB);
TheCall->setCallingConv(F->getCallingConv());
TheCall->setTailCall();
- if (TheCall->getType() != Type::VoidTy)
- ReturnInst::Create(TheCall, StubBB); // Return result of the call.
+ if (!TheCall->getType()->isVoidTy())
+ // Return result of the call.
+ ReturnInst::Create(F->getContext(), TheCall, StubBB);
else
- ReturnInst::Create(StubBB); // Just return void.
+ ReturnInst::Create(F->getContext(), StubBB); // Just return void.
// Finally, return the value returned by our nullary stub function.
return runFunction(Stub, std::vector<GenericValue>());
}
}
-void JIT::NotifyFreeingMachineCode(const Function &F, void *OldPtr) {
+void JIT::NotifyFreeingMachineCode(void *OldPtr) {
MutexGuard locked(lock);
for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
- EventListeners[I]->NotifyFreeingMachineCode(F, OldPtr);
+ EventListeners[I]->NotifyFreeingMachineCode(OldPtr);
}
}
}
};
MCIListener MCIL(MCI);
- RegisterJITEventListener(&MCIL);
+ if (MCI)
+ RegisterJITEventListener(&MCIL);
runJITOnFunctionUnlocked(F, locked);
- UnregisterJITEventListener(&MCIL);
+ if (MCI)
+ UnregisterJITEventListener(&MCIL);
}
void JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) {
isAlreadyCodeGenerating = false;
// If the function referred to another function that had not yet been
- // read from bitcode, but we are jitting non-lazily, emit it now.
+ // read from bitcode, and we are jitting non-lazily, emit it now.
while (!jitstate->getPendingFunctions(locked).empty()) {
Function *PF = jitstate->getPendingFunctions(locked).back();
jitstate->getPendingFunctions(locked).pop_back();
+ assert(!PF->hasAvailableExternallyLinkage() &&
+ "Externally-defined function should not be in pending list.");
+
// JIT the function
isAlreadyCodeGenerating = true;
jitstate->getPM(locked).run(*PF);
// the stub with real address of the function.
updateFunctionStub(PF);
}
-
- // If the JIT is configured to emit info so that dlsym can be used to
- // rewrite stubs to external globals, do so now.
- if (areDlsymStubsEnabled() && isLazyCompilationDisabled())
- updateDlsymStubTable();
}
/// getPointerToFunction - This method is used to get the address of the
return Addr; // Check if function already code gen'd
MutexGuard locked(lock);
-
- // Now that this thread owns the lock, check if another thread has already
- // code gen'd the function.
- if (void *Addr = getPointerToGlobalIfAvailable(F))
- return Addr;
- // Make sure we read in the function if it exists in this Module.
- if (F->hasNotBeenReadFromBitcode()) {
- // Determine the module provider this function is provided by.
- Module *M = F->getParent();
- ModuleProvider *MP = 0;
- for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
- if (Modules[i]->getModule() == M) {
- MP = Modules[i];
- break;
- }
- }
- assert(MP && "Function isn't in a module we know about!");
-
- std::string ErrorMsg;
- if (MP->materializeFunction(F, &ErrorMsg)) {
- llvm_report_error("Error reading function '" + F->getName()+
- "' from bitcode file: " + ErrorMsg);
- }
-
- // Now retry to get the address.
- if (void *Addr = getPointerToGlobalIfAvailable(F))
- return Addr;
+ // Now that this thread owns the lock, make sure we read in the function if it
+ // exists in this Module.
+ std::string ErrorMsg;
+ if (materializeFunction(F, &ErrorMsg)) {
+ llvm_report_error("Error reading function '" + F->getName()+
+ "' from bitcode file: " + ErrorMsg);
}
- if (F->isDeclaration()) {
- bool AbortOnFailure =
- !areDlsymStubsEnabled() && !F->hasExternalWeakLinkage();
+ // ... and check if another thread has already code gen'd the function.
+ if (void *Addr = getPointerToGlobalIfAvailable(F))
+ return Addr;
+
+ if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
+ bool AbortOnFailure = !F->hasExternalWeakLinkage();
void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure);
addGlobalMapping(F, Addr);
return Addr;
if (Ptr) return Ptr;
// If the global is external, just remember the address.
- if (GV->isDeclaration()) {
+ if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
#if HAVE___DSO_HANDLE
if (GV->getName() == "__dso_handle")
return (void*)&__dso_handle;
#endif
Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(GV->getName());
- if (Ptr == 0 && !areDlsymStubsEnabled()) {
+ if (Ptr == 0) {
llvm_report_error("Could not resolve external global address: "
+GV->getName());
}