Unverified Commit 5e80b771 authored by Robert Kimball's avatar Robert Kimball Committed by GitHub

Fix error where compiler's result is properly set to nullptr if compile fails (#375)

Add support for reinitializing the compiler if a compile fails, allowing subsequent compiles to succeed
parent 2775b0bf
...@@ -109,7 +109,7 @@ void Compiler::add_header_search_path(const std::string& path) ...@@ -109,7 +109,7 @@ void Compiler::add_header_search_path(const std::string& path)
std::unique_ptr<ngraph::codegen::Module> Compiler::compile(const std::string& source) std::unique_ptr<ngraph::codegen::Module> Compiler::compile(const std::string& source)
{ {
lock_guard<mutex> lock(m_mutex); lock_guard<mutex> lock(m_mutex);
return s_static_compiler.compile(compiler_action, source); return s_static_compiler.compile(m_compiler_action, source);
} }
static std::string GetExecutablePath(const char* Argv0) static std::string GetExecutablePath(const char* Argv0)
...@@ -125,6 +125,12 @@ StaticCompiler::StaticCompiler() ...@@ -125,6 +125,12 @@ StaticCompiler::StaticCompiler()
, m_debuginfo_enabled(false) , m_debuginfo_enabled(false)
, m_source_name("code.cpp") , m_source_name("code.cpp")
{ {
initialize();
}
void StaticCompiler::initialize()
{
m_extra_search_path_list.clear();
#if NGCPU_DEBUGINFO #if NGCPU_DEBUGINFO
m_debuginfo_enabled = true; m_debuginfo_enabled = true;
#endif #endif
...@@ -145,6 +151,7 @@ StaticCompiler::StaticCompiler() ...@@ -145,6 +151,7 @@ StaticCompiler::StaticCompiler()
// Prepare DiagnosticEngine // Prepare DiagnosticEngine
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
DiagOpts->ErrorLimit = 20;
TextDiagnosticPrinter* textDiagPrinter = new clang::TextDiagnosticPrinter(errs(), &*DiagOpts); TextDiagnosticPrinter* textDiagPrinter = new clang::TextDiagnosticPrinter(errs(), &*DiagOpts);
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
DiagnosticsEngine DiagEngine(DiagID, &*DiagOpts, textDiagPrinter); DiagnosticsEngine DiagEngine(DiagID, &*DiagOpts, textDiagPrinter);
...@@ -157,15 +164,6 @@ StaticCompiler::StaticCompiler() ...@@ -157,15 +164,6 @@ StaticCompiler::StaticCompiler()
CompilerInvocation::CreateFromArgs( CompilerInvocation::CreateFromArgs(
m_compiler->getInvocation(), &args[0], &args[0] + args.size(), DiagEngine); m_compiler->getInvocation(), &args[0], &args[0] + args.size(), DiagEngine);
// Infer the builtin include path if unspecified.
if (m_compiler->getHeaderSearchOpts().UseBuiltinIncludes &&
m_compiler->getHeaderSearchOpts().ResourceDir.empty())
{
void* MainAddr = reinterpret_cast<void*>(GetExecutablePath);
auto path = CompilerInvocation::GetResourcesPath(args[0], MainAddr);
m_compiler->getHeaderSearchOpts().ResourceDir = path;
}
configure_search_path(); configure_search_path();
// Language options // Language options
...@@ -248,9 +246,10 @@ void StaticCompiler::add_header_search_path(const string& path) ...@@ -248,9 +246,10 @@ void StaticCompiler::add_header_search_path(const string& path)
} }
std::unique_ptr<ngraph::codegen::Module> std::unique_ptr<ngraph::codegen::Module>
StaticCompiler::compile(std::unique_ptr<clang::CodeGenAction>& compiler_action, StaticCompiler::compile(std::unique_ptr<clang::CodeGenAction>& m_compiler_action,
const string& source) const string& source)
{ {
PreprocessorOptions& preprocessor_options = m_compiler->getInvocation().getPreprocessorOpts();
if (!m_precompiled_header_valid && m_precomiled_header_source.empty() == false) if (!m_precompiled_header_valid && m_precomiled_header_source.empty() == false)
{ {
generate_pch(m_precomiled_header_source); generate_pch(m_precomiled_header_source);
...@@ -258,40 +257,60 @@ std::unique_ptr<ngraph::codegen::Module> ...@@ -258,40 +257,60 @@ std::unique_ptr<ngraph::codegen::Module>
if (m_precompiled_header_valid) if (m_precompiled_header_valid)
{ {
// Preprocessor options // Preprocessor options
auto& PPO = m_compiler->getInvocation().getPreprocessorOpts(); preprocessor_options.ImplicitPCHInclude = m_pch_path;
PPO.ImplicitPCHInclude = m_pch_path; preprocessor_options.DisablePCHValidation = 0;
PPO.DisablePCHValidation = 0;
} }
// Map code filename to a memoryBuffer // Map code filename to a memoryBuffer
StringRef source_ref(source); StringRef source_ref(source);
unique_ptr<MemoryBuffer> buffer = MemoryBuffer::getMemBufferCopy(source_ref); unique_ptr<MemoryBuffer> buffer = MemoryBuffer::getMemBufferCopy(source_ref);
m_compiler->getInvocation().getPreprocessorOpts().addRemappedFile(m_source_name, buffer.get()); preprocessor_options.RemappedFileBuffers.push_back({m_source_name, buffer.get()});
// Create and execute action // Create and execute action
compiler_action.reset(new EmitCodeGenOnlyAction()); m_compiler_action.reset(new EmitCodeGenOnlyAction());
std::unique_ptr<llvm::Module> rc; std::unique_ptr<llvm::Module> rc;
if (m_compiler->ExecuteAction(*compiler_action) == true) bool reinitialize = false;
if (m_compiler->ExecuteAction(*m_compiler_action) == true)
{
rc = m_compiler_action->takeModule();
}
else
{ {
rc = compiler_action->takeModule(); reinitialize = true;
} }
buffer.release(); buffer.release();
m_compiler->getInvocation().getPreprocessorOpts().clearRemappedFiles(); preprocessor_options.RemappedFileBuffers.pop_back();
return unique_ptr<ngraph::codegen::Module>(new ngraph::codegen::Module(move(rc))); unique_ptr<ngraph::codegen::Module> result;
if (rc)
{
result = move(unique_ptr<ngraph::codegen::Module>(new ngraph::codegen::Module(move(rc))));
}
else
{
result = move(unique_ptr<ngraph::codegen::Module>(nullptr));
}
if (reinitialize)
{
StaticCompiler::initialize();
}
return result;
} }
void StaticCompiler::generate_pch(const string& source) void StaticCompiler::generate_pch(const string& source)
{ {
PreprocessorOptions& preprocessor_options = m_compiler->getInvocation().getPreprocessorOpts();
m_pch_path = file_util::tmp_filename(); m_pch_path = file_util::tmp_filename();
m_compiler->getFrontendOpts().OutputFile = m_pch_path; m_compiler->getFrontendOpts().OutputFile = m_pch_path;
// Map code filename to a memoryBuffer // Map code filename to a memoryBuffer
StringRef source_ref(source); StringRef source_ref(source);
unique_ptr<MemoryBuffer> buffer = MemoryBuffer::getMemBufferCopy(source_ref); unique_ptr<MemoryBuffer> buffer = MemoryBuffer::getMemBufferCopy(source_ref);
m_compiler->getInvocation().getPreprocessorOpts().addRemappedFile(m_source_name, buffer.get()); preprocessor_options.RemappedFileBuffers.push_back({m_source_name, buffer.get()});
// Create and execute action // Create and execute action
clang::GeneratePCHAction* compilerAction = new clang::GeneratePCHAction(); clang::GeneratePCHAction* compilerAction = new clang::GeneratePCHAction();
...@@ -301,15 +320,14 @@ void StaticCompiler::generate_pch(const string& source) ...@@ -301,15 +320,14 @@ void StaticCompiler::generate_pch(const string& source)
} }
buffer.release(); buffer.release();
preprocessor_options.RemappedFileBuffers.pop_back();
m_compiler->getInvocation().getPreprocessorOpts().clearRemappedFiles();
delete compilerAction; delete compilerAction;
} }
void StaticCompiler::configure_search_path() void StaticCompiler::configure_search_path()
{ {
#ifdef USE_BUILTIN #ifdef USE_BUILTIN
load_header_search_path_from_resource();
load_headers_from_resource(); load_headers_from_resource();
#else #else
// Add base toolchain-supplied header paths // Add base toolchain-supplied header paths
...@@ -361,33 +379,30 @@ void StaticCompiler::configure_search_path() ...@@ -361,33 +379,30 @@ void StaticCompiler::configure_search_path()
#endif #endif
} }
void StaticCompiler::load_header_search_path_from_resource() void StaticCompiler::load_headers_from_resource()
{ {
HeaderSearchOptions& hso = m_compiler->getInvocation().getHeaderSearchOpts(); HeaderSearchOptions& hso = m_compiler->getInvocation().getHeaderSearchOpts();
PreprocessorOptions& preprocessor_options = m_compiler->getInvocation().getPreprocessorOpts();
std::vector<std::string> header_search_paths; std::set<std::string> header_search_paths;
for (const HeaderInfo& hi : header_info) for (const HeaderInfo& hi : header_info)
{ {
string search_path = hi.search_path; string search_path = hi.search_path;
string absolute_path = file_util::path_join(search_path, hi.header_path);
string builtin = "/$builtin" + absolute_path;
std::unique_ptr<llvm::MemoryBuffer> mb(
llvm::MemoryBuffer::getMemBuffer(hi.header_data, builtin));
preprocessor_options.addRemappedFile(builtin, mb.release());
if (!contains(header_search_paths, search_path)) if (!contains(header_search_paths, search_path))
{ {
string builtin = "/$builtin" + search_path; string builtin = "/$builtin" + search_path;
hso.AddPath(builtin, clang::frontend::System, false, false); hso.AddPath(builtin, clang::frontend::System, false, false);
header_search_paths.push_back(search_path); header_search_paths.insert(search_path);
} }
} }
} }
void StaticCompiler::load_headers_from_resource() void StaticCompiler::set_precompiled_header_source(const std::string& source)
{ {
HeaderSearchOptions& hso = m_compiler->getInvocation().getHeaderSearchOpts(); m_precomiled_header_source = source;
for (const HeaderInfo& hi : header_info)
{
string search_path = hi.search_path;
string absolute_path = file_util::path_join(search_path, hi.header_path);
string builtin = "/$builtin" + absolute_path;
std::unique_ptr<llvm::MemoryBuffer> mb(
llvm::MemoryBuffer::getMemBuffer(hi.header_data, builtin));
m_compiler->getPreprocessorOpts().addRemappedFile(builtin, mb.release());
}
} }
...@@ -61,9 +61,9 @@ public: ...@@ -61,9 +61,9 @@ public:
void set_precompiled_header_source(const std::string& source); void set_precompiled_header_source(const std::string& source);
void add_header_search_path(const std::string& path); void add_header_search_path(const std::string& path);
std::unique_ptr<ngraph::codegen::Module> compile(const std::string& source); std::unique_ptr<ngraph::codegen::Module> compile(const std::string& source);
std::unique_ptr<clang::CodeGenAction>& get_compiler_action() { return compiler_action; } std::unique_ptr<clang::CodeGenAction>& get_compiler_action() { return m_compiler_action; }
private: private:
std::unique_ptr<clang::CodeGenAction> compiler_action; std::unique_ptr<clang::CodeGenAction> m_compiler_action;
}; };
class ngraph::codegen::StaticCompiler class ngraph::codegen::StaticCompiler
...@@ -74,15 +74,13 @@ public: ...@@ -74,15 +74,13 @@ public:
void set_debuginfo_enabled(bool state) { m_debuginfo_enabled = state; } void set_debuginfo_enabled(bool state) { m_debuginfo_enabled = state; }
bool is_debuginfo_enabled() { return m_debuginfo_enabled; } bool is_debuginfo_enabled() { return m_debuginfo_enabled; }
void set_precompiled_header_source(const std::string& source) void set_precompiled_header_source(const std::string& source);
{
m_precomiled_header_source = source;
}
void add_header_search_path(const std::string& path); void add_header_search_path(const std::string& path);
std::unique_ptr<ngraph::codegen::Module> std::unique_ptr<ngraph::codegen::Module>
compile(std::unique_ptr<clang::CodeGenAction>& compiler_action, const std::string& source); compile(std::unique_ptr<clang::CodeGenAction>& compiler_action, const std::string& source);
void generate_pch(const std::string& source); void generate_pch(const std::string& source);
void initialize();
private: private:
std::unique_ptr<clang::CompilerInstance> m_compiler; std::unique_ptr<clang::CompilerInstance> m_compiler;
...@@ -95,6 +93,5 @@ private: ...@@ -95,6 +93,5 @@ private:
bool is_version_number(const std::string& path); bool is_version_number(const std::string& path);
void configure_search_path(); void configure_search_path();
void load_header_search_path_from_resource();
void load_headers_from_resource(); void load_headers_from_resource();
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment