impala-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tarmstr...@apache.org
Subject [46/50] [abbrv] incubator-impala git commit: IMPALA-3166: basic perf support and asm dumps for codegened code
Date Thu, 12 May 2016 22:10:21 GMT
IMPALA-3166: basic perf support and asm dumps for codegened code

Adds support for communicating function-level symbols to perf by writing
/tmp/perf-<pid>.data if the --perf_map=true argument is set. Perf must
be run under the same user as Impala. I.e. 'sudo perf top' does not
work. To get perf to work under a non-root user you will probably need
to disable some kernel security features that perf complains about:

sudo bash -c 'echo -1 > /proc/sys/kernel/perf_event_paranoid'
sudo bash -c 'echo 0 > /proc/sys/kernel/kptr_restrict'

Once you get it working you should see IR function names concatenated with
the fragment instance id in 'perf top'. 'perf annotate' does not work.

Implements --asm_module_dir, analogous to --opt_module_dir. We dump
disassembly to files there. Debug symbols are interleaved with the
assembly if they are available. I enabled them for the debug
build, now that we have some purpose for them.  In some cases
it would be useful to have them for the release build, but
they make the llvm module much larger so I haven't enabled them
there.

The asm dump for a random exception constructor looks like this:

Disassembly for __cxx_global_var_init.165:324bc8754182e7c6:22735c36d7a2bc0 (0x7f50f2140300):
        date_facet.hpp:date_facet.hpp:<invalid>:363:0
        date_facet.hpp:date_facet.hpp:<invalid>:363:58
0:              movabsq $0, %rax
10:             movb    (%rax), %cl
12:             cmpb    $0, %cl
15:             jne     17
        date_facet.hpp:date_facet.hpp:<invalid>:363:58
17:             movabsq $0, %rax
27:             movq    $1, (%rax)
        date_facet.hpp:date_facet.hpp:<invalid>:363:58
34:             retq

Change-Id: If25de61e46f4db005956686cddbd4d71a1424528
Reviewed-on: http://gerrit.cloudera.org:8080/2793
Reviewed-by: Tim Armstrong <tarmstrong@cloudera.com>
Tested-by: Internal Jenkins


Project: http://git-wip-us.apache.org/repos/asf/incubator-impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-impala/commit/1c704f3c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-impala/tree/1c704f3c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-impala/diff/1c704f3c

Branch: refs/heads/master
Commit: 1c704f3cfd79614d9b98e2c8bbbb002e932201b5
Parents: 8e8df2f
Author: Tim Armstrong <tarmstrong@cloudera.com>
Authored: Sun Feb 28 19:29:00 2016 -0800
Committer: Tim Armstrong <tarmstrong@cloudera.com>
Committed: Thu May 12 14:18:03 2016 -0700

----------------------------------------------------------------------
 be/CMakeLists.txt                        |   6 +
 be/src/codegen/CMakeLists.txt            |   1 +
 be/src/codegen/codegen-symbol-emitter.cc | 206 ++++++++++++++++++++++++++
 be/src/codegen/codegen-symbol-emitter.h  | 104 +++++++++++++
 be/src/codegen/llvm-codegen.cc           |  27 ++++
 be/src/codegen/llvm-codegen.h            |  12 +-
 cmake_modules/FindLlvm.cmake             |   2 +-
 7 files changed, 356 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/1c704f3c/be/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/be/CMakeLists.txt b/be/CMakeLists.txt
index bb90e20..6ae5cd8 100644
--- a/be/CMakeLists.txt
+++ b/be/CMakeLists.txt
@@ -150,6 +150,12 @@ if (IMPALA_TOOLCHAIN)
   # -Werror: compile warnings should be errors when using the toolchain compiler.
   SET(CLANG_IR_CXX_FLAGS "${CLANG_IR_CXX_FLAGS}" "-Werror")
 endif()
