[Beignet] [PATCH 1/2] GBE: fix a corner case when allocate registers for local buffer.

Song, Ruiling ruiling.song at intel.com
Mon Dec 16 23:24:09 PST 2013


I am Ok with this patch, thanks for the fix and feedback to me.

-----Original Message-----
From: beignet-bounces at lists.freedesktop.org [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of Zhigang Gong
Sent: Tuesday, December 17, 2013 1:26 PM
To: beignet at lists.freedesktop.org
Cc: Gong, Zhigang
Subject: [Beignet] [PATCH 1/2] GBE: fix a corner case when allocate registers for local buffer.

We use a simple way to find a instruction which refer to the local data. Then we can identify the parent function. We found there is a corner case that the instruction may be modified at the optimization pass, for example the GVN pass. When all of the instruction's operand are modified to constant, then the whole instruction seens to be a constant either.

If that is the case, we fail to get a valid instruction and may trigger an assert. This patch change to check another use of the local data to avoid this assert.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/llvm/llvm_gen_backend.cpp |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 1316d4b..5755ac4 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1387,15 +1387,18 @@ namespace gbe
         uint32_t padding = getPadding(oldSlm*8, align);
 
         f.setSLMSize(oldSlm + padding/8 + getTypeByteSize(unit, ty));
-        const Value * parent = cast<Value>(&v);
+        const Value * val = cast<Value>(&v);
         // local variable can only be used in one kernel function. so, don't need to check its all uses.
         // loop through the Constant to find the instruction that use the global variable
-        do {
-          Value::const_use_iterator it = parent->use_begin();
-          parent = cast<Value>(*it);
-        } while(isa<Constant>(parent));
-
-        const Instruction * insn = cast<Instruction>(parent);
+        const Instruction * insn = NULL;
+        for( Value::const_use_iterator innerIt = val->use_begin(), prev = val->use_begin();
+             innerIt != prev->use_end() && insn == NULL;
+             prev = innerIt, innerIt = innerIt->use_begin() )
+          for( Value::const_use_iterator it = innerIt;
+               it != val->use_end() && insn == NULL;
+               it++)
+            insn = dyn_cast<Instruction>(*it);
+        GBE_ASSERT(insn && "Can't find a valid reference instruction 
+ for local variable.");
         const BasicBlock * bb = insn->getParent();
         const Function * func = bb->getParent();
         if(func != &F) continue;
--
1.7.9.5

_______________________________________________
Beignet mailing list
Beignet at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list