20 auto KernelModuleTmp = std::make_unique<Module>(
"JitModule", M.getContext());
21 KernelModuleTmp->setSourceFileName(M.getSourceFileName());
22 KernelModuleTmp->setDataLayout(M.getDataLayout());
23 KernelModuleTmp->setTargetTriple(M.getTargetTriple());
24 KernelModuleTmp->setModuleInlineAsm(M.getModuleInlineAsm());
25#if LLVM_VERSION_MAJOR >= 18
26 KernelModuleTmp->IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
29 auto *KernelFunction = M.getFunction(Name);
33 SmallPtrSet<Function *, 8> ReachableFunctions;
34 SmallPtrSet<GlobalVariable *, 16> ReachableGlobals;
35 SmallPtrSet<Function *, 8> ReachableDeclarations;
36 SmallVector<Function *, 8> ToVisit;
37 ReachableFunctions.insert(KernelFunction);
38 ToVisit.push_back(KernelFunction);
39 while (!ToVisit.empty()) {
40 Function *VisitF = ToVisit.pop_back_val();
41 CallGraphNode *CGNode = CG[VisitF];
43 for (
const auto &Callee : *CGNode) {
44 Function *CalleeF = Callee.second->getFunction();
47 if (CalleeF->isDeclaration()) {
48 ReachableDeclarations.insert(CalleeF);
51 if (ReachableFunctions.contains(CalleeF))
53 ReachableFunctions.insert(CalleeF);
54 ToVisit.push_back(CalleeF);
58 auto ProcessInstruction = [&](GlobalVariable &GV,
const Instruction *I) {
59 const Function *ParentF = I->getFunction();
60 if (ReachableFunctions.contains(ParentF))
61 ReachableGlobals.insert(&GV);
64 for (
auto &GV : M.globals()) {
65 for (
const User *Usr : GV.users()) {
66 const Instruction *I = dyn_cast<Instruction>(Usr);
69 ProcessInstruction(GV, I);
77 for (
const User *NextUser : Usr->users()) {
78 I = dyn_cast<Instruction>(NextUser);
82 ProcessInstruction(GV, I);
87 ValueToValueMapTy VMap;
89 for (
auto *GV : ReachableGlobals) {
91 GlobalVariable *NewGV =
new GlobalVariable(
92 *KernelModuleTmp, GV->getValueType(), GV->isConstant(),
93 GV->getLinkage(),
nullptr, GV->getName(),
nullptr,
94 GV->getThreadLocalMode(), GV->getAddressSpace());
95 NewGV->copyAttributesFrom(GV);
99 for (
auto *F : ReachableFunctions) {
100 auto *NewFunction = Function::Create(F->getFunctionType(), F->getLinkage(),
101 F->getAddressSpace(), F->getName(),
102 KernelModuleTmp.get());
103 NewFunction->copyAttributesFrom(F);
104 VMap[F] = NewFunction;
107 for (
auto *F : ReachableDeclarations) {
108 auto *NewFunction = Function::Create(F->getFunctionType(), F->getLinkage(),
109 F->getAddressSpace(), F->getName(),
110 KernelModuleTmp.get());
111 NewFunction->copyAttributesFrom(F);
112 NewFunction->setLinkage(GlobalValue::ExternalLinkage);
113 VMap[F] = NewFunction;
116 for (GlobalVariable *GV : ReachableGlobals) {
117 if (GV->hasInitializer()) {
118 GlobalVariable *NewGV = cast<GlobalVariable>(VMap[GV]);
119 NewGV->setInitializer(MapValue(GV->getInitializer(), VMap));
123 for (
auto *F : ReachableFunctions) {
124 SmallVector<ReturnInst *, 8> Returns;
125 auto *NewFunction = dyn_cast<Function>(VMap[F]);
126 Function::arg_iterator DestI = NewFunction->arg_begin();
127 for (
const Argument &I : F->args())
128 if (VMap.count(&I) == 0) {
129 DestI->setName(I.getName());
130 VMap[&I] = &*DestI++;
132 llvm::CloneFunctionInto(NewFunction, F, VMap,
133 CloneFunctionChangeType::DifferentModule, Returns);
138 const std::string MetadataToCopy[] = {
"llvm.annotations",
"nvvm.annotations",
139 "nvvmir.version",
"llvm.module.flags"};
140 for (
auto &MetadataName : MetadataToCopy) {
141 NamedMDNode *NamedMD = M.getNamedMetadata(MetadataName);
145 auto *NewNamedMD = KernelModuleTmp->getOrInsertNamedMetadata(MetadataName);
146 for (
unsigned I = 0, E = NamedMD->getNumOperands(); I < E; ++I) {
147 MDNode *MDEntry = NamedMD->getOperand(I);
148 bool ShouldClone =
true;
151 for (
auto &Operand : MDEntry->operands()) {
152 Metadata *MD = Operand.get();
153 auto *CMD = dyn_cast<ConstantAsMetadata>(MD);
157 auto *GV = dyn_cast<GlobalValue>(CMD->getValue());
161 if (!VMap.count(GV)) {
170 NewNamedMD->addOperand(MapMetadata(MDEntry, VMap));
176 if (verifyModule(*KernelModuleTmp, &errs()))
180 return KernelModuleTmp;
498 StringRef EntryName) {
503 Function *EntryF =
nullptr;
504 Module *EntryM =
nullptr;
505 for (Module &M : Mods) {
506 if ((EntryF = M.getFunction(EntryName)) && !EntryF->isDeclaration()) {
515 SmallVector<Function *> ToVisit{EntryF};
516 SmallPtrSet<Function *, 32> VisitSet{EntryF};
517 SmallPtrSet<GlobalValue *, 32> Reachable;
518 while (!ToVisit.empty()) {
519 auto *F = ToVisit.pop_back_val();
522 if (
auto E = F->materialize())
525 auto ThisReachable = Cloner.findTransitiveClosure(F, Defs);
526 for (
auto *GV : ThisReachable) {
527 Reachable.insert(GV);
528 if (
auto *ThisF = dyn_cast<Function>(GV)) {
529 if (!VisitSet.contains(ThisF)) {
530 VisitSet.insert(ThisF);
531 ToVisit.push_back(ThisF);
539 Cloner.cloneClosure(*EntryM, EntryF->getContext(), Reachable);