Skip to content

Commit

Permalink
new runOn method
Browse files Browse the repository at this point in the history
remove templates

unit tests added

format

updated data structures

format
  • Loading branch information
Casperento committed Oct 3, 2024
1 parent 5df7d88 commit 69e1cc7
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 2 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/Transforms/IPO/MergeFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
#ifndef LLVM_TRANSFORMS_IPO_MERGEFUNCTIONS_H
#define LLVM_TRANSFORMS_IPO_MERGEFUNCTIONS_H

#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
#include <map>
#include <set>

namespace llvm {

Expand All @@ -25,6 +28,10 @@ class Module;
class MergeFunctionsPass : public PassInfoMixin<MergeFunctionsPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);

static bool runOnModule(Module &M);
static std::pair<bool, std::map<Function *, Function *>>
runOnFunctions(std::set<Function *> &F);
};

} // end namespace llvm
Expand Down
63 changes: 61 additions & 2 deletions llvm/lib/Transforms/IPO/MergeFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
#include <algorithm>
#include <cassert>
#include <iterator>
#include <map>
#include <set>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -198,6 +199,8 @@ class MergeFunctions {
}

bool runOnModule(Module &M);
bool runOnFunctions(std::set<Function *> &F);
std::map<Function *, Function *> &getDelToNewMap();

private:
// The function comparison operator is provided here so that FunctionNodes do
Expand Down Expand Up @@ -298,17 +301,31 @@ class MergeFunctions {
// dangling iterators into FnTree. The invariant that preserves this is that
// there is exactly one mapping F -> FN for each FunctionNode FN in FnTree.
DenseMap<AssertingVH<Function>, FnTreeType::iterator> FNodesInTree;

/// Deleted-New functions mapping
std::map<Function *, Function *> DelToNewMap;
};
} // end anonymous namespace

PreservedAnalyses MergeFunctionsPass::run(Module &M,
ModuleAnalysisManager &AM) {
MergeFunctions MF;
if (!MF.runOnModule(M))
if (!MergeFunctionsPass::runOnModule(M))
return PreservedAnalyses::all();
return PreservedAnalyses::none();
}

bool MergeFunctionsPass::runOnModule(Module &M) {
MergeFunctions MF;
return MF.runOnModule(M);
}

std::pair<bool, std::map<Function *, Function *>>
MergeFunctionsPass::runOnFunctions(std::set<Function *> &F) {
MergeFunctions MF;
bool MergeResult = MF.runOnFunctions(F);
return {MergeResult, MF.getDelToNewMap()};
}

#ifndef NDEBUG
bool MergeFunctions::doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist) {
if (const unsigned Max = NumFunctionsForVerificationCheck) {
Expand Down Expand Up @@ -468,6 +485,47 @@ bool MergeFunctions::runOnModule(Module &M) {
return Changed;
}

bool MergeFunctions::runOnFunctions(std::set<Function *> &F) {
bool Changed = false;
std::vector<std::pair<IRHash, Function *>> HashedFuncs;
for (Function *Func : F) {
if (isEligibleForMerging(*Func)) {
HashedFuncs.push_back({StructuralHash(*Func), Func});
}
}
llvm::stable_sort(HashedFuncs, less_first());
auto S = HashedFuncs.begin();
for (auto I = HashedFuncs.begin(), IE = HashedFuncs.end(); I != IE; ++I) {
if ((I != S && std::prev(I)->first == I->first) ||
(std::next(I) != IE && std::next(I)->first == I->first)) {
Deferred.push_back(WeakTrackingVH(I->second));
}
}
do {
std::vector<WeakTrackingVH> Worklist;
Deferred.swap(Worklist);
LLVM_DEBUG(dbgs() << "size of function: " << F.size() << '\n');
LLVM_DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n');
for (WeakTrackingVH &I : Worklist) {
if (!I)
continue;
Function *F = cast<Function>(I);
if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) {
Changed |= insert(F);
}
}
LLVM_DEBUG(dbgs() << "size of FnTree: " << FnTree.size() << '\n');
} while (!Deferred.empty());
FnTree.clear();
FNodesInTree.clear();
GlobalNumbers.clear();
return Changed;
}

std::map<Function *, Function *> &MergeFunctions::getDelToNewMap() {
return this->DelToNewMap;
}

// Replace direct callers of Old with New.
void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {
for (Use &U : llvm::make_early_inc_range(Old->uses())) {
Expand Down Expand Up @@ -1004,6 +1062,7 @@ bool MergeFunctions::insert(Function *NewFunction) {

Function *DeleteF = NewFunction;
mergeTwoFunctions(OldF.getFunc(), DeleteF);
this->DelToNewMap.emplace(DeleteF, OldF.getFunc());
return true;
}

Expand Down
1 change: 1 addition & 0 deletions llvm/unittests/Transforms/Utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ add_llvm_unittest(UtilsTests
LoopUtilsTest.cpp
MemTransferLowering.cpp
ModuleUtilsTest.cpp
MergeFunctionsTest.cpp
ScalarEvolutionExpanderTest.cpp
SizeOptsTest.cpp
SSAUpdaterBulkTest.cpp
Expand Down
Loading

0 comments on commit 69e1cc7

Please sign in to comment.