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>    30 class 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;
    62         _includePaths = includePaths;
    76     std::unique_ptr<LlvmModelLibrary<Base>> 
create() {
    78         llvm::sys::Path clangPath = llvm::sys::Program::FindProgramByName(
"clang");
    82         args.push_back(clangPath.c_str());
    83         args.push_back(inputPath.c_str());
    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());
    91         clang::DiagnosticsEngine Diags(DiagID, DiagClient);
    94         clang::driver::Driver TheDriver(args[0], llvm::sys::getDefaultTargetTriple(), outputPath, 
true, Diags);
    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();
   110         for (
const auto& p : models) {
   111             const std::map<std::string, std::string>& modelSources = this->getSources(*p.second);
   112             createLlvmModules(modelSources);
   115         const std::map<std::string, std::string>& sources = this->getLibrarySources();
   116         createLlvmModules(sources);
   118         const std::map<std::string, std::string>& customSource = this->modelLibraryHelper_->getCustomSources();
   119         createLlvmModules(customSource);
   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);
   151             const std::set<std::string>& bcFiles = this->
createBitCode(clang, 
"3.8");
   156             llvm::InitializeAllTargets();
   157             llvm::InitializeAllAsmPrinters();
   159             _context.reset(
new llvm::LLVMContext());
   161             std::unique_ptr<Module> linkerModule;
   163             for (
const std::string& itbc : bcFiles) {
   166                 ErrorOr<std::unique_ptr<MemoryBuffer>> buffer = MemoryBuffer::getFile(itbc);
   167                 if (buffer.get() == 
nullptr) {
   172                 ErrorOr<std::unique_ptr<Module>> module = llvm::parseBitcodeFile(buffer.get()->getMemBufferRef(), *_context.get());
   173                 if(module.get() == 
nullptr) {
   178                 if (_linker.get() == 
nullptr) {
   179                     linkerModule.reset(module.get().release());
   180                     _linker.reset(
new llvm::Linker(*linkerModule)); 
   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) {
   212         for (
const auto& p : 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())
   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))
   275         std::unique_ptr<llvm::Module> module = action.takeModule();
   276         if (module.get() == 
nullptr)
   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))) {
 
std::unique_ptr< LlvmModelLibrary< Base > > create()
std::unique_ptr< LlvmModelLibrary< Base > > create(ClangCompiler< Base > &clang)
const std::vector< std::string > & getIncludePaths() const
const std::set< std::string > & createBitCode(ClangCompiler< Base > &clang, const std::string &version)
void setIncludePaths(const std::vector< std::string > &includePaths)
LlvmModelLibraryProcessor(ModelLibraryCSourceGen< Base > &librarySourceGen)
const std::string & getVersion() const