|
123 | 123 | #include <algorithm> |
124 | 124 | #include <cassert> |
125 | 125 | #include <iterator> |
| 126 | +#include <map> |
126 | 127 | #include <set> |
127 | 128 | #include <utility> |
128 | 129 | #include <vector> |
@@ -198,6 +199,8 @@ class MergeFunctions { |
198 | 199 | } |
199 | 200 |
|
200 | 201 | bool runOnModule(Module &M); |
| 202 | + bool runOnFunctions(std::set<Function *> &F); |
| 203 | + std::map<Function *, Function *> &getDelToNewMap(); |
201 | 204 |
|
202 | 205 | private: |
203 | 206 | // The function comparison operator is provided here so that FunctionNodes do |
@@ -298,17 +301,31 @@ class MergeFunctions { |
298 | 301 | // dangling iterators into FnTree. The invariant that preserves this is that |
299 | 302 | // there is exactly one mapping F -> FN for each FunctionNode FN in FnTree. |
300 | 303 | DenseMap<AssertingVH<Function>, FnTreeType::iterator> FNodesInTree; |
| 304 | + |
| 305 | + /// Deleted-New functions mapping |
| 306 | + std::map<Function *, Function *> DelToNewMap; |
301 | 307 | }; |
302 | 308 | } // end anonymous namespace |
303 | 309 |
|
304 | 310 | PreservedAnalyses MergeFunctionsPass::run(Module &M, |
305 | 311 | ModuleAnalysisManager &AM) { |
306 | | - MergeFunctions MF; |
307 | | - if (!MF.runOnModule(M)) |
| 312 | + if (!MergeFunctionsPass::runOnModule(M)) |
308 | 313 | return PreservedAnalyses::all(); |
309 | 314 | return PreservedAnalyses::none(); |
310 | 315 | } |
311 | 316 |
|
| 317 | +bool MergeFunctionsPass::runOnModule(Module &M) { |
| 318 | + MergeFunctions MF; |
| 319 | + return MF.runOnModule(M); |
| 320 | +} |
| 321 | + |
| 322 | +std::pair<bool, std::map<Function *, Function *>> |
| 323 | +MergeFunctionsPass::runOnFunctions(std::set<Function *> &F) { |
| 324 | + MergeFunctions MF; |
| 325 | + bool MergeResult = MF.runOnFunctions(F); |
| 326 | + return {MergeResult, MF.getDelToNewMap()}; |
| 327 | +} |
| 328 | + |
312 | 329 | #ifndef NDEBUG |
313 | 330 | bool MergeFunctions::doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist) { |
314 | 331 | if (const unsigned Max = NumFunctionsForVerificationCheck) { |
@@ -468,6 +485,47 @@ bool MergeFunctions::runOnModule(Module &M) { |
468 | 485 | return Changed; |
469 | 486 | } |
470 | 487 |
|
| 488 | +bool MergeFunctions::runOnFunctions(std::set<Function *> &F) { |
| 489 | + bool Changed = false; |
| 490 | + std::vector<std::pair<IRHash, Function *>> HashedFuncs; |
| 491 | + for (Function *Func : F) { |
| 492 | + if (isEligibleForMerging(*Func)) { |
| 493 | + HashedFuncs.push_back({StructuralHash(*Func), Func}); |
| 494 | + } |
| 495 | + } |
| 496 | + llvm::stable_sort(HashedFuncs, less_first()); |
| 497 | + auto S = HashedFuncs.begin(); |
| 498 | + for (auto I = HashedFuncs.begin(), IE = HashedFuncs.end(); I != IE; ++I) { |
| 499 | + if ((I != S && std::prev(I)->first == I->first) || |
| 500 | + (std::next(I) != IE && std::next(I)->first == I->first)) { |
| 501 | + Deferred.push_back(WeakTrackingVH(I->second)); |
| 502 | + } |
| 503 | + } |
| 504 | + do { |
| 505 | + std::vector<WeakTrackingVH> Worklist; |
| 506 | + Deferred.swap(Worklist); |
| 507 | + LLVM_DEBUG(dbgs() << "size of function: " << F.size() << '\n'); |
| 508 | + LLVM_DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n'); |
| 509 | + for (WeakTrackingVH &I : Worklist) { |
| 510 | + if (!I) |
| 511 | + continue; |
| 512 | + Function *F = cast<Function>(I); |
| 513 | + if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) { |
| 514 | + Changed |= insert(F); |
| 515 | + } |
| 516 | + } |
| 517 | + LLVM_DEBUG(dbgs() << "size of FnTree: " << FnTree.size() << '\n'); |
| 518 | + } while (!Deferred.empty()); |
| 519 | + FnTree.clear(); |
| 520 | + FNodesInTree.clear(); |
| 521 | + GlobalNumbers.clear(); |
| 522 | + return Changed; |
| 523 | +} |
| 524 | + |
| 525 | +std::map<Function *, Function *> &MergeFunctions::getDelToNewMap() { |
| 526 | + return this->DelToNewMap; |
| 527 | +} |
| 528 | + |
471 | 529 | // Replace direct callers of Old with New. |
472 | 530 | void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) { |
473 | 531 | for (Use &U : llvm::make_early_inc_range(Old->uses())) { |
@@ -1004,6 +1062,7 @@ bool MergeFunctions::insert(Function *NewFunction) { |
1004 | 1062 |
|
1005 | 1063 | Function *DeleteF = NewFunction; |
1006 | 1064 | mergeTwoFunctions(OldF.getFunc(), DeleteF); |
| 1065 | + this->DelToNewMap.emplace(DeleteF, OldF.getFunc()); |
1007 | 1066 | return true; |
1008 | 1067 | } |
1009 | 1068 |
|
|
0 commit comments