Esempio n. 1
0
/// OptimizeGlobals - This method uses information taken from DSA to optimize
/// global variables.
///
bool DSOpt::OptimizeGlobals(Module &M) {
  DSGraph* GG = TD->getGlobalsGraph();
  const DSGraph::ScalarMapTy &SM = GG->getScalarMap();
  bool Changed = false;

  for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
    if (!I->isDeclaration()) { // Loop over all of the non-external globals...
      // Look up the node corresponding to this global, if it exists.
      DSNode *GNode = 0;
      DSGraph::ScalarMapTy::const_iterator SMI = SM.find(I);
      if (SMI != SM.end()) GNode = SMI->second.getNode();

      if (GNode == 0 && I->hasInternalLinkage()) {
        // If there is no entry in the scalar map for this global, it was never
        // referenced in the program.  If it has internal linkage, that means we
        // can delete it.  We don't ACTUALLY want to delete the global, just
        // remove anything that references the global: later passes will take
        // care of nuking it.
        if (!I->use_empty()) {
          I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
          ++NumGlobalsIsolated;
        }
      } else if (GNode && GNode->NodeType.isCompleteNode()) {

        // If the node has not been read or written, and it is not externally
        // visible, kill any references to it so it can be DCE'd.
        if (!GNode->NodeType.isModifiedNode() && !GNode->NodeType.isReadNode() &&I->hasInternalLinkage()){
          if (!I->use_empty()) {
            I->replaceAllUsesWith(ConstantPointerNull::get(I->getType()));
            ++NumGlobalsIsolated;
          }
        }

        // We expect that there will almost always be a node for this global.
        // If there is, and the node doesn't have the M bit set, we can set the
        // 'constant' bit on the global.
        if (!GNode->NodeType.isModifiedNode() && !I->isConstant()) {
          I->setConstant(true);
          ++NumGlobalsConstanted;
          Changed = true;
        }
      }
    }
  return Changed;
}
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;
}
Esempio n. 3
0
bool GlobalMerge::doInitialization(Module &M) {
  if (!EnableGlobalMerge)
    return false;

  auto &DL = M.getDataLayout();
  DenseMap<unsigned, SmallVector<GlobalVariable*, 16> > Globals, ConstGlobals,
                                                        BSSGlobals;
  bool Changed = false;
  setMustKeepGlobalVariables(M);

  // Grab all non-const globals.
  for (Module::global_iterator I = M.global_begin(),
         E = M.global_end(); I != E; ++I) {
    // Merge is safe for "normal" internal or external globals only
    if (I->isDeclaration() || I->isThreadLocal() || I->hasSection())
      continue;

    if (!(EnableGlobalMergeOnExternal && I->hasExternalLinkage()) &&
        !I->hasInternalLinkage())
      continue;

    PointerType *PT = dyn_cast<PointerType>(I->getType());
    assert(PT && "Global variable is not a pointer!");

    unsigned AddressSpace = PT->getAddressSpace();

    // Ignore fancy-aligned globals for now.
    unsigned Alignment = DL.getPreferredAlignment(I);
    Type *Ty = I->getType()->getElementType();
    if (Alignment > DL.getABITypeAlignment(Ty))
      continue;

    // Ignore all 'special' globals.
    if (I->getName().startswith("llvm.") ||
        I->getName().startswith(".llvm."))
      continue;

    // Ignore all "required" globals:
    if (isMustKeepGlobalVariable(I))
      continue;

    if (DL.getTypeAllocSize(Ty) < MaxOffset) {
      if (TargetLoweringObjectFile::getKindForGlobal(I, *TM).isBSSLocal())
        BSSGlobals[AddressSpace].push_back(I);
      else if (I->isConstant())
        ConstGlobals[AddressSpace].push_back(I);
      else
        Globals[AddressSpace].push_back(I);
    }
  }

  for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
       I = Globals.begin(), E = Globals.end(); I != E; ++I)
    if (I->second.size() > 1)
      Changed |= doMerge(I->second, M, false, I->first);

  for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
       I = BSSGlobals.begin(), E = BSSGlobals.end(); I != E; ++I)
    if (I->second.size() > 1)
      Changed |= doMerge(I->second, M, false, I->first);

  if (EnableGlobalMergeOnConst)
    for (DenseMap<unsigned, SmallVector<GlobalVariable*, 16> >::iterator
         I = ConstGlobals.begin(), E = ConstGlobals.end(); I != E; ++I)
      if (I->second.size() > 1)
        Changed |= doMerge(I->second, M, true, I->first);

  return Changed;
}