diff options
author | Duncan Sands <baldrick@free.fr> | 2009-01-02 15:16:38 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2009-01-02 15:16:38 +0000 |
commit | 773c3b3600d7684351df02ea91d45f18db2c0db1 (patch) | |
tree | 04627ff9b42cce3a7467a07a3aab5f0d2a332052 /lib/Transforms/IPO | |
parent | 0d9e876a4135ae35f95744de2829c1200d3f4eb6 (diff) | |
download | external_llvm-773c3b3600d7684351df02ea91d45f18db2c0db1.zip external_llvm-773c3b3600d7684351df02ea91d45f18db2c0db1.tar.gz external_llvm-773c3b3600d7684351df02ea91d45f18db2c0db1.tar.bz2 |
Load tracking means that the value analyzed may
not have pointer type. In particular, it may
be the condition argument for a select or a GEP
index. While I was unable to construct a testcase
for which some bits of the original pointer are
captured due to one of these, it's very very close
to being possible - so play safe and exclude these
possibilities.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61580 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r-- | lib/Transforms/IPO/FunctionAttrs.cpp | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp index 13fb756..aea4cb4 100644 --- a/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/lib/Transforms/IPO/FunctionAttrs.cpp @@ -198,6 +198,7 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) { UseWithDepth UD = Worklist.pop_back_val(); Use *U = UD.getPointer(); Instruction *I = cast<Instruction>(U->getUser()); + // The value V may have any type if it comes from tracking a load. V = U->get(); // The depth represents the number of loads that need to be performed to // get back the original pointer (or a bitcast etc of it). For example, @@ -253,7 +254,10 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) { // Only passed via 'nocapture' arguments, or is the called function - not // captured. } else if (isa<BitCastInst>(I) || isa<LoadInst>(I) || isa<PHINode>(I) || - isa<GetElementPtrInst>(I) || isa<SelectInst>(I)) { + // Play safe and exclude GEP indices. + (isa<GetElementPtrInst>(I) && V == I->getOperand(0)) || + // Play safe and exclude the select condition. + (isa<SelectInst>(I) && V != I->getOperand(0))) { // Usually loads can be ignored because they dereference the original // pointer. However the loaded value needs to be tracked if loading @@ -267,7 +271,9 @@ bool FunctionAttrs::isCaptured(Function &F, Value *V) { continue; // Loading a pointer to (a pointer to...) the original pointer or a // variation of it. Track uses of the loaded value, noting that one - // dereference was performed. + // dereference was performed. Note that the loaded value need not be + // of pointer type. For example, an alloca may have been bitcast to + // a pointer to another type, which was then loaded. --Depth; } |