summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRebecca N. Palmer <rebecca_palmer@zoho.com>2016-06-06 23:37:59 +0100
committerYang Rong <rong.r.yang@intel.com>2016-07-13 17:57:27 +0800
commit1fd1c6d1faaa5be44ccda0cbdc0dd6d85fa8b2c0 (patch)
treec8c83596e6dc4dfa7b7dddb5014d8ad3fc758ff1
parent6901899ec90af0014128d2f87baa7e5a3863c41d (diff)
downloadbeignet-1fd1c6d1faaa5be44ccda0cbdc0dd6d85fa8b2c0.tar.gz
Report build failures in backend to the build log
As noted at llvm_gen_backend:94, we currently lack a mechanism for reporting failures in backend (beignet-managed) compiler passes to the build log, and instead print the error to stderr and assert-fail. This patch creates such a mechanism, and uses it for "function not found". Please note that it has not had much testing yet. Points for discussion/improvement: -Does not currently print source location information. -Are there other assertions that can be triggered by invalid input, and hence should also use this? Signed-off-by: Rebecca Palmer <rebecca_palmer@zoho.com> Reviewed-by: Yang Rong <rong.r.yang@intel.com>
-rw-r--r--backend/src/backend/program.cpp18
-rw-r--r--backend/src/llvm/llvm_gen_backend.cpp12
-rw-r--r--backend/src/llvm/llvm_to_gen.cpp41
-rw-r--r--backend/src/llvm/llvm_to_gen.hpp2
4 files changed, 59 insertions, 14 deletions
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index d13cba54..9746b22b 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -122,7 +122,7 @@ namespace gbe {
bool Program::buildFromLLVMFile(const char *fileName, const void* module, std::string &error, int optLevel) {
ir::Unit *unit = new ir::Unit();
llvm::Module * cloned_module = NULL;
- bool ret = true;
+ bool ret = false;
if(module){
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8
cloned_module = llvm::CloneModule((llvm::Module*)module).release();
@@ -133,7 +133,7 @@ namespace gbe {
bool strictMath = true;
if (fast_relaxed_math || !OCL_STRICT_CONFORMANCE)
strictMath = false;
- if (llvmToGen(*unit, fileName, module, optLevel, strictMath, OCL_PROFILING_LOG) == false) {
+ if (llvmToGen(*unit, fileName, module, optLevel, strictMath, OCL_PROFILING_LOG, error) == false) {
if (fileName)
error = std::string(fileName) + " not found";
delete unit;
@@ -146,15 +146,19 @@ namespace gbe {
unit = new ir::Unit();
if(cloned_module){
//suppose file exists and llvmToGen will not return false.
- llvmToGen(*unit, fileName, cloned_module, 0, strictMath, OCL_PROFILING_LOG);
+ llvmToGen(*unit, fileName, cloned_module, 0, strictMath, OCL_PROFILING_LOG, error);
}else{
//suppose file exists and llvmToGen will not return false.
- llvmToGen(*unit, fileName, module, 0, strictMath, OCL_PROFILING_LOG);
+ llvmToGen(*unit, fileName, module, 0, strictMath, OCL_PROFILING_LOG, error);
}
}
- assert(unit->getValid());
- if (!this->buildFromUnit(*unit, error))
- ret = false;
+ if(unit->getValid()){
+ std::string error2;
+ if (this->buildFromUnit(*unit, error2)){
+ ret = true;
+ }
+ error = error + error2;
+ }
delete unit;
if(cloned_module){
delete (llvm::Module*) cloned_module;
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 41cb7830..e2f6e4c4 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -513,6 +513,7 @@ namespace gbe
Function *Func;
const Module *TheModule;
int btiBase;
+ bool has_errors;
/*! legacyMode is for hardware before BDW,
* which do not support stateless memory access */
bool legacyMode;
@@ -528,6 +529,7 @@ namespace gbe
LI(0),
TheModule(0),
btiBase(BTI_RESERVED_NUM),
+ has_errors(false),
legacyMode(true)
{
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >=7
@@ -2921,6 +2923,9 @@ namespace gbe
pass = PASS_EMIT_REGISTERS;
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I)
visit(*I);
+
+ // Abort if this found an error (otherwise emitBasicBlock will assert)
+ if(has_errors){return;}
// First create all the labels (one per block) ...
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
@@ -3760,11 +3765,8 @@ namespace gbe
break;
case GEN_OCL_NOT_FOUND:
default:
- std::cerr << "Caller instruction: " << std::endl;
- I.dump();
- std::cerr << "Callee function: " << std::endl;
- Callee->dump();
- GBE_ASSERT(0);
+ has_errors = true;
+ Func->getContext().emitError(&I,"function '" + fnName + "' not found or cannot be inlined");
};
}
diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
index 41723d1b..02a69ec3 100644
--- a/backend/src/llvm/llvm_to_gen.cpp
+++ b/backend/src/llvm/llvm_to_gen.cpp
@@ -26,6 +26,8 @@
#include "llvm/llvm_gen_backend.hpp"
#include "llvm/llvm_to_gen.hpp"
+#include <llvm/IR/DiagnosticInfo.h>
+#include <llvm/IR/DiagnosticPrinter.h>
#include "sys/cvar.hpp"
#include "sys/platform.hpp"
#include "ir/unit.hpp"
@@ -249,8 +251,36 @@ namespace gbe
BVAR(OCL_OUTPUT_LLVM_AFTER_LINK, false);
BVAR(OCL_OUTPUT_LLVM_AFTER_GEN, false);
+ class gbeDiagnosticContext
+ {
+ public:
+ gbeDiagnosticContext() : _str(""), messages(_str), printer(messages), _has_errors(false) {}
+ void process(const llvm::DiagnosticInfo &diagnostic)
+ {
+ if (diagnostic.getSeverity() != DS_Remark) { // avoid noise from function inlining remarks
+ diagnostic.print(printer);
+ }
+ if (diagnostic.getSeverity() == DS_Error) {
+ _has_errors = true;
+ }
+ }
+ std::string str(){return messages.str();}
+ bool has_errors(){return _has_errors;}
+ private:
+ std::string _str;
+ llvm::raw_string_ostream messages;
+ llvm::DiagnosticPrinterRawOStream printer;
+ bool _has_errors;
+ };
+
+ void gbeDiagnosticHandler(const llvm::DiagnosticInfo &diagnostic, void *context)
+ {
+ gbeDiagnosticContext *dc = reinterpret_cast<gbeDiagnosticContext*>(context);
+ dc->process(diagnostic);
+ }
+
bool llvmToGen(ir::Unit &unit, const char *fileName,const void* module,
- int optLevel, bool strictMath, int profiling)
+ int optLevel, bool strictMath, int profiling, std::string &errors)
{
std::string errInfo;
std::unique_ptr<llvm::raw_fd_ostream> o = NULL;
@@ -287,6 +317,9 @@ namespace gbe
Module &mod = *M.get();
DataLayout DL(&mod);
+
+ gbeDiagnosticContext dc;
+ mod.getContext().setDiagnosticHandler(&gbeDiagnosticHandler,&dc);
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7
mod.setDataLayout(DL);
@@ -345,6 +378,12 @@ namespace gbe
passes.add(createCFGOnlyPrinterPass());
passes.add(createGenPass(unit));
passes.run(mod);
+ errors = dc.str();
+ if(dc.has_errors()){
+ unit.setValid(false);
+ delete libraryInfo;
+ return true;
+ }
// Print the code extra optimization passes
OUTPUT_BITCODE(AFTER_GEN, mod);
diff --git a/backend/src/llvm/llvm_to_gen.hpp b/backend/src/llvm/llvm_to_gen.hpp
index 56671973..e0a6145c 100644
--- a/backend/src/llvm/llvm_to_gen.hpp
+++ b/backend/src/llvm/llvm_to_gen.hpp
@@ -33,7 +33,7 @@ namespace gbe {
/*! Convert the LLVM IR code to a GEN IR code,
optLevel 0 equal to clang -O1 and 1 equal to clang -O2*/
bool llvmToGen(ir::Unit &unit, const char *fileName, const void* module,
- int optLevel, bool strictMath, int profiling);
+ int optLevel, bool strictMath, int profiling, std::string &errors);
} /* namespace gbe */