diff options
author | Zhigang Gong <zhigang.gong@intel.com> | 2015-11-12 16:47:02 +0800 |
---|---|---|
committer | Yang Rong <rong.r.yang@intel.com> | 2015-11-25 11:44:59 +0800 |
commit | d71c96dcd1d51832d400c1c4f254c39038bda270 (patch) | |
tree | 1482c0fb041c22354dcaa2ecace8cf3efc2cbe4e | |
parent | 56d450fe75a3f44655ac7acac0b58a9d311df047 (diff) |
GBE: don't assert even if we fail to compile kernel at the backend stage.
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.gong@intel.com>
Reviewed-by: Ruiling Song <ruiling.song@intel.com>
-rw-r--r-- | backend/src/backend/context.cpp | 3 | ||||
-rw-r--r-- | backend/src/backend/gen_context.hpp | 1 | ||||
-rw-r--r-- | backend/src/backend/gen_program.cpp | 2 | ||||
-rw-r--r-- | backend/src/backend/gen_reg_allocation.cpp | 18 | ||||
-rw-r--r-- | backend/src/backend/program.cpp | 24 |
5 files changed, 31 insertions, 17 deletions
diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp index 51d643e1..47d8a457 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 af252ed5..da9bbbed 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 80143463..5149d498 100644 --- a/backend/src/backend/gen_program.cpp +++ b/backend/src/backend/gen_program.cpp @@ -204,7 +204,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 e797458e..cd819d14 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 08b33daf..adf22182 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -117,10 +117,12 @@ namespace gbe { BVAR(OCL_OUTPUT_GEN_IR, false); BVAR(OCL_STRICT_CONFORMANCE, true); IVAR(OCL_PROFILING_LOG, 0, 0, 1); // Int for different profiling types. + 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); } @@ -144,12 +146,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) { @@ -161,8 +164,15 @@ namespace gbe { for (const auto &pair : set) { const std::string &name = pair.first; Kernel *kernel = this->compileKernel(unit, name, !OCL_STRICT_CONFORMANCE, OCL_PROFILING_LOG); - kernel->setProfilingInfo(new ir::ProfilingInfo(*unit.getProfilingInfo())); + 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->setProfilingInfo(new ir::ProfilingInfo(*unit.getProfilingInfo())); kernel->setImageSet(pair.second->getImageSet()); kernel->setPrintfSet(pair.second->getPrintfSet()); kernel->setCompileWorkGroupSize(pair.second->getCompileWorkGroupSize()); @@ -520,8 +530,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) { @@ -831,10 +839,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; } |