diff --git a/common_clang.cpp b/common_clang.cpp index 982c9dd3..392a0e31 100644 --- a/common_clang.cpp +++ b/common_clang.cpp @@ -201,97 +201,94 @@ Compile(const char *pszProgramSource, const char **pInputHeaders, try { std::unique_ptr pResult(new OCLFEBinaryResult()); - // LLVM doesn't guarantee thread safety, - // therefore we serialize execution of LLVM code. - llvm::sys::SmartScopedLock compileGuard {*compileMutex}; + // Create the clang compiler + std::unique_ptr compiler( + new clang::CompilerInstance()); - // Parse options CompileOptionsParser optionsParser(pszOpenCLVer); - optionsParser.processOptions(pszOptions, pszOptionsEx); // Prepare error log llvm::raw_string_ostream err_ostream(pResult->getLogRef()); - - // Prepare our diagnostic client. - llvm::IntrusiveRefCntPtr DiagID( - new clang::DiagnosticIDs()); - llvm::IntrusiveRefCntPtr DiagOpts( - new clang::DiagnosticOptions()); - DiagOpts->ShowPresumedLoc = true; - clang::TextDiagnosticPrinter *DiagsPrinter = + { + llvm::sys::SmartScopedLock compileGuard {*compileMutex}; + + // Parse options + optionsParser.processOptions(pszOptions, pszOptionsEx); + + // Prepare our diagnostic client. + llvm::IntrusiveRefCntPtr DiagID( + new clang::DiagnosticIDs()); + llvm::IntrusiveRefCntPtr DiagOpts( + new clang::DiagnosticOptions()); + DiagOpts->ShowPresumedLoc = true; + clang::TextDiagnosticPrinter *DiagsPrinter = new clang::TextDiagnosticPrinter(err_ostream, &*DiagOpts); - llvm::IntrusiveRefCntPtr Diags( - new clang::DiagnosticsEngine(DiagID, &*DiagOpts, DiagsPrinter)); - - // Create the clang compiler - std::unique_ptr compiler( - new clang::CompilerInstance()); + llvm::IntrusiveRefCntPtr Diags( + new clang::DiagnosticsEngine(DiagID, &*DiagOpts, DiagsPrinter)); - // Prepare output buffer - std::unique_ptr + // Prepare output buffer + std::unique_ptr ir_ostream(new llvm::raw_svector_ostream(pResult->getIRBufferRef())); - // Set buffers - // CompilerInstance takes ownership over output stream - compiler->setOutputStream(std::move(ir_ostream)); + // Set buffers + // CompilerInstance takes ownership over output stream + compiler->setOutputStream(std::move(ir_ostream)); - compiler->setDiagnostics(&*Diags); + compiler->setDiagnostics(&*Diags); - llvm::IntrusiveRefCntPtr OverlayFS( - new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem())); - llvm::IntrusiveRefCntPtr MemFS( - new llvm::vfs::InMemoryFileSystem); - OverlayFS->pushOverlay(MemFS); + llvm::IntrusiveRefCntPtr OverlayFS( + new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem())); + llvm::IntrusiveRefCntPtr MemFS( + new llvm::vfs::InMemoryFileSystem); + OverlayFS->pushOverlay(MemFS); - compiler->createFileManager(OverlayFS); - compiler->createSourceManager(compiler->getFileManager()); + compiler->createFileManager(OverlayFS); + compiler->createSourceManager(compiler->getFileManager()); - // Calling ResetAllOptionOccurrences as WA for issue from here: - // https://reviews.llvm.org/D66324?id=219733#1680231 - llvm::cl::ResetAllOptionOccurrences(); - // Create compiler invocation from user args before trickering with it - clang::CompilerInvocation::CreateFromArgs(compiler->getInvocation(), - optionsParser.args(), *Diags); + // Calling ResetAllOptionOccurrences as WA for issue from here: + // https://reviews.llvm.org/D66324?id=219733#1680231 + llvm::cl::ResetAllOptionOccurrences(); + // Create compiler invocation from user args before trickering with it + clang::CompilerInvocation::CreateFromArgs(compiler->getInvocation(), + optionsParser.args(), *Diags); - // Configure our handling of diagnostics. - ProcessWarningOptions(*Diags, compiler->getDiagnosticOpts()); + // Configure our handling of diagnostics. + ProcessWarningOptions(*Diags, compiler->getDiagnosticOpts()); - // Map memory buffers to a virtual file system + // Map memory buffers to a virtual file system - // Source file - MemFS->addFile( - optionsParser.getSourceName(), (time_t)0, - llvm::MemoryBuffer::getMemBuffer( + // Source file + MemFS->addFile( + optionsParser.getSourceName(), (time_t)0, + llvm::MemoryBuffer::getMemBuffer( llvm::StringRef(pszProgramSource), optionsParser.getSourceName())); - // Input header with OpenCL defines. - std::vector vHeaderWithDefs; - if (!GetHeaders(vHeaderWithDefs)) { - return CL_COMPILE_PROGRAM_FAILURE; - } + // Input header with OpenCL defines. + std::vector vHeaderWithDefs; + if (!GetHeaders(vHeaderWithDefs)) { + return CL_COMPILE_PROGRAM_FAILURE; + } - for (const auto &Header:vHeaderWithDefs) { - auto Buf = llvm::MemoryBuffer::getMemBuffer( - llvm::StringRef(Header.m_data, Header.m_size), - Header.m_name); + for (const auto &Header:vHeaderWithDefs) { + auto Buf = llvm::MemoryBuffer::getMemBuffer( + llvm::StringRef(Header.m_data, Header.m_size), + Header.m_name); - MemFS->addFile(Header.m_name,(time_t)0, std::move(Buf)); - } + MemFS->addFile(Header.m_name,(time_t)0, std::move(Buf)); + } - // Input Headers - for (unsigned int i = 0; i < uiNumInputHeaders; ++i) { - auto Header = llvm::MemoryBuffer::getMemBuffer( - pInputHeaders[i], pInputHeadersNames[i]); - MemFS->addFile(pInputHeadersNames[i], (time_t)0, std::move(Header)); + // Input Headers + for (unsigned int i = 0; i < uiNumInputHeaders; ++i) { + auto Header = llvm::MemoryBuffer::getMemBuffer( + pInputHeaders[i], pInputHeadersNames[i]); + MemFS->addFile(pInputHeadersNames[i], (time_t)0, std::move(Header)); + } } - - // Execute the frontend actions. bool success = false; try { success = clang::ExecuteCompilerInvocation(compiler.get()); } catch (const std::exception &) { } - pResult->setIRType(IR_TYPE_COMPILED_OBJECT); pResult->setIRName(optionsParser.getSourceName()); @@ -306,11 +303,11 @@ Compile(const char *pszProgramSource, const char **pInputHeaders, if (success && optionsParser.hasEmitSPIRV()) { // Translate LLVM IR to SPIR-V. llvm::StringRef LLVM_IR(static_cast(pResult->GetIR()), - pResult->GetIRSize()); + pResult->GetIRSize()); std::unique_ptr MB = llvm::MemoryBuffer::getMemBuffer(LLVM_IR, pResult->GetIRName(), false); llvm::LLVMContext Context; auto E = llvm::getOwningLazyBitcodeModule(std::move(MB), Context, - /*ShouldLazyLoadMetadata=*/true); + /*ShouldLazyLoadMetadata=*/true); llvm::logAllUnhandledErrors(E.takeError(), err_ostream, "error: "); std::unique_ptr M = std::move(*E); @@ -334,9 +331,11 @@ Compile(const char *pszProgramSource, const char **pInputHeaders, err_ostream << Err.c_str(); err_ostream.flush(); } - - if (pBinaryResult) { - *pBinaryResult = pResult.release(); + { + llvm::sys::SmartScopedLock compileGuard {*compileMutex}; + if (pBinaryResult) { + *pBinaryResult = pResult.release(); + } } return success ? CL_SUCCESS : CL_COMPILE_PROGRAM_FAILURE; } catch (std::bad_alloc &) {