summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/src/backend/program.cpp73
-rw-r--r--src/cl_api.c5
-rw-r--r--src/cl_program.c13
-rw-r--r--src/cl_program.h3
4 files changed, 70 insertions, 24 deletions
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index 093febc5..8e80bbb7 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -464,7 +464,8 @@ namespace gbe {
GBE_SAFE_DELETE(program);
}
- static void buildModuleFromSource(const char* input, const char* output, std::string options) {
+ static bool buildModuleFromSource(const char* input, const char* output, std::string options,
+ size_t stringSize, char *err, size_t *errSize) {
// Arguments to pass to the clang frontend
vector<const char *> args;
bool bOpt = true;
@@ -516,24 +517,26 @@ namespace gbe {
args.push_back(input);
// 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;
#if LLVM_VERSION_MINOR <= 1
args.push_back("-triple");
args.push_back("ptx32");
clang::TextDiagnosticPrinter *DiagClient =
- new clang::TextDiagnosticPrinter(llvm::errs(), clang::DiagnosticOptions());
+ new clang::TextDiagnosticPrinter(ErrorInfo, *DiagOpts)
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
clang::DiagnosticsEngine Diags(DiagID, DiagClient);
#else
args.push_back("-ffp-contract=off");
- llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts = new clang::DiagnosticOptions();
clang::TextDiagnosticPrinter *DiagClient =
- new clang::TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
+ new clang::TextDiagnosticPrinter(ErrorInfo, &*DiagOpts);
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
#endif /* LLVM_VERSION_MINOR <= 1 */
-
// Create the compiler invocation
llvm::OwningPtr<clang::CompilerInvocation> CI(new clang::CompilerInvocation);
clang::CompilerInvocation::CreateFromArgs(*CI,
@@ -548,10 +551,12 @@ namespace gbe {
#if LLVM_VERSION_MINOR <= 2
Clang.createDiagnostics(args.size(), &args[0]);
#else
- Clang.createDiagnostics();
+ Clang.createDiagnostics(DiagClient, false);
#endif /* LLVM_VERSION_MINOR <= 2 */
+
+ Clang.getDiagnosticOpts().ShowCarets = false;
if (!Clang.hasDiagnostics())
- return;
+ return false;
// Set Language
clang::LangOptions & lang_opts = Clang.getLangOpts();
@@ -573,23 +578,42 @@ namespace gbe {
// Create an action and make the compiler instance carry it out
llvm::OwningPtr<clang::CodeGenAction> Act(new clang::EmitLLVMOnlyAction());
auto retVal = Clang.ExecuteAction(*Act);
+
+ if (err != NULL) {
+ GBE_ASSERT(errSize != NULL);
+ *errSize = ErrorString.copy(err, stringSize - 1, 0);
+ ErrorString.clear();
+ } else {
+ // flush the error messages to the errs() if there is no
+ // error string buffer.
+ llvm::errs() << ErrorString;
+ }
if (!retVal)
- return;
+ return false;
llvm::Module *module = Act->takeModule();
- std::string ErrorInfo;
#if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR > 3)
auto mode = llvm::sys::fs::F_Binary;
#else
auto mode = llvm::raw_fd_ostream::F_Binary;
#endif
- llvm::raw_fd_ostream OS(output, ErrorInfo, mode);
+ llvm::raw_fd_ostream OS(output, ErrorString, mode);
//still write to temp file for code simply, otherwise need add another function.
//because gbe_program_new_from_llvm also be used by cl_program_create_from_llvm, can't be removed
//TODO: Pass module to llvmToGen, if use module, should return Act and use OwningPtr out of this funciton
llvm::WriteBitcodeToFile(module, OS);
+ if (err != NULL && *errSize < stringSize - 1 && ErrorString.size() > 0) {
+ size_t errLen;
+ errLen = ErrorString.copy(err + *errSize, stringSize - *errSize - 1, 0);
+ *errSize += errLen;
+ } else if (err == NULL) {
+ // flush the error messages to the errs() if there is no
+ // error string buffer.
+ llvm::errs() << ErrorString;
+ }
OS.close();
+ return true;
}
extern std::string ocl_stdlib_str;
@@ -640,15 +664,28 @@ namespace gbe {
fwrite(source, strlen(source), 1, clFile);
fclose(clFile);
- buildModuleFromSource(clName.c_str(), llName.c_str(), clOpt.c_str());
- remove(clName.c_str());
-
+ gbe_program p;
+ if (buildModuleFromSource(clName.c_str(), llName.c_str(), clOpt.c_str(),
+ stringSize, err, errSize)) {
// Now build the program from llvm
- static std::mutex gbe_mutex;
- gbe_mutex.lock();
- gbe_program p = gbe_program_new_from_llvm(llName.c_str(), stringSize, err, errSize);
- gbe_mutex.unlock();
- remove(llName.c_str());
+ static std::mutex gbe_mutex;
+ gbe_mutex.lock();
+ size_t clangErrSize = 0;
+ if (err != NULL) {
+ GBE_ASSERT(errSize != NULL);
+ stringSize -= *errSize;
+ err += *errSize;
+ clangErrSize = *errSize;
+ }
+ p = gbe_program_new_from_llvm(llName.c_str(), stringSize,
+ err, errSize);
+ if (err != NULL)
+ *errSize += clangErrSize;
+ gbe_mutex.unlock();
+ remove(llName.c_str());
+ } else
+ p = NULL;
+ remove(clName.c_str());
return p;
}
diff --git a/src/cl_api.c b/src/cl_api.c
index 59c47d3e..0978129c 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -975,8 +975,9 @@ clGetProgramBuildInfo(cl_program program,
FILL_GETINFO_RET (char, (strlen(ret_str)+1), ret_str, CL_SUCCESS);
} else if (param_name == CL_PROGRAM_BUILD_LOG) {
- // TODO: need to add logs in backend when compiling.
- FILL_GETINFO_RET (char, (strlen(ret_str)+1), ret_str, CL_SUCCESS);
+ FILL_GETINFO_RET (char, program->build_log_sz + 1, program->build_log, CL_SUCCESS);
+ if (param_value_size_ret)
+ *param_value_size_ret = program->build_log_sz + 1;
} else {
return CL_INVALID_VALUE;
}
diff --git a/src/cl_program.c b/src/cl_program.c
index df2f1e09..d6d68c07 100644
--- a/src/cl_program.c
+++ b/src/cl_program.c
@@ -109,7 +109,9 @@ cl_program_new(cl_context ctx)
p->ref_n = 1;
p->magic = CL_MAGIC_PROGRAM_HEADER;
p->ctx = ctx;
-
+ p->build_log = calloc(200, sizeof(char));
+ if (p->build_log)
+ p->build_log_max_sz = 200;
/* The queue also belongs to its context */
cl_context_add_ref(ctx);
@@ -223,7 +225,7 @@ cl_program_create_from_llvm(cl_context ctx,
INVALID_VALUE_IF (file_name == NULL);
program = cl_program_new(ctx);
- program->opaque = gbe_program_new_from_llvm(file_name, 0, NULL, NULL);
+ program->opaque = gbe_program_new_from_llvm(file_name, program->build_log_max_sz, program->build_log, &program->build_log_sz);
if (UNLIKELY(program->opaque == NULL)) {
err = CL_INVALID_PROGRAM;
goto error;
@@ -324,9 +326,12 @@ cl_program_build(cl_program p, const char *options)
}
if (p->source_type == FROM_SOURCE) {
- p->opaque = gbe_program_new_from_source(p->source, 0, options, NULL, NULL);
+ p->opaque = gbe_program_new_from_source(p->source, p->build_log_max_sz, options, p->build_log, &p->build_log_sz);
if (UNLIKELY(p->opaque == NULL)) {
- err = CL_BUILD_PROGRAM_FAILURE;
+ if (p->build_log_sz > 0 && strstr(p->build_log, "error: error reading 'options'"))
+ err = CL_INVALID_BUILD_OPTIONS;
+ else
+ err = CL_BUILD_PROGRAM_FAILURE;
goto error;
}
diff --git a/src/cl_program.h b/src/cl_program.h
index 2cb547a0..a6d75da8 100644
--- a/src/cl_program.h
+++ b/src/cl_program.h
@@ -54,6 +54,9 @@ struct _cl_program {
uint32_t source_type:2; /* Built from binary, source or LLVM */
uint32_t is_built:1; /* Did we call clBuildProgram on it? */
char *build_opts; /* The build options for this program */
+ size_t build_log_max_sz; /*build log maximum size in byte.*/
+ char *build_log; /* The build log for this program. */
+ size_t build_log_sz; /* The actual build log size.*/
};
/* Create a empty program */