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

Zhigang Gong zhigang.gong at linux.intel.com
Tue Dec 17 23:26:07 PST 2013


Please ignore this one as it was reviewed by ruiling already, I will push it
soon. Thanks.

-----Original Message-----
From: beignet-bounces at lists.freedesktop.org
[mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of Zhigang Gong
Sent: Wednesday, December 18, 2013 2:37 PM
To: beignet at lists.freedesktop.org
Cc: Zhigang Gong
Subject: [Beignet] [PATCH V2] 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