1 #ifndef CPPAD_CG_LLVM_BASE_MODEL_LIBRARY_PROCESSOR_IMPL_INCLUDED     2 #define CPPAD_CG_LLVM_BASE_MODEL_LIBRARY_PROCESSOR_IMPL_INCLUDED    19 #include <cppad/cg/model/llvm/llvm_base_model_library_processor.hpp>    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;
    45                                       std::string version) :
    47             _version(
std::move(version)) {
    63         _includePaths = includePaths;
    77     std::unique_ptr<LlvmModelLibrary<Base>> 
create() {
    81         _linker.reset(
nullptr);
    83         this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
    85         llvm::InitializeAllTargetMCs();
    86         llvm::InitializeAllTargets();
    87         llvm::InitializeAllAsmPrinters();
    89         _context.reset(
new llvm::LLVMContext());
    91         const std::map<std::string, ModelCSourceGen<Base>*>& models = this->modelLibraryHelper_->getModels();
    92         for (
const auto& p : models) {
    93             const std::map<std::string, std::string>& modelSources = this->getSources(*p.second);
    94             createLlvmModules(modelSources);
    97         const std::map<std::string, std::string>& sources = this->getLibrarySources();
    98         createLlvmModules(sources);
   100         const std::map<std::string, std::string>& customSource = this->modelLibraryHelper_->getCustomSources();
   101         createLlvmModules(customSource);
   103         llvm::InitializeNativeTarget();
   107         this->modelLibraryHelper_->finishedJob();
   120         using namespace llvm;
   127         std::unique_ptr<LlvmModelLibrary<Base>> lib;
   129         this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
   135             const std::set<std::string>& bcFiles = this->
createBitCode(clang, _version);
   140             llvm::InitializeAllTargets();
   141             llvm::InitializeAllAsmPrinters();
   143             _context.reset(
new llvm::LLVMContext());
   145             std::unique_ptr<Module> linkerModule;
   147             for (
const std::string& itbc : bcFiles) {
   150                 ErrorOr<std::unique_ptr<MemoryBuffer>> buffer = MemoryBuffer::getFile(itbc);
   151                 if (buffer.get() == 
nullptr) {
   156                 Expected<std::unique_ptr<Module>> moduleOrError = llvm::parseBitcodeFile(buffer.get()->getMemBufferRef(), *_context.get());
   157                 if (!moduleOrError) {
   158                     std::ostringstream error;
   160                     handleAllErrors(moduleOrError.takeError(), [&](ErrorInfoBase& eib) {
   161                         if (nError > 0) error << 
"; ";
   162                         error << eib.message();
   169                 if (_linker.get() == 
nullptr) {
   170                     linkerModule = std::move(moduleOrError.get());
   171                     _linker.reset(
new llvm::Linker(*linkerModule)); 
   173                     if (_linker->linkInModule(std::move(moduleOrError.get()))) { 
   179             llvm::InitializeNativeTarget();
   190         this->modelLibraryHelper_->finishedJob();
   197     virtual void createLlvmModules(
const std::map<std::string, std::string>& sources) {
   198         for (
const auto& p : sources) {
   199             createLlvmModule(p.first, p.second);
   203     virtual void createLlvmModule(
const std::string& filename,
   204                                   const std::string& source) {
   205         using namespace llvm;
   206         using namespace clang;
   208         ArrayRef<StringRef> paths;
   209         llvm::sys::findProgramByName(
"clang", paths);
   211         IntrusiveRefCntPtr<DiagnosticOptions> diagOpts = 
new DiagnosticOptions();
   212         auto* diagClient = 
new TextDiagnosticPrinter(llvm::errs(), &*diagOpts); 
   213         IntrusiveRefCntPtr<DiagnosticIDs> diagID(
new DiagnosticIDs());
   214         IntrusiveRefCntPtr<DiagnosticsEngine> diags(
new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
   216         std::vector<const char*> args {
"-Wall", 
"-x", 
"c", 
"string-input"}; 
   217         std::shared_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
   218         if (invocation == 
nullptr)
   219             throw CGException(
"Failed to create compiler invocation");
   223         CompilerInvocation::setLangDefaults(*invocation->getLangOpts(),
   224 #if LLVM_VERSION_MAJOR >= 10   225                                             InputKind(clang::Language::C),
   229                                             llvm::Triple(invocation->TargetOpts->Triple),
   230                                             invocation->getPreprocessorOpts(),
   231                                             LangStandard::lang_unspecified);
   232         invocation->getFrontendOpts().DisableFree = 
false; 
   235         CompilerInstance compiler;
   236         compiler.setInvocation(invocation);
   240         compiler.createDiagnostics(); 
   241         if (!compiler.hasDiagnostics())
   245         std::unique_ptr<llvm::MemoryBuffer> buffer = llvm::MemoryBuffer::getMemBufferCopy(source, 
"SIMPLE_BUFFER");
   246         if (buffer == 
nullptr)
   247             throw CGException(
"Failed to create memory buffer");
   250         PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
   251         po.addRemappedFile(
"string-input", buffer.release());
   253         HeaderSearchOptions& hso = compiler.getInvocation().getHeaderSearchOpts();
   254         std::string iClangHeaders = this->findInternalClangCHeaders(_version, hso.ResourceDir);
   255         if(!iClangHeaders.empty()) {
   256             hso.AddPath(llvm::StringRef(iClangHeaders), clang::frontend::Angled, 
false, 
false);
   259         for (
size_t s = 0; s < _includePaths.size(); s++)
   260             hso.AddPath(llvm::StringRef(_includePaths[s]), clang::frontend::Angled, 
false, 
false);
   263         clang::EmitLLVMOnlyAction action(_context.get());
   264         if (!compiler.ExecuteAction(action))
   267         std::unique_ptr<llvm::Module> module = action.takeModule();
   268         if (module == 
nullptr)
   271         if (_linker == 
nullptr) {
   272             _module = std::move(module);
   273             _linker.reset(
new llvm::Linker(*_module.get()));
   275             if (_linker->linkInModule(std::move(module))) {
 void setIncludePaths(const std::vector< std::string > &includePaths)
const std::vector< std::string > & getIncludePaths() const
const std::set< std::string > & createBitCode(ClangCompiler< Base > &clang, const std::string &version)
LlvmBaseModelLibraryProcessorImpl(ModelLibraryCSourceGen< Base > &librarySourceGen, std::string version)
std::unique_ptr< LlvmModelLibrary< Base > > create()
const std::string & getVersion() const
std::unique_ptr< LlvmModelLibrary< Base > > create(ClangCompiler< Base > &clang)