1 #ifndef CPPAD_CG_LLVM_MODEL_LIBRARY_PROCESSOR_INCLUDED 2 #define CPPAD_CG_LLVM_MODEL_LIBRARY_PROCESSOR_INCLUDED 18 #include <cppad/cg/model/llvm/llvm_base_model_library_processor.hpp> 29 class LlvmModelLibraryProcessor :
public LlvmBaseModelLibraryProcessor<Base> {
31 std::vector<std::string> _includePaths;
32 std::shared_ptr<llvm::LLVMContext> _context;
33 std::unique_ptr<llvm::Linker> _linker;
34 std::unique_ptr<llvm::Module> _module;
52 _includePaths = includePaths;
66 std::unique_ptr<LlvmModelLibrary<Base>>
create() {
70 _linker.reset(
nullptr);
72 this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
74 llvm::InitializeAllTargetMCs();
75 llvm::InitializeAllTargets();
76 llvm::InitializeAllAsmPrinters();
78 _context.reset(
new llvm::LLVMContext());
80 const std::map<std::string, ModelCSourceGen<Base>*>& models = this->modelLibraryHelper_->getModels();
81 for (
const auto& p : models) {
82 const std::map<std::string, std::string>& modelSources = this->getSources(*p.second);
83 createLlvmModules(modelSources);
86 const std::map<std::string, std::string>& sources = this->getLibrarySources();
87 createLlvmModules(sources);
89 const std::map<std::string, std::string>& customSource = this->modelLibraryHelper_->getCustomSources();
90 createLlvmModules(customSource);
92 llvm::InitializeNativeTarget();
96 this->modelLibraryHelper_->finishedJob();
107 using namespace llvm;
114 std::unique_ptr<LlvmModelLibrary<Base>> lib;
116 this->modelLibraryHelper_->startingJob(
"", JobTimer::JIT_MODEL_LIBRARY);
122 const std::set<std::string>& bcFiles = this->
createBitCode(clang,
"3.6");
127 llvm::InitializeAllTargets();
128 llvm::InitializeAllAsmPrinters();
130 _context.reset(
new llvm::LLVMContext());
132 std::unique_ptr<Module> linkerModule;
134 for (
const std::string& itbc : bcFiles) {
137 ErrorOr<std::unique_ptr<MemoryBuffer>> buffer = MemoryBuffer::getFile(itbc);
138 if (buffer.get() ==
nullptr) {
143 ErrorOr<Module*> module = llvm::parseBitcodeFile(buffer.get()->getMemBufferRef(), *_context.get());
144 if (module.get() ==
nullptr) {
149 if (_linker.get() ==
nullptr) {
150 linkerModule.reset(module.get());
151 _linker.reset(
new llvm::Linker(linkerModule.get()));
153 if (_linker->linkInModule(module.get())) {
159 llvm::InitializeNativeTarget();
170 this->modelLibraryHelper_->finishedJob();
182 virtual void createLlvmModules(
const std::map<std::string, std::string>& sources) {
183 for (
const auto& p : sources) {
184 createLlvmModule(p.first, p.second);
188 virtual void createLlvmModule(
const std::string& filename,
189 const std::string& source) {
190 using namespace llvm;
191 using namespace clang;
193 static const char* argv [] = {
"program",
"-Wall",
"-x",
"c",
"string-input"};
194 static const int argc =
sizeof (argv) /
sizeof (argv[0]);
196 IntrusiveRefCntPtr<DiagnosticOptions> diagOpts =
new DiagnosticOptions();
197 TextDiagnosticPrinter* diagClient =
new TextDiagnosticPrinter(llvm::errs(), &*diagOpts);
198 IntrusiveRefCntPtr<DiagnosticIDs> diagID(
new DiagnosticIDs());
199 IntrusiveRefCntPtr<DiagnosticsEngine> diags(
new DiagnosticsEngine(diagID, &*diagOpts, diagClient));
201 ArrayRef<const char*> args(argv + 1,
203 std::unique_ptr<CompilerInvocation> invocation(createInvocationFromCommandLine(args, diags));
204 if (invocation.get() ==
nullptr)
205 throw CGException(
"Failed to create compiler invocation");
206 CompilerInvocation::setLangDefaults(*invocation->getLangOpts(), IK_C,
207 LangStandard::lang_unspecified);
208 invocation->getFrontendOpts().DisableFree =
false;
211 CompilerInstance compiler;
212 compiler.setInvocation(invocation.release());
216 compiler.createDiagnostics();
217 if (!compiler.hasDiagnostics())
220 compiler.createFileManager();
221 compiler.createSourceManager(compiler.getFileManager());
222 std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>();
223 pto->Triple = llvm::sys::getDefaultTargetTriple();
224 clang::TargetInfo *pti = clang::TargetInfo::CreateTargetInfo(compiler.getDiagnostics(), pto);
225 compiler.setTarget(pti);
226 compiler.createPreprocessor(clang::TU_Complete);
230 std::unique_ptr<llvm::MemoryBuffer> buffer = llvm::MemoryBuffer::getMemBufferCopy(source,
"SIMPLE_BUFFER");
231 if (buffer.get() ==
nullptr)
232 throw CGException(
"Failed to create memory buffer");
235 PreprocessorOptions& po = compiler.getInvocation().getPreprocessorOpts();
236 po.addRemappedFile(
"string-input", buffer.release());
238 HeaderSearchOptions& hso = compiler.getInvocation().getHeaderSearchOpts();
239 std::string iClangHeaders = this->findInternalClangCHeaders(
"3.6", hso.ResourceDir);
240 if(!iClangHeaders.empty()) {
241 hso.AddPath(llvm::StringRef(iClangHeaders), clang::frontend::Angled,
false,
false);
244 for (
size_t s = 0; s < _includePaths.size(); s++)
245 hso.AddPath(llvm::StringRef(_includePaths[s]), clang::frontend::Angled,
false,
false);
248 clang::EmitLLVMOnlyAction action(_context.get());
249 if (!compiler.ExecuteAction(action))
252 std::unique_ptr<llvm::Module> module = action.takeModule();
253 if (module.get() ==
nullptr)
256 if (_linker.get() ==
nullptr) {
257 _module.reset(module.release());
258 _linker.reset(
new llvm::Linker(_module.get()));
260 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)