//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/CallSite.h"
+
using namespace llvm;
CaptureTracker::~CaptureTracker() {}
+bool CaptureTracker::shouldExplore(Use *U) { return true; }
+
namespace {
struct SimpleCaptureTracker : public CaptureTracker {
explicit SimpleCaptureTracker(bool ReturnCaptures)
void tooManyUses() { Captured = true; }
- bool shouldExplore(Use *U) { return true; }
-
- bool captured(Instruction *I) {
- if (isa<ReturnInst>(I) && !ReturnCaptures)
- return false;
+ bool captured(Use *U) {
+ if (isa<ReturnInst>(U->getUser()) && !ReturnCaptures)
+ return false;
Captured = true;
return true;
for (CallSite::arg_iterator A = B; A != E; ++A)
if (A->get() == V && !CS.doesNotCapture(A - B))
// The parameter is not marked 'nocapture' - captured.
- if (Tracker->captured(I))
+ if (Tracker->captured(U))
return;
break;
}
case Instruction::Store:
if (V == I->getOperand(0))
// Stored the pointer - conservatively assume it may be captured.
- if (Tracker->captured(I))
+ if (Tracker->captured(U))
return;
// Storing to the pointee does not cause the pointer to be captured.
break;
case Instruction::PHI:
case Instruction::Select:
// The original value is not captured via this if the new value isn't.
+ Count = 0;
for (Instruction::use_iterator UI = I->use_begin(), UE = I->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 Tracker->tooManyUses();
+
Use *U = &UI.getUse();
if (Visited.insert(U))
if (Tracker->shouldExplore(U))
// 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)
+ if (ConstantPointerNull *CPN =
+ dyn_cast<ConstantPointerNull>(I->getOperand(1)))
+ if (CPN->getType()->getAddressSpace() == 0)
+ if (isNoAliasCall(V->stripPointerCasts()))
break;
// Otherwise, be conservative. There are crazy ways to capture pointers
// using comparisons.
- if (Tracker->captured(I))
+ if (Tracker->captured(U))
return;
break;
default:
// Something else - be conservative and say it is captured.
- if (Tracker->captured(I))
+ if (Tracker->captured(U))
return;
break;
}