diff options
author | Yang Rong <rong.r.yang@intel.com> | 2015-08-24 11:59:36 +0800 |
---|---|---|
committer | Yang Rong <rong.r.yang@intel.com> | 2015-09-18 16:21:18 +0800 |
commit | 811de6ddd6bf2fa7f68900dc6233739bb761893d (patch) | |
tree | b053dabeaa45a7342e1a4c68ddf965e2970f4889 | |
parent | ff5bb6aa39792799d6396062bb088d72c85fbce8 (diff) |
Fix piglit clLinkProgram fail.
1. return CL_INVALID_LINKER_OPTIONS when invalid options, using clang to check the options.
2. return CL_INVALID_OPERATION when the binary type is not same.
3. When link fail, will not return CL_LINK_PROGRAM_FAILURE, fix it.
4. Should not delete program in genProgramBuildFromLLVM, the program is new and delete from runtime.
Signed-off-by: Yang Rong <rong.r.yang@intel.com>
Reviewed-by: Luo, Xionghu <xionghu.luo@intel.com>
-rw-r--r-- | backend/src/backend/gen_program.cpp | 5 | ||||
-rw-r--r-- | backend/src/backend/program.cpp | 47 | ||||
-rw-r--r-- | backend/src/backend/program.h | 10 | ||||
-rw-r--r-- | src/cl_api.c | 1 | ||||
-rw-r--r-- | src/cl_gbe_loader.cpp | 5 | ||||
-rw-r--r-- | src/cl_gbe_loader.h | 1 | ||||
-rw-r--r-- | src/cl_program.c | 20 |
7 files changed, 80 insertions, 9 deletions
diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp index 3c4983ed..04da692b 100644 --- a/backend/src/backend/gen_program.cpp +++ b/backend/src/backend/gen_program.cpp @@ -386,7 +386,7 @@ namespace gbe { return (gbe_program) program; } - static void genProgramLinkFromLLVM(gbe_program dst_program, + static bool genProgramLinkFromLLVM(gbe_program dst_program, gbe_program src_program, size_t stringSize, char * err, @@ -408,10 +408,12 @@ namespace gbe { err[stringSize-1] = '\0'; *errSize = strlen(err); } + return true; } } // Everything run fine #endif + return false; } static void genProgramBuildFromLLVM(gbe_program program, @@ -444,7 +446,6 @@ namespace gbe { std::memcpy(err, error.c_str(), msgSize); *errSize = error.size(); } - GBE_DELETE(p); } releaseLLVMContextLock(); #endif diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index f5865c22..0ee76fcc 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -902,23 +902,64 @@ namespace gbe { #endif #ifdef GBE_COMPILER_AVAILABLE - static void programLinkProgram(gbe_program dst_program, + static bool programLinkProgram(gbe_program dst_program, gbe_program src_program, size_t stringSize, char * err, size_t * errSize) { + bool ret = 0; acquireLLVMContextLock(); - gbe_program_link_from_llvm(dst_program, src_program, stringSize, err, errSize); + ret = gbe_program_link_from_llvm(dst_program, src_program, stringSize, err, errSize); releaseLLVMContextLock(); if (OCL_OUTPUT_BUILD_LOG && err) llvm::errs() << err; + return ret; } #endif +#ifdef GBE_COMPILER_AVAILABLE + static bool programCheckOption(const char * option) + { + vector<const char *> args; + if (option == NULL) return 1; //if NULL, return ok + std::string s(option); + size_t pos = s.find("-create-library"); + //clang don't accept -create-library and -enable-link-options, erase them + if(pos != std::string::npos) { + s.erase(pos, strlen("-create-library")); + } + pos = s.find("-enable-link-options"); + if(pos != std::string::npos) { + s.erase(pos, strlen("-enable-link-options")); + } + args.push_back(s.c_str()); + + // The compiler invocation needs a DiagnosticsEngine so it can report problems + std::string ErrorString; + llvm::raw_string_ostream ErrorInfo(ErrorString); + llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts = new clang::DiagnosticOptions(); + DiagOpts->ShowCarets = false; + DiagOpts->ShowPresumedLoc = true; + + clang::TextDiagnosticPrinter *DiagClient = + new clang::TextDiagnosticPrinter(ErrorInfo, &*DiagOpts); + llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs()); + clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); + + // Create the compiler invocation + std::unique_ptr<clang::CompilerInvocation> CI(new clang::CompilerInvocation); + return clang::CompilerInvocation::CreateFromArgs(*CI, + &args[0], + &args[0] + args.size(), + Diags); + } +#endif + + static size_t programGetGlobalConstantSize(gbe_program gbeProgram) { if (gbeProgram == NULL) return 0; const gbe::Program *program = (const gbe::Program*) gbeProgram; @@ -1163,6 +1204,7 @@ void releaseLLVMContextLock() GBE_EXPORT_SYMBOL gbe_program_new_from_source_cb *gbe_program_new_from_source = NULL; GBE_EXPORT_SYMBOL gbe_program_compile_from_source_cb *gbe_program_compile_from_source = NULL; GBE_EXPORT_SYMBOL gbe_program_link_program_cb *gbe_program_link_program = NULL; +GBE_EXPORT_SYMBOL gbe_program_check_opt_cb *gbe_program_check_opt = NULL; GBE_EXPORT_SYMBOL gbe_program_new_from_binary_cb *gbe_program_new_from_binary = NULL; GBE_EXPORT_SYMBOL gbe_program_new_from_llvm_binary_cb *gbe_program_new_from_llvm_binary = NULL; GBE_EXPORT_SYMBOL gbe_program_serialize_to_binary_cb *gbe_program_serialize_to_binary = NULL; @@ -1218,6 +1260,7 @@ namespace gbe gbe_program_new_from_source = gbe::programNewFromSource; gbe_program_compile_from_source = gbe::programCompileFromSource; gbe_program_link_program = gbe::programLinkProgram; + gbe_program_check_opt = gbe::programCheckOption; gbe_program_get_global_constant_size = gbe::programGetGlobalConstantSize; gbe_program_get_global_constant_data = gbe::programGetGlobalConstantData; gbe_program_clean_llvm_resource = gbe::programCleanLlvmResource; diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h index 3267714f..84ce3333 100644 --- a/backend/src/backend/program.h +++ b/backend/src/backend/program.h @@ -30,6 +30,7 @@ #include <stdint.h> #include <stdlib.h> +#include <stdbool.h> #ifdef __cplusplus extern "C" { @@ -181,14 +182,19 @@ typedef gbe_program (gbe_program_compile_from_source_cb)(uint32_t deviceID, char *err, size_t *err_size); extern gbe_program_compile_from_source_cb *gbe_program_compile_from_source; + /*! link the programs. */ -typedef void (gbe_program_link_program_cb)(gbe_program dst_program, +typedef bool (gbe_program_link_program_cb)(gbe_program dst_program, gbe_program src_program, size_t stringSize, char * err, size_t * errSize); extern gbe_program_link_program_cb *gbe_program_link_program; +/*! check link option. */ +typedef bool (gbe_program_check_opt_cb)(const char *option); +extern gbe_program_check_opt_cb *gbe_program_check_opt; + /*! create s new genprogram for link. */ typedef gbe_program (gbe_program_new_gen_program_cb)(uint32_t deviceID, const void *module, @@ -220,7 +226,7 @@ typedef gbe_program (gbe_program_new_from_llvm_cb)(uint32_t deviceID, extern gbe_program_new_from_llvm_cb *gbe_program_new_from_llvm; /*! link the programs from llvm level. */ -typedef void (gbe_program_link_from_llvm_cb)(gbe_program dst_program, +typedef bool (gbe_program_link_from_llvm_cb)(gbe_program dst_program, gbe_program src_program, size_t stringSize, char * err, diff --git a/src/cl_api.c b/src/cl_api.c index dbbcbb08..0c16a429 100644 --- a/src/cl_api.c +++ b/src/cl_api.c @@ -1015,6 +1015,7 @@ clLinkProgram(cl_context context, INVALID_VALUE_IF (pfn_notify == 0 && user_data != NULL); INVALID_VALUE_IF (num_input_programs == 0 && input_programs != NULL); INVALID_VALUE_IF (num_input_programs != 0 && input_programs == NULL); + INVALID_VALUE_IF (num_input_programs == 0 && input_programs == NULL); program = cl_program_link(context, num_input_programs, input_programs, options, &err); diff --git a/src/cl_gbe_loader.cpp b/src/cl_gbe_loader.cpp index c3454e83..e832a535 100644 --- a/src/cl_gbe_loader.cpp +++ b/src/cl_gbe_loader.cpp @@ -27,6 +27,7 @@ gbe_program_new_from_source_cb *compiler_program_new_from_source = NULL; gbe_program_compile_from_source_cb *compiler_program_compile_from_source = NULL; gbe_program_new_gen_program_cb *compiler_program_new_gen_program = NULL; gbe_program_link_program_cb *compiler_program_link_program = NULL; +gbe_program_check_opt_cb *compiler_program_check_opt = NULL; gbe_program_build_from_llvm_cb *compiler_program_build_from_llvm = NULL; gbe_program_new_from_llvm_binary_cb *compiler_program_new_from_llvm_binary = NULL; gbe_program_serialize_to_binary_cb *compiler_program_serialize_to_binary = NULL; @@ -279,6 +280,10 @@ struct GbeLoaderInitializer if (compiler_program_link_program == NULL) return; + compiler_program_check_opt = *(gbe_program_check_opt_cb **)dlsym(dlhCompiler, "gbe_program_check_opt"); + if (compiler_program_check_opt == NULL) + return; + compiler_program_build_from_llvm = *(gbe_program_build_from_llvm_cb **)dlsym(dlhCompiler, "gbe_program_build_from_llvm"); if (compiler_program_build_from_llvm == NULL) return; diff --git a/src/cl_gbe_loader.h b/src/cl_gbe_loader.h index 6fa4c988..de91c85f 100644 --- a/src/cl_gbe_loader.h +++ b/src/cl_gbe_loader.h @@ -28,6 +28,7 @@ extern gbe_program_new_from_source_cb *compiler_program_new_from_source; extern gbe_program_compile_from_source_cb *compiler_program_compile_from_source; extern gbe_program_new_gen_program_cb *compiler_program_new_gen_program; extern gbe_program_link_program_cb *compiler_program_link_program; +extern gbe_program_check_opt_cb *compiler_program_check_opt; extern gbe_program_build_from_llvm_cb *compiler_program_build_from_llvm; extern gbe_program_new_from_llvm_binary_cb *compiler_program_new_from_llvm_binary; extern gbe_program_serialize_to_binary_cb *compiler_program_serialize_to_binary; diff --git a/src/cl_program.c b/src/cl_program.c index 4870d5d7..ee5b8b1a 100644 --- a/src/cl_program.c +++ b/src/cl_program.c @@ -605,20 +605,34 @@ cl_program_link(cl_context context, cl_int i = 0; int copyed = 0; p = cl_program_new(context); + cl_bool ret = 0; if (!check_cl_version_option(p, options)) { err = CL_BUILD_PROGRAM_FAILURE; goto error; } + //Although we don't use options, but still need check options + if(!compiler_program_check_opt(options)) { + err = CL_INVALID_LINKER_OPTIONS; + goto error; + } + p->opaque = compiler_program_new_gen_program(context->device->device_id, NULL, NULL); + for(i = 1; i < num_input_programs; i++) { + //num_input_programs >0 and input_programs MUST not NULL, so compare with input_programs[0] directly. + if(input_programs[i]->binary_type != input_programs[0]->binary_type) { + err = CL_INVALID_OPERATION; + goto error; + } + } for(i = 0; i < num_input_programs; i++) { // if program create with llvm binary, need deserilize first to get module. if(input_programs[i]) - compiler_program_link_program(p->opaque, input_programs[i]->opaque, - p->build_log_max_sz, p->build_log, &p->build_log_sz); - if (UNLIKELY(p->opaque == NULL)) { + ret = compiler_program_link_program(p->opaque, input_programs[i]->opaque, + p->build_log_max_sz, p->build_log, &p->build_log_sz); + if (UNLIKELY(ret)) { err = CL_LINK_PROGRAM_FAILURE; goto error; } |