Skip to content

Commit

Permalink
Add module clone pass.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel-Durov committed Sep 14, 2024
1 parent dbc1aca commit bdb2a25
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 0 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ void initializeXRayInstrumentationPass(PassRegistry&);
void initializeYkStackmapsPass(PassRegistry&);
void initializeYkSplitBlocksAfterCallsPass(PassRegistry&);
void initializeYkBasicBlockTracerPass(PassRegistry&);
void initializeYkModuleClonePass(PassRegistry&);
} // end namespace llvm

#endif // LLVM_INITIALIZEPASSES_H
10 changes: 10 additions & 0 deletions llvm/include/llvm/Transforms/Yk/ModuleClone.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef LLVM_TRANSFORMS_YK_MODULE_CLONE_H
#define LLVM_TRANSFORMS_YK_MODULE_CLONE_H

#include "llvm/Pass.h"

namespace llvm {
ModulePass *createYkModuleClonePass();
} // namespace llvm

#endif
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/CodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,5 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeYkStackmapsPass(Registry);
initializeYkSplitBlocksAfterCallsPass(Registry);
initializeYkBasicBlockTracerPass(Registry);
initializeYkModuleClonePass(Registry);
}
7 changes: 7 additions & 0 deletions llvm/lib/CodeGen/TargetPassConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "llvm/Transforms/Yk/Stackmaps.h"
#include "llvm/Transforms/Yk/NoCallsInEntryBlocks.h"
#include "llvm/Transforms/Yk/BasicBlockTracer.h"
#include "llvm/Transforms/Yk/ModuleClone.h"
#include <cassert>
#include <optional>
#include <string>
Expand Down Expand Up @@ -297,6 +298,9 @@ static cl::opt<bool>
YkBasicBlockTracer("yk-basicblock-tracer", cl::init(false), cl::NotHidden,
cl::desc("Enables YK Software Tracer capability"));

static cl::opt<bool>
YkModuleClone("yk-module-clone", cl::init(false), cl::NotHidden,
cl::desc("Enables YK Module Cloning capability"));

/// Allow standard passes to be disabled by command line options. This supports
/// simple binary flags that either suppress the pass or do nothing.
Expand Down Expand Up @@ -1190,6 +1194,9 @@ bool TargetPassConfig::addISelPasses() {
if (YkBasicBlockTracer) {
addPass(createYkBasicBlockTracerPass());
}
if (YkModuleClone){
addPass(createYkModuleClonePass());
}

addISelPrepare();
return addCoreISelPasses();
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Transforms/Yk/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_llvm_component_library(LLVMYkPasses
NoCallsInEntryBlocks.cpp
SplitBlocksAfterCalls.cpp
BasicBlockTracer.cpp
ModuleClone.cpp

DEPENDS
intrinsics_gen
Expand All @@ -16,4 +17,6 @@ add_llvm_component_library(LLVMYkPasses
Analysis
Core
Support
TransformUtils # Module Clone
Linker # Module Linker
)
78 changes: 78 additions & 0 deletions llvm/lib/Transforms/Yk/ModuleClone.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "llvm/Transforms/Yk/ModuleClone.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/InitializePasses.h"
#include "llvm/Linker/Linker.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/Cloning.h"

#define DEBUG_TYPE "yk-module-clone-pass"

using namespace llvm;

namespace llvm {
void initializeYkModuleClonePass(PassRegistry &);
} // namespace llvm

namespace {
struct YkModuleClone : public ModulePass {
static char ID;
const std::string ClonePrefix = "__yk_clone_";

YkModuleClone() : ModulePass(ID) {
initializeYkModuleClonePass(*PassRegistry::getPassRegistry());
}

void updateClonedFunctions(Module &M) {
for (llvm::Function &F : M) {
if (F.hasExternalLinkage() && F.isDeclaration()) {
continue;
}
F.setName(ClonePrefix + F.getName().str());
}
}

void updateClonedGlobals(Module &M) {
for (llvm::GlobalVariable &GV : M.globals()) {
std::string GlobalName = GV.getName().str();
if (GlobalName.find('.') == 0) {
continue; // This is likely not user-defined. Example: `.L.str`.
}
GV.setInitializer(nullptr); // Remove the initializer
GV.setLinkage(llvm::GlobalValue::ExternalLinkage); // Set external linkage
}
}

bool runOnModule(Module &M) override {
if (M.getName() == "src/perf/collect.c") {
return false;
}
std::unique_ptr<Module> Cloned = CloneModule(M);
if (!Cloned) {
errs() << "Error: CloneModule returned null for module: " << M.getName()
<< "\n";
return false;
}
updateClonedFunctions(*Cloned);
updateClonedGlobals(*Cloned);

llvm::Linker TheLinker(M);
if (TheLinker.linkInModule(std::move(Cloned))) {
llvm::report_fatal_error("Error linking the modules");
return false;
}
return true;
}
};
} // namespace

char YkModuleClone::ID = 0;

INITIALIZE_PASS(YkModuleClone, DEBUG_TYPE, "yk module clone", false, false)

ModulePass *llvm::createYkModuleClonePass() { return new YkModuleClone(); }
2 changes: 2 additions & 0 deletions llvm/lib/YkIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ add_llvm_component_library(LLVMYkIR
Core
MC
Support
TransformUtils
Linker
)

0 comments on commit bdb2a25

Please sign in to comment.