コード例 #1
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;
}
コード例 #2
0
bool MergeFunctions::runOnModule(Module &M) {
  bool Changed = false;
  TD = getAnalysisIfAvailable<TargetData>();

  bool LocalChanged;
  do {
    DEBUG(dbgs() << "size of module: " << M.size() << '\n');
    LocalChanged = false;
    FnSetType FnSet;

    // Insert only strong functions and merge them. Strong function merging
    // always deletes one of them.
    for (Module::iterator I = M.begin(), E = M.end(); I != E;) {
      Function *F = I++;
      if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
          !F->mayBeOverridden() && !IsThunk(F)) {
        ComparableFunction CF = ComparableFunction(F, TD);
        LocalChanged |= Insert(FnSet, 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 (Module::iterator I = M.begin(), E = M.end(); I != E;) {
      Function *F = I++;
      if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
          F->mayBeOverridden() && !IsThunk(F)) {
        ComparableFunction CF = ComparableFunction(F, TD);
        LocalChanged |= Insert(FnSet, CF);
      }
    }
    DEBUG(dbgs() << "size of FnSet: " << FnSet.size() << '\n');
    Changed |= LocalChanged;
  } while (LocalChanged);

  return Changed;
}
コード例 #3
0
// Insert - Insert a ComparableFunction into the FnSet, or merge it away if
// equal to one that's already inserted.
bool MergeFunctions::Insert(FnSetType &FnSet, ComparableFunction &NewF) {
  std::pair<FnSetType::iterator, bool> Result = FnSet.insert(NewF);
  if (Result.second)
    return false;

  const ComparableFunction &OldF = *Result.first;

  // Never thunk a strong function to a weak function.
  assert(!OldF.getFunc()->mayBeOverridden() ||
         NewF.getFunc()->mayBeOverridden());

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

  Function *DeleteF = NewF.getFunc();
  NewF.release();
  MergeTwoFunctions(OldF.getFunc(), DeleteF);
  return true;
}