Skip to content

Commit

Permalink
gras: jit factory api + unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
guruofquality committed Aug 1, 2013
1 parent 1897808 commit a23bf59
Show file tree
Hide file tree
Showing 13 changed files with 550 additions and 58 deletions.
50 changes: 50 additions & 0 deletions cmake/Modules/FindClang.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Find Clang
#
# It defines the following variables
# CLANG_FOUND - True if Clang found.
# CLANG_INCLUDE_DIRS - where to find Clang include files
# CLANG_LIBS - list of clang libs

if (NOT LLVM_INCLUDE_DIRS OR NOT LLVM_LIBRARY_DIRS)
message(FATAL_ERROR "No LLVM and Clang support requires LLVM")
else (NOT LLVM_INCLUDE_DIRS OR NOT LLVM_LIBRARY_DIRS)

MACRO(FIND_AND_ADD_CLANG_LIB _libname_)
find_library(CLANG_${_libname_}_LIB ${_libname_} ${LLVM_LIBRARY_DIRS} ${CLANG_LIBRARY_DIRS})
if (CLANG_${_libname_}_LIB)
set(CLANG_LIBS ${CLANG_LIBS} ${CLANG_${_libname_}_LIB})
endif (CLANG_${_libname_}_LIB)
ENDMACRO(FIND_AND_ADD_CLANG_LIB)

# Clang shared library provides just the limited C interface, so it
# can not be used. We look for the static libraries.
FIND_AND_ADD_CLANG_LIB(clangFrontend)
FIND_AND_ADD_CLANG_LIB(clangDriver)
FIND_AND_ADD_CLANG_LIB(clangCodeGen)
FIND_AND_ADD_CLANG_LIB(clangEdit)
FIND_AND_ADD_CLANG_LIB(clangSema)
FIND_AND_ADD_CLANG_LIB(clangChecker)
FIND_AND_ADD_CLANG_LIB(clangAnalysis)
FIND_AND_ADD_CLANG_LIB(clangRewrite)
FIND_AND_ADD_CLANG_LIB(clangAST)
FIND_AND_ADD_CLANG_LIB(clangParse)
FIND_AND_ADD_CLANG_LIB(clangLex)
FIND_AND_ADD_CLANG_LIB(clangBasic)
FIND_AND_ADD_CLANG_LIB(clang)

find_path(CLANG_INCLUDE_DIRS clang/Basic/Version.h HINTS ${LLVM_INCLUDE_DIRS})

if (CLANG_LIBS AND CLANG_INCLUDE_DIRS)
MESSAGE(STATUS "Clang libs: " ${CLANG_LIBS})
set(CLANG_FOUND TRUE)
endif (CLANG_LIBS AND CLANG_INCLUDE_DIRS)

if (CLANG_FOUND)
message(STATUS "Found Clang: ${CLANG_INCLUDE_DIRS}")
else (CLANG_FOUND)
if (CLANG_FIND_REQUIRED)
message(FATAL_ERROR "Could NOT find Clang")
endif (CLANG_FIND_REQUIRED)
endif (CLANG_FOUND)

endif (NOT LLVM_INCLUDE_DIRS OR NOT LLVM_LIBRARY_DIRS)
73 changes: 73 additions & 0 deletions cmake/Modules/FindLLVM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Find LLVM
#
# It defines the following variables
# LLVM_FOUND - True if llvm found.
# LLVM_INCLUDE_DIRS - where to find llvm include files
# LLVM_LIBRARY_DIRS - where to find llvm libs
# LLVM_CFLAGS - llvm compiler flags
# LLVM_LDFLAGS - llvm linker flags
# LLVM_MODULE_LIBS - list of llvm libs for working with modules.

find_program(LLVM_CONFIG_EXECUTABLE llvm-config DOC "llvm-config executable")

if (LLVM_CONFIG_EXECUTABLE)
message(STATUS "LLVM llvm-config found at: ${LLVM_CONFIG_EXECUTABLE}")
else (LLVM_CONFIG_EXECUTABLE)
message(FATAL_ERROR "Could NOT find LLVM executable")
endif (LLVM_CONFIG_EXECUTABLE)

execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --version
OUTPUT_VARIABLE LLVM_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)

string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*" "\\1" LLVM_VERSION_MAJOR
"${LLVM_VERSION}")

string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*" "\\2" LLVM_VERSION_MINOR
"${LLVM_VERSION}")

execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --includedir
OUTPUT_VARIABLE LLVM_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE
)

execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --libdir
OUTPUT_VARIABLE LLVM_LIBRARY_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE
)

execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --cppflags
OUTPUT_VARIABLE LLVM_CFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if (LLVM_CFLAGS MATCHES "\\-DNDEBUG")
set(LLVM_WITH_NDEBUG TRUE)
else (LLVM_CFLAGS MATCHES "\\-DNDEBUG")
set(LLVM_WITH_NDEBUG FALSE)
endif (LLVM_CFLAGS MATCHES "\\-DNDEBUG")


find_library(LLVM_MODULE_LIBS LLVM-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR} ${LLVM_LIBRARY_DIRS})
if (NOT LLVM_MODULE_LIBS)
execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --libs
OUTPUT_VARIABLE LLVM_MODULE_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif (NOT LLVM_MODULE_LIBS)

