static int runCompilePasses(Module *ModuleRef, unsigned ModuleIndex, ThreadedFunctionQueue *FuncQueue, const Triple &TheTriple, TargetMachine &Target, StringRef ProgramName, raw_pwrite_stream &OS){ PNaClABIErrorReporter ABIErrorReporter; if (SplitModuleCount > 1 || ExternalizeAll) { // Add function and global names, and give them external linkage. // This relies on LLVM's consistent auto-generation of names, we could // maybe do our own in case something changes there. for (Function &F : *ModuleRef) { if (!F.hasName()) F.setName("Function"); if (F.hasInternalLinkage()) F.setLinkage(GlobalValue::ExternalLinkage); } for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { if (!GI->hasName()) GI->setName("Global"); if (GI->hasInternalLinkage()) GI->setLinkage(GlobalValue::ExternalLinkage); } if (ModuleIndex > 0) { // Remove the initializers for all global variables, turning them into // declarations. for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { assert(GI->hasInitializer() && "Global variable missing initializer"); Constant *Init = GI->getInitializer(); GI->setInitializer(nullptr); if (Init->getNumUses() == 0) Init->destroyConstant(); } } } // Make all non-weak symbols hidden for better code. We cannot do // this for weak symbols. The linker complains when some weak // symbols are not resolved. for (Function &F : *ModuleRef) { if (!F.isWeakForLinker() && !F.hasLocalLinkage()) F.setVisibility(GlobalValue::HiddenVisibility); } for (Module::global_iterator GI = ModuleRef->global_begin(), GE = ModuleRef->global_end(); GI != GE; ++GI) { if (!GI->isWeakForLinker() && !GI->hasLocalLinkage()) GI->setVisibility(GlobalValue::HiddenVisibility); } // Build up all of the passes that we want to do to the module. std::unique_ptr<legacy::PassManagerBase> PM; if (LazyBitcode) PM.reset(new legacy::FunctionPassManager(ModuleRef)); else PM.reset(new legacy::PassManager()); // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *DL = Target.getDataLayout()) ModuleRef->setDataLayout(*DL); // For conformance with llc, we let the user disable LLVM IR verification with // -disable-verify. Unlike llc, when LLVM IR verification is enabled we only // run it once, before PNaCl ABI verification. if (!NoVerify) PM->add(createVerifierPass()); // Add the ABI verifier pass before the analysis and code emission passes. if (PNaClABIVerify) PM->add(createPNaClABIVerifyFunctionsPass(&ABIErrorReporter)); // Add the intrinsic resolution pass. It assumes ABI-conformant code. PM->add(createResolvePNaClIntrinsicsPass()); // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(TheTriple); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); PM->add(new TargetLibraryInfoWrapperPass(TLII)); // Allow subsequent passes and the backend to better optimize instructions // that were simplified for PNaCl's ABI. This pass uses the TargetLibraryInfo // above. PM->add(createBackendCanonicalizePass()); // Ask the target to add backend passes as necessary. We explicitly ask it // not to add the verifier pass because we added it earlier. if (Target.addPassesToEmitFile(*PM, OS, FileType, /* DisableVerify */ true)) { errs() << ProgramName << ": target does not support generation of this file type!\n"; return 1; } if (LazyBitcode) { auto FPM = static_cast<legacy::FunctionPassManager *>(PM.get()); FPM->doInitialization(); unsigned FuncIndex = 0; switch (SplitModuleSched) { case SplitModuleStatic: for (Function &F : *ModuleRef) { if (FuncQueue->GrabFunctionStatic(FuncIndex, ModuleIndex)) { FPM->run(F); CheckABIVerifyErrors(ABIErrorReporter, "Function " + F.getName()); F.Dematerialize(); } ++FuncIndex; } break; case SplitModuleDynamic: unsigned ChunkSize = 0; unsigned NumFunctions = FuncQueue->Size(); Module::iterator I = ModuleRef->begin(); while (FuncIndex < NumFunctions) { ChunkSize = FuncQueue->RecommendedChunkSize(); unsigned NextIndex; bool grabbed = FuncQueue->GrabFunctionDynamic(FuncIndex, ChunkSize, NextIndex); if (grabbed) { while (FuncIndex < NextIndex) { if (!I->isMaterializable() && I->isDeclaration()) { ++I; continue; } FPM->run(*I); CheckABIVerifyErrors(ABIErrorReporter, "Function " + I->getName()); I->Dematerialize(); ++FuncIndex; ++I; } } else { while (FuncIndex < NextIndex) { if (!I->isMaterializable() && I->isDeclaration()) { ++I; continue; } ++FuncIndex; ++I; } } } break; } FPM->doFinalization(); } else static_cast<legacy::PassManager *>(PM.get())->run(*ModuleRef); return 0; }
bool ModuleLinker::run() { assert(DstM && "Null destination module"); assert(SrcM && "Null source module"); // Inherit the target data from the source module if the destination module // doesn't have one already. if (DstM->getDataLayout().empty() && !SrcM->getDataLayout().empty()) DstM->setDataLayout(SrcM->getDataLayout()); // Copy the target triple from the source to dest if the dest's is empty. if (DstM->getTargetTriple().empty() && !SrcM->getTargetTriple().empty()) DstM->setTargetTriple(SrcM->getTargetTriple()); if (!SrcM->getDataLayout().empty() && !DstM->getDataLayout().empty() && SrcM->getDataLayout() != DstM->getDataLayout()) errs() << "WARNING: Linking two modules of different data layouts!\n"; if (!SrcM->getTargetTriple().empty() && DstM->getTargetTriple() != SrcM->getTargetTriple()) { errs() << "WARNING: Linking two modules of different target triples: "; if (!SrcM->getModuleIdentifier().empty()) errs() << SrcM->getModuleIdentifier() << ": "; errs() << "'" << SrcM->getTargetTriple() << "' and '" << DstM->getTargetTriple() << "'\n"; } // Append the module inline asm string. if (!SrcM->getModuleInlineAsm().empty()) { if (DstM->getModuleInlineAsm().empty()) DstM->setModuleInlineAsm(SrcM->getModuleInlineAsm()); else DstM->setModuleInlineAsm(DstM->getModuleInlineAsm()+"\n"+ SrcM->getModuleInlineAsm()); } // Update the destination module's dependent libraries list with the libraries // from the source module. There's no opportunity for duplicates here as the // Module ensures that duplicate insertions are discarded. for (Module::lib_iterator SI = SrcM->lib_begin(), SE = SrcM->lib_end(); SI != SE; ++SI) DstM->addLibrary(*SI); // If the source library's module id is in the dependent library list of the // destination library, remove it since that module is now linked in. StringRef ModuleId = SrcM->getModuleIdentifier(); if (!ModuleId.empty()) DstM->removeLibrary(sys::path::stem(ModuleId)); // Loop over all of the linked values to compute type mappings. computeTypeMapping(); // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). for (Module::global_iterator I = SrcM->global_begin(), E = SrcM->global_end(); I != E; ++I) if (linkGlobalProto(I)) return true; // Link the functions together between the two modules, without doing function // bodies... this just adds external function prototypes to the DstM // function... We do this so that when we begin processing function bodies, // all of the global values that may be referenced are available in our // ValueMap. for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I) if (linkFunctionProto(I)) return true; // If there were any aliases, link them now. for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end(); I != E; ++I) if (linkAliasProto(I)) return true; for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i) linkAppendingVarInit(AppendingVars[i]); // Update the initializers in the DstM module now that all globals that may // be referenced are in DstM. linkGlobalInits(); // Link in the function bodies that are defined in the source module into // DstM. for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) { // Skip if not linking from source. if (DoNotLinkFromSource.count(SF)) continue; // Skip if no body (function is external) or materialize. if (SF->isDeclaration()) { if (!SF->isMaterializable()) continue; if (SF->Materialize(&ErrorMsg)) return true; } linkFunctionBody(cast<Function>(ValueMap[SF]), SF); } // Resolve all uses of aliases with aliasees. linkAliasBodies(); // Remap all of the named MDNodes in Src into the DstM module. We do this // after linking GlobalValues so that MDNodes that reference GlobalValues // are properly remapped. linkNamedMDNodes(); // Merge the module flags into the DstM module. if (linkModuleFlagsMetadata()) return true; // Process vector of lazily linked in functions. bool LinkedInAnyFunctions; do { LinkedInAnyFunctions = false; for(std::vector<Function*>::iterator I = LazilyLinkFunctions.begin(), E = LazilyLinkFunctions.end(); I != E; ++I) { if (!*I) continue; Function *SF = *I; Function *DF = cast<Function>(ValueMap[SF]); if (!DF->use_empty()) { // Materialize if necessary. if (SF->isDeclaration()) { if (!SF->isMaterializable()) continue; if (SF->Materialize(&ErrorMsg)) return true; } // Link in function body. linkFunctionBody(DF, SF); // "Remove" from vector by setting the element to 0. *I = 0; // Set flag to indicate we may have more functions to lazily link in // since we linked in a function. LinkedInAnyFunctions = true; } } } while (LinkedInAnyFunctions); // Remove any prototypes of functions that were not actually linked in. for(std::vector<Function*>::iterator I = LazilyLinkFunctions.begin(), E = LazilyLinkFunctions.end(); I != E; ++I) { if (!*I) continue; Function *SF = *I; Function *DF = cast<Function>(ValueMap[SF]); if (DF->use_empty()) DF->eraseFromParent(); } // Now that all of the types from the source are used, resolve any structs // copied over to the dest that didn't exist there. TypeMap.linkDefinedTypeBodies(); return false; }