@@ -5169,6 +5169,24 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
51695169 O << " \n " ;
51705170 }
51715171
5172+ // Generate declaration of variable of type __sycl_host_pipe_registration
5173+ // whose sole purpose is to run its constructor before the application's
5174+ // main() function.
5175+ if (NeedToEmitHostPipeRegistration) {
5176+ O << " namespace {\n " ;
5177+
5178+ O << " class __sycl_host_pipe_registration {\n " ;
5179+ O << " public:\n " ;
5180+ O << " __sycl_host_pipe_registration() noexcept;\n " ;
5181+ O << " };\n " ;
5182+ O << " __sycl_host_pipe_registration __sycl_host_pipe_registrar;\n " ;
5183+
5184+ O << " } // namespace\n " ;
5185+
5186+ O << " \n " ;
5187+ }
5188+
5189+
51725190 O << " // names of all kernels defined in the corresponding source\n " ;
51735191 O << " static constexpr\n " ;
51745192 O << " const char* const kernel_names[] = {\n " ;
@@ -5359,6 +5377,7 @@ void SYCLIntegrationFooter::addVarDecl(const VarDecl *VD) {
53595377 return ;
53605378 // Step 1: ensure that this is of the correct type template specialization.
53615379 if (!isSyclType (VD->getType (), SYCLTypeAttr::specialization_id) &&
5380+ !isSyclType (VD->getType (), SYCLTypeAttr::host_pipe) &&
53625381 !S.isTypeDecoratedWithDeclAttribute <SYCLDeviceGlobalAttr>(
53635382 VD->getType ())) {
53645383 // Handle the case where this could be a deduced type, such as a deduction
@@ -5528,19 +5547,23 @@ bool SYCLIntegrationFooter::emit(raw_ostream &OS) {
55285547 llvm::SmallSet<const VarDecl *, 8 > Visited;
55295548 bool EmittedFirstSpecConstant = false ;
55305549 bool DeviceGlobalsEmitted = false ;
5550+ bool HostPipesEmitted = false ;
55315551
55325552 // Used to uniquely name the 'shim's as we generate the names in each
55335553 // anonymous namespace.
55345554 unsigned ShimCounter = 0 ;
55355555
55365556 std::string DeviceGlobalsBuf;
55375557 llvm::raw_string_ostream DeviceGlobOS (DeviceGlobalsBuf);
5558+ std::string HostPipesBuf;
5559+ llvm::raw_string_ostream HostPipesOS (HostPipesBuf);
55385560 for (const VarDecl *VD : GlobalVars) {
55395561 VD = VD->getCanonicalDecl ();
55405562
5541- // Skip if this isn't a SpecIdType or DeviceGlobal . This can happen if it
5542- // was a deduced type.
5563+ // Skip if this isn't a SpecIdType, DeviceGlobal, or HostPipe . This
5564+ // can happen if it was a deduced type.
55435565 if (!isSyclType (VD->getType (), SYCLTypeAttr::specialization_id) &&
5566+ !isSyclType (VD->getType (), SYCLTypeAttr::host_pipe) &&
55445567 !S.isTypeDecoratedWithDeclAttribute <SYCLDeviceGlobalAttr>(
55455568 VD->getType ()))
55465569 continue ;
@@ -5551,7 +5574,7 @@ bool SYCLIntegrationFooter::emit(raw_ostream &OS) {
55515574
55525575 // We only want to emit the #includes if we have a variable that needs
55535576 // them, so emit this one on the first time through the loop.
5554- if (!EmittedFirstSpecConstant && !DeviceGlobalsEmitted)
5577+ if (!EmittedFirstSpecConstant && !DeviceGlobalsEmitted && !HostPipesEmitted )
55555578 OS << " #include <sycl/detail/defines_elementary.hpp>\n " ;
55565579
55575580 Visited.insert (VD);
@@ -5571,6 +5594,20 @@ bool SYCLIntegrationFooter::emit(raw_ostream &OS) {
55715594 DeviceGlobOS << SYCLUniqueStableIdExpr::ComputeName (S.getASTContext (),
55725595 VD);
55735596 DeviceGlobOS << " \" );\n " ;
5597+ } else if (isSyclType (VD->getType (), SYCLTypeAttr::host_pipe)) {
5598+ HostPipesEmitted = true ;
5599+ HostPipesOS << " host_pipe_map::add(" ;
5600+ HostPipesOS << " (void *)&" ;
5601+ if (VD->isInAnonymousNamespace ()) {
5602+ HostPipesOS << TopShim;
5603+ } else {
5604+ HostPipesOS << " ::" ;
5605+ VD->getNameForDiagnostic (HostPipesOS, Policy, true );
5606+ }
5607+ HostPipesOS << " , \" " ;
5608+ HostPipesOS << SYCLUniqueStableIdExpr::ComputeName (S.getASTContext (),
5609+ VD);
5610+ HostPipesOS << " \" );\n " ;
55745611 } else {
55755612 EmittedFirstSpecConstant = true ;
55765613 OS << " namespace sycl {\n " ;
@@ -5614,5 +5651,21 @@ bool SYCLIntegrationFooter::emit(raw_ostream &OS) {
56145651
56155652 S.getSyclIntegrationHeader ().addDeviceGlobalRegistration ();
56165653 }
5654+
5655+ if (HostPipesEmitted) {
5656+ OS << " #include <sycl/detail/host_pipe_map.hpp>\n " ;
5657+ HostPipesOS.flush ();
5658+ OS << " namespace sycl::detail {\n " ;
5659+ OS << " namespace {\n " ;
5660+ OS << " __sycl_host_pipe_registration::__sycl_host_pipe_"
5661+ " registration() noexcept {\n " ;
5662+ OS << HostPipesBuf;
5663+ OS << " }\n " ;
5664+ OS << " } // namespace (unnamed)\n " ;
5665+ OS << " } // namespace sycl::detail\n " ;
5666+
5667+ S.getSyclIntegrationHeader ().addHostPipeRegistration ();
5668+ }
5669+
56175670 return true ;
56185671}
0 commit comments