1#ifndef CPPAD_CG_LLVM_MODEL_LIBRARY_PROCESSOR_INCLUDED
2#define CPPAD_CG_LLVM_MODEL_LIBRARY_PROCESSOR_INCLUDED
19#include <cppad/cg/model/llvm/llvm_base_model_library_processor.hpp>
30class LlvmModelLibraryProcessor :
public LlvmBaseModelLibraryProcessor<Base> {
32 const std::string _version;
33 std::vector<std::string> _includePaths;
34 std::shared_ptr<llvm::LLVMContext> _context;
35 std::unique_ptr<llvm::Linker> _linker;
36 std::unique_ptr<llvm::Module> _module;
76 std::unique_ptr<LlvmModelLibrary<Base>>
create() {
78 llvm::sys::Path
clangPath = llvm::sys::Program::FindProgramByName(
"clang");
85 args.push_back(
"curl");
89 clang::TextDiagnosticPrinter *
DiagClient =
new clang::TextDiagnosticPrinter(llvm::errs(), clang::DiagnosticOptions());
90 clang::IntrusiveRefCntPtr<clang::DiagnosticIDs>
DiagID(
new clang::DiagnosticIDs());
99 _linker.reset(
nullptr);
101 this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
103 llvm::InitializeAllTargetMCs();
104 llvm::InitializeAllTargets();
105 llvm::InitializeAllAsmPrinters();
107 _context.reset(
new llvm::LLVMContext());
109 const std::map<std::string, ModelCSourceGen<Base>*>&
models = this->modelLibraryHelper_->getModels();
111 const std::map<std::string, std::string>&
modelSources = this->getSources(*
p.second);
115 const std::map<std::string, std::string>&
sources = this->getLibrarySources();
118 const std::map<std::string, std::string>&
customSource = this->modelLibraryHelper_->getCustomSources();
121 llvm::InitializeNativeTarget();
125 this->modelLibraryHelper_->finishedJob();
136 using namespace llvm;
143 std::unique_ptr<LlvmModelLibrary<Base>>
lib;
145 this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
156 llvm::InitializeAllTargets();
157 llvm::InitializeAllAsmPrinters();
159 _context.reset(
new llvm::LLVMContext());
167 if (
buffer.get() ==
nullptr) {
173 if(
module.get() ==
nullptr) {
178 if (_linker.get() ==
nullptr) {
182 if (_linker->linkInModule(std::move(
module.get()))) {
188 llvm::InitializeNativeTarget();
199 this->modelLibraryHelper_->finishedJob();
211 virtual void createLlvmModules(
const std::map<std::string, std::string>&
sources) {
213 createLlvmModule(
p.first,
p.second);
217 virtual void createLlvmModule(
const std::string& filename,
218 const std::string& source) {
219 using namespace llvm;
220 using namespace clang;
222 ArrayRef<StringRef> paths;
223 llvm::sys::findProgramByName(
"clang", paths);
225 static const char* argv [] = {
"program",
"-Wall",
"-x",
"c",
"string-input"};
226 static const int argc =
sizeof (argv) /
sizeof (argv[0]);
228 IntrusiveRefCntPtr<DiagnosticOptions> diagOpts =
new DiagnosticOptions();
229 TextDiagnosticPrinter* diagClient =
new TextDiagnosticPrinter(llvm::errs(), &*diagOpts);
230 IntrusiveRefCntPtr<DiagnosticIDs> diagID(
new DiagnosticIDs());
231 IntrusiveRefCntPtr<DiagnosticsEngine> diags(
new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
233 ArrayRef<const char*> args(argv + 1,
235 std::unique_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
236 if (invocation.get() ==
nullptr)
237 throw CGException(
"Failed to create compiler invocation");
238 CompilerInvocation::setLangDefaults(*invocation->getLangOpts(), IK_C,
239 LangStandard::lang_unspecified);
240 invocation->getFrontendOpts().DisableFree =
false;
243 CompilerInstance compiler;
244 compiler.setInvocation(invocation.release());
248 compiler.createDiagnostics();
249 if (!compiler.hasDiagnostics())
250 throw CGException(
"No diagnostics");
253 std::unique_ptr<llvm::MemoryBuffer> buffer = llvm::MemoryBuffer::getMemBufferCopy(source,
"SIMPLE_BUFFER");
254 if (buffer.get() ==
nullptr)
255 throw CGException(
"Failed to create memory buffer");
258 PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
259 po.addRemappedFile(
"string-input", buffer.release());
261 HeaderSearchOptions& hso = compiler.getInvocation().getHeaderSearchOpts();
262 std::string iClangHeaders = this->findInternalClangCHeaders(
"3.8", hso.ResourceDir);
263 if(!iClangHeaders.empty()) {
264 hso.AddPath(llvm::StringRef(iClangHeaders), clang::frontend::Angled,
false,
false);
267 for (
size_t s = 0; s < _includePaths.size(); s++)
268 hso.AddPath(llvm::StringRef(_includePaths[s]), clang::frontend::Angled,
false,
false);
271 clang::EmitLLVMOnlyAction action(_context.get());
272 if (!compiler.ExecuteAction(action))
273 throw CGException(
"Failed to emit LLVM bitcode");
275 std::unique_ptr<llvm::Module>
module = action.takeModule();
276 if (module.get() ==
nullptr)
277 throw CGException(
"No module");
279 if (_linker.get() ==
nullptr) {
280 _module.reset(module.release());
281 _linker.reset(
new llvm::Linker(*_module.get()));
283 if (_linker->linkInModule(std::move(module))) {
284 throw CGException(
"LLVM failed to link module");
const std::set< std::string > & createBitCode(ClangCompiler< Base > &clang, const std::string &version)
std::unique_ptr< LlvmModelLibrary< Base > > create(ClangCompiler< Base > &clang)
const std::string & getVersion() const
void setIncludePaths(const std::vector< std::string > &includePaths)
std::unique_ptr< LlvmModelLibrary< Base > > create()
const std::vector< std::string > & getIncludePaths() const
LlvmModelLibraryProcessor(ModelLibraryCSourceGen< Base > &librarySourceGen)