aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/CaptureTracking.cpp
diff options
context:
space:
mode:
authorLogan Chien <loganchien@google.com>2011-11-15 14:23:13 +0800
committerLogan Chien <loganchien@google.com>2011-11-15 14:39:40 +0800
commitf9c1b92c27bf4ac40a52e0f1ef6d006d7e74bed3 (patch)
tree8c51041910d92818635c052f2b5e17f3abc21f98 /lib/Analysis/CaptureTracking.cpp
parente21ddb78968d087cf2b970df624abda64fca4e30 (diff)
parentbfc9429c2b814469adf3930dda31539d1c3319d8 (diff)
downloadexternal_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.cpp147
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;
}