+if ("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
+  # -g: emit debug symbols in IR. These increase IR size, but are useful for debugging
+  #     codegened code and interpreting codegen disassembly dumps. In some cases (e.g.
+  #     reading optimised disassembly, it would be useful to have in the release build.
+  SET(CLANG_IR_CXX_FLAGS "${CLANG_IR_CXX_FLAGS}" "-g")
+endif()
 
 # Flags to pass to LLVM's opt to further optimize cross-compiled IR.
 #  -inline: inline with low threshold to get rid of trivial accessor functions.

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/1c704f3c/be/src/codegen/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/be/src/codegen/CMakeLists.txt b/be/src/codegen/CMakeLists.txt
index cdc1b66..b5dbd88 100644
--- a/be/src/codegen/CMakeLists.txt
+++ b/be/src/codegen/CMakeLists.txt
@@ -25,6 +25,7 @@ set(IR_NO_SSE_C_FILE $ENV{IMPALA_HOME}/be/generated-sources/impala-ir/impala-no-
 
 add_library(CodeGen
   codegen-anyval.cc
+  codegen-symbol-emitter.cc
   llvm-codegen.cc
   instruction-counter.cc
   ${IR_SSE_C_FILE}

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/1c704f3c/be/src/codegen/codegen-symbol-emitter.cc
----------------------------------------------------------------------
diff --git a/be/src/codegen/codegen-symbol-emitter.cc b/be/src/codegen/codegen-symbol-emitter.cc
new file mode 100644
index 0000000..7a939af
--- /dev/null
+++ b/be/src/codegen/codegen-symbol-emitter.cc
@@ -0,0 +1,206 @@
+// Copyright 2016 Cloudera Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "codegen/codegen-symbol-emitter.h"
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread/locks.hpp>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <llvm/CodeGen/MachineFunction.h>
+#include <llvm/DebugInfo/DIContext.h>
+#include <llvm/DebugInfo/DWARF/DWARFContext.h>
+#include <llvm/IR/DebugInfo.h>
+#include <llvm/IR/Function.h>
+#include <llvm/Object/SymbolSize.h>
+#include <llvm/Support/Debug.h>
+#include "llvm/Support/raw_ostream.h"
+#include <llvm-c/Disassembler.h>
+#include <unistd.h>
+
+#include "common/logging.h"
+#include "gutil/strings/substitute.h"
+#include "util/error-util.h"
+
+#include "common/names.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using std::fstream;
+using std::hex;
+using std::ofstream;
+using std::rename;
+using std::unique_ptr;
+using strings::Substitute;
+
+namespace impala {
+
+SpinLock CodegenSymbolEmitter::perf_map_lock_;
+unordered_map<const void*, vector<CodegenSymbolEmitter::PerfMapEntry>>
+    CodegenSymbolEmitter::perf_map_;
+
+void CodegenSymbolEmitter::NotifyObjectEmitted(const ObjectFile &obj,
+   const RuntimeDyld::LoadedObjectInfo &loaded_obj) {
+  vector<PerfMapEntry> perf_map_entries;
+
+  ofstream asm_file;
+  if (!asm_path_.empty()) {
+    asm_file.open(asm_path_, fstream::out | fstream::trunc);
+    if (asm_file.fail()) {
+      // Log error and continue if we can't write the disassembly to a file. Note that
+      // fstream operations don't throw exceptions by default unless configured to do so.
+      LOG(ERROR) << "Could not save disassembly to: " << asm_file;
+    }
+  }
+
+  OwningBinary<ObjectFile> debug_obj_owner = loaded_obj.getObjectForDebug(obj);
+  const ObjectFile &debug_obj = *debug_obj_owner.getBinary();
+  DWARFContextInMemory dwarf_ctx(debug_obj);
+
+  // Use symbol info to iterate functions in the object.
+  for (const std::pair<SymbolRef, uint64_t> &pair: computeSymbolSizes(debug_obj))
{
+    ProcessSymbol(&dwarf_ctx, pair.first, pair.second, &perf_map_entries, asm_file);
+  }
+
+  if (asm_file.is_open()) asm_file.close();
+
+  ofstream perf_map_file;
+  if (emit_perf_map_) {
+    lock_guard<SpinLock> perf_map_lock(perf_map_lock_);
+    DCHECK(perf_map_.find(obj.getData().data()) == perf_map_.end());
+    perf_map_[obj.getData().data()] = std::move(perf_map_entries);
+    WritePerfMapLocked();
+  }
+}
+
+void CodegenSymbolEmitter::NotifyFreeingObject(const ObjectFile &obj) {
+  lock_guard<SpinLock> perf_map_lock(perf_map_lock_);
+  DCHECK(perf_map_.find(obj.getData().data()) != perf_map_.end());
+  perf_map_.erase(obj.getData().data());
+  WritePerfMapLocked();
+}
+
+void CodegenSymbolEmitter::ProcessSymbol(DIContext* debug_ctx,
+    const SymbolRef& symbol, uint64_t size, vector<PerfMapEntry>* perf_map_entries,
+    ofstream& asm_file) {
+  if (symbol.getType() != SymbolRef::ST_Function) return;
+
+  ErrorOr<StringRef> name_or_err = symbol.getName();
+  ErrorOr<uint64_t> addr_or_err = symbol.getAddress();
+  if (!name_or_err || !addr_or_err) return;
+
+  uint64_t addr = *addr_or_err;
+  // Append id to symbol to disambiguate different instances of jitted functions.
+  string fn_symbol = Substitute("$0:$1", name_or_err->data(), id_);
+
+  if (emit_perf_map_) {
+    PerfMapEntry entry;
+    entry.symbol = fn_symbol;
+    entry.addr = addr;
+    entry.size = size;
+    perf_map_entries->push_back(entry);
+  }
+
+  if (asm_file.is_open()) {
+    EmitFunctionAsm(debug_ctx, fn_symbol, addr, size, asm_file);
+  }
+}
+
+void CodegenSymbolEmitter::WritePerfMap() {
+  lock_guard<SpinLock> perf_map_lock(perf_map_lock_);
+  WritePerfMapLocked();
+}
+
+void CodegenSymbolEmitter::WritePerfMapLocked() {
+  perf_map_lock_.DCheckLocked();
+  string perf_map_path = Substitute("/tmp/perf-$0.map", getpid());
+  string tmp_perf_map_path = perf_map_path + ".tmp";
+
+  ofstream tmp_perf_map_file;
+  tmp_perf_map_file.open(tmp_perf_map_path, fstream::out | fstream::trunc);
+  if (tmp_perf_map_file.fail()) {
+    LOG(ERROR) << "Could not write perf map to: " << tmp_perf_map_path;
+    return;
+  }
+
+  for (pair<const void*, vector<PerfMapEntry>> entries: perf_map_) {
+    for (PerfMapEntry& entry: entries.second) {
+      // Write perf.map file. Each line has format <address> <size> <label>
+      tmp_perf_map_file << hex << entry.addr << " " << entry.size
<< " "
+                        << entry.symbol << "\n";
+    }
+  }
+  tmp_perf_map_file.close();
+
+  // Atomically move the temprorary file to the new one.
+  if (rename(tmp_perf_map_path.c_str(), perf_map_path.c_str()) != 0) {
+    string err_msg = GetStrErrMsg();
+    LOG(ERROR) << "Failed to move perf map from: " << tmp_perf_map_path <<
" to "
+               << perf_map_path << ": " << err_msg;
+  }
+}
+
+void CodegenSymbolEmitter::EmitFunctionAsm(DIContext* debug_ctx,
+    const string& fn_symbol, uint64_t addr, uint64_t size, ofstream& asm_file) {
+  DCHECK(asm_file.is_open());
+  DILineInfoTable di_lines = debug_ctx->getLineInfoForAddressRange(addr, size);
+  auto di_line_it = di_lines.begin();
+
+  // LLVM's C disassembler API is much simpler than the C++ API, so let's use it.
+  string triple = sys::getProcessTriple();
+  LLVMDisasmContextRef disasm = LLVMCreateDisasm(triple.c_str(), NULL, 0, NULL, NULL);
+  if (disasm == NULL) {
+    LOG(WARNING) << "Could not create LLVM disassembler for target triple " <<
triple;
+    return;
+  }
+
+  char line_buf[2048];
+  uint8_t* code = reinterpret_cast<uint8_t*>(addr);
+  uint8_t* code_end = code + size;
+
+  asm_file << "Disassembly for " << fn_symbol << " (" << reinterpret_cast<void*>(addr)
+           << "):" << "\n";
+
+  while (code < code_end) {
+    uint64_t inst_addr = reinterpret_cast<uint64_t>(code);
+    // Emit any debug symbols before instruction.
+    for (; di_line_it != di_lines.end() && di_line_it->first <= inst_addr;
++di_line_it) {
+      DILineInfo line = di_line_it->second;
+      asm_file << "\t" << line.FileName << ":" << line.FileName <<
":"
+               << line.FunctionName << ":" << line.Line << ":" <<
line.Column << "\n";
+    }
+
+    size_t inst_len = LLVMDisasmInstruction(disasm, code, code_end - code, 0, line_buf,
+        sizeof(line_buf));
+    if (inst_len == 0) {
+      LOG(WARNING) << "Invalid instruction at " << static_cast<void*>(code);
+      break;
+    }
+
+    uint64_t offset = inst_addr - addr;
+    asm_file << offset << ":\t" << line_buf << "\n";
+    code += inst_len;
+  }
+
+  for (; di_line_it != di_lines.end(); ++di_line_it) {
+    DILineInfo line = di_line_it->second;
+    asm_file << "\t" << line.FileName << ":" << line.FileName <<
":"
+             << line.FunctionName << ":" << line.Line << ":" <<
line.Column << "\n";
+  }
+  asm_file << "\n";
+}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/1c704f3c/be/src/codegen/codegen-symbol-emitter.h
----------------------------------------------------------------------
diff --git a/be/src/codegen/codegen-symbol-emitter.h b/be/src/codegen/codegen-symbol-emitter.h
new file mode 100644
index 0000000..9c34714
--- /dev/null
+++ b/be/src/codegen/codegen-symbol-emitter.h
@@ -0,0 +1,104 @@
+// Copyright 2016 Cloudera Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+#ifndef IMPALA_CODEGEN_JIT_SYMBOL_EMITTER_H
+#define IMPALA_CODEGEN_JIT_SYMBOL_EMITTER_H
+
+#include <boost/thread/locks.hpp>
+#include <boost/unordered_map.hpp>
+#include <iosfwd>
+#include <llvm/ExecutionEngine/JITEventListener.h>
+
+#include "util/spinlock.h"
+
+namespace llvm {
+  class DIContext;
+  namespace object {
+    class SymbolRef;
+  }
+}
+
+namespace impala {
+
+/// Class to emit debug symbols and associated info from jitted object files.
+/// The methods of this listener are called whenever the query fragment emits
+/// a compiled machine code object. We can then process any debug symbols
+/// associated with the code object and emit useful information such as disassembly
+/// and symbols for perf profiling.
+class CodegenSymbolEmitter : public llvm::JITEventListener {
+ public:
+  CodegenSymbolEmitter(std::string id) : id_(id), emit_perf_map_(false) { }
+
+  ~CodegenSymbolEmitter() { }
+
+  /// Write the current contents of 'perf_map_' to /tmp/perf-<pid>.map
+  /// Atomically updates the current map by writing to a temporary file then moving it.
+  static void WritePerfMap();
+
+  /// Called whenever MCJIT module code is emitted.
+  void NotifyObjectEmitted(const llvm::object::ObjectFile &obj,
+     const llvm::RuntimeDyld::LoadedObjectInfo &loaded_obj) override;
+
+  /// Called whenever MCJIT module code is freed.
+  void NotifyFreeingObject(const llvm::object::ObjectFile &obj) override;
+
+  void set_emit_perf_map(bool emit_perf_map) { emit_perf_map_ = emit_perf_map; }
+
+  void set_asm_path(const std::string& asm_path) { asm_path_ = asm_path; }
+
+ private:
+  struct PerfMapEntry {
+    std::string symbol;
+    uint64_t addr;
+    uint64_t size;
+  };
+
+  /// Process the given 'symbol' with 'size'. For function symbols, append to
+  /// 'perf_map_entries' if 'emit_perf_map_' is true and write disassembly to 'asm_file'
+  /// if it is open.
+  void ProcessSymbol(llvm::DIContext* debug_ctx, const llvm::object::SymbolRef& symbol,
+      uint64_t size, std::vector<PerfMapEntry>* perf_map_entries,
+      std::ofstream& asm_file);
+
+  /// Implementation of WritePerfMap(). 'perf_map_lock_' must be held by caller.
+  static void WritePerfMapLocked();
+
+  /// Emit disassembly for the function. If symbols are present for the code object,
+  /// the symbols will be interleaved with the disassembly.
+  void EmitFunctionAsm(llvm::DIContext* debug_ctx, const std::string& fn_symbol,
+      uint64_t addr, uint64_t size, std::ofstream& asm_file);
+
+  /// Identifier to append to symbols, e.g. a fragment instance id. The identifier is
+  /// passed by the caller when the CodegenSymbolEmitter is constructed. Without this
+  /// identifier, many distinct codegen'd functions will have the same symbol.
+  std::string id_;
+
+  /// If true, emit perf map info to /tmp/perf-<pid>.map.
+  bool emit_perf_map_;
+
+  /// File to emit disassembly to. If empty string, don't emit.
+  std::string asm_path_;
+
+  /// Global lock to protect 'perf_map_' and writes to /tmp/perf-<pid>.map.
+  static SpinLock perf_map_lock_;
+
+  /// All current entries that should be emitted into the perf map file.
+  /// Maps the address of each ObjectFile's data to the symbols in the object.
+  static boost::unordered_map<const void*, std::vector<PerfMapEntry>> perf_map_;
+};
+
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/1c704f3c/be/src/codegen/llvm-codegen.cc
----------------------------------------------------------------------
diff --git a/be/src/codegen/llvm-codegen.cc b/be/src/codegen/llvm-codegen.cc
index 2b3e245..0651bf7 100644
--- a/be/src/codegen/llvm-codegen.cc
+++ b/be/src/codegen/llvm-codegen.cc
@@ -49,6 +49,7 @@
 
 #include "common/logging.h"
 #include "codegen/codegen-anyval.h"
+#include "codegen/codegen-symbol-emitter.h"
 #include "codegen/impala-ir-data.h"
 #include "codegen/instruction-counter.h"
 #include "codegen/mcjit-mem-mgr.h"
@@ -72,10 +73,15 @@ DEFINE_bool(print_llvm_ir_instruction_count, false,
 DEFINE_bool(disable_optimization_passes, false,
     "if true, disables llvm optimization passes (used for testing)");
 DEFINE_bool(dump_ir, false, "if true, output IR after optimization passes");
+DEFINE_bool(perf_map, false,
+    "if true, generate /tmp/perf-<pid>.map file for linux perf symbols. "
+    "This is not recommended for production use because it may affect performance.");
 DEFINE_string(unopt_module_dir, "",
     "if set, saves unoptimized generated IR modules to the specified directory.");
 DEFINE_string(opt_module_dir, "",
     "if set, saves optimized generated IR modules to the specified directory.");
+DEFINE_string(asm_module_dir, "",
+    "if set, saves disassembly for generated IR modules to the specified directory.");
 DECLARE_string(local_library_dir);
 
 namespace impala {
@@ -99,6 +105,7 @@ void LlvmCodeGen::InitializeLlvm(bool load_backend) {
   llvm::InitializeNativeTarget();
   llvm::InitializeNativeTargetAsmPrinter();
   llvm::InitializeNativeTargetAsmParser();
+  llvm::InitializeNativeTargetDisassembler();
   llvm_initialized_ = true;
 
   if (load_backend) {
@@ -114,6 +121,9 @@ void LlvmCodeGen::InitializeLlvm(bool load_backend) {
   GetHostCPUAttrs(&cpu_attrs_);
   LOG(INFO) << "CPU flags for runtime code generation: "
             << boost::algorithm::join(cpu_attrs_, ",");
+
+  // Write an empty map file for perf to find.
+  if (FLAGS_perf_map) CodegenSymbolEmitter::WritePerfMap();
 }
 
 LlvmCodeGen::LlvmCodeGen(ObjectPool* pool, const string& id) :
@@ -349,12 +359,29 @@ Status LlvmCodeGen::Init(unique_ptr<Module> module) {
   true_value_ = ConstantInt::get(context(), APInt(1, true, true));
   false_value_ = ConstantInt::get(context(), APInt(1, false, true));
 
+  SetupJITListeners();
+
   RETURN_IF_ERROR(LoadIntrinsics());
 
   return Status::OK();
 }
 
+void LlvmCodeGen::SetupJITListeners() {
+  bool need_symbol_emitter = !FLAGS_asm_module_dir.empty() || FLAGS_perf_map;
+  if (!need_symbol_emitter) return;
+  symbol_emitter_.reset(new CodegenSymbolEmitter(id_));
+  execution_engine_->RegisterJITEventListener(symbol_emitter_.get());
+  symbol_emitter_->set_emit_perf_map(FLAGS_perf_map);
+
+  if (!FLAGS_asm_module_dir.empty()) {
+    symbol_emitter_->set_asm_path(Substitute("$0/$1.asm", FLAGS_asm_module_dir, id_));
+  }
+}
+
 LlvmCodeGen::~LlvmCodeGen() {
+  // Execution engine executes callback on event listener, so tear down engine first.
+  execution_engine_.reset();
+  symbol_emitter_.reset();
 }
 
 void LlvmCodeGen::EnableOptimizations(bool enable) {

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/1c704f3c/be/src/codegen/llvm-codegen.h
----------------------------------------------------------------------
diff --git a/be/src/codegen/llvm-codegen.h b/be/src/codegen/llvm-codegen.h
index b4b5223..d4255a0 100644
--- a/be/src/codegen/llvm-codegen.h
+++ b/be/src/codegen/llvm-codegen.h
@@ -23,7 +23,7 @@
 #include <string>
 #include <vector>
 #include <boost/scoped_ptr.hpp>
-#include <boost/thread/mutex.hpp>
+
 #include <boost/unordered_set.hpp>
 
 #include <llvm/IR/DerivedTypes.h>
@@ -69,6 +69,7 @@ namespace llvm {
 namespace impala {
 
 class CodegenAnyVal;
+class CodegenSymbolEmitter;
 class SubExprElimination;
 
 /// LLVM code generator.  This is the top level object to generate jitted code.
@@ -439,6 +440,10 @@ class LlvmCodeGen {
   /// anyway (they must be explicitly invoked) so it is dead code.
   static void StripGlobalCtorsDtors(llvm::Module* module);
 
+  // Setup any JIT listeners to process generated machine code object, e.g. to generate
+  // perf symbol map or disassembly.
+  void SetupJITListeners();
+
   /// Load the intrinsics impala needs.  This is a one time initialization.
   /// Values are stored in 'llvm_intrinsics_'
   Status LoadIntrinsics();
@@ -569,6 +574,11 @@ class LlvmCodeGen {
   /// llvm constants to help with code gen verbosity
   llvm::Value* true_value_;
   llvm::Value* false_value_;
+
+  /// The symbol emitted associated with 'execution_engine_'. Methods on
+  /// 'symbol_emitter_' are called by 'execution_engine_' when code is emitted or freed.
+  /// The lifetime of the symbol emitter must be longer than 'execution_engine_'.
+  boost::scoped_ptr<CodegenSymbolEmitter> symbol_emitter_;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/1c704f3c/cmake_modules/FindLlvm.cmake
----------------------------------------------------------------------
diff --git a/cmake_modules/FindLlvm.cmake b/cmake_modules/FindLlvm.cmake
index 589d203..4f885ef 100644
--- a/cmake_modules/FindLlvm.cmake
+++ b/cmake_modules/FindLlvm.cmake
@@ -66,7 +66,7 @@ execute_process(
 # Get the link libs we need.  llvm has many and we don't want to link all of the libs
 # if we don't need them.
 execute_process(
-  COMMAND ${LLVM_CONFIG_EXECUTABLE} --libnames core mcjit native ipo bitreader target linker
analysis
+  COMMAND ${LLVM_CONFIG_EXECUTABLE} --libnames core mcjit native ipo bitreader target linker
analysis debuginfodwarf
   OUTPUT_VARIABLE LLVM_MODULE_LIBS
   OUTPUT_STRIP_TRAILING_WHITESPACE
 )


Mime
View raw message