bool ExpandTls::runOnModule(Module &M) { ModulePass *Pass = createExpandTlsConstantExprPass(); Pass->runOnModule(M); delete Pass; std::vector<VarInfo> TlsVars; PointerType *TemplatePtrType = buildTlsTemplate(M, &TlsVars); rewriteTlsVars(M, &TlsVars, TemplatePtrType); defineTlsLayoutIntrinsics(M); return true; }
static void runModulePass(ir::Module* module, Pass* pass) { report(" Running module pass '" << pass->toString() << "'" ); switch(pass->type) { case Pass::ImmutablePass: { ImmutablePass* immutablePass = static_cast<ImmutablePass*>(pass); immutablePass->runOnModule(*module); } break; case Pass::ModulePass: { ModulePass* modulePass = static_cast<ModulePass*>(pass); modulePass->runOnModule(*module); } break; case Pass::KernelPass: /* fall through */ case Pass::BasicBlockPass: break; case Pass::InvalidPass: assertM(false, "Invalid pass type."); } }
//===----------------------------------------------------------------------===// // main Driver function // int main(int argc, char **argv, char * const *envp) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); atexit(do_shutdown); // Call llvm_shutdown() on exit. // If we have a native target, initialize it to ensure it is linked in and // usable by the JIT. InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); cl::ParseCommandLineOptions(argc, argv, "llvm interpreter & dynamic compiler\n"); // If the user doesn't want core files, disable them. if (DisableCoreFiles) sys::Process::PreventCoreFiles(); // Load the bitcode... SMDiagnostic Err; Module *Mod = ParseIRFile(InputFile, Err, Context); if (!Mod) { Err.print(argv[0], errs()); return 1; } if (EnableCacheManager) { if (UseMCJIT) { std::string CacheName("file:"); CacheName.append(InputFile); Mod->setModuleIdentifier(CacheName); } else errs() << "warning: -enable-cache-manager can only be used with MCJIT."; } // If not jitting lazily, load the whole bitcode file eagerly too. if (NoLazyCompilation) { if (std::error_code EC = Mod->materializeAllPermanently()) { errs() << argv[0] << ": bitcode didn't read correctly.\n"; errs() << "Reason: " << EC.message() << "\n"; exit(1); } } if (DebugIR) { if (!UseMCJIT) { errs() << "warning: -debug-ir used without -use-mcjit. Only partial debug" << " information will be emitted by the non-MC JIT engine. To see full" << " source debug information, enable the flag '-use-mcjit'.\n"; } ModulePass *DebugIRPass = createDebugIRPass(); DebugIRPass->runOnModule(*Mod); } std::string ErrorMsg; EngineBuilder builder(Mod); builder.setMArch(MArch); builder.setMCPU(MCPU); builder.setMAttrs(MAttrs); builder.setRelocationModel(RelocModel); builder.setCodeModel(CMModel); builder.setErrorStr(&ErrorMsg); builder.setEngineKind(ForceInterpreter ? EngineKind::Interpreter : EngineKind::JIT); // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) Mod->setTargetTriple(Triple::normalize(TargetTriple)); // Enable MCJIT if desired. RTDyldMemoryManager *RTDyldMM = nullptr; if (UseMCJIT && !ForceInterpreter) { builder.setUseMCJIT(true); if (RemoteMCJIT) RTDyldMM = new RemoteMemoryManager(); else RTDyldMM = new SectionMemoryManager(); builder.setMCJITMemoryManager(RTDyldMM); } else { if (RemoteMCJIT) { errs() << "error: Remote process execution requires -use-mcjit\n"; exit(1); } builder.setJITMemoryManager(ForceInterpreter ? nullptr : JITMemoryManager::CreateDefaultMemManager()); } CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } builder.setOptLevel(OLvl); TargetOptions Options; Options.UseSoftFloat = GenerateSoftFloatCalls; if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; if (GenerateSoftFloatCalls) FloatABIForCalls = FloatABI::Soft; // Remote target execution doesn't handle EH or debug registration. if (!RemoteMCJIT) { Options.JITEmitDebugInfo = EmitJitDebugInfo; Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk; } builder.setTargetOptions(Options); EE = builder.create(); if (!EE) { if (!ErrorMsg.empty()) errs() << argv[0] << ": error creating EE: " << ErrorMsg << "\n"; else errs() << argv[0] << ": unknown error creating EE!\n"; exit(1); } if (EnableCacheManager) { CacheManager = new LLIObjectCache(ObjectCacheDir); EE->setObjectCache(CacheManager); } // Load any additional modules specified on the command line. for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) { Module *XMod = ParseIRFile(ExtraModules[i], Err, Context); if (!XMod) { Err.print(argv[0], errs()); return 1; } if (EnableCacheManager) { if (UseMCJIT) { std::string CacheName("file:"); CacheName.append(ExtraModules[i]); XMod->setModuleIdentifier(CacheName); } // else, we already printed a warning above. } EE->addModule(XMod); } for (unsigned i = 0, e = ExtraObjects.size(); i != e; ++i) { ErrorOr<object::ObjectFile *> Obj = object::ObjectFile::createObjectFile(ExtraObjects[i]); if (!Obj) { Err.print(argv[0], errs()); return 1; } EE->addObjectFile(std::unique_ptr<object::ObjectFile>(Obj.get())); } for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) { ErrorOr<std::unique_ptr<MemoryBuffer>> ArBuf = MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]); if (!ArBuf) { Err.print(argv[0], errs()); return 1; } std::error_code EC; object::Archive *Ar = new object::Archive(std::move(ArBuf.get()), EC); if (EC || !Ar) { Err.print(argv[0], errs()); return 1; } EE->addArchive(Ar); } // If the target is Cygwin/MingW and we are generating remote code, we // need an extra module to help out with linking. if (RemoteMCJIT && Triple(Mod->getTargetTriple()).isOSCygMing()) { addCygMingExtraModule(EE, Context, Mod->getTargetTriple()); } // The following functions have no effect if their respective profiling // support wasn't enabled in the build configuration. EE->RegisterJITEventListener( JITEventListener::createOProfileJITEventListener()); EE->RegisterJITEventListener( JITEventListener::createIntelJITEventListener()); if (!NoLazyCompilation && RemoteMCJIT) { errs() << "warning: remote mcjit does not support lazy compilation\n"; NoLazyCompilation = true; } EE->DisableLazyCompilation(NoLazyCompilation); // If the user specifically requested an argv[0] to pass into the program, // do it now. if (!FakeArgv0.empty()) { InputFile = FakeArgv0; } else { // Otherwise, if there is a .bc suffix on the executable strip it off, it // might confuse the program. if (StringRef(InputFile).endswith(".bc")) InputFile.erase(InputFile.length() - 3); } // Add the module's name to the start of the vector of arguments to main(). InputArgv.insert(InputArgv.begin(), InputFile); // Call the main function from M as if its signature were: // int main (int argc, char **argv, const char **envp) // using the contents of Args to determine argc & argv, and the contents of // EnvVars to determine envp. // Function *EntryFn = Mod->getFunction(EntryFunc); if (!EntryFn) { errs() << '\'' << EntryFunc << "\' function not found in module.\n"; return -1; } // Reset errno to zero on entry to main. errno = 0; int Result; if (!RemoteMCJIT) { // If the program doesn't explicitly call exit, we will need the Exit // function later on to make an explicit call, so get the function now. Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context), Type::getInt32Ty(Context), NULL); // Run static constructors. if (UseMCJIT && !ForceInterpreter) { // Give MCJIT a chance to apply relocations and set page permissions. EE->finalizeObject(); } EE->runStaticConstructorsDestructors(false); if (!UseMCJIT && NoLazyCompilation) { for (Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) { Function *Fn = &*I; if (Fn != EntryFn && !Fn->isDeclaration()) EE->getPointerToFunction(Fn); } } // Trigger compilation separately so code regions that need to be // invalidated will be known. (void)EE->getPointerToFunction(EntryFn); // Clear instruction cache before code will be executed. if (RTDyldMM) static_cast<SectionMemoryManager*>(RTDyldMM)->invalidateInstructionCache(); // Run main. Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp); // Run static destructors. EE->runStaticConstructorsDestructors(true); // If the program didn't call exit explicitly, we should call it now. // This ensures that any atexit handlers get called correctly. if (Function *ExitF = dyn_cast<Function>(Exit)) { std::vector<GenericValue> Args; GenericValue ResultGV; ResultGV.IntVal = APInt(32, Result); Args.push_back(ResultGV); EE->runFunction(ExitF, Args); errs() << "ERROR: exit(" << Result << ") returned!\n"; abort(); } else { errs() << "ERROR: exit defined with wrong prototype!\n"; abort(); } } else { // else == "if (RemoteMCJIT)" // Remote target MCJIT doesn't (yet) support static constructors. No reason // it couldn't. This is a limitation of the LLI implemantation, not the // MCJIT itself. FIXME. // RemoteMemoryManager *MM = static_cast<RemoteMemoryManager*>(RTDyldMM); // Everything is prepared now, so lay out our program for the target // address space, assign the section addresses to resolve any relocations, // and send it to the target. std::unique_ptr<RemoteTarget> Target; if (!ChildExecPath.empty()) { // Remote execution on a child process #ifndef LLVM_ON_UNIX // FIXME: Remove this pointless fallback mode which causes tests to "pass" // on platforms where they should XFAIL. errs() << "Warning: host does not support external remote targets.\n" << " Defaulting to simulated remote execution\n"; Target.reset(new RemoteTarget); #else if (!sys::fs::can_execute(ChildExecPath)) { errs() << "Unable to find usable child executable: '" << ChildExecPath << "'\n"; return -1; } Target.reset(new RemoteTargetExternal(ChildExecPath)); #endif } else { // No child process name provided, use simulated remote execution. Target.reset(new RemoteTarget); } // Give the memory manager a pointer to our remote target interface object. MM->setRemoteTarget(Target.get()); // Create the remote target. if (!Target->create()) { errs() << "ERROR: " << Target->getErrorMsg() << "\n"; return EXIT_FAILURE; } // Since we're executing in a (at least simulated) remote address space, // we can't use the ExecutionEngine::runFunctionAsMain(). We have to // grab the function address directly here and tell the remote target // to execute the function. // // Our memory manager will map generated code into the remote address // space as it is loaded and copy the bits over during the finalizeMemory // operation. // // FIXME: argv and envp handling. uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str()); DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x" << format("%llx", Entry) << "\n"); if (!Target->executeCode(Entry, Result)) errs() << "ERROR: " << Target->getErrorMsg() << "\n"; // Like static constructors, the remote target MCJIT support doesn't handle // this yet. It could. FIXME. // Stop the remote target Target->stop(); } return Result; }