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;
    61         _includePaths = includePaths;
    75     std::unique_ptr<LlvmModelLibrary<Base>> 
create() {
    79         _linker.reset(
nullptr);
    81         this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
    83         llvm::InitializeAllTargetMCs();
    84         llvm::InitializeAllTargets();
    85         llvm::InitializeAllAsmPrinters();
    87         _context.reset(
new llvm::LLVMContext());
    89         const std::map<std::string, ModelCSourceGen<Base>*>& models = this->modelLibraryHelper_->getModels();
    90         for (
const auto& p : models) {
    91             const std::map<std::string, std::string>& modelSources = this->getSources(*p.second);
    92             createLlvmModules(modelSources);
    95         const std::map<std::string, std::string>& sources = this->getLibrarySources();
    96         createLlvmModules(sources);
    98         const std::map<std::string, std::string>& customSource = this->modelLibraryHelper_->getCustomSources();
    99         createLlvmModules(customSource);
   101         llvm::InitializeNativeTarget();
   105         this->modelLibraryHelper_->finishedJob();
   116         using namespace llvm;
   123         std::unique_ptr<LlvmModelLibrary<Base>> lib;
   125         this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
   131             const std::set<std::string>& bcFiles = this->
createBitCode(clang, 
"3.6");
   136             llvm::InitializeAllTargets();
   137             llvm::InitializeAllAsmPrinters();
   139             _context.reset(
new llvm::LLVMContext());
   141             std::unique_ptr<Module> linkerModule;
   143             for (
const std::string& itbc : bcFiles) {
   146                 ErrorOr<std::unique_ptr<MemoryBuffer>> buffer = MemoryBuffer::getFile(itbc);
   147                 if (buffer.get() == 
nullptr) {
   152                 ErrorOr<Module*> module = llvm::parseBitcodeFile(buffer.get()->getMemBufferRef(), *_context.get());
   153                 if (module.get() == 
nullptr) {
   158                 if (_linker.get() == 
nullptr) {
   159                     linkerModule.reset(module.get());
   160                     _linker.reset(
new llvm::Linker(linkerModule.get())); 
   162                     if (_linker->linkInModule(module.get())) { 
   168             llvm::InitializeNativeTarget();
   179         this->modelLibraryHelper_->finishedJob();
   191     virtual void createLlvmModules(
const std::map<std::string, std::string>& sources) {
   192         for (
const auto& p : sources) {
   193             createLlvmModule(p.first, p.second);
   197     virtual void createLlvmModule(
const std::string& filename,
   198                                   const std::string& source) {
   199         using namespace llvm;
   200         using namespace clang;
   202         static const char* argv [] = {
"program", 
"-Wall", 
"-x", 
"c", 
"string-input"};  
   203         static const int argc = 
sizeof (argv) / 
sizeof (argv[0]);
   205         IntrusiveRefCntPtr<DiagnosticOptions> diagOpts = 
new DiagnosticOptions();
   206         TextDiagnosticPrinter* diagClient = 
new TextDiagnosticPrinter(llvm::errs(), &*diagOpts); 
   207         IntrusiveRefCntPtr<DiagnosticIDs> diagID(
new DiagnosticIDs());
   208         IntrusiveRefCntPtr<DiagnosticsEngine> diags(
new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
   210         ArrayRef<const char*> args(argv + 1, 
   212         std::unique_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
   213         if (invocation.get() == 
nullptr)
   214             throw CGException(
"Failed to create compiler invocation");
   215         CompilerInvocation::setLangDefaults(*invocation->getLangOpts(), IK_C,
   216                                             LangStandard::lang_unspecified);
   217         invocation->getFrontendOpts().DisableFree = 
false; 
   220         CompilerInstance compiler;
   221         compiler.setInvocation(invocation.release());
   225         compiler.createDiagnostics(); 
   226         if (!compiler.hasDiagnostics())
   229         compiler.createFileManager();
   230         compiler.createSourceManager(compiler.getFileManager());
   231         std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>();
   232         pto->Triple = llvm::sys::getDefaultTargetTriple();
   233         clang::TargetInfo *pti = clang::TargetInfo::CreateTargetInfo(compiler.getDiagnostics(), pto);
   234         compiler.setTarget(pti);
   235         compiler.createPreprocessor(clang::TU_Complete);
   239         std::unique_ptr<llvm::MemoryBuffer> buffer = llvm::MemoryBuffer::getMemBufferCopy(source, 
"SIMPLE_BUFFER");
   240         if (buffer.get() == 
nullptr)
   241             throw CGException(
"Failed to create memory buffer");
   244         PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
   245         po.addRemappedFile(
"string-input", buffer.release());
   247         HeaderSearchOptions& hso = compiler.getInvocation().getHeaderSearchOpts();
   248         std::string iClangHeaders = this->findInternalClangCHeaders(
"3.6", hso.ResourceDir);
   249         if(!iClangHeaders.empty()) {
   250             hso.AddPath(llvm::StringRef(iClangHeaders), clang::frontend::Angled, 
false, 
false);
   253         for (
size_t s = 0; s < _includePaths.size(); s++)
   254             hso.AddPath(llvm::StringRef(_includePaths[s]), clang::frontend::Angled, 
false, 
false);
   257         clang::EmitLLVMOnlyAction action(_context.get());
   258         if (!compiler.ExecuteAction(action))
   261         std::unique_ptr<llvm::Module> module = action.takeModule();
   262         if (module.get() == 
nullptr)
   265         if (_linker.get() == 
nullptr) {
   266             _module.reset(module.release());
   267             _linker.reset(
new llvm::Linker(_module.get()));
   269             if (_linker->linkInModule(module.release())) {
 
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