diff options
author | Duncan Sands <baldrick@free.fr> | 2010-01-06 15:37:47 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2010-01-06 15:37:47 +0000 |
commit | c8493da5b18fec8995ba90a0e609cf4bd9003554 (patch) | |
tree | 5d1beb08643f9e7f16e86fac6e73f1602fb5cc7d /llvm/lib/Transforms | |
parent | fd0b2f8fe486f707b4f7b71501c1b60e5e7b5fd2 (diff) | |
download | bcm5719-llvm-c8493da5b18fec8995ba90a0e609cf4bd9003554.tar.gz bcm5719-llvm-c8493da5b18fec8995ba90a0e609cf4bd9003554.zip |
Fix a README item: have functionattrs look through selects and
phi nodes when deciding which pointers point to local memory.
I actually checked long ago how useful this is, and it isn't
very: it hardly ever fires in the testsuite, but since Chris
wants it here it is!
llvm-svn: 92836
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 0bff2b94e9d..f41698adc5e 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -79,16 +79,47 @@ Pass *llvm::createFunctionAttrsPass() { return new FunctionAttrs(); } /// memory that is local to the function. Global constants are considered /// local to all functions. bool FunctionAttrs::PointsToLocalMemory(Value *V) { - V = V->getUnderlyingObject(); - // An alloca instruction defines local memory. - if (isa<AllocaInst>(V)) - return true; - // A global constant counts as local memory for our purposes. - if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) - return GV->isConstant(); - // Could look through phi nodes and selects here, but it doesn't seem - // to be useful in practice. - return false; + SmallVector<Value*, 8> Worklist; + unsigned MaxLookup = 4; + + Worklist.push_back(V); + + do { + V = Worklist.pop_back_val()->getUnderlyingObject(); + + // An alloca instruction defines local memory. + if (isa<AllocaInst>(V)) + continue; + + // A global constant counts as local memory for our purposes. + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { + if (!GV->isConstant()) + return false; + continue; + } + + // If both select values point to local memory, then so does the select. + if (SelectInst *SI = dyn_cast<SelectInst>(V)) { + Worklist.push_back(SI->getTrueValue()); + Worklist.push_back(SI->getFalseValue()); + continue; + } + + // If all values incoming to a phi node point to local memory, then so does + // the phi. + if (PHINode *PN = dyn_cast<PHINode>(V)) { + // Don't bother inspecting phi nodes with many operands. + if (PN->getNumIncomingValues() > MaxLookup) + return false; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + Worklist.push_back(PN->getIncomingValue(i)); + continue; + } + + return false; + } while (!Worklist.empty() && --MaxLookup); + + return Worklist.empty(); } /// AddReadAttrs - Deduce readonly/readnone attributes for the SCC. |