diff options
| author | Logan Chien <loganchien@google.com> | 2011-11-15 14:23:13 +0800 |
|---|---|---|
| committer | Logan Chien <loganchien@google.com> | 2011-11-15 14:39:40 +0800 |
| commit | f9c1b92c27bf4ac40a52e0f1ef6d006d7e74bed3 (patch) | |
| tree | 8c51041910d92818635c052f2b5e17f3abc21f98 /lib/Analysis/CaptureTracking.cpp | |
| parent | e21ddb78968d087cf2b970df624abda64fca4e30 (diff) | |
| parent | bfc9429c2b814469adf3930dda31539d1c3319d8 (diff) | |
| download | external_llvm-f9c1b92c27bf4ac40a52e0f1ef6d006d7e74bed3.zip external_llvm-f9c1b92c27bf4ac40a52e0f1ef6d006d7e74bed3.tar.gz external_llvm-f9c1b92c27bf4ac40a52e0f1ef6d006d7e74bed3.tar.bz2 | |
Merge with LLVM upstream r144606 (Nov 15th 2011)
Conflicts:
Makefile.rules
configure
docs/ReleaseNotes.html
lib/Analysis/ScalarEvolution.cpp
lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
lib/CodeGen/ExecutionDepsFix.cpp
lib/CodeGen/MachineBlockPlacement.cpp
lib/CodeGen/MachineBranchProbabilityInfo.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/ExecutionEngine/JIT/LLVMBuild.txt
lib/MC/LLVMBuild.txt
lib/MC/MCDisassembler/LLVMBuild.txt
lib/MC/MCDwarf.cpp
lib/Object/LLVMBuild.txt
lib/Target/ARM/ARMExpandPseudoInsts.cpp
lib/Target/ARM/ARMFastISel.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/Disassembler/ARMDisassembler.cpp
lib/Target/ARM/Disassembler/LLVMBuild.txt
lib/Target/ARM/TargetInfo/LLVMBuild.txt
lib/Target/CBackend/TargetInfo/LLVMBuild.txt
lib/Target/CellSPU/MCTargetDesc/LLVMBuild.txt
lib/Target/CellSPU/TargetInfo/LLVMBuild.txt
lib/Target/CppBackend/TargetInfo/LLVMBuild.txt
lib/Target/LLVMBuild.txt
lib/Target/MBlaze/Disassembler/LLVMBuild.txt
lib/Target/MBlaze/TargetInfo/LLVMBuild.txt
lib/Target/MSP430/MCTargetDesc/LLVMBuild.txt
lib/Target/MSP430/TargetInfo/LLVMBuild.txt
lib/Target/Mips/CMakeLists.txt
lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsMCInstLower.cpp
lib/Target/Mips/TargetInfo/LLVMBuild.txt
lib/Target/PTX/LLVMBuild.txt
lib/Target/PTX/PTXAsmPrinter.cpp
lib/Target/PTX/TargetInfo/LLVMBuild.txt
lib/Target/PowerPC/TargetInfo/LLVMBuild.txt
lib/Target/Sparc/TargetInfo/LLVMBuild.txt
lib/Target/X86/TargetInfo/LLVMBuild.txt
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86InstrSSE.td
lib/Target/XCore/MCTargetDesc/LLVMBuild.txt
lib/Target/XCore/TargetInfo/LLVMBuild.txt
lib/Transforms/IPO/LLVMBuild.txt
lib/Transforms/Utils/LLVMBuild.txt
test/CodeGen/ARM/2011-10-26-memset-with-neon.ll
test/CodeGen/ARM/2011-11-07-PromoteVectorLoadStore.ll
test/CodeGen/ARM/fast-isel-cmp-imm.ll
test/CodeGen/ARM/fast-isel-ldrh-strh-arm.ll
test/CodeGen/CellSPU/call_indirect.ll
test/CodeGen/X86/avx2-logic.ll
test/CodeGen/X86/block-placement.ll
test/CodeGen/X86/sse-domains.ll
test/CodeGen/X86/sse3.ll
test/CodeGen/X86/vec_shuffle-39.ll
test/MC/ARM/neon-vld-encoding.s
test/MC/ARM/neon-vst-encoding.s
tools/llvm-config-2/llvm-config.cpp
utils/TableGen/LLVMBuild.txt
Change-Id: I70f454db6fc79d7799f56d0f6f2eb7b99561c504
Diffstat (limited to 'lib/Analysis/CaptureTracking.cpp')
| -rw-r--r-- | lib/Analysis/CaptureTracking.cpp | 147 |
1 files changed, 31 insertions, 116 deletions
diff --git a/lib/Analysis/CaptureTracking.cpp b/lib/Analysis/CaptureTracking.cpp index b2c27d1..a84dafb 100644 --- a/lib/Analysis/CaptureTracking.cpp +++ b/lib/Analysis/CaptureTracking.cpp @@ -17,24 +17,30 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/Value.h" -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/CallSite.h" using namespace llvm; -/// As its comment mentions, PointerMayBeCaptured can be expensive. -/// However, it's not easy for BasicAA to cache the result, because -/// it's an ImmutablePass. To work around this, bound queries at a -/// fixed number of uses. -/// -/// TODO: Write a new FunctionPass AliasAnalysis so that it can keep -/// a cache. Then we can move the code from BasicAliasAnalysis into -/// that path, and remove this threshold. -static int const Threshold = 20; +namespace { + struct SimpleCaptureTracker { + explicit SimpleCaptureTracker(bool ReturnCaptures) + : ReturnCaptures(ReturnCaptures), Captured(false) {} + + void tooManyUses() { Captured = true; } + + bool shouldExplore(Use *U) { return true; } + + bool captured(Instruction *I) { + if (isa<ReturnInst>(I) && !ReturnCaptures) + return false; + + Captured = true; + return true; + } + + bool ReturnCaptures; + + bool Captured; + }; +} /// PointerMayBeCaptured - Return true if this pointer value may be captured /// by the enclosing function (which is required to exist). This routine can @@ -45,104 +51,13 @@ static int const Threshold = 20; /// counts as capturing it or not. bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures) { - assert(V->getType()->isPointerTy() && "Capture is for pointers only!"); - SmallVector<Use*, Threshold> Worklist; - SmallSet<Use*, Threshold> Visited; - int Count = 0; - - for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end(); - UI != UE; ++UI) { - // If there are lots of uses, conservatively say that the value - // is captured to avoid taking too much compile time. - if (Count++ >= Threshold) - return true; - - Use *U = &UI.getUse(); - Visited.insert(U); - Worklist.push_back(U); - } - - while (!Worklist.empty()) { - Use *U = Worklist.pop_back_val(); - Instruction *I = cast<Instruction>(U->getUser()); - V = U->get(); - - switch (I->getOpcode()) { - case Instruction::Call: - case Instruction::Invoke: { - CallSite CS(I); - // Not captured if the callee is readonly, doesn't return a copy through - // its return value and doesn't unwind (a readonly function can leak bits - // by throwing an exception or not depending on the input value). - if (CS.onlyReadsMemory() && CS.doesNotThrow() && I->getType()->isVoidTy()) - break; - - // Not captured if only passed via 'nocapture' arguments. Note that - // calling a function pointer does not in itself cause the pointer to - // be captured. This is a subtle point considering that (for example) - // the callee might return its own address. It is analogous to saying - // that loading a value from a pointer does not cause the pointer to be - // captured, even though the loaded value might be the pointer itself - // (think of self-referential objects). - CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end(); - for (CallSite::arg_iterator A = B; A != E; ++A) - if (A->get() == V && !CS.paramHasAttr(A - B + 1, Attribute::NoCapture)) - // The parameter is not marked 'nocapture' - captured. - return true; - // Only passed via 'nocapture' arguments, or is the called function - not - // captured. - break; - } - case Instruction::Load: - // Loading from a pointer does not cause it to be captured. - break; - case Instruction::VAArg: - // "va-arg" from a pointer does not cause it to be captured. - break; - case Instruction::Ret: - if (ReturnCaptures) - return true; - break; - case Instruction::Store: - if (V == I->getOperand(0)) - // Stored the pointer - conservatively assume it may be captured. - // TODO: If StoreCaptures is not true, we could do Fancy analysis - // to determine whether this store is not actually an escape point. - // In that case, BasicAliasAnalysis should be updated as well to - // take advantage of this. - return true; - // Storing to the pointee does not cause the pointer to be captured. - break; - case Instruction::BitCast: - case Instruction::GetElementPtr: - case Instruction::PHI: - case Instruction::Select: - // The original value is not captured via this if the new value isn't. - for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); - UI != UE; ++UI) { - Use *U = &UI.getUse(); - if (Visited.insert(U)) - Worklist.push_back(U); - } - break; - case Instruction::ICmp: - // Don't count comparisons of a no-alias return value against null as - // captures. This allows us to ignore comparisons of malloc results - // with null, for example. - if (isNoAliasCall(V->stripPointerCasts())) - if (ConstantPointerNull *CPN = - dyn_cast<ConstantPointerNull>(I->getOperand(1))) - if (CPN->getType()->getAddressSpace() == 0) - break; - // Otherwise, be conservative. There are crazy ways to capture pointers - // using comparisons. - return true; - default: - // Something else - be conservative and say it is captured. - return true; - } - } - - // All uses examined - not captured. - return false; + // TODO: If StoreCaptures is not true, we could do Fancy analysis + // to determine whether this store is not actually an escape point. + // In that case, BasicAliasAnalysis should be updated as well to + // take advantage of this. + (void)StoreCaptures; + + SimpleCaptureTracker SCT(ReturnCaptures); + PointerMayBeCaptured(V, SCT); + return SCT.Captured; } |
