# HG changeset patch # User Max Brister # Date 1338755920 18000 # Node ID 1f914446157d32d260828df50abb72f7f7cd6562 # Parent 3b067a247c1d23673d8ab7c2eeafef25d20196b8 Locate and link with LLVM properly * build-aux/common.mk: Add LLVM flags. * configure.ac: Add llvm-config option, use llvm-config more correctly, fix compile check, and add jit-debug option. * src/pt-eval.cc: Check HAVE_LLVM. * src/pt-jit.h: Check HAVE_LLVM. * src/pt-jit.cc: Check HAVE_LLVM and OCTAVE_JIT_DEBUG. diff --git a/build-aux/common.mk b/build-aux/common.mk --- a/build-aux/common.mk +++ b/build-aux/common.mk @@ -181,6 +181,10 @@ Z_LDFLAGS = @Z_LDFLAGS@ Z_LIBS = @Z_LIBS@ +LLVM_CPPFLAGS = @LLVM_CPPFLAGS@ +LLVM_LDFLAGS = @LLVM_LDFLAGS@ +LLVM_LIBS = @LLVM_LIBS@ + GRAPHICS_LIBS = @GRAPHICS_LIBS@ QHULL_CPPFLAGS = @QHULL_CPPFLAGS@ @@ -252,7 +256,7 @@ DL_LIBS = @DL_LIBS@ LIBS = @LIBS@ -ALL_CPPFLAGS = $(CPPFLAGS) $(HDF5_CPPFLAGS) $(Z_CPPFLAGS) +ALL_CPPFLAGS = $(CPPFLAGS) $(HDF5_CPPFLAGS) $(Z_CPPFLAGS) $(LLVM_CPPFLAGS) SPARSE_XCPPFLAGS = \ $(CHOLMOD_CPPFLAGS) $(UMFPACK_CPPFLAGS) \ diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -718,32 +718,56 @@ dnl llvm is odd and has its own pkg-config like script. We should probably check dnl for existance and dnl +warn_llvm="LLVM library fails tests. JIT compilation will be disabled." -LLVM_CONFIG=llvm-config +AC_ARG_VAR(LLVM_CONFIG, [path to llvm-config utility]) +if test "x$ac_cv_env_LLVM_CONFIG_set" != "xset"; then + AC_PATH_TOOL([LLVM_CONFIG], [llvm-config]) +fi + +AC_ARG_ENABLE([jit-debug], + AS_HELP_STRING([--enable-jit-debug], [Enable debug printing of jit IRs])) + +AS_IF([test "x$enable_jit_debug" = "xyes"], [ + AC_DEFINE(OCTAVE_JIT_DEBUG, 1, [Define for jit debug printing]) +]) + LLVM_CPPFLAGS= LLVM_LDFLAGS= LLVM_LIBS= -LLVM_LDFLAGS=`$LLVM_CONFIG --ldflags` -LLVM_LIBS=`$LLVM_CONFIG --libs` -LLVM_CPPFLAGS=`$LLVM_CONFIG --cxxflags` - -warn_llvm="LLVM library fails tests. JIT compilation will be disabled." +dnl llvm-config is messed up +if test -n "$LLVM_CONFIG"; then + LLVM_LDFLAGS="-L`$LLVM_CONFIG --libdir`" + LLVM_LIBS=`$LLVM_CONFIG --libs` + dnl Use -isystem so we don't get warnings from llvm headers + LLVM_CPPFLAGS="-isystem `$LLVM_CONFIG --includedir`" +fi save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" save_LDFLAGS="$LDFLAGS" -CPPFLAGS="$LLVM_CPPFLAGS $CPPFLAGS" +dnl +dnl We define some extra flags that llvm requires in order to include headers. +dnl Idealy we should get these from llvm-config, but llvm-config isn't very +dnl helpful. +dnl +CPPFLAGS="-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS $LLVM_CPPFLAGS $CPPFLAGS" LIBS="$LLVM_LIBS $LIBS" LDFLAGS="$LLVM_LDFLAGS $LDFLAGS" + AC_LANG_PUSH(C++) AC_CHECK_HEADER([llvm/LLVMContext.h], [ - AC_MSG_CHECKING([for llvm::getGlobalContext in llvm/LLVMContext.h]) - AC_TRY_LINK([#include ], [llvm::getGlobalContext ()], [ - AC_MSG_RESULT(yes) - warn_llvm= - ], [ - AC_MSG_RESULT(no) + AC_MSG_CHECKING([for llvm::getGlobalContext in llvm/LLVMContext.h]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[llvm::LLVMContext& ctx = llvm::getGlobalContext ();]])], + [ + AC_MSG_RESULT([yes]) + warn_llvm= + XTRA_CXXFLAGS="$XTRA_CXXFLAGS $LLVM_CPPFLAGS" + ], + [AC_MSG_RESULT([no]) ]) ]) AC_LANG_POP(C++) @@ -752,14 +776,13 @@ LDFLAGS="$save_LDFLAGS" if test -z "$warn_llvm"; then - AC_DEFINE(HAVE_LLVM, 1, [Define if LLVM is available.]) + AC_DEFINE(HAVE_LLVM, 1, [Define if LLVM is available]) else LLVM_CPPFLAGS= LLVM_LDFLAGS= LLVM_LIBS= AC_MSG_WARN([$warn_llvm]) fi -AC_DEFINE(HAVE_LLVM, 1, [Define if LLVM is available.]) AC_SUBST(LLVM_CPPFLAGS) AC_SUBST(LLVM_LDFLAGS) diff --git a/src/pt-eval.cc b/src/pt-eval.cc --- a/src/pt-eval.cc +++ b/src/pt-eval.cc @@ -44,9 +44,11 @@ #include "symtab.h" #include "unwind-prot.h" +#if HAVE_LLVM //FIXME: This should be part of tree_evaluator #include "pt-jit.h" static tree_jit jiter; +#endif static tree_evaluator std_evaluator; @@ -294,8 +296,10 @@ if (debug_mode) do_breakpoint (cmd.is_breakpoint ()); +#if HAVE_LLVM if (jiter.execute (cmd)) return; +#endif // FIXME -- need to handle PARFOR loops here using cmd.in_parallel () // and cmd.maxproc_expr (); diff --git a/src/pt-jit.cc b/src/pt-jit.cc --- a/src/pt-jit.cc +++ b/src/pt-jit.cc @@ -27,6 +27,8 @@ #include #endif +#ifdef HAVE_LLVM + #include "pt-jit.h" #include @@ -54,10 +56,6 @@ #include "ov-scalar.h" #include "pt-all.h" -// FIXME: Remove eventually -// For now we leave this in so people tell when JIT actually happens -static const bool debug_print = false; - static llvm::IRBuilder<> builder (llvm::getGlobalContext ()); static llvm::LLVMContext& context = llvm::getGlobalContext (); @@ -84,11 +82,19 @@ throw jit_fail_exception (); } +#ifdef OCTAVE_JIT_DEBUG static void fail (const std::string& reason) { throw jit_fail_exception (reason); } +#else +static void +fail (const std::string&) +{ + throw jit_fail_exception (); +} +#endif // OCTAVE_JIT_DEBUG std::ostream& jit_print (std::ostream& os, jit_type *atype) { @@ -1076,8 +1082,9 @@ iter != constants.end (); ++iter) append_users (*iter); - if (debug_print) - print_blocks ("octave jit ir"); +#ifdef OCTAVE_JIT_DEBUG + print_blocks ("octave jit ir"); +#endif // FIXME: Describe algorithm here while (worklist.size ()) @@ -1089,12 +1096,11 @@ append_users (next); } - if (debug_print) - { - std::cout << "-------------------- Compiling tree --------------------\n"; - std::cout << tee.str_print_code () << std::endl; - print_blocks ("octave jit ir"); - } +#ifdef OCTAVE_JIT_DEBUG + std::cout << "-------------------- Compiling tree --------------------\n"; + std::cout << tee.str_print_code () << std::endl; + print_blocks ("octave jit ir"); +#endif // for now just init arguments from entry, later we will have to do something // more interesting @@ -1108,14 +1114,13 @@ convert_llvm to_llvm; function = to_llvm.convert (module, arguments, blocks); - if (debug_print) - { - std::cout << "-------------------- llvm ir --------------------"; - llvm::raw_os_ostream llvm_cout (std::cout); - function->print (llvm_cout); - std::cout << std::endl; - llvm::verifyFunction (*function); - } +#ifdef OCTAVE_JIT_DEBUG + std::cout << "-------------------- llvm ir --------------------"; + llvm::raw_os_ostream llvm_cout (std::cout); + function->print (llvm_cout); + std::cout << std::endl; + llvm::verifyFunction (*function); +#endif } jit_convert::~jit_convert (void) @@ -2066,8 +2071,10 @@ } catch (const jit_fail_exception& e) { - if (debug_print && e.known ()) +#ifdef OCTAVE_JIT_DEBUG + if (e.known ()) std::cout << "jit fail: " << e.what () << std::endl; +#endif } if (! fun) @@ -2078,13 +2085,12 @@ tjit.optimize (fun); - if (debug_print) - { - std::cout << "-------------------- optimized llvm ir --------------------\n"; - llvm::raw_os_ostream llvm_cout (std::cout); - fun->print (llvm_cout); - std::cout << std::endl; - } +#ifdef OCTAVE_JIT_DEBUG + std::cout << "-------------------- optimized llvm ir --------------------\n"; + llvm::raw_os_ostream llvm_cout (std::cout); + fun->print (llvm_cout); + std::cout << std::endl; +#endif function = reinterpret_cast(engine->getPointerToFunction (fun)); } @@ -2134,3 +2140,4 @@ return true; } +#endif diff --git a/src/pt-jit.h b/src/pt-jit.h --- a/src/pt-jit.h +++ b/src/pt-jit.h @@ -23,6 +23,8 @@ #if !defined (octave_tree_jit_h) #define octave_tree_jit_h 1 +#ifdef HAVE_LLVM + #include #include #include @@ -1709,5 +1711,5 @@ std::vector > arguments; type_bound_vector bounds; }; - #endif +#endif