19 auto KernelModuleTmp = std::make_unique<Module>(
"JitModule", M.getContext());
20 KernelModuleTmp->setSourceFileName(M.getSourceFileName());
21 KernelModuleTmp->setDataLayout(M.getDataLayout());
22 KernelModuleTmp->setTargetTriple(M.getTargetTriple());
23 KernelModuleTmp->setModuleInlineAsm(M.getModuleInlineAsm());
24#if LLVM_VERSION_MAJOR >= 18
25 KernelModuleTmp->IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
28 auto *KernelFunction = M.getFunction(Name);
32 SmallPtrSet<Function *, 8> ReachableFunctions;
33 SmallPtrSet<GlobalVariable *, 16> ReachableGlobals;
34 SmallPtrSet<Function *, 8> ReachableDeclarations;
35 SmallVector<Function *, 8> ToVisit;
36 ReachableFunctions.insert(KernelFunction);
37 ToVisit.push_back(KernelFunction);
38 while (!ToVisit.empty()) {
39 Function *VisitF = ToVisit.pop_back_val();
40 CallGraphNode *CGNode = CG[VisitF];
42 for (
const auto &Callee : *CGNode) {
43 Function *CalleeF = Callee.second->getFunction();
46 if (CalleeF->isDeclaration()) {
47 ReachableDeclarations.insert(CalleeF);
50 if (ReachableFunctions.contains(CalleeF))
52 ReachableFunctions.insert(CalleeF);
53 ToVisit.push_back(CalleeF);
57 auto ProcessInstruction = [&](GlobalVariable &GV,
const Instruction *I) {
58 const Function *ParentF = I->getFunction();
59 if (ReachableFunctions.contains(ParentF))
60 ReachableGlobals.insert(&GV);
63 for (
auto &GV : M.globals()) {
64 for (
const User *Usr : GV.users()) {
65 const Instruction *I = dyn_cast<Instruction>(Usr);
68 ProcessInstruction(GV, I);
76 for (
const User *NextUser : Usr->users()) {
77 I = dyn_cast<Instruction>(NextUser);
81 ProcessInstruction(GV, I);
86 ValueToValueMapTy VMap;
88 for (
auto *GV : ReachableGlobals) {
90 GlobalVariable *NewGV =
new GlobalVariable(
91 *KernelModuleTmp, GV->getValueType(), GV->isConstant(),
92 GV->getLinkage(),
nullptr, GV->getName(),
nullptr,
93 GV->getThreadLocalMode(), GV->getAddressSpace());
94 NewGV->copyAttributesFrom(GV);
98 for (
auto *F : ReachableFunctions) {
99 auto *NewFunction = Function::Create(F->getFunctionType(), F->getLinkage(),
100 F->getAddressSpace(), F->getName(),
101 KernelModuleTmp.get());
102 NewFunction->copyAttributesFrom(F);
103 VMap[F] = NewFunction;
106 for (
auto *F : ReachableDeclarations) {
107 auto *NewFunction = Function::Create(F->getFunctionType(), F->getLinkage(),
108 F->getAddressSpace(), F->getName(),
109 KernelModuleTmp.get());
110 NewFunction->copyAttributesFrom(F);
111 NewFunction->setLinkage(GlobalValue::ExternalLinkage);
112 VMap[F] = NewFunction;
115 for (GlobalVariable *GV : ReachableGlobals) {
116 if (GV->hasInitializer()) {
117 GlobalVariable *NewGV = cast<GlobalVariable>(VMap[GV]);
118 NewGV->setInitializer(MapValue(GV->getInitializer(), VMap));
122 for (
auto *F : ReachableFunctions) {
123 SmallVector<ReturnInst *, 8> Returns;
124 auto *NewFunction = dyn_cast<Function>(VMap[F]);
125 Function::arg_iterator DestI = NewFunction->arg_begin();
126 for (
const Argument &I : F->args())
127 if (VMap.count(&I) == 0) {
128 DestI->setName(I.getName());
129 VMap[&I] = &*DestI++;
131 llvm::CloneFunctionInto(NewFunction, F, VMap,
132 CloneFunctionChangeType::DifferentModule, Returns);
137 const std::string MetadataToCopy[] = {
"llvm.annotations",
"nvvm.annotations",
138 "nvvmir.version",
"llvm.module.flags"};
139 for (
auto &MetadataName : MetadataToCopy) {
140 NamedMDNode *NamedMD = M.getNamedMetadata(MetadataName);
144 auto *NewNamedMD = KernelModuleTmp->getOrInsertNamedMetadata(MetadataName);
145 for (
unsigned I = 0, E = NamedMD->getNumOperands(); I < E; ++I) {
146 MDNode *MDEntry = NamedMD->getOperand(I);
147 bool ShouldClone =
true;
150 for (
auto &Operand : MDEntry->operands()) {
151 Metadata *MD = Operand.get();
152 auto *CMD = dyn_cast<ConstantAsMetadata>(MD);
156 auto *GV = dyn_cast<GlobalValue>(CMD->getValue());
160 if (!VMap.count(GV)) {
169 NewNamedMD->addOperand(MapMetadata(MDEntry, VMap));
173#if PROTEUS_ENABLE_DEBUG
175 if (verifyModule(*KernelModuleTmp, &errs()))
179 return KernelModuleTmp;
497 StringRef EntryName) {
502 Function *EntryF =
nullptr;
503 Module *EntryM =
nullptr;
504 for (Module &M : Mods) {
505 if ((EntryF = M.getFunction(EntryName)) && !EntryF->isDeclaration()) {
514 SmallVector<Function *> ToVisit{EntryF};
515 SmallPtrSet<Function *, 32> VisitSet{EntryF};
516 SmallPtrSet<GlobalValue *, 32> Reachable;
517 while (!ToVisit.empty()) {
518 auto *F = ToVisit.pop_back_val();
521 if (
auto E = F->materialize())
524 auto ThisReachable = Cloner.findTransitiveClosure(F, Defs);
525 for (
auto *GV : ThisReachable) {
526 Reachable.insert(GV);
527 if (
auto *ThisF = dyn_cast<Function>(GV)) {
528 if (!VisitSet.contains(ThisF)) {
529 VisitSet.insert(ThisF);
530 ToVisit.push_back(ThisF);
538 Cloner.cloneClosure(*EntryM, EntryF->getContext(), Reachable);