diff options
author | Francisco Jerez <[email protected]> | 2016-05-17 16:02:49 +0200 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2016-07-11 20:22:50 -0700 |
commit | 3ce6ab068ced4341bbb404df12fb9bcca294e94c (patch) | |
tree | 6209f053c84025007202918c8067b5fd8a26f250 /src/gallium/state_trackers | |
parent | 7bcefa59031992a39ac997c2000dbad26153aed2 (diff) |
clover/llvm: Clean up compile_native().
This switches compile_native() to the C++ API (which the rest of this
file makes use of anyway so there is little benefit from using the C
API), what should get rid of an amount of boilerplate and fix a leak
of the TargetMachine object in the error path.
v2: Additional fixes for LLVM 3.6.
v3: Update for the latest LLVM SVN changes.
Reviewed-by: Serge Martin <[email protected]>
Tested-by: Jan Vesely <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r-- | src/gallium/state_trackers/clover/llvm/compat.hpp | 30 | ||||
-rw-r--r-- | src/gallium/state_trackers/clover/llvm/invocation.cpp | 102 | ||||
-rw-r--r-- | src/gallium/state_trackers/clover/llvm/util.hpp | 5 |
3 files changed, 74 insertions, 63 deletions
diff --git a/src/gallium/state_trackers/clover/llvm/compat.hpp b/src/gallium/state_trackers/clover/llvm/compat.hpp index 3206f77c6cc..82dd649837c 100644 --- a/src/gallium/state_trackers/clover/llvm/compat.hpp +++ b/src/gallium/state_trackers/clover/llvm/compat.hpp @@ -38,6 +38,7 @@ #include <llvm/Linker/Linker.h> #include <llvm/Transforms/IPO.h> +#include <llvm/Target/TargetMachine.h> #if HAVE_LLVM >= 0x0307 #include <llvm/IR/LegacyPassManager.h> @@ -45,6 +46,8 @@ #else #include <llvm/PassManager.h> #include <llvm/Target/TargetLibraryInfo.h> +#include <llvm/Target/TargetSubtargetInfo.h> +#include <llvm/Support/FormattedStream.h> #endif #include <clang/Frontend/CodeGenOptions.h> @@ -109,6 +112,33 @@ namespace clover { map(std::mem_fn(&std::string::data), names)))); #endif } + +#if HAVE_LLVM >= 0x0307 + typedef ::llvm::raw_svector_ostream &raw_ostream_to_emit_file; +#else + typedef ::llvm::formatted_raw_ostream raw_ostream_to_emit_file; +#endif + +#if HAVE_LLVM >= 0x0307 + typedef ::llvm::DataLayout data_layout; +#else + typedef const ::llvm::DataLayout *data_layout; +#endif + + inline data_layout + get_data_layout(::llvm::TargetMachine &tm) { +#if HAVE_LLVM >= 0x0307 + return tm.createDataLayout(); +#else + return tm.getSubtargetImpl()->getDataLayout(); +#endif + } + +#if HAVE_LLVM >= 0x0309 + const auto default_reloc_model = ::llvm::None; +#else + const auto default_reloc_model = ::llvm::Reloc::Default; +#endif } } } diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp index 9612216c418..1e4bed81270 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -81,6 +81,7 @@ using ::llvm::Function; using ::llvm::LLVMContext; using ::llvm::Module; using ::llvm::raw_string_ostream; +using ::llvm::TargetMachine; namespace { // XXX - Temporary hack to avoid breaking the build for the moment, will @@ -542,80 +543,55 @@ namespace { return m; } - void - emit_code(LLVMTargetMachineRef tm, LLVMModuleRef mod, - LLVMCodeGenFileType file_type, - LLVMMemoryBufferRef *out_buffer, + std::vector<char> + emit_code(::llvm::Module &mod, const target &target, + TargetMachine::CodeGenFileType ft, std::string &r_log) { - char *err_message = NULL; + std::string err; + auto t = ::llvm::TargetRegistry::lookupTarget(target.triple, err); + if (!t) + fail(r_log, compile_error(), err); + + std::unique_ptr<TargetMachine> tm { + t->createTargetMachine(target.triple, target.cpu, "", {}, + compat::default_reloc_model, + ::llvm::CodeModel::Default, + ::llvm::CodeGenOpt::Default) }; + if (!tm) + fail(r_log, compile_error(), + "Could not create TargetMachine: " + target.triple); - try { - if (LLVMTargetMachineEmitToMemoryBuffer(tm, mod, file_type, - &err_message, out_buffer)) - fail(r_log, compile_error(), err_message); + ::llvm::SmallVector<char, 1024> data; - } catch (...) { - LLVMDisposeMessage(err_message); - throw; - } - } + { + compat::pass_manager pm; + ::llvm::raw_svector_ostream os { data }; + compat::raw_ostream_to_emit_file fos { os }; - std::vector<char> - compile_native(const llvm::Module *mod, const target &t, - std::string &r_log) { + mod.setDataLayout(compat::get_data_layout(*tm)); + tm->Options.MCOptions.AsmVerbose = + (ft == TargetMachine::CGFT_AssemblyFile); - std::string log; - LLVMTargetRef target; - char *error_message; - LLVMMemoryBufferRef out_buffer; - unsigned buffer_size; - const char *buffer_data; - LLVMModuleRef mod_ref = wrap(mod); - - try { - if (LLVMGetTargetFromTriple(t.triple.c_str(), &target, &error_message)) - fail(r_log, compile_error(), error_message); - - } catch (...) { - LLVMDisposeMessage(error_message); - throw; + if (tm->addPassesToEmitFile(pm, fos, ft)) + fail(r_log, compile_error(), "TargetMachine can't emit this file"); + + pm.run(mod); } - LLVMTargetMachineRef tm = LLVMCreateTargetMachine( - target, t.triple.c_str(), t.cpu.c_str(), "", - LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault); - if (!tm) - fail(r_log, compile_error(), - "Could not create TargetMachine: " + t.triple); + return { data.begin(), data.end() }; + } + std::vector<char> + compile_native(llvm::Module *mod, const target &target, + std::string &r_log) { if (has_flag(debug::native)) { - LLVMSetTargetMachineAsmVerbosity(tm, true); -#if HAVE_LLVM >= 0x0308 - LLVMModuleRef debug_mod = wrap(llvm::CloneModule(mod).release()); -#else - LLVMModuleRef debug_mod = wrap(llvm::CloneModule(mod)); -#endif - emit_code(tm, debug_mod, LLVMAssemblyFile, &out_buffer, r_log); - buffer_size = LLVMGetBufferSize(out_buffer); - buffer_data = LLVMGetBufferStart(out_buffer); - debug::log(".asm", std::string(buffer_data, buffer_size)); - - LLVMSetTargetMachineAsmVerbosity(tm, false); - LLVMDisposeMemoryBuffer(out_buffer); - LLVMDisposeModule(debug_mod); + std::unique_ptr<llvm::Module> cmod { CloneModule(mod) }; + debug::log(".asm", as_string( + emit_code(*cmod, target, + TargetMachine::CGFT_AssemblyFile, r_log))); } - emit_code(tm, mod_ref, LLVMObjectFile, &out_buffer, r_log); - - buffer_size = LLVMGetBufferSize(out_buffer); - buffer_data = LLVMGetBufferStart(out_buffer); - - std::vector<char> code(buffer_data, buffer_data + buffer_size); - - LLVMDisposeMemoryBuffer(out_buffer); - LLVMDisposeTargetMachine(tm); - - return code; + return emit_code(*mod, target, TargetMachine::CGFT_ObjectFile, r_log); } namespace elf { diff --git a/src/gallium/state_trackers/clover/llvm/util.hpp b/src/gallium/state_trackers/clover/llvm/util.hpp index f9a057d878c..8db6f20e5a7 100644 --- a/src/gallium/state_trackers/clover/llvm/util.hpp +++ b/src/gallium/state_trackers/clover/llvm/util.hpp @@ -51,6 +51,11 @@ namespace clover { return ss; } + inline std::string + as_string(const std::vector<char> &v) { + return { v.begin(), v.end() }; + } + struct target { target(const std::string &s) : cpu(s.begin(), s.begin() + s.find_first_of("-")), |