+ std::cout << " Non-optimized portion: ";
+ ToNotOptimize = swapProgramIn(ToNotOptimize);
+ EmitProgressBytecode("tonotoptimize", true);
+ setNewProgram(ToNotOptimize); // Delete hacked module.
+
+ std::cout << " Portion that is input to optimizer: ";
+ ToOptimize = swapProgramIn(ToOptimize);
+ EmitProgressBytecode("tooptimize");
+ setNewProgram(ToOptimize); // Delete hacked module.
+
+ return false;
+}
+
+/// CleanupAndPrepareModules - Get the specified modules ready for code
+/// generator testing.
+///
+static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
+ Module *Safe) {
+ // Clean up the modules, removing extra cruft that we don't need anymore...
+ Test = BD.performFinalCleanups(Test);
+
+ // If we are executing the JIT, we have several nasty issues to take care of.
+ if (!BD.isExecutingJIT()) return;
+
+ // First, if the main function is in the Safe module, we must add a stub to
+ // the Test module to call into it. Thus, we create a new function `main'
+ // which just calls the old one.
+ if (Function *oldMain = Safe->getNamedFunction("main"))
+ if (!oldMain->isExternal()) {
+ // Rename it
+ oldMain->setName("llvm_bugpoint_old_main");
+ // Create a NEW `main' function with same type in the test module.
+ Function *newMain = new Function(oldMain->getFunctionType(),
+ GlobalValue::ExternalLinkage,
+ "main", Test);
+ // Create an `oldmain' prototype in the test module, which will
+ // corresponds to the real main function in the same module.
+ Function *oldMainProto = new Function(oldMain->getFunctionType(),
+ GlobalValue::ExternalLinkage,
+ oldMain->getName(), Test);
+ // Set up and remember the argument list for the main function.
+ std::vector<Value*> args;
+ for (Function::arg_iterator
+ I = newMain->arg_begin(), E = newMain->arg_end(),
+ OI = oldMain->arg_begin(); I != E; ++I, ++OI) {
+ I->setName(OI->getName()); // Copy argument names from oldMain
+ args.push_back(I);
+ }
+
+ // Call the old main function and return its result
+ BasicBlock *BB = new BasicBlock("entry", newMain);
+ CallInst *call = new CallInst(oldMainProto, args, "", BB);
+
+ // If the type of old function wasn't void, return value of call
+ new ReturnInst(call, BB);
+ }
+
+ // The second nasty issue we must deal with in the JIT is that the Safe
+ // module cannot directly reference any functions defined in the test
+ // module. Instead, we use a JIT API call to dynamically resolve the
+ // symbol.
+
+ // Add the resolver to the Safe module.
+ // Prototype: void *getPointerToNamedFunction(const char* Name)
+ Function *resolverFunc =
+ Safe->getOrInsertFunction("getPointerToNamedFunction",
+ PointerType::get(Type::SByteTy),
+ PointerType::get(Type::SByteTy), (Type *)0);
+
+ // Use the function we just added to get addresses of functions we need.
+ for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
+ if (F->isExternal() && !F->use_empty() && &*F != resolverFunc &&
+ F->getIntrinsicID() == 0 /* ignore intrinsics */) {
+ Function *TestFn = Test->getNamedFunction(F->getName());
+
+ // Don't forward functions which are external in the test module too.
+ if (TestFn && !TestFn->isExternal()) {
+ // 1. Add a string constant with its name to the global file
+ Constant *InitArray = ConstantArray::get(F->getName());
+ GlobalVariable *funcName =
+ new GlobalVariable(InitArray->getType(), true /*isConstant*/,
+ GlobalValue::InternalLinkage, InitArray,
+ F->getName() + "_name", Safe);
+
+ // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an
+ // sbyte* so it matches the signature of the resolver function.
+
+ // GetElementPtr *funcName, ulong 0, ulong 0
+ std::vector<Constant*> GEPargs(2,Constant::getNullValue(Type::IntTy));
+ Value *GEP =
+ ConstantExpr::getGetElementPtr(funcName, GEPargs);
+ std::vector<Value*> ResolverArgs;
+ ResolverArgs.push_back(GEP);
+
+ // Rewrite uses of F in global initializers, etc. to uses of a wrapper
+ // function that dynamically resolves the calls to F via our JIT API
+ if (!F->use_empty()) {
+ // Create a new global to hold the cached function pointer.
+ Constant *NullPtr = ConstantPointerNull::get(F->getType());
+ GlobalVariable *Cache =
+ new GlobalVariable(F->getType(), false,GlobalValue::InternalLinkage,
+ NullPtr,F->getName()+".fpcache", F->getParent());
+
+ // Construct a new stub function that will re-route calls to F
+ const FunctionType *FuncTy = F->getFunctionType();
+ Function *FuncWrapper = new Function(FuncTy,
+ GlobalValue::InternalLinkage,
+ F->getName() + "_wrapper",
+ F->getParent());
+ BasicBlock *EntryBB = new BasicBlock("entry", FuncWrapper);
+ BasicBlock *DoCallBB = new BasicBlock("usecache", FuncWrapper);
+ BasicBlock *LookupBB = new BasicBlock("lookupfp", FuncWrapper);
+
+ // Check to see if we already looked up the value.
+ Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB);
+ Value *IsNull = new SetCondInst(Instruction::SetEQ, CachedVal,
+ NullPtr, "isNull", EntryBB);
+ new BranchInst(LookupBB, DoCallBB, IsNull, EntryBB);
+
+ // Resolve the call to function F via the JIT API:
+ //
+ // call resolver(GetElementPtr...)
+ CallInst *Resolver = new CallInst(resolverFunc, ResolverArgs,
+ "resolver", LookupBB);
+ // cast the result from the resolver to correctly-typed function
+ CastInst *CastedResolver =
+ new CastInst(Resolver, PointerType::get(F->getFunctionType()),
+ "resolverCast", LookupBB);
+ // Save the value in our cache.
+ new StoreInst(CastedResolver, Cache, LookupBB);
+ new BranchInst(DoCallBB, LookupBB);
+
+ PHINode *FuncPtr = new PHINode(NullPtr->getType(), "fp", DoCallBB);
+ FuncPtr->addIncoming(CastedResolver, LookupBB);
+ FuncPtr->addIncoming(CachedVal, EntryBB);
+
+ // Save the argument list.
+ std::vector<Value*> Args;
+ for (Function::arg_iterator i = FuncWrapper->arg_begin(),
+ e = FuncWrapper->arg_end(); i != e; ++i)
+ Args.push_back(i);
+
+ // Pass on the arguments to the real function, return its result
+ if (F->getReturnType() == Type::VoidTy) {
+ CallInst *Call = new CallInst(FuncPtr, Args, "", DoCallBB);
+ new ReturnInst(DoCallBB);
+ } else {
+ CallInst *Call = new CallInst(FuncPtr, Args, "retval", DoCallBB);
+ new ReturnInst(Call, DoCallBB);
+ }
+
+ // Use the wrapper function instead of the old function
+ F->replaceAllUsesWith(FuncWrapper);
+ }
+ }
+ }