diff options
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp | 24 | ||||
-rw-r--r-- | llvm/test/Analysis/BasicAA/memset_pattern.ll | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/InferFunctionAttrs/annotate.ll | 5 |
4 files changed, 35 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index ace596dc5f6..85404d87a61 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -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; diff --git a/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp b/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp index 0f0182ef92b..4295a7595c2 100644 --- a/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/InferFunctionAttrs.cpp @@ -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. diff --git a/llvm/test/Analysis/BasicAA/memset_pattern.ll b/llvm/test/Analysis/BasicAA/memset_pattern.ll index 25bdb2e202f..821cbdf4bb0 100644 --- a/llvm/test/Analysis/BasicAA/memset_pattern.ll +++ b/llvm/test/Analysis/BasicAA/memset_pattern.ll @@ -18,4 +18,4 @@ entry: ret i32 %l } -declare void @memset_pattern16(i8*, i8*, i64) +declare void @memset_pattern16(i8*, i8* readonly, i64) argmemonly diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll index 709feb486c2..1cb7ab137c0 100644 --- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll +++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll @@ -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 } |