summaryrefslogtreecommitdiff
path: root/backend/src
diff options
context:
space:
mode:
authorRuiling Song <ruiling.song@intel.com>2014-05-09 12:54:25 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-05-09 12:27:56 +0800
commitd6227270310a9fd4601a042899701312a8d4823e (patch)
tree829e4f202cd9718b01464c643f80a4d75dc512fa /backend/src
parent6f7e6852e8924d428affe8874d658eb2809663a5 (diff)
downloadbeignet-d6227270310a9fd4601a042899701312a8d4823e.tar.gz
GBE: Refine logic of finding where the local variable is defined.
Traverse all uses of the local variable as there maybe some dead use. Most time, the function will return fast, as the use tree is not deep. Signed-off-by: Ruiling Song <ruiling.song@intel.com> Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
Diffstat (limited to 'backend/src')
-rw-r--r--backend/src/llvm/llvm_gen_backend.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 8489c871..c71a17dc 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1402,6 +1402,18 @@ namespace gbe
BVAR(OCL_OPTIMIZE_PHI_MOVES, true);
BVAR(OCL_OPTIMIZE_LOADI, true);
+ static const Instruction *getInstructionUseLocal(const Value *v) {
+ // Local variable can only be used in one kernel function. So, if we find
+ // one instruction that use the local variable, simply return.
+ const Instruction *insn = NULL;
+ for(Value::const_use_iterator iter = v->use_begin(); iter != v->use_end(); ++iter) {
+ if(isa<Instruction>(*iter)) return cast<const Instruction>(*iter);
+ insn = getInstructionUseLocal(*iter);
+ if(insn != NULL) break;
+ }
+ return insn;
+ }
+
void GenWriter::allocateGlobalVariableRegister(Function &F)
{
// Allocate a address register for each global variable
@@ -1414,18 +1426,9 @@ namespace gbe
ir::AddressSpace addrSpace = addressSpaceLLVMToGen(v.getType()->getAddressSpace());
if(addrSpace == ir::MEM_LOCAL) {
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
- // FIXME need to find a more grace way to find the function which use this local data.
- const Instruction * insn = NULL;
- for( Value::const_use_iterator it = val->use_begin(), prev = val->use_begin();
- it != prev->use_end() && insn == NULL;
- prev = it, it = it->use_begin() )
- for( Value::const_use_iterator innerIt = it;
- innerIt != val->use_end() && insn == NULL;
- innerIt++)
- insn = dyn_cast<Instruction>(*innerIt);
+ const Instruction *insn = getInstructionUseLocal(val);
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;