mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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 llvm-svn: 274197
This commit is contained in:
parent
18577887ec
commit
ab525e4a97
@ -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)
|
||||
|
@ -1047,6 +1047,77 @@ AliasResult CFLAAResult::query(const MemoryLocation &LocA,
|
||||
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) {
|
||||
|
@ -11,6 +11,8 @@ define i32* @return_arg_callee(i32* %arg1, i32* %arg2) {
|
||||
; 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user