| 367 | : ExportAll{ExportByDefault} {} |
| 368 | |
| 369 | llvm::PreservedAnalyses |
| 370 | EntrypointPreparationPass::run(llvm::Module &M, llvm::ModuleAnalysisManager &AM) { |
| 371 | |
| 372 | static constexpr const char* SSCPKernelMarker = "hipsycl_sscp_kernel"; |
| 373 | static constexpr const char* SSCPOutliningMarker = "hipsycl_sscp_outlining"; |
| 374 | |
| 375 | llvm::SmallSet<std::string, 16> Kernels; |
| 376 | |
| 377 | |
| 378 | llvm::DenseSet<llvm::Function*> MarkedFunctions; |
| 379 | auto MarkThisFunctionForOutlining = [&](llvm::Function* F) { |
| 380 | HIPSYCL_DEBUG_INFO << "Found SSCP outlining entrypoint: " << F->getName() << "\n"; |
| 381 | // Make kernel have external linkage to avoid having everything optimized away |
| 382 | F->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| 383 | |
| 384 | // If we have a definition, we need to perform outlining. |
| 385 | // Otherwise, we would need to treat the function as imported -- |
| 386 | // however this cannot really happen as clang does not codegen our |
| 387 | // attribute((annotate("hipsycl_sscp_outlining"))) for declarations |
| 388 | // without definition. |
| 389 | if(F->size() > 0 && !MarkedFunctions.contains(F)) { |
| 390 | this->OutliningEntrypoints.push_back(F->getName().str()); |
| 391 | MarkedFunctions.insert(F); |
| 392 | } |
| 393 | }; |
| 394 | |
| 395 | llvm::SmallPtrSet<llvm::Function*, 16> KernelFunctionsWithDimAnnotations; |
| 396 | utils::findFunctionsWithStringAnnotationsWithArg(M, [&](llvm::Function* F, llvm::StringRef Annotation, llvm::Constant* Argument){ |
| 397 | if(F) { |
| 398 | if(Annotation.compare(SscpKernelDimensionName) == 0){ |
| 399 | HIPSYCL_DEBUG_INFO << "Found kernel dim annotation: " << F->getName() << " with arg: " << * Argument << "\n"; |
| 400 | // annotate the actual kernel with the dimension |
| 401 | for (auto &U : F->uses()) { |
| 402 | if (auto *CI = llvm::dyn_cast<llvm::CallInst>(U.getUser())) { |
| 403 | if (CI->getCalledFunction() == F) { |
| 404 | auto DimVal = llvm::cast<llvm::Constant>(Argument->getOperand(0)); |
| 405 | if (DimVal->getNumOperands() > 0) { |
| 406 | DimVal = llvm::cast<llvm::Constant>(DimVal->getOperand(0)); |
| 407 | } |
| 408 | attachKernelDim(M, CI->getFunction(), DimVal); |
| 409 | KernelFunctionsWithDimAnnotations.insert(CI->getFunction()); |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | } |
| 414 | if(Annotation.compare(SSCPKernelMarker) == 0) { |
| 415 | HIPSYCL_DEBUG_INFO << "Found SSCP kernel: " << F->getName() << "\n"; |
| 416 | this->KernelNames.push_back(F->getName().str()); |
| 417 | Kernels.insert(F->getName().str()); |
| 418 | } |
| 419 | |
| 420 | if(Annotation.compare(SSCPOutliningMarker) == 0) { |
| 421 | MarkThisFunctionForOutlining(F); |
| 422 | } |
| 423 | } |
| 424 | }); |
| 425 | for(auto KernelName : Kernels) { |
| 426 | if(auto* F = M.getFunction(KernelName)) { |
no test coverage detected