summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@intel.com>2015-11-12 16:47:02 +0800
committerYang Rong <rong.r.yang@intel.com>2015-11-25 11:44:59 +0800
commitd71c96dcd1d51832d400c1c4f254c39038bda270 (patch)
tree1482c0fb041c22354dcaa2ecace8cf3efc2cbe4e
parent56d450fe75a3f44655ac7acac0b58a9d311df047 (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.cpp3
-rw-r--r--backend/src/backend/gen_context.hpp1
-rw-r--r--backend/src/backend/gen_program.cpp2
-rw-r--r--backend/src/backend/gen_reg_allocation.cpp18
-rw-r--r--backend/src/backend/program.cpp24
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;
}