Пример #1
0
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;
}
Пример #2
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;
}