예제 #1
0
bool MergeFunctions::runOnModule(Module &M) {
  bool Changed = false;
  DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
  DL = DLP ? &DLP->getDataLayout() : nullptr;

  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage())
      Deferred.push_back(WeakVH(I));
  }
  FnSet.resize(Deferred.size());

  do {
    std::vector<WeakVH> Worklist;
    Deferred.swap(Worklist);

    DEBUG(dbgs() << "size of module: " << M.size() << '\n');
    DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n');

    // Insert only strong functions and merge them. Strong function merging
    // always deletes one of them.
    for (std::vector<WeakVH>::iterator I = Worklist.begin(),
           E = Worklist.end(); I != E; ++I) {
      if (!*I) continue;
      Function *F = cast<Function>(*I);
      if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
          !F->mayBeOverridden()) {
        ComparableFunction CF = ComparableFunction(F, DL);
        Changed |= insert(CF);
      }
    }

    // Insert only weak functions and merge them. By doing these second we
    // create thunks to the strong function when possible. When two weak
    // functions are identical, we create a new strong function with two weak
    // weak thunks to it which are identical but not mergable.
    for (std::vector<WeakVH>::iterator I = Worklist.begin(),
           E = Worklist.end(); I != E; ++I) {
      if (!*I) continue;
      Function *F = cast<Function>(*I);
      if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
          F->mayBeOverridden()) {
        ComparableFunction CF = ComparableFunction(F, DL);
        Changed |= insert(CF);
      }
    }
    DEBUG(dbgs() << "size of FnSet: " << FnSet.size() << '\n');
  } while (!Deferred.empty());

  FnSet.clear();

  return Changed;
}
예제 #2
0
파일: MergeFunctions.cpp 프로젝트: CPFL/guc
bool MergeFunctions::runOnModule(Module &M) {
  typedef DenseSet<ComparableFunction *, MergeFunctionsEqualityInfo> FnSetType;

  bool Changed = false;
  TD = getAnalysisIfAvailable<TargetData>();

  std::vector<Function *> Funcs;
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage())
      Funcs.push_back(F);
  }

  bool LocalChanged;
  do {
    LocalChanged = false;

    FnSetType FnSet;
    for (unsigned i = 0, e = Funcs.size(); i != e;) {
      Function *F = Funcs[i];
      ComparableFunction *NewF = new ComparableFunction(F, TD);
      std::pair<FnSetType::iterator, bool> Result = FnSet.insert(NewF);
      if (!Result.second) {
        ComparableFunction *&OldF = *Result.first;
        assert(OldF && "Expected a hash collision");

        // NewF will be deleted in favour of OldF unless NewF is strong and
        // OldF is weak in which case swap them to keep the strong definition.

        if (OldF->Func->isWeakForLinker() && !NewF->Func->isWeakForLinker())
          std::swap(OldF, NewF);

        DEBUG(dbgs() << "  " << OldF->Func->getName() << " == "
                     << NewF->Func->getName() << '\n');

	Funcs.erase(Funcs.begin() + i);
	--e;

        Function *DeleteF = NewF->Func;
        delete NewF;
        MergeTwoFunctions(OldF->Func, DeleteF);
	LocalChanged = true;
        Changed = true;
      } else {
	++i;
      }
    }
    DeleteContainerPointers(FnSet);
  } while (LocalChanged);

  return Changed;
}
예제 #3
0
bool StripExternals::runOnModule(Module &M) {
  bool Changed = false;

  for (Module::iterator I = M.begin(); I != M.end(); ) {
    if (I->hasAvailableExternallyLinkage()) {
      assert(!I->isDeclaration()&&"Declarations can't be available_externally");
      Changed = true;
      ++NumFunctions;
      if (I->use_empty()) {
        DEBUG(errs() << "Deleting function: " << *I);
        Module::iterator todelete = I;
        ++I;
        todelete->eraseFromParent();
        continue;
      } else {
        I->deleteBody();
        DEBUG(errs() << "Deleted function body: " << *I);
      }
    }
    ++I;
  }

  for (Module::global_iterator I = M.global_begin();
       I != M.global_end(); ) {
    if (I->hasAvailableExternallyLinkage()) {
      assert(!I->isDeclaration()&&"Declarations can't be available_externally");
      Changed = true;
      ++NumVariables;
      if (I->use_empty()) {
        DEBUG(errs() << "Deleting global: " << *I);
        Module::global_iterator todelete = I;
        ++I;
        todelete->eraseFromParent();
        continue;
      } else {
        I->setInitializer(0);
        I->setLinkage(GlobalValue::ExternalLinkage);
        DEBUG(errs() << "Deleted initializer: " << *I);
      }
    }
    ++I;
  }

  return Changed;
}
예제 #4
0
bool InternalizePass::runOnModule(Module &M) {
  CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
  CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
  
  if (ExternalNames.empty()) {
    // Return if we're not in 'all but main' mode and have no external api
    if (!AllButMain)
      return false;
    // If no list or file of symbols was specified, check to see if there is a
    // "main" symbol defined in the module.  If so, use it, otherwise do not
    // internalize the module, it must be a library or something.
    //
    Function *MainFunc = M.getFunction("main");
    if (MainFunc == 0 || MainFunc->isDeclaration())
      return false;  // No main found, must be a library...

    // Preserve main, internalize all else.
    ExternalNames.insert(MainFunc->getName());
  }

  bool Changed = false;

  // Never internalize functions which code-gen might insert.
  ExternalNames.insert("__stack_chk_fail");

  // Mark all functions not in the api as internal.
  // FIXME: maybe use private linkage?
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration() &&         // Function must be defined here
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !I->hasLocalLinkage() &&  // Can't already have internal linkage
        !ExternalNames.count(I->getName())) {// Not marked to keep external?
      I->setLinkage(GlobalValue::InternalLinkage);
      // Remove a callgraph edge from the external node to this function.
      if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]);
      Changed = true;
      ++NumFunctions;
      DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n");
    }

  // Never internalize the llvm.used symbol.  It is used to implement
  // attribute((used)).
  // FIXME: Shouldn't this just filter on llvm.metadata section??
  ExternalNames.insert("llvm.used");
  ExternalNames.insert("llvm.compiler.used");

  // Never internalize anchors used by the machine module info, else the info
  // won't find them.  (see MachineModuleInfo.)
  ExternalNames.insert("llvm.global_ctors");
  ExternalNames.insert("llvm.global_dtors");
  ExternalNames.insert("llvm.global.annotations");

  // Never internalize symbols code-gen inserts.
  ExternalNames.insert("__stack_chk_guard");

  // Mark all global variables with initializers that are not in the api as
  // internal as well.
  // FIXME: maybe use private linkage?
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasLocalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumGlobals;
      DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n");
    }

  // Mark all aliases that are not in the api as internal as well.
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasInternalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumAliases;
      DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n");
    }

  return Changed;
}
예제 #5
0
bool InternalizePass::runOnModule(Module &M) {
  CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
  CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
  bool Changed = false;

  // Never internalize functions which code-gen might insert.
  // FIXME: We should probably add this (and the __stack_chk_guard) via some
  // type of call-back in CodeGen.
  ExternalNames.insert("__stack_chk_fail");

  // Mark all functions not in the api as internal.
  // FIXME: maybe use private linkage?
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration() &&         // Function must be defined here
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !I->hasLocalLinkage() &&  // Can't already have internal linkage
        !ExternalNames.count(I->getName())) {// Not marked to keep external?
      I->setLinkage(GlobalValue::InternalLinkage);
      // Remove a callgraph edge from the external node to this function.
      if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]);
      Changed = true;
      ++NumFunctions;
      DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n");
    }

  // Never internalize the llvm.used symbol.  It is used to implement
  // attribute((used)).
  // FIXME: Shouldn't this just filter on llvm.metadata section??
  ExternalNames.insert("llvm.used");
  ExternalNames.insert("llvm.compiler.used");

  // Never internalize anchors used by the machine module info, else the info
  // won't find them.  (see MachineModuleInfo.)
  ExternalNames.insert("llvm.global_ctors");
  ExternalNames.insert("llvm.global_dtors");
  ExternalNames.insert("llvm.global.annotations");

  // Never internalize symbols code-gen inserts.
  ExternalNames.insert("__stack_chk_guard");

  // Mark all global variables with initializers that are not in the api as
  // internal as well.
  // FIXME: maybe use private linkage?
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasLocalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumGlobals;
      DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n");
    }

  // Mark all aliases that are not in the api as internal as well.
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
       I != E; ++I)
    if (!I->isDeclaration() && !I->hasInternalLinkage() &&
        // Available externally is really just a "declaration with a body".
        !I->hasAvailableExternallyLinkage() &&
        !ExternalNames.count(I->getName())) {
      I->setLinkage(GlobalValue::InternalLinkage);
      Changed = true;
      ++NumAliases;
      DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n");
    }

  return Changed;
}
예제 #6
0
bool GlobalDCE::runOnModule(Module &M) {
  bool Changed = false;
  
  // Loop over the module, adding globals which are obviously necessary.
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Functions with external linkage are needed if they have a body
    if (!I->isDiscardableIfUnused() &&
        !I->isDeclaration() && !I->hasAvailableExternallyLinkage())
      GlobalIsNeeded(I);
  }

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Externally visible & appending globals are needed, if they have an
    // initializer.
    if (!I->isDiscardableIfUnused() &&
        !I->isDeclaration() && !I->hasAvailableExternallyLinkage())
      GlobalIsNeeded(I);
  }

  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
       I != E; ++I) {
    Changed |= RemoveUnusedGlobalValue(*I);
    // Externally visible aliases are needed.
    if (!I->isDiscardableIfUnused())
      GlobalIsNeeded(I);
  }

  // Now that all globals which are needed are in the AliveGlobals set, we loop
  // through the program, deleting those which are not alive.
  //

  // The first pass is to drop initializers of global variables which are dead.
  std::vector<GlobalVariable*> DeadGlobalVars;   // Keep track of dead globals
  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E; ++I)
    if (!AliveGlobals.count(I)) {
      DeadGlobalVars.push_back(I);         // Keep track of dead globals
      I->setInitializer(0);
    }

  // The second pass drops the bodies of functions which are dead...
  std::vector<Function*> DeadFunctions;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!AliveGlobals.count(I)) {
      DeadFunctions.push_back(I);         // Keep track of dead globals
      if (!I->isDeclaration())
        I->deleteBody();
    }

  // The third pass drops targets of aliases which are dead...
  std::vector<GlobalAlias*> DeadAliases;
  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
       ++I)
    if (!AliveGlobals.count(I)) {
      DeadAliases.push_back(I);
      I->setAliasee(0);
    }

  if (!DeadFunctions.empty()) {
    // Now that all interferences have been dropped, delete the actual objects
    // themselves.
    for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadFunctions[i]);
      M.getFunctionList().erase(DeadFunctions[i]);
    }
    NumFunctions += DeadFunctions.size();
    Changed = true;
  }

  if (!DeadGlobalVars.empty()) {
    for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
      M.getGlobalList().erase(DeadGlobalVars[i]);
    }
    NumVariables += DeadGlobalVars.size();
    Changed = true;
  }

  // Now delete any dead aliases.
  if (!DeadAliases.empty()) {
    for (unsigned i = 0, e = DeadAliases.size(); i != e; ++i) {
      RemoveUnusedGlobalValue(*DeadAliases[i]);
      M.getAliasList().erase(DeadAliases[i]);
    }
    NumAliases += DeadAliases.size();
    Changed = true;
  }

  // Make sure that all memory is released
  AliveGlobals.clear();

  return Changed;
}