We should not assert even if the application triggers a internal limitation such as lack of scratch space. We should return error to the application and let the application to make further decision.
Signed-off-by: Zhigang Gong <zhigang.g...@intel.com> --- backend/src/backend/context.cpp | 3 +-- backend/src/backend/gen_context.hpp | 1 + backend/src/backend/gen_program.cpp | 2 +- backend/src/backend/gen_reg_allocation.cpp | 18 ++++++++++++------ backend/src/backend/program.cpp | 22 +++++++++++++++------- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp index 51d643e..47d8a45 100644 --- a/backend/src/backend/context.cpp +++ b/backend/src/backend/context.cpp @@ -229,8 +229,7 @@ namespace gbe // We have a valid offset now return aligned; } - GBE_ASSERT( !assertFail ); - return 0; + return -1; } void SimpleAllocator::deallocate(int32_t offset) diff --git a/backend/src/backend/gen_context.hpp b/backend/src/backend/gen_context.hpp index 155b68e..c622236 100644 --- a/backend/src/backend/gen_context.hpp +++ b/backend/src/backend/gen_context.hpp @@ -49,6 +49,7 @@ namespace gbe REGISTER_ALLOCATION_FAIL, REGISTER_SPILL_EXCEED_THRESHOLD, REGISTER_SPILL_FAIL, + REGISTER_SPILL_NO_SPACE, OUT_OF_RANGE_IF_ENDIF, } CompileErrorCode; diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp index bb22542..a12ab39 100644 --- a/backend/src/backend/gen_program.cpp +++ b/backend/src/backend/gen_program.cpp @@ -197,7 +197,7 @@ namespace gbe { GBE_ASSERT(!(ctx->getErrCode() == OUT_OF_RANGE_IF_ENDIF && ctx->getIFENDIFFix())); } - GBE_ASSERTM(kernel != NULL, "Fail to compile kernel, may need to increase reserved registers for spilling."); + //GBE_ASSERTM(kernel != NULL, "Fail to compile kernel, may need to increase reserved registers for spilling."); return kernel; #else return NULL; diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp index a9338c5..13c856e 100644 --- a/backend/src/backend/gen_reg_allocation.cpp +++ b/backend/src/backend/gen_reg_allocation.cpp @@ -192,7 +192,7 @@ namespace gbe INLINE bool spillReg(GenRegInterval interval, bool isAllocated = false); INLINE bool spillReg(ir::Register reg, bool isAllocated = false); INLINE bool vectorCanSpill(SelectionVector *vector); - INLINE void allocateScratchForSpilled(); + INLINE bool allocateScratchForSpilled(); void allocateCurbePayload(void); /*! replace specified source/dst register with temporary register and update interval */ @@ -788,7 +788,10 @@ namespace gbe return false; } } - allocateScratchForSpilled(); + if (!allocateScratchForSpilled()) { + ctx.errCode = REGISTER_SPILL_NO_SPACE; + return false; + } bool success = selection.spillRegs(spilledRegs, reservedReg); if (!success) { ctx.errCode = REGISTER_SPILL_FAIL; @@ -799,7 +802,7 @@ namespace gbe return true; } - INLINE void GenRegAllocator::Opaque::allocateScratchForSpilled() + INLINE bool GenRegAllocator::Opaque::allocateScratchForSpilled() { const uint32_t regNum = spilledRegs.size(); this->starting.resize(regNum); @@ -833,7 +836,10 @@ namespace gbe ir::RegisterFamily family = ctx.sel->getRegisterFamily(cur->reg); it->second.addr = ctx.allocateScratchMem(getFamilySize(family) * ctx.getSimdWidth()); - } + if (it->second.addr == -1) + return false; + } + return true; } INLINE bool GenRegAllocator::Opaque::expireReg(ir::Register reg) @@ -1019,7 +1025,7 @@ namespace gbe INLINE uint32_t GenRegAllocator::Opaque::allocateReg(GenRegInterval interval, uint32_t size, uint32_t alignment) { - uint32_t grfOffset; + int32_t grfOffset; // Doing expireGRF too freqently will cause the post register allocation // scheduling very hard. As it will cause a very high register conflict rate. // The tradeoff here is to reduce the freqency here. And if we are under spilling @@ -1032,7 +1038,7 @@ namespace gbe // and the source is a scalar Dword. If that is the case, the byte register // must get 4byte alignment register offset. alignment = (alignment + 3) & ~3; - while ((grfOffset = ctx.allocate(size, alignment)) == 0) { + while ((grfOffset = ctx.allocate(size, alignment)) == -1) { const bool success = this->expireGRF(interval); if (success == false) { if (spillAtInterval(interval, size, alignment) == false) diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index 472734b..15d6909 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -114,10 +114,12 @@ namespace gbe { #ifdef GBE_COMPILER_AVAILABLE BVAR(OCL_OUTPUT_GEN_IR, false); BVAR(OCL_STRICT_CONFORMANCE, true); + BVAR(OCL_OUTPUT_BUILD_LOG, false); 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; if(module){ cloned_module = llvm::CloneModule((llvm::Module*)module); } @@ -141,12 +143,13 @@ namespace gbe { } } assert(unit->getValid()); - this->buildFromUnit(*unit, error); + if (!this->buildFromUnit(*unit, error)) + ret = false; delete unit; if(cloned_module){ delete (llvm::Module*) cloned_module; } - return true; + return ret; } bool Program::buildFromUnit(const ir::Unit &unit, std::string &error) { @@ -158,6 +161,13 @@ namespace gbe { for (const auto &pair : set) { const std::string &name = pair.first; Kernel *kernel = this->compileKernel(unit, name, !OCL_STRICT_CONFORMANCE); + if (!kernel) { + error += name; + error += ":(GBE): error: failed in Gen backend.\n"; + if (OCL_OUTPUT_BUILD_LOG) + llvm::errs() << error; + return false; + } kernel->setSamplerSet(pair.second->getSamplerSet()); kernel->setImageSet(pair.second->getImageSet()); kernel->setPrintfSet(pair.second->getPrintfSet()); @@ -516,8 +526,6 @@ namespace gbe { } #ifdef GBE_COMPILER_AVAILABLE - BVAR(OCL_OUTPUT_BUILD_LOG, false); - static bool buildModuleFromSource(const char *source, llvm::Module** out_module, llvm::LLVMContext* llvm_ctx, std::string dumpLLVMFileName, std::vector<std::string>& options, size_t stringSize, char *err, size_t *errSize) { @@ -827,10 +835,10 @@ namespace gbe { stringSize, err, errSize)) { // Now build the program from llvm size_t clangErrSize = 0; - if (err != NULL) { + if (err != NULL && *errSize != 0) { GBE_ASSERT(errSize != NULL); - stringSize -= *errSize; - err += *errSize; + stringSize = stringSize - *errSize; + err = err + *errSize; clangErrSize = *errSize; } -- 1.9.1 _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/beignet