execute_process(
COMMAND ${LLVM_CONFIG_EXECUTABLE} --ldflags
OUTPUT_VARIABLE LLVM_LDFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if (LLVM_CONFIG_EXECUTABLE)
set(LLVM_FOUND TRUE)
endif (LLVM_CONFIG_EXECUTABLE)
44 changes: 22 additions & 22 deletions include/gras/detail/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ template <typename ReturnType>
void register_factory(const std::string &path, ReturnType(*fcn)())
{
void *r = new FactoryRegistryEntryImpl0<ReturnType>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -64,7 +64,7 @@ template <typename ReturnType, typename A0>
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &))
{
void *r = new FactoryRegistryEntryImpl1<ReturnType, A0>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -88,7 +88,7 @@ template <typename ReturnType, typename A0, typename A1>
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &))
{
void *r = new FactoryRegistryEntryImpl2<ReturnType, A0, A1>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -112,7 +112,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2>
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &))
{
void *r = new FactoryRegistryEntryImpl3<ReturnType, A0, A1, A2>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -136,7 +136,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2, typename A
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &))
{
void *r = new FactoryRegistryEntryImpl4<ReturnType, A0, A1, A2, A3>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -160,7 +160,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2, typename A
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &))
{
void *r = new FactoryRegistryEntryImpl5<ReturnType, A0, A1, A2, A3, A4>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -184,7 +184,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2, typename A
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &))
{
void *r = new FactoryRegistryEntryImpl6<ReturnType, A0, A1, A2, A3, A4, A5>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -208,7 +208,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2, typename A
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &))
{
void *r = new FactoryRegistryEntryImpl7<ReturnType, A0, A1, A2, A3, A4, A5, A6>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -232,7 +232,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2, typename A
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &))
{
void *r = new FactoryRegistryEntryImpl8<ReturnType, A0, A1, A2, A3, A4, A5, A6, A7>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -256,7 +256,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2, typename A
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &))
{
void *r = new FactoryRegistryEntryImpl9<ReturnType, A0, A1, A2, A3, A4, A5, A6, A7, A8>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -280,7 +280,7 @@ template <typename ReturnType, typename A0, typename A1, typename A2, typename A
void register_factory(const std::string &path, ReturnType(*fcn)(const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &))
{
void *r = new FactoryRegistryEntryImpl10<ReturnType, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>(fcn);
Factory::_register_factory(path, r);
_register_factory(path, r);
}

/***********************************************************************
Expand All @@ -290,15 +290,15 @@ inline
Element *make(const std::string &path)
{
PMCList args(0);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0>
Element *make(const std::string &path, const A0 &a0)
{
PMCList args(1);
args[0] = PMC_M(a0);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1>
Expand All @@ -307,7 +307,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1)
PMCList args(2);
args[0] = PMC_M(a0);
args[1] = PMC_M(a1);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2>
Expand All @@ -317,7 +317,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2)
args[0] = PMC_M(a0);
args[1] = PMC_M(a1);
args[2] = PMC_M(a2);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2, typename A3>
Expand All @@ -328,7 +328,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2,
args[1] = PMC_M(a1);
args[2] = PMC_M(a2);
args[3] = PMC_M(a3);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2, typename A3, typename A4>
Expand All @@ -340,7 +340,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2,
args[2] = PMC_M(a2);
args[3] = PMC_M(a3);
args[4] = PMC_M(a4);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
Expand All @@ -353,7 +353,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2,
args[3] = PMC_M(a3);
args[4] = PMC_M(a4);
args[5] = PMC_M(a5);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
Expand All @@ -367,7 +367,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2,
args[4] = PMC_M(a4);
args[5] = PMC_M(a5);
args[6] = PMC_M(a6);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
Expand All @@ -382,7 +382,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2,
args[5] = PMC_M(a5);
args[6] = PMC_M(a6);
args[7] = PMC_M(a7);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
Expand All @@ -398,7 +398,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2,
args[6] = PMC_M(a6);
args[7] = PMC_M(a7);
args[8] = PMC_M(a8);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
Expand All @@ -415,7 +415,7 @@ Element *make(const std::string &path, const A0 &a0, const A1 &a1, const A2 &a2,
args[7] = PMC_M(a7);
args[8] = PMC_M(a8);
args[9] = PMC_M(a9);
return Factory::_handle_make(path, PMC_M(args));
return _handle_make(path, PMC_M(args));
}

}
Expand Down
32 changes: 21 additions & 11 deletions include/gras/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@
#include <gras/gras.hpp>
#include <gras/element.hpp>
#include <PMC/PMC.hpp>
#include <vector>
#include <string>

namespace gras
{

/*!
* Element factory:
* - Register factory functions into the global factory.
* - Call make() to create element from global factory.
* The just in time factory:
* Compile a C++ source and load it into the element factory.
*
* Flags are an optional list of compiler flags.
* See the man page for clang for possible options.
* Example: flags.push_back("-O3")
*
* Include directories control the header file search path.
* Users may leave this empty unless headers
* are installed into non-standard directories.
*
* \param source C++ source code in a string
* \param flags optional compiler flags
*/
struct GRAS_API Factory
{
/*******************************************************************
* Private registration hooks
******************************************************************/
static void _register_factory(const std::string &, void *);
static Element *_handle_make(const std::string &, const PMCC &);
};
GRAS_API void jit_factory(const std::string &source, const std::vector<std::string> &flags);

/***********************************************************************
* Register API - don't look here, template magic, not helpful
Expand Down Expand Up @@ -101,6 +105,12 @@ static Element *make(const std::string &path, const A0 &, const A1 &, const A2 &
template <typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
static Element *make(const std::string &path, const A0 &, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &, const A8 &, const A9 &);


//! Register factory functions into the global factory.
GRAS_API void _register_factory(const std::string &, void *);

//! Call make() to create element from global factory.
GRAS_API Element *_handle_make(const std::string &, const PMCC &);
}

/*!
Expand Down
Loading

0 comments on commit a23bf59

Please sign in to comment.