forked from OSchip/llvm-project
[Attributor] Implement "noalias" callsite argument deduction
Summary: Now, `nocapture` is deduced in Attributor therefore, this patch introduces deduction for `noalias` callsite argument using `nocapture`. Reviewers: jdoerfert, sstefan1 Reviewed By: jdoerfert Subscribers: lebedev.ri, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D67286 llvm-svn: 371590
This commit is contained in:
parent
3736764657
commit
1d68ed8c24
|
@ -1672,8 +1672,9 @@ struct AANoAliasFloating final : AANoAliasImpl {
|
|||
|
||||
/// See AbstractAttribute::initialize(...).
|
||||
void initialize(Attributor &A) override {
|
||||
// TODO: It isn't sound to initialize as the same with `AANoAliasImpl`
|
||||
// because `noalias` may not be valid in the current position.
|
||||
AANoAliasImpl::initialize(A);
|
||||
if (isa<AllocaInst>(getAnchorValue()))
|
||||
indicateOptimisticFixpoint();
|
||||
}
|
||||
|
||||
/// See AbstractAttribute::updateImpl(...).
|
||||
|
@ -1711,8 +1712,53 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl {
|
|||
|
||||
/// See AbstractAttribute::updateImpl(...).
|
||||
ChangeStatus updateImpl(Attributor &A) override {
|
||||
// TODO: Implement this.
|
||||
return indicatePessimisticFixpoint();
|
||||
// We can deduce "noalias" if the following conditions hold.
|
||||
// (i) Associated value is assumed to be noalias in the definition.
|
||||
// (ii) Associated value is assumed to be no-capture in all the uses
|
||||
// possibly executed before this callsite.
|
||||
// (iii) There is no other pointer argument which could alias with the
|
||||
// value.
|
||||
|
||||
const Value &V = getAssociatedValue();
|
||||
const IRPosition IRP = IRPosition::value(V);
|
||||
|
||||
// (i) Check whether noalias holds in the definition.
|
||||
|
||||
auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
|
||||
|
||||
if (!NoAliasAA.isAssumedNoAlias())
|
||||
return indicatePessimisticFixpoint();
|
||||
|
||||
LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
|
||||
<< " is assumed NoAlias in the definition\n");
|
||||
|
||||
// (ii) Check whether the value is captured in the scope using AANoCapture.
|
||||
// FIXME: This is conservative though, it is better to look at CFG and
|
||||
// check only uses possibly executed before this callsite.
|
||||
|
||||
auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
|
||||
if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned())
|
||||
return indicatePessimisticFixpoint();
|
||||
|
||||
// (iii) Check there is no other pointer argument which could alias with the
|
||||
// value.
|
||||
ImmutableCallSite ICS(&getAnchorValue());
|
||||
for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
|
||||
if (getArgNo() == (int)i)
|
||||
continue;
|
||||
const Value *ArgOp = ICS.getArgOperand(i);
|
||||
if (!ArgOp->getType()->isPointerTy())
|
||||
continue;
|
||||
|
||||
// TODO: Use AliasAnalysis
|
||||
// AAResults& AAR = ..;
|
||||
// if(AAR.isNoAlias(&getAssociatedValue(), ArgOp))
|
||||
// return indicatePessimitisicFixpoint();
|
||||
|
||||
return indicatePessimisticFixpoint();
|
||||
}
|
||||
|
||||
return ChangeStatus::UNCHANGED;
|
||||
}
|
||||
|
||||
/// See AbstractAttribute::trackStatistics()
|
||||
|
|
|
@ -191,3 +191,79 @@ define void @test11(i8* noalias %a) {
|
|||
tail call void @test11_helper(i8* %a, i8* %a)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; TEST 12
|
||||
; CallSite Argument
|
||||
declare void @use_nocapture(i8* nocapture)
|
||||
declare void @use(i8*)
|
||||
define void @test12_1() {
|
||||
; CHECK-LABEL: @test12_1(
|
||||
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 4
|
||||
; CHECK-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
|
||||
; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nonnull align 4 dereferenceable(1) [[A]])
|
||||
; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nonnull align 4 dereferenceable(1) [[A]])
|
||||
; CHECK-NEXT: tail call void @use_nocapture(i8* noalias [[B]])
|
||||
; CHECK-NEXT: tail call void @use_nocapture(i8* noalias [[B]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%A = alloca i8, align 4
|
||||
%B = tail call noalias i8* @malloc(i64 4)
|
||||
tail call void @use_nocapture(i8* %A)
|
||||
tail call void @use_nocapture(i8* %A)
|
||||
tail call void @use_nocapture(i8* %B)
|
||||
tail call void @use_nocapture(i8* %B)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test12_2(){
|
||||
; CHECK-LABEL: @test12_2(
|
||||
; CHECK-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
|
||||
; FIXME: This should be @use_nocapture(i8* noalias [[A]])
|
||||
; CHECK-NEXT: tail call void @use_nocapture(i8* [[A]])
|
||||
; FIXME: This should be @use_nocapture(i8* noalias [[A]])
|
||||
; CHECK-NEXT: tail call void @use_nocapture(i8* [[A]])
|
||||
; CHECK-NEXT: tail call void @use(i8* [[A]])
|
||||
; CHECK-NEXT: tail call void @use_nocapture(i8* [[A]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%A = tail call noalias i8* @malloc(i64 4)
|
||||
tail call void @use_nocapture(i8* %A)
|
||||
tail call void @use_nocapture(i8* %A)
|
||||
tail call void @use(i8* %A)
|
||||
tail call void @use_nocapture(i8* %A)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @two_args(i8* nocapture , i8* nocapture)
|
||||
define void @test12_3(){
|
||||
; CHECK-LABEL: @test12_3(
|
||||
%A = tail call noalias i8* @malloc(i64 4)
|
||||
; CHECK: tail call void @two_args(i8* %A, i8* %A)
|
||||
tail call void @two_args(i8* %A, i8* %A)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test12_4(){
|
||||
; CHECK-LABEL: @test12_4(
|
||||
%A = tail call noalias i8* @malloc(i64 4)
|
||||
%B = tail call noalias i8* @malloc(i64 4)
|
||||
%A_0 = getelementptr i8, i8* %A, i64 0
|
||||
%A_1 = getelementptr i8, i8* %A, i64 1
|
||||
%B_0 = getelementptr i8, i8* %B, i64 0
|
||||
|
||||
; FIXME: This should be @two_args(i8* noalias %A, i8* noalias %B)
|
||||
; CHECK: tail call void @two_args(i8* %A, i8* %B)
|
||||
tail call void @two_args(i8* %A, i8* %B)
|
||||
|
||||
; CHECK: tail call void @two_args(i8* %A, i8* %A_0)
|
||||
tail call void @two_args(i8* %A, i8* %A_0)
|
||||
|
||||
; CHECK: tail call void @two_args(i8* %A, i8* %A_1)
|
||||
tail call void @two_args(i8* %A, i8* %A_1)
|
||||
|
||||
; FIXME: This should be @two_args(i8* noalias %A_0, i8* noalias %B_0)
|
||||
; CHECK: tail call void @two_args(i8* %A_0, i8* %B_0)
|
||||
tail call void @two_args(i8* %A_0, i8* %B_0)
|
||||
ret void
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue