From 6e522684b89f13f932a54266c5eb01937a68d92c Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 29 Aug 2009 19:35:30 -0400 Subject: lots of various changes --- CMakeLists.txt | 2 + cmake/modules/FindClang.cmake | 40 +++++++ cmake/modules/FindGallium.cmake | 40 +++++++ cmake/modules/FindLLVM.cmake | 2 +- src/CMakeLists.txt | 71 ++---------- src/compiler/compiler.cpp | 245 ++++++++++++++++++++++++++++++++++++++-- src/compiler/compiler.h | 1 + src/core/device.cpp | 2 +- src/tools/CMakeLists.txt | 10 ++ src/tools/clcompiler.cpp | 23 ++++ 10 files changed, 359 insertions(+), 77 deletions(-) create mode 100644 cmake/modules/FindClang.cmake create mode 100644 cmake/modules/FindGallium.cmake create mode 100644 src/tools/CMakeLists.txt create mode 100644 src/tools/clcompiler.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fc1772..2b26770 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,9 @@ SET(${PROJECT_NAME}_SOVERSION 1.0.0) OPTION(BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON) +Find_Package(Gallium REQUIRED) Find_Package(LLVM REQUIRED) +Find_Package(Clang REQUIRED) add_subdirectory(src) add_subdirectory(examples) diff --git a/cmake/modules/FindClang.cmake b/cmake/modules/FindClang.cmake new file mode 100644 index 0000000..e46de74 --- /dev/null +++ b/cmake/modules/FindClang.cmake @@ -0,0 +1,40 @@ +# Detect CLANG +if (NOT CLANG_SRC_DIR OR NOT CLANG_BUILD_DIR) + message(FATAL_ERROR "Define CLANG_SRC_DIR and CLANG_BUILD_DIR to build Clover") +else (NOT CLANG_SRC_DIR OR NOT CLANG_BUILD_DIR) + +MACRO(FIND_AND_ADD_CLANG_LIB _libname_) +find_library(CLANG_${_libname_}_LIB ${_libname_} ${CLANG_SRC_DIR}/Debug/lib ${CLANG_BUILD_DIR}/Debug/lib) +if (CLANG_${_libname_}_LIB) + set(CLANG_LIBS ${CLANG_LIBS} ${CLANG_${_libname_}_LIB}) +endif(CLANG_${_libname_}_LIB) +ENDMACRO(FIND_AND_ADD_CLANG_LIB) + +set(CLANG_INCLUDE_DIRS ${CLANG_INCLUDE_DIRS} ${CLANG_SRC_DIR}/tools/clang/include) +set(CLANG_INCLUDE_DIRS ${CLANG_INCLUDE_DIRS} ${CLANG_BUILD_DIR}/tools/clang/include) + +FIND_AND_ADD_CLANG_LIB(clangFrontend) +FIND_AND_ADD_CLANG_LIB(clangCodeGen) +FIND_AND_ADD_CLANG_LIB(clangAnalysis) +FIND_AND_ADD_CLANG_LIB(clangRewrite) +FIND_AND_ADD_CLANG_LIB(clangSema) +FIND_AND_ADD_CLANG_LIB(clangAST) +FIND_AND_ADD_CLANG_LIB(clangParse) +FIND_AND_ADD_CLANG_LIB(clangLex) +FIND_AND_ADD_CLANG_LIB(clangBasic) + +MESSAGE(STATUS "Clang libs: " ${CLANG_LIBS}) + +if(CLANG_LIBS) + set(CLANG_FOUND TRUE) +endif(CLANG_LIBS) + +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 CLANG_SRC_DIR OR NOT CLANG_BUILD_DIR) diff --git a/cmake/modules/FindGallium.cmake b/cmake/modules/FindGallium.cmake new file mode 100644 index 0000000..2b49910 --- /dev/null +++ b/cmake/modules/FindGallium.cmake @@ -0,0 +1,40 @@ +# Detect Gallium +if (NOT GALLIUM_DIR) + message(FATAL_ERROR "Define GALLIUM_DIR to build Clover") +else (NOT GALLIUM_DIR) + +MACRO(FIND_AND_ADD_GALLIUM_LIB _libname_) +find_library(GALLIUM_${_libname_}_LIB ${_libname_} ${GALLIUM_DIR}//src/gallium/auxiliary/${_libname_}) +if (GALLIUM_${_libname_}_LIB) + set(GALLIUM_LIBS ${GALLIUM_LIBS} ${GALLIUM_${_libname_}_LIB}) +endif(GALLIUM_${_libname_}_LIB) +ENDMACRO(FIND_AND_ADD_GALLIUM_LIB) + +set(GALLIUM_INCLUDE_DIRS ${GALLIUM_INCLUDE_DIRS} ${GALLIUM_DIR}/src/gallium/include) +set(GALLIUM_INCLUDE_DIRS ${GALLIUM_INCLUDE_DIRS} ${GALLIUM_DIR}/src/gallium/auxiliary) +set(GALLIUM_INCLUDE_DIRS ${GALLIUM_INCLUDE_DIRS} ${GALLIUM_DIR}/src/gallium/drivers) + +FIND_AND_ADD_GALLIUM_LIB(pipebuffer) +FIND_AND_ADD_GALLIUM_LIB(sct) +FIND_AND_ADD_GALLIUM_LIB(draw) +FIND_AND_ADD_GALLIUM_LIB(rtasm) +FIND_AND_ADD_GALLIUM_LIB(translate) +FIND_AND_ADD_GALLIUM_LIB(cso_cache) +FIND_AND_ADD_GALLIUM_LIB(tgsi) +FIND_AND_ADD_GALLIUM_LIB(util) + +MESSAGE(STATUS "Gallium libs: " ${GALLIUM_LIBS}) + +if(GALLIUM_LIBS) + set(GALLIUM_FOUND TRUE) +endif(GALLIUM_LIBS) + +if(GALLIUM_FOUND) + message(STATUS "Found Gallium") +else(GALLIUM_FOUND) + if(GALLIUM_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find Gallium") + endif(GALLIUM_FIND_REQUIRED) +endif(GALLIUM_FOUND) + +endif (NOT GALLIUM_DIR) diff --git a/cmake/modules/FindLLVM.cmake b/cmake/modules/FindLLVM.cmake index ef8f7f1..3f969fa 100644 --- a/cmake/modules/FindLLVM.cmake +++ b/cmake/modules/FindLLVM.cmake @@ -41,7 +41,7 @@ exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --cxxflags OUTPUT_VARIABLE LLVM_COM MESSAGE(STATUS "LLVM CXX flags: " ${LLVM_COMPILE_FLAGS}) exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --ldflags OUTPUT_VARIABLE LLVM_LDFLAGS ) MESSAGE(STATUS "LLVM LD flags: " ${LLVM_LDFLAGS}) -exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --libs core bitreader bitwriter linker scalaropts ipo codegen selectiondag OUTPUT_VARIABLE LLVM_LIBS_CORE ) +exec_program(${LLVM_CONFIG_EXECUTABLE} ARGS --libs OUTPUT_VARIABLE LLVM_LIBS_CORE ) MESSAGE(STATUS "LLVM core libs: " ${LLVM_LIBS_CORE}) FIND_LLVM_LIBS( ${LLVM_CONFIG_EXECUTABLE} "jit native" LLVM_LIBS_JIT LLVM_LIBS_JIT_OBJECTS ) #STRING(REPLACE " -lLLVMCore -lLLVMSupport -lLLVMSystem" "" LLVM_LIBS_JIT ${LLVM_LIBS_JIT_RAW}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b2ded24..d41c7ec 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,11 @@ include_directories (${Clover_SOURCE_DIR}/include ${Clover_SOURCE_DIR} ${LLVM_INCLUDE_DIR} - ${GALLIUM}/include - ${GALLIUM}/src/gallium/include - ${GALLIUM}/src/gallium/auxiliary - ${GALLIUM}/src/gallium/drivers + ${GALLIUM_INCLUDE_DIRS} + ${CLANG_INCLUDE_DIRS} ) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") set(CLOVER_SRC_FILES core/api_command.cpp core/api_device.cpp @@ -34,66 +32,11 @@ set_source_files_properties( ${CLOVER_SRC_FILES} set_target_properties(OpenCL PROPERTIES LINK_FLAGS ${LLVM_LDFLAGS}) -find_library(CLANG_CODEGEN_LIB clangCodeGen) -if (CLANG_CODEGEN_LIB) - target_link_libraries(OpenCL ${CLANG_CODEGEN_LIB}) -endif(CLANG_CODEGEN_LIB) - -find_library(CLANG_ANALYSIS_LIB clangAnalysis) -if (CLANG_ANALYSIS_LIB) - target_link_libraries(OpenCL ${CLANG_ANALYSIS_LIB}) -endif(CLANG_ANALYSIS_LIB) - -find_library(CLANG_REWRITE_LIB clangRewrite) -if (CLANG_REWRITE_LIB) - target_link_libraries(OpenCL ${CLANG_REWRITE_LIB}) -endif(CLANG_REWRITE_LIB) - -find_library(CLANG_SEMA_LIB clangSema) -if (CLANG_SEMA_LIB) - target_link_libraries(OpenCL ${CLANG_SEMA_LIB}) -endif(CLANG_SEMA_LIB) - -find_library(CLANG_DRIVER_LIB clangDriver) -if (CLANG_DRIVER_LIB) - target_link_libraries(OpenCL ${CLANG_DRIVER_LIB}) -endif(CLANG_DRIVER_LIB) - -find_library(CLANG_AST_LIB clangAST) -if (CLANG_AST_LIB) - target_link_libraries(OpenCL ${CLANG_AST_LIB}) -endif(CLANG_AST_LIB) - -find_library(CLANG_PARSE_LIB clangParse) -if (CLANG_PARSE_LIB) - target_link_libraries(OpenCL ${CLANG_PARSE_LIB}) -endif(CLANG_PARSE_LIB) - -find_library(CLANG_LEX_LIB clangLex) -if (CLANG_LEX_LIB) - target_link_libraries(OpenCL ${CLANG_LEX_LIB}) -endif(CLANG_LEX_LIB) - -find_library(CLANG_BASIC_LIB clangBasic) -if (CLANG_BASIC_LIB) - target_link_libraries(OpenCL ${CLANG_BASIC_LIB}) -endif(CLANG_BASIC_LIB) - -find_library(CLANG_FRONTEND_LIB clangFrontend) -if (CLANG_FRONTEND_LIB) - target_link_libraries(OpenCL ${CLANG_FRONTEND_LIB}) -endif(CLANG_FRONTEND_LIB) - TARGET_LINK_LIBRARIES(OpenCL - ${GALLIUM}/src/gallium/auxiliary/pipebuffer/libpipebuffer.a - ${GALLIUM}/src/gallium/auxiliary/sct/libsct.a - ${GALLIUM}/src/gallium/auxiliary/draw/libdraw.a - ${GALLIUM}/src/gallium/auxiliary/rtasm/librtasm.a - ${GALLIUM}/src/gallium/auxiliary/translate/libtranslate.a - ${GALLIUM}/src/gallium/auxiliary/cso_cache/libcso_cache.a - ${GALLIUM}/src/gallium/auxiliary/tgsi/libtgsi.a - ${GALLIUM}/src/gallium/drivers/softpipe/libsoftpipe.a - ${GALLIUM}/src/gallium/auxiliary/util/libutil.a + ${CLANG_LIBS} ${LLVM_LIBS_CORE} + ${GALLIUM_LIBS} ) + +add_subdirectory(tools) diff --git a/src/compiler/compiler.cpp b/src/compiler/compiler.cpp index 57b2579..f055102 100644 --- a/src/compiler/compiler.cpp +++ b/src/compiler/compiler.cpp @@ -1,11 +1,144 @@ #include "compiler.h" +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include #include +#include #include +#include + +using namespace clang; + +static void llvmErrorHandler(void *userData, const std::string &message) +{ + clang::Diagnostic &diags = *static_cast(userData); + + diags.Report(clang::FullSourceLoc(), clang::diag::err_fe_error_backend) << message; + + // We cannot recover from llvm errors. + exit(1); +} + +static void +initializePreprocessorInitOptions(clang::PreprocessorInitOptions &InitOpts) +{ + //add macros and paths +} + +/* almost verbatim copy of the class from clang-cc.cpp */ +namespace { +class DriverPreprocessorFactory : public PreprocessorFactory { + clang::Diagnostic &Diags; + const clang::LangOptions &LangInfo; + clang::TargetInfo &Target; + clang::SourceManager &SourceMgr; + clang::HeaderSearch &HeaderInfo; + +public: + DriverPreprocessorFactory(clang::Diagnostic &diags, const clang::LangOptions &opts, + clang::TargetInfo &target, clang::SourceManager &SM, + clang::HeaderSearch &Headers) + : Diags(diags), LangInfo(opts), Target(target), + SourceMgr(SM), HeaderInfo(Headers) + {} + + virtual ~DriverPreprocessorFactory() + {} + + virtual Preprocessor * CreatePreprocessor() { + llvm::OwningPtr PTHMgr; + + if (Diags.hasErrorOccurred()) + exit(1); + + // Create the Preprocessor. + llvm::OwningPtr PP( + new clang::Preprocessor(Diags, LangInfo, Target, + SourceMgr, HeaderInfo, + PTHMgr.get())); + + // Note that this is different then passing PTHMgr to Preprocessor's ctor. + // That argument is used as the IdentifierInfoLookup argument to + // IdentifierTable's ctor. + if (PTHMgr) { + PTHMgr->setPreprocessor(PP.get()); + PP->setPTHManager(PTHMgr.take()); + } + + clang::PreprocessorInitOptions InitOpts; + initializePreprocessorInitOptions(InitOpts); + if (clang::InitializePreprocessor(*PP, InitOpts)) + return 0; + + return PP.take(); + } +}; +} + + +static bool +initializeSourceManager(Preprocessor &pp, + const std::string &inFile, + const std::string &sourceStr) +{ + // Figure out where to get and map in the main file. + SourceManager &sourceMgr = pp.getSourceManager(); + FileManager &fileMgr = pp.getFileManager(); + + if (inFile != "-") { + const FileEntry *file = fileMgr.getFile(inFile); + if (file) sourceMgr.createMainFileID(file, SourceLocation()); + if (sourceMgr.getMainFileID().isInvalid()) { + pp.getDiagnostics().Report(FullSourceLoc(), diag::err_fe_error_reading) + << inFile.c_str(); + return true; + } + } else { + const char *source = sourceStr.c_str(); + llvm::MemoryBuffer *sb = + llvm::MemoryBuffer::getMemBuffer(source, + &source[sourceStr.size()], + "OpenCL Source"); + + sourceMgr.createMainFileIDForMemBuffer(sb); + if (sourceMgr.getMainFileID().isInvalid()) { + pp.getDiagnostics().Report(FullSourceLoc(), + diag::err_fe_error_reading_stdin); + return true; + } + } + + return false; +} + +static void initializeIncludePaths(clang::HeaderSearch &headers, + clang::FileManager &fm, + const clang::LangOptions &lang) +{ + clang::InitHeaderSearch init(headers, true, "/"); + + init.AddDefaultEnvVarPaths(lang); + init.AddDefaultSystemIncludePaths(lang); + + init.Realize(); +} Compiler::Compiler() { @@ -19,24 +152,114 @@ Compiler::~Compiler() void Compiler::init() { - m_langOptions.OpenCL = true; + m_langOptions.OpenCL = 1; + m_langOptions.AltiVec = 1; + m_langOptions.CXXOperatorNames = 1; + m_langOptions.LaxVectorConversions = 1; + m_langOptions.C99 = 1; + m_langOptions.HexFloats = 1; + m_langOptions.BCPLComment = 1; + m_langOptions.Digraphs = 1; + m_langOptions.Bool = 1; } llvm::Module * Compiler::compile(const std::string &text) { - clang::Diagnostic diags; - clang::ASTConsumer *consumer = 0; + llvm::OwningPtr consumer; std::string moduleId; std::string llvmIr; llvm::raw_string_ostream output(llvmIr); + llvm::OwningPtr diagClient; + std::vector optWarnings; + std::string targetTriple = llvm::sys::getHostTriple(); + llvm::OwningPtr sourceMgr; + + diagClient.reset(new clang::TextDiagnosticPrinter(llvm::errs())); + clang::Diagnostic diags(diagClient.get()); + + if (clang::ProcessWarningOptions(diags, + optWarnings, + true /*pedantic warnings*/, + false /*OptPedanticErrors */, + false /*OptNoWarnings*/)) + return 0; + + // Set an error handler, so that any LLVM backend diagnostics go through our + // error handler. + llvm::llvm_install_error_handler(llvmErrorHandler, + static_cast(&diags)); + + llvm::OwningPtr target( + clang::TargetInfo::CreateTargetInfo(targetTriple)); + + if (target == 0) { + diags.Report(clang::FullSourceLoc(), clang::diag::err_fe_unknown_triple) + << targetTriple.c_str(); + return 0; + } + + llvm::StringMap features; + target->getDefaultFeatures(m_targetCpu, features); + + if (!sourceMgr) + sourceMgr.reset(new clang::SourceManager()); + else + sourceMgr->clearIDTables(); + + diagClient->setLangOptions(&m_langOptions); + + // Allow the target to set the default the langauge options as it sees fit. + target->getDefaultLangOptions(m_langOptions); + + // Pass the map of target features to the target for validation and + // processing. + target->HandleTargetFeatures(features); + + clang::FileManager fileMgr; + clang::HeaderSearch headerInfo(fileMgr); + initializeIncludePaths(headerInfo, fileMgr, m_langOptions); + + // Set up the preprocessor with these options. + DriverPreprocessorFactory ppFactory(diags, m_langOptions, *target, + *sourceMgr.get(), headerInfo); + + llvm::OwningPtr pp(ppFactory.CreatePreprocessor()); + + if (!pp) + return 0; + + if (initializeSourceManager(*pp.get(), std::string(), text)) + return 0; + + pp->getBuiltinInfo().InitializeBuiltins(pp->getIdentifierTable(), + pp->getLangOptions().NoBuiltin); + + consumer.reset(clang::CreateBackendConsumer( + clang::Backend_EmitLL, + pp->getDiagnostics(), + pp->getLangOptions(), + m_compileOptions, + moduleId, + &output, + llvm::getGlobalContext())); + + llvm::OwningPtr contextOwner; + if (consumer) + contextOwner.reset(new ASTContext(pp->getLangOptions(), + pp->getSourceManager(), + pp->getTargetInfo(), + pp->getIdentifierTable(), + pp->getSelectorTable(), + pp->getBuiltinInfo(), + /* FreeMemory = */ true, + /* size_reserve = */0)); + + if (consumer) + ParseAST(*pp.get(), consumer.get(), *contextOwner.get(), + false, true); - consumer = clang::CreateBackendConsumer( - clang::Backend_EmitLL, - diags, - m_langOptions, - m_compileOptions, - moduleId, - &output, - llvm::getGlobalContext()); + consumer.reset(); + contextOwner.reset(); + return 0; } diff --git a/src/compiler/compiler.h b/src/compiler/compiler.h index ea57314..987a5a9 100644 --- a/src/compiler/compiler.h +++ b/src/compiler/compiler.h @@ -22,6 +22,7 @@ private: private: clang::LangOptions m_langOptions; clang::CompileOptions m_compileOptions; + std::string m_targetCpu; }; #endif diff --git a/src/core/device.cpp b/src/core/device.cpp index e7306ba..4553d1b 100644 --- a/src/core/device.cpp +++ b/src/core/device.cpp @@ -17,7 +17,7 @@ Device * Device::create(cl_uint type) case CL_DEVICE_TYPE_CPU: { struct pipe_winsys *ws = cpu_winsys(); struct pipe_screen *screen = - softpipe_create_screen(ws); + /*softpipe_create_screen(ws);*/ 0; return new Device(CL_DEVICE_TYPE_CPU, screen); } break; diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 0000000..6ea3704 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,10 @@ +include_directories (${Clover_SOURCE_DIR}/include + ${Clover_SOURCE_DIR}/src/tools + ${Clover_SOURCE_DIR}/src/compiler) + +message(STATUS "XXXXXXX source is ${Clover_SOURCE_DIR}") +link_directories(${Clover_BINARY_DIR}/src) + +add_executable(clcompiler clcompiler.cpp ${Clover_SOURCE_DIR}/src/compiler) + +target_link_libraries(clcompiler OpenCL) diff --git a/src/tools/clcompiler.cpp b/src/tools/clcompiler.cpp new file mode 100644 index 0000000..5d24132 --- /dev/null +++ b/src/tools/clcompiler.cpp @@ -0,0 +1,23 @@ +#include "compiler.h" + +#include + +static +void usage(const char *progName) +{ + std::cout << "Usage: " << progName << " file.cl" << std::endl; +} + +int main(int argc, char **argv) +{ + Compiler compiler; + + if (argc < 2) { + usage(argv[0]); + return 1; + } + + compiler.compile(argv[1]); + + return 0; +} -- cgit v1.2.3