21 auto KernelModuleTmp = std::make_unique<Module>(
"JitModule", M.getContext());
22 KernelModuleTmp->setSourceFileName(M.getSourceFileName());
23 KernelModuleTmp->setDataLayout(M.getDataLayout());
24 KernelModuleTmp->setTargetTriple(M.getTargetTriple());
25 KernelModuleTmp->setModuleInlineAsm(M.getModuleInlineAsm());
26#if LLVM_VERSION_MAJOR >= 18
27 KernelModuleTmp->IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
30 auto *KernelFunction = M.getFunction(Name);
34 SmallPtrSet<Function *, 8> ReachableFunctions;
35 SmallPtrSet<GlobalVariable *, 16> ReachableGlobals;
36 SmallPtrSet<Function *, 8> ReachableDeclarations;
37 SmallVector<Function *, 8> ToVisit;
38 ReachableFunctions.insert(KernelFunction);
39 ToVisit.push_back(KernelFunction);
40 while (!ToVisit.empty()) {
41 Function *VisitF = ToVisit.pop_back_val();
42 CallGraphNode *CGNode = CG[VisitF];
44 for (
const auto &Callee : *CGNode) {
45 Function *CalleeF = Callee.second->getFunction();
48 if (CalleeF->isDeclaration()) {
49 ReachableDeclarations.insert(CalleeF);
52 if (ReachableFunctions.contains(CalleeF))
54 ReachableFunctions.insert(CalleeF);
55 ToVisit.push_back(CalleeF);
59 auto ProcessInstruction = [&](GlobalVariable &GV,
const Instruction *I) {
60 const Function *ParentF = I->getFunction();
61 if (ReachableFunctions.contains(ParentF))
62 ReachableGlobals.insert(&GV);
65 for (
auto &GV : M.globals()) {
66 for (
const User *Usr : GV.users()) {
67 const Instruction *I = dyn_cast<Instruction>(Usr);
70 ProcessInstruction(GV, I);
78 for (
const User *NextUser : Usr->users()) {
79 I = dyn_cast<Instruction>(NextUser);
83 ProcessInstruction(GV, I);
88 ValueToValueMapTy VMap;
90 for (
auto *GV : ReachableGlobals) {
92 GlobalVariable *NewGV =
new GlobalVariable(
93 *KernelModuleTmp, GV->getValueType(), GV->isConstant(),
94 GV->getLinkage(),
nullptr, GV->getName(),
nullptr,
95 GV->getThreadLocalMode(), GV->getAddressSpace());
96 NewGV->copyAttributesFrom(GV);
100 for (
auto *F : ReachableFunctions) {
101 auto *NewFunction = Function::Create(F->getFunctionType(), F->getLinkage(),
102 F->getAddressSpace(), F->getName(),
103 KernelModuleTmp.get());
104 NewFunction->copyAttributesFrom(F);
105 VMap[F] = NewFunction;
108 for (
auto *F : ReachableDeclarations) {
109 auto *NewFunction = Function::Create(F->getFunctionType(), F->getLinkage(),
110 F->getAddressSpace(), F->getName(),
111 KernelModuleTmp.get());
112 NewFunction->copyAttributesFrom(F);
113 NewFunction->setLinkage(GlobalValue::ExternalLinkage);
114 VMap[F] = NewFunction;
117 for (GlobalVariable *GV : ReachableGlobals) {
118 if (GV->hasInitializer()) {
119 GlobalVariable *NewGV = cast<GlobalVariable>(VMap[GV]);
120 NewGV->setInitializer(MapValue(GV->getInitializer(), VMap));
124 for (
auto *F : ReachableFunctions) {
125 SmallVector<ReturnInst *, 8> Returns;
126 auto *NewFunction = dyn_cast<Function>(VMap[F]);
127 Function::arg_iterator DestI = NewFunction->arg_begin();
128 for (
const Argument &I : F->args())
129 if (VMap.count(&I) == 0) {
130 DestI->setName(I.getName());
131 VMap[&I] = &*DestI++;
133 llvm::CloneFunctionInto(NewFunction, F, VMap,
134 CloneFunctionChangeType::DifferentModule, Returns);
139 const std::string MetadataToCopy[] = {
"llvm.annotations",
"nvvm.annotations",
140 "nvvmir.version",
"llvm.module.flags"};
141 for (
auto &MetadataName : MetadataToCopy) {
142 NamedMDNode *NamedMD = M.getNamedMetadata(MetadataName);
146 auto *NewNamedMD = KernelModuleTmp->getOrInsertNamedMetadata(MetadataName);
147 for (
unsigned I = 0, E = NamedMD->getNumOperands(); I < E; ++I) {
148 MDNode *MDEntry = NamedMD->getOperand(I);
149 bool ShouldClone =
true;
152 for (
auto &Operand : MDEntry->operands()) {
153 Metadata *MD = Operand.get();
154 auto *CMD = dyn_cast<ConstantAsMetadata>(MD);
158 auto *GV = dyn_cast<GlobalValue>(CMD->getValue());
162 if (!VMap.count(GV)) {
171 NewNamedMD->addOperand(MapMetadata(MDEntry, VMap));
177 if (verifyModule(*KernelModuleTmp, &errs()))
181 return KernelModuleTmp;
514 ArrayRef<std::reference_wrapper<Module>> Mods, StringRef EntryName,
515 function_ref<
bool(
const GlobalValue *)> ShouldCloneDefinition =
nullptr) {
520 Function *EntryF =
nullptr;
521 Module *EntryM =
nullptr;
522 for (Module &M : Mods) {
523 if ((EntryF = M.getFunction(EntryName)) && !EntryF->isDeclaration()) {
532 SmallVector<Function *> ToVisit{EntryF};
533 SmallPtrSet<Function *, 32> VisitSet{EntryF};
534 SmallPtrSet<GlobalValue *, 32> Reachable;
535 while (!ToVisit.empty()) {
536 auto *F = ToVisit.pop_back_val();
539 if (
auto E = F->materialize())
542 auto ThisReachable = Cloner.findTransitiveClosure(F, Defs);
543 for (
auto *GV : ThisReachable) {
544 Reachable.insert(GV);
545 if (
auto *ThisF = dyn_cast<Function>(GV)) {
546 if (!VisitSet.contains(ThisF)) {
547 VisitSet.insert(ThisF);
548 ToVisit.push_back(ThisF);
555 auto KernelModule = Cloner.cloneClosure(*EntryM, EntryF->getContext(),
556 Reachable, ShouldCloneDefinition);