예제 #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;
}