Skip to content

Commit

Permalink
Released original compiler to lock only I/O relevant portions
Browse files Browse the repository at this point in the history
  • Loading branch information
yeonbok committed Mar 17, 2021
1 parent c2a27ea commit db7696e
Showing 1 changed file with 105 additions and 105 deletions.
210 changes: 105 additions & 105 deletions common_clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,142 +208,142 @@ Compile(const char *pszProgramSource, const char **pInputHeaders,
try {
std::unique_ptr<OCLFEBinaryResult> pResult(new OCLFEBinaryResult());

// LLVM doesn't guarantee thread safety,
// therefore we serialize execution of LLVM code.
llvm::sys::SmartScopedLock<true> compileGuard {*compileMutex};
// Create the clang compiler
std::unique_ptr<clang::CompilerInstance> 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<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
new clang::DiagnosticOptions());
DiagOpts->ShowPresumedLoc = true;
clang::TextDiagnosticPrinter *DiagsPrinter =
{
llvm::sys::SmartScopedLock<true> compileGuard {*compileMutex};

// Parse options
optionsParser.processOptions(pszOptions, pszOptionsEx);

// Prepare our diagnostic client.
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(
new clang::DiagnosticIDs());
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
new clang::DiagnosticOptions());
DiagOpts->ShowPresumedLoc = true;
clang::TextDiagnosticPrinter *DiagsPrinter =
new clang::TextDiagnosticPrinter(err_ostream, &*DiagOpts);
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> Diags(
new clang::DiagnosticsEngine(DiagID, &*DiagOpts, DiagsPrinter));

// Create the clang compiler
std::unique_ptr<clang::CompilerInstance> compiler(
new clang::CompilerInstance());
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> Diags(
new clang::DiagnosticsEngine(DiagID, &*DiagOpts, DiagsPrinter));

// Prepare output buffer
std::unique_ptr<llvm::raw_pwrite_stream>
// Prepare output buffer
std::unique_ptr<llvm::raw_pwrite_stream>
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<llvm::vfs::OverlayFileSystem> OverlayFS(
new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
new llvm::vfs::InMemoryFileSystem);
OverlayFS->pushOverlay(MemFS);
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS(
new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MemFS(
new llvm::vfs::InMemoryFileSystem);
OverlayFS->pushOverlay(MemFS);

compiler->createFileManager(OverlayFS);
compiler->createSourceManager(compiler->getFileManager());
compiler->createFileManager(OverlayFS);
compiler->createSourceManager(compiler->getFileManager());

// Create compiler invocation from user args before trickering with it
clang::CompilerInvocation::CreateFromArgs(compiler->getInvocation(),
optionsParser.beginArgs(),
optionsParser.endArgs(), *Diags);
// Create compiler invocation from user args before trickering with it
clang::CompilerInvocation::CreateFromArgs(compiler->getInvocation(),
optionsParser.beginArgs(),
optionsParser.endArgs(), *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<Resource> vHeaderWithDefs;
if (!GetHeaders(vHeaderWithDefs)) {
return CL_COMPILE_PROGRAM_FAILURE;
}
// Input header with OpenCL defines.
std::vector<Resource> 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 &) {
}
{
llvm::sys::SmartScopedLock<true> compileGuard {*compileMutex};
pResult->setIRType(IR_TYPE_COMPILED_OBJECT);
pResult->setIRName(optionsParser.getSourceName());

// Our error handler depends on the Diagnostics object, which we're
// potentially about to delete. Uninstall the handler now so that any
// later errors use the default handling behavior instead.
// (currently commented out since setting the llvm error handling in
// multi-threaded environment is unsupported)
// llvm::remove_fatal_error_handler();
err_ostream.flush();

pResult->setIRType(IR_TYPE_COMPILED_OBJECT);
pResult->setIRName(optionsParser.getSourceName());

// Our error handler depends on the Diagnostics object, which we're
// potentially about to delete. Uninstall the handler now so that any
// later errors use the default handling behavior instead.
// (currently commented out since setting the llvm error handling in
// multi-threaded environment is unsupported)
// llvm::remove_fatal_error_handler();
err_ostream.flush();

if (success && (optionsParser.hasEmitSPIRV() || optionsParser.hasEmitSPIRVText())) {
// Translate LLVM IR to SPIR-V.
if (optionsParser.hasEmitSPIRVText())
SPIRV::SPIRVUseTextFormat = true;
llvm::StringRef LLVM_IR(static_cast<const char*>(pResult->GetIR()),
pResult->GetIRSize());
std::unique_ptr<llvm::MemoryBuffer> MB = llvm::MemoryBuffer::getMemBuffer(LLVM_IR, pResult->GetIRName(), false);
llvm::LLVMContext Context;
auto E = llvm::getOwningLazyBitcodeModule(std::move(MB), Context,
/*ShouldLazyLoadMetadata=*/true);
llvm::logAllUnhandledErrors(E.takeError(), err_ostream, "error: ");
std::unique_ptr<llvm::Module> M = std::move(*E);

if (M->materializeAll()) {
if (pBinaryResult) {
*pBinaryResult = nullptr;
if (success && (optionsParser.hasEmitSPIRV() || optionsParser.hasEmitSPIRVText())) {
// Translate LLVM IR to SPIR-V.
if (optionsParser.hasEmitSPIRVText())
SPIRV::SPIRVUseTextFormat = true;
llvm::StringRef LLVM_IR(static_cast<const char*>(pResult->GetIR()),
pResult->GetIRSize());
std::unique_ptr<llvm::MemoryBuffer> MB = llvm::MemoryBuffer::getMemBuffer(LLVM_IR, pResult->GetIRName(), false);
llvm::LLVMContext Context;
auto E = llvm::getOwningLazyBitcodeModule(std::move(MB), Context,
/*ShouldLazyLoadMetadata=*/true);
llvm::logAllUnhandledErrors(E.takeError(), err_ostream, "error: ");
std::unique_ptr<llvm::Module> M = std::move(*E);

if (M->materializeAll()) {
if (pBinaryResult) {
*pBinaryResult = nullptr;
}
assert(!"Failed to read just compiled LLVM IR!");
return CL_COMPILE_PROGRAM_FAILURE;
}
assert(!"Failed to read just compiled LLVM IR!");
return CL_COMPILE_PROGRAM_FAILURE;
}
pResult->getIRBufferRef().clear();
SmallVectorBuffer StreamBuf(pResult->getIRBufferRef());
std::ostream OS(&StreamBuf);
std::string Err;
SPIRV::TranslatorOpts SPIRVOpts;
SPIRVOpts.enableAllExtensions();
if (!optionsParser.hasOptDisable()) {
SPIRVOpts.setMemToRegEnabled(true);
pResult->getIRBufferRef().clear();
SmallVectorBuffer StreamBuf(pResult->getIRBufferRef());
std::ostream OS(&StreamBuf);
std::string Err;
SPIRV::TranslatorOpts SPIRVOpts;
SPIRVOpts.enableAllExtensions();
if (!optionsParser.hasOptDisable()) {
SPIRVOpts.setMemToRegEnabled(true);
}
success = llvm::writeSpirv(M.get(), SPIRVOpts, OS, Err);
err_ostream << Err.c_str();
err_ostream.flush();
}
success = llvm::writeSpirv(M.get(), SPIRVOpts, OS, Err);
err_ostream << Err.c_str();
err_ostream.flush();
}

if (pBinaryResult) {
*pBinaryResult = pResult.release();
if (pBinaryResult) {
*pBinaryResult = pResult.release();
}
}
return success ? CL_SUCCESS : CL_COMPILE_PROGRAM_FAILURE;
} catch (std::bad_alloc &) {
Expand Down

0 comments on commit db7696e

Please sign in to comment.