[beignet] 02/07: Return failure (instead of asserting) on input containing unresolvable function calls
Rebecca Palmer
rnpalmer-guest at moszumanska.debian.org
Sat Jun 18 18:27:38 UTC 2016
This is an automated email from the git hooks/post-receive script.
rnpalmer-guest pushed a commit to branch master
in repository beignet.
commit 739cc4c39be06dfaf27e4c4787270f96f36e4317
Author: Rebecca N. Palmer <rebecca_palmer at zoho.com>
Date: Wed Jun 8 22:24:49 2016 +0100
Return failure (instead of asserting) on input containing
unresolvable function calls
---
debian/changelog | 2 +
debian/patches/noassert-missing-function.patch | 182 +++++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 185 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 857b9fe..5b3390c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,8 @@
beignet (1.1.2-3) UNRELEASED; urgency=medium
* Make profiling work on multiarch systems.
+ * Return failure (instead of asserting) on input containing
+ unresolvable function calls.
-- Rebecca N. Palmer <rebecca_palmer at zoho.com> Wed, 08 Jun 2016 22:10:03 +0100
diff --git a/debian/patches/noassert-missing-function.patch b/debian/patches/noassert-missing-function.patch
new file mode 100644
index 0000000..6393d9c
--- /dev/null
+++ b/debian/patches/noassert-missing-function.patch
@@ -0,0 +1,182 @@
+Description: Return error, don't assert-fail, on bad input
+
+As Beignet inlines all functions and does not otherwise support
+function calls, attempting to call a non-existent function is a
+codegen-time (not link-time) error, which currently print a message to
+stderr (which might not be visible in a graphical application) then
+assert-fail. This replaces this with an error in the build log.
+
+This is mostly for the benefit of jessie-backports (llvm 3.5), as
+sid (llvm 3.7) rejects these before getting this far.
+
+Author: Rebecca N. Palmer <rebecca_palmer at zoho.com>
+Forwarded: https://lists.freedesktop.org/archives/beignet/2016-June/007626.html
+
+--- beignet-1.1.2.orig/backend/src/backend/program.cpp
++++ beignet-1.1.2/backend/src/backend/program.cpp
+@@ -125,7 +125,7 @@ namespace gbe {
+ cloned_module = llvm::CloneModule((llvm::Module*)module);
+ #endif
+ }
+- if (llvmToGen(*unit, fileName, module, optLevel, OCL_STRICT_CONFORMANCE) == false) {
++ if (llvmToGen(*unit, fileName, module, optLevel, OCL_STRICT_CONFORMANCE, error) == false) {
+ if (fileName)
+ error = std::string(fileName) + " not found";
+ delete unit;
+@@ -138,19 +138,24 @@ namespace gbe {
+ unit = new ir::Unit();
+ if(cloned_module){
+ //suppose file exists and llvmToGen will not return false.
+- llvmToGen(*unit, fileName, cloned_module, 0, OCL_STRICT_CONFORMANCE);
++ llvmToGen(*unit, fileName, cloned_module, 0, OCL_STRICT_CONFORMANCE, error);
+ }else{
+ //suppose file exists and llvmToGen will not return false.
+- llvmToGen(*unit, fileName, module, 0, OCL_STRICT_CONFORMANCE);
++ llvmToGen(*unit, fileName, module, 0, OCL_STRICT_CONFORMANCE, error);
+ }
+ }
+- assert(unit->getValid());
+- this->buildFromUnit(*unit, error);
++ bool ret = false;
++ if(unit->getValid()){
++ std::string error2;
++ this->buildFromUnit(*unit, error2);
++ error = error + error2;
++ ret = true;
++ }
+ delete unit;
+ if(cloned_module){
+ delete (llvm::Module*) cloned_module;
+ }
+- return true;
++ return ret;
+ }
+
+ bool Program::buildFromUnit(const ir::Unit &unit, std::string &error) {
+--- beignet-1.1.2.orig/backend/src/llvm/llvm_gen_backend.cpp
++++ beignet-1.1.2/backend/src/llvm/llvm_gen_backend.cpp
+@@ -437,6 +437,7 @@ namespace gbe
+ Function *Func;
+ const Module *TheModule;
+ int btiBase;
++ bool has_errors;
+ public:
+ static char ID;
+ explicit GenWriter(ir::Unit &unit)
+@@ -446,7 +447,8 @@ namespace gbe
+ regTranslator(ctx),
+ LI(0),
+ TheModule(0),
+- btiBase(BTI_RESERVED_NUM)
++ btiBase(BTI_RESERVED_NUM),
++ has_errors(false)
+ {
+ #if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >=7
+ initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
+@@ -2662,6 +2664,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)
+@@ -3440,11 +3445,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");
+ };
+ }
+
+--- beignet-1.1.2.orig/backend/src/llvm/llvm_to_gen.cpp
++++ beignet-1.1.2/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"
+@@ -246,8 +248,36 @@ namespace gbe
+ BVAR(OCL_OUTPUT_LLVM_BEFORE_LINK, false);
+ 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)
++ bool llvmToGen(ir::Unit &unit, const char *fileName,const void* module, int optLevel, bool strictMath, std::string &errors)
+ {
+ std::string errInfo;
+ std::unique_ptr<llvm::raw_fd_ostream> o = NULL;
+@@ -284,6 +314,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);
+@@ -339,6 +372,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);
+--- beignet-1.1.2.orig/backend/src/llvm/llvm_to_gen.hpp
++++ beignet-1.1.2/backend/src/llvm/llvm_to_gen.hpp
+@@ -32,7 +32,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);
++ bool llvmToGen(ir::Unit &unit, const char *fileName, const void* module, int optLevel, bool strictMath, std::string &errors);
+
+ } /* namespace gbe */
+
diff --git a/debian/patches/series b/debian/patches/series
index 1004af4..e53670b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,4 @@ Enable-test-debug.patch
llvm38-support.patch
find-python35.patch
profiling-32on64.patch
+noassert-missing-function.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opencl/beignet.git
More information about the Pkg-opencl-commits
mailing list