+// FIXME: this is really just shoring-up a deficiency in alias analysis.
+// BasicAA isn't willing to spend linear time determining whether an alloca
+// was captured before or after this particular call, while we are. However,
+// with a smarter AA in place, this test is just wasting compile time.
+AliasAnalysis::ModRefResult
+AliasAnalysis::callCapturesBefore(const Instruction *I,
+ const AliasAnalysis::Location &MemLoc,
+ DominatorTree *DT) {
+ if (!DT || !DL) return AliasAnalysis::ModRef;
+
+ const Value *Object = GetUnderlyingObject(MemLoc.Ptr, DL);
+ if (!isIdentifiedObject(Object) || isa<GlobalValue>(Object) ||
+ isa<Constant>(Object))
+ return AliasAnalysis::ModRef;
+
+ ImmutableCallSite CS(I);
+ if (!CS.getInstruction() || CS.getInstruction() == Object)
+ return AliasAnalysis::ModRef;
+
+ if (llvm::PointerMayBeCapturedBefore(Object, /* ReturnCaptures */ true,
+ /* StoreCaptures */ true, I, DT,
+ /* include Object */ true))
+ return AliasAnalysis::ModRef;
+
+ unsigned ArgNo = 0;
+ AliasAnalysis::ModRefResult R = AliasAnalysis::NoModRef;
+ for (ImmutableCallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
+ CI != CE; ++CI, ++ArgNo) {
+ // Only look at the no-capture or byval pointer arguments. If this
+ // pointer were passed to arguments that were neither of these, then it
+ // couldn't be no-capture.
+ if (!(*CI)->getType()->isPointerTy() ||
+ (!CS.doesNotCapture(ArgNo) && !CS.isByValArgument(ArgNo)))
+ continue;
+
+ // If this is a no-capture pointer argument, see if we can tell that it
+ // is impossible to alias the pointer we're checking. If not, we have to
+ // assume that the call could touch the pointer, even though it doesn't
+ // escape.
+ if (isNoAlias(AliasAnalysis::Location(*CI),
+ AliasAnalysis::Location(Object)))
+ continue;
+ if (CS.doesNotAccessMemory(ArgNo))
+ continue;
+ if (CS.onlyReadsMemory(ArgNo)) {
+ R = AliasAnalysis::Ref;
+ continue;
+ }
+ return AliasAnalysis::ModRef;
+ }
+ return R;
+}