summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2016-05-17 16:02:49 +0200
committerFrancisco Jerez <[email protected]>2016-07-11 20:22:50 -0700
commit3ce6ab068ced4341bbb404df12fb9bcca294e94c (patch)
tree6209f053c84025007202918c8067b5fd8a26f250 /src/gallium/state_trackers
parent7bcefa59031992a39ac997c2000dbad26153aed2 (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.hpp30
-rw-r--r--src/gallium/state_trackers/clover/llvm/invocation.cpp102
-rw-r--r--src/gallium/state_trackers/clover/llvm/util.hpp5
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("-")),