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::unique_ptr<llvm::Linker> _linker;
35 std::unique_ptr<llvm::LLVMContext> _context;
56 inline void setIncludePaths(
const std::vector<std::string>& includePaths) {
57 _includePaths = includePaths;
60 inline const std::vector<std::string>& getIncludePaths()
const {
64 std::unique_ptr<LlvmModelLibrary<Base>> create() {
70 this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
72 llvm::InitializeAllTargets();
73 llvm::InitializeAllAsmPrinters();
75 _context.reset(
new llvm::LLVMContext());
77 const std::map<std::string, ModelCSourceGen<Base>*>& models = this->modelLibraryHelper_->getModels();
78 for (
const auto& p : models) {
79 const std::map<std::string, std::string>& modelSources = this->getSources(*p.second);
80 createLlvmModules(modelSources);
83 const std::map<std::string, std::string>& sources = this->getLibrarySources();
84 createLlvmModules(sources);
86 const std::map<std::string, std::string>& customSource = this->modelLibraryHelper_->getCustomSources();
87 createLlvmModules(customSource);
89 llvm::InitializeNativeTarget();
91 std::unique_ptr<LlvmModelLibrary<Base>> lib (
new LlvmModelLibrary3_2<Base>(_linker->releaseModule(), _context.release()));
93 this->modelLibraryHelper_->finishedJob();
105 virtual void createLlvmModules(
const std::map<std::string, std::string>& sources) {
106 for (
const auto& p : sources) {
107 createLlvmModule(p.first, p.second);
111 virtual void createLlvmModule(
const std::string& filename,
112 const std::string& source) {
113 using namespace llvm;
114 using namespace clang;
116 static const char* argv [] = {
"program",
"-Wall",
"-x",
"c",
"string-input"};
117 static const int argc =
sizeof (argv) /
sizeof (argv[0]);
119 IntrusiveRefCntPtr<DiagnosticOptions> diagOpts =
new DiagnosticOptions();
120 TextDiagnosticPrinter *diagClient =
new TextDiagnosticPrinter(llvm::errs(), &*diagOpts);
121 IntrusiveRefCntPtr<DiagnosticIDs> diagID(
new DiagnosticIDs());
122 IntrusiveRefCntPtr<DiagnosticsEngine> diags(
new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
124 ArrayRef<const char *> args(argv + 1,
126 std::unique_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
127 if (invocation.get() ==
nullptr)
128 throw CGException(
"Failed to create compiler invocation");
129 CompilerInvocation::setLangDefaults(*invocation->getLangOpts(), IK_C,
130 LangStandard::lang_unspecified);
131 invocation->getFrontendOpts().DisableFree =
false;
134 CompilerInstance compiler;
135 compiler.setInvocation(invocation.release());
138 compiler.createDiagnostics(argc, const_cast<char**> (argv));
139 if (!compiler.hasDiagnostics())
143 llvm::MemoryBuffer * buffer = llvm::MemoryBuffer::getMemBufferCopy(source,
"SIMPLE_BUFFER");
144 if (buffer ==
nullptr)
145 throw CGException(
"Failed to create memory buffer");
148 PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
149 po.addRemappedFile(
"string-input", buffer);
151 HeaderSearchOptions& hso = compiler.getInvocation().getHeaderSearchOpts();
152 for (
size_t s = 0; s < _includePaths.size(); s++)
153 hso.AddPath(llvm::StringRef(_includePaths[s]), clang::frontend::Angled,
true,
false,
false);
156 OwningPtr<CodeGenAction> action(
new clang::EmitLLVMOnlyAction(_context.get()));
157 if (!compiler.ExecuteAction(*action))
160 llvm::Module* module = action->takeModule();
161 if (module ==
nullptr)
164 if (_linker.get() ==
nullptr) {
165 _linker.reset(
new llvm::Linker(std::string(
"MyLinker"), module));
167 std::string errorMsg;
168 if (_linker->LinkInModule(module, &errorMsg)) {
178 inline llvm::Module* mergeModules(
const std::vector<llvm::Module*>& modules) {
182 std::string progName(
"MyLinker");
183 std::unique_ptr<llvm::Linker> ld(
new llvm::Linker(progName, modules[0]));
185 for (
size_t m = 1; m < modules.size(); m++) {
186 std::string errorMsg;
187 if (ld->LinkInModule(modules[m], &errorMsg)) {
192 return ld->releaseModule();
LlvmModelLibraryProcessor(ModelLibraryCSourceGen< Base > &modelLibraryHelper)
const std::string & getVersion() const