diff options
author | Ruiling Song <ruiling.song@intel.com> | 2014-05-09 12:54:25 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-05-09 12:27:56 +0800 |
commit | d6227270310a9fd4601a042899701312a8d4823e (patch) | |
tree | 829e4f202cd9718b01464c643f80a4d75dc512fa /backend/src | |
parent | 6f7e6852e8924d428affe8874d658eb2809663a5 (diff) | |
download | beignet-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.cpp | 25 |
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; |