mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[BasicAA] Remove special casing of memset_pattern16 in favor of generic attribute inference
Most of the properties of memset_pattern16 can be now covered by the generic attributes and inferred by InferFunctionAttrs. The only exceptions are: - We don't yet have a writeonly attribute for the first argument. - We don't have an attribute for modeling the access size facts encoded in MemoryLocation.cpp. Differential Revision: http://reviews.llvm.org/D15879 llvm-svn: 256911
This commit is contained in:
parent
23e3fb6f4a
commit
780b59a41c
@ -543,7 +543,6 @@ static bool isMemsetPattern16(const Function *MS,
|
||||
isa<IntegerType>(MemsetType->getParamType(2)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -583,9 +582,6 @@ FunctionModRefBehavior BasicAAResult::getModRefBehavior(const Function *F) {
|
||||
if (F->onlyAccessesArgMemory())
|
||||
Min = FunctionModRefBehavior(Min & FMRB_OnlyAccessesArgumentPointees);
|
||||
|
||||
if (isMemsetPattern16(F, TLI))
|
||||
Min = FMRB_OnlyAccessesArgumentPointees;
|
||||
|
||||
// Otherwise be conservative.
|
||||
return FunctionModRefBehavior(AAResultBase::getModRefBehavior(F) & Min);
|
||||
}
|
||||
@ -609,14 +605,11 @@ ModRefInfo BasicAAResult::getArgModRefInfo(ImmutableCallSite CS,
|
||||
// We can bound the aliasing properties of memset_pattern16 just as we can
|
||||
// for memcpy/memset. This is particularly important because the
|
||||
// LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
|
||||
// whenever possible.
|
||||
if (CS.getCalledFunction() &&
|
||||
isMemsetPattern16(CS.getCalledFunction(), TLI)) {
|
||||
assert((ArgIdx == 0 || ArgIdx == 1) &&
|
||||
"Invalid argument index for memset_pattern16");
|
||||
return ArgIdx ? MRI_Ref : MRI_Mod;
|
||||
}
|
||||
// FIXME: Handle memset_pattern4 and memset_pattern8 also.
|
||||
// whenever possible. Note that all but the missing writeonly attribute are
|
||||
// handled via InferFunctionAttr.
|
||||
if (CS.getCalledFunction() && isMemsetPattern16(CS.getCalledFunction(), TLI))
|
||||
if (ArgIdx == 0)
|
||||
return MRI_Mod;
|
||||
|
||||
if (CS.paramHasAttr(ArgIdx + 1, Attribute::ReadOnly))
|
||||
return MRI_Ref;
|
||||
|
@ -22,6 +22,7 @@ using namespace llvm;
|
||||
|
||||
STATISTIC(NumReadNone, "Number of functions inferred as readnone");
|
||||
STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
|
||||
STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
|
||||
STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
|
||||
STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
|
||||
STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
|
||||
@ -44,6 +45,15 @@ static bool setOnlyReadsMemory(Function &F) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setOnlyAccessesArgMemory(Function &F) {
|
||||
if (F.onlyAccessesArgMemory())
|
||||
return false;
|
||||
F.setOnlyAccessesArgMemory ();
|
||||
++NumArgMemOnly;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool setDoesNotThrow(Function &F) {
|
||||
if (F.doesNotThrow())
|
||||
return false;
|
||||
@ -900,6 +910,20 @@ static bool inferPrototypeAttributes(Function &F,
|
||||
Changed |= setDoesNotAlias(F, AttributeSet::ReturnIndex);
|
||||
return Changed;
|
||||
|
||||
//TODO: add LibFunc entries for:
|
||||
//case LibFunc::memset_pattern4:
|
||||
//case LibFunc::memset_pattern8:
|
||||
case LibFunc::memset_pattern16:
|
||||
if (FTy->isVarArg() || FTy->getNumParams() != 3 ||
|
||||
!isa<PointerType>(FTy->getParamType(0)) ||
|
||||
!isa<PointerType>(FTy->getParamType(1)) ||
|
||||
!isa<IntegerType>(FTy->getParamType(2)))
|
||||
return false;
|
||||
|
||||
Changed |= setOnlyAccessesArgMemory(F);
|
||||
Changed |= setOnlyReadsMemory(F, 2);
|
||||
return Changed;
|
||||
|
||||
default:
|
||||
// FIXME: It'd be really nice to cover all the library functions we're
|
||||
// aware of here.
|
||||
|
@ -18,4 +18,4 @@ entry:
|
||||
ret i32 %l
|
||||
}
|
||||
|
||||
declare void @memset_pattern16(i8*, i8*, i64)
|
||||
declare void @memset_pattern16(i8*, i8* readonly, i64) argmemonly
|
||||
|
@ -22,9 +22,14 @@ declare i8* @_Znwj(i64)
|
||||
declare i8* @_Znwm(i64)
|
||||
; CHECK: declare noalias nonnull i8* @_Znwm(i64)
|
||||
|
||||
declare void @memset_pattern16(i8*, i8*, i64)
|
||||
; CHECK: declare void @memset_pattern16(i8*, i8*, i64)
|
||||
; CHECK-POSIX: declare void @memset_pattern16(i8*, i8* readonly, i64) [[G2:#[0-9]+]]
|
||||
|
||||
declare i32 @gettimeofday(i8*, i8*)
|
||||
; CHECK-POSIX: declare i32 @gettimeofday(i8* nocapture, i8* nocapture) [[G0:#[0-9]+]]
|
||||
|
||||
; CHECK: attributes [[G0]] = { nounwind }
|
||||
; CHECK: attributes [[G1]] = { nounwind readonly }
|
||||
; CHECK-POSIX: attributes [[G0]] = { nounwind }
|
||||
; CHECK-POSIX: attributes [[G2]] = { argmemonly }
|
||||
|
Loading…
x
Reference in New Issue
Block a user