[llvm] r274197 - [CFLAA] Add support for ModRef queries.
George Burgess IV via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 29 19:11:27 PDT 2016
Author: gbiv
Date: Wed Jun 29 21:11:26 2016
New Revision: 274197
URL: http://llvm.org/viewvc/llvm-project?rev=274197&view=rev
Log:
[CFLAA] Add support for ModRef queries.
This patch makes CFLAA answer some ModRef queries. Because we don't
distinguish between reading/writing when making StratifiedSets, we're
unable to offer any of the readonly-related answers.
Patch by Jia Chen.
Differential Revision: http://reviews.llvm.org/D21858
Modified:
llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h
llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll
Modified: llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h?rev=274197&r1=274196&r2=274197&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/CFLAliasAnalysis.h Wed Jun 29 21:11:26 2016
@@ -73,6 +73,16 @@ public:
return QueryResult;
}
+ /// Get the location associated with a pointer argument of a callsite.
+ ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx);
+
+ /// Returns the behavior when calling the given call site.
+ FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS);
+
+ /// Returns the behavior when calling the given function. For use when the
+ /// call site is not known.
+ FunctionModRefBehavior getModRefBehavior(const Function *F);
+
private:
struct FunctionHandle final : public CallbackVH {
FunctionHandle(Function *Fn, CFLAAResult *Result)
Modified: llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp?rev=274197&r1=274196&r2=274197&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/CFLAliasAnalysis.cpp Wed Jun 29 21:11:26 2016
@@ -1047,6 +1047,77 @@ AliasResult CFLAAResult::query(const Mem
return NoAlias;
}
+ModRefInfo CFLAAResult::getArgModRefInfo(ImmutableCallSite CS,
+ unsigned ArgIdx) {
+ if (auto CalledFunc = CS.getCalledFunction()) {
+ auto &MaybeInfo = ensureCached(const_cast<Function *>(CalledFunc));
+ if (!MaybeInfo.hasValue())
+ return MRI_ModRef;
+ auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
+ auto &RetParamRelations = MaybeInfo->getRetParamRelations();
+
+ bool ArgAttributeIsWritten =
+ std::any_of(RetParamAttributes.begin(), RetParamAttributes.end(),
+ [ArgIdx](const ExternalAttribute &ExtAttr) {
+ return ExtAttr.IValue.Index == ArgIdx + 1;
+ });
+ bool ArgIsAccessed =
+ std::any_of(RetParamRelations.begin(), RetParamRelations.end(),
+ [ArgIdx](const ExternalRelation &ExtRelation) {
+ return ExtRelation.To.Index == ArgIdx + 1 ||
+ ExtRelation.From.Index == ArgIdx + 1;
+ });
+
+ return (!ArgIsAccessed && !ArgAttributeIsWritten) ? MRI_NoModRef
+ : MRI_ModRef;
+ }
+
+ return MRI_ModRef;
+}
+
+FunctionModRefBehavior CFLAAResult::getModRefBehavior(ImmutableCallSite CS) {
+ // If we know the callee, try analyzing it
+ if (auto CalledFunc = CS.getCalledFunction())
+ return getModRefBehavior(CalledFunc);
+
+ // Otherwise, be conservative
+ return FMRB_UnknownModRefBehavior;
+}
+
+FunctionModRefBehavior CFLAAResult::getModRefBehavior(const Function *F) {
+ assert(F != nullptr);
+
+ // TODO: Remove the const_cast
+ auto &MaybeInfo = ensureCached(const_cast<Function *>(F));
+ if (!MaybeInfo.hasValue())
+ return FMRB_UnknownModRefBehavior;
+ auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
+ auto &RetParamRelations = MaybeInfo->getRetParamRelations();
+
+ // First, if any argument is marked Escpaed, Unknown or Global, anything may
+ // happen to them and thus we can't draw any conclusion.
+ if (!RetParamAttributes.empty())
+ return FMRB_UnknownModRefBehavior;
+
+ // Currently we don't (and can't) distinguish reads from writes in
+ // RetParamRelations. All we can say is whether there may be memory access or
+ // not.
+ if (RetParamRelations.empty())
+ return FMRB_DoesNotAccessMemory;
+
+ // Check if something beyond argmem gets touched.
+ bool AccessArgMemoryOnly =
+ std::all_of(RetParamRelations.begin(), RetParamRelations.end(),
+ [](const ExternalRelation &ExtRelation) {
+ // Both DerefLevels has to be 0, since we don't know which
+ // one is a read and which is a write.
+ return ExtRelation.From.DerefLevel == 0 &&
+ ExtRelation.To.DerefLevel == 0;
+ });
+ return AccessArgMemoryOnly ? FMRB_OnlyAccessesArgumentPointees
+ : FMRB_UnknownModRefBehavior;
+}
+
char CFLAA::PassID;
CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> &AM) {
Modified: llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll?rev=274197&r1=274196&r2=274197&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll (original)
+++ llvm/trunk/test/Analysis/CFLAliasAnalysis/interproc-ret-arg.ll Wed Jun 29 21:11:26 2016
@@ -11,6 +11,8 @@ define i32* @return_arg_callee(i32* %arg
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: MayAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
+
+; CHECK: NoModRef: Ptr: i32* %b <-> %c = call i32* @return_arg_callee(i32* %a, i32* %b)
define void @test_return_arg() {
%a = alloca i32, align 4
%b = alloca i32, align 4
More information about the llvm-commits
mailing list