forked from OSchip/llvm-project
[Attributor] AANoRecurse check all call sites for `norecurse`
If all call sites are in `norecurse` functions we can derive `norecurse` as the ReversePostOrderFunctionAttrsPass does. This should make ReversePostOrderFunctionAttrsLegacyPass obsolete once the Attributor is enabled. Reviewed By: uenoku Differential Revision: https://reviews.llvm.org/D72017
This commit is contained in:
parent
368f7ee7a5
commit
26d02b0f28
|
@ -2082,14 +2082,33 @@ struct AANoRecurseFunction final : AANoRecurseImpl {
|
|||
void initialize(Attributor &A) override {
|
||||
AANoRecurseImpl::initialize(A);
|
||||
if (const Function *F = getAnchorScope())
|
||||
if (A.getInfoCache().getSccSize(*F) == 1)
|
||||
return;
|
||||
indicatePessimisticFixpoint();
|
||||
if (A.getInfoCache().getSccSize(*F) != 1)
|
||||
indicatePessimisticFixpoint();
|
||||
}
|
||||
|
||||
/// See AbstractAttribute::updateImpl(...).
|
||||
ChangeStatus updateImpl(Attributor &A) override {
|
||||
|
||||
// If all live call sites are known to be no-recurse, we are as well.
|
||||
auto CallSitePred = [&](AbstractCallSite ACS) {
|
||||
const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(
|
||||
*this, IRPosition::function(*ACS.getInstruction()->getFunction()),
|
||||
/* TrackDependence */ false, DepClassTy::OPTIONAL);
|
||||
return NoRecurseAA.isKnownNoRecurse();
|
||||
};
|
||||
bool AllCallSitesKnown;
|
||||
if (A.checkForAllCallSites(CallSitePred, *this, true, AllCallSitesKnown)) {
|
||||
// If we know all call sites and all are known no-recurse, we are done.
|
||||
// If all known call sites, which might not be all that exist, are known
|
||||
// to be no-recurse, we are not done but we can continue to assume
|
||||
// no-recurse. If one of the call sites we have not visited will become
|
||||
// live, another update is triggered.
|
||||
if (AllCallSitesKnown)
|
||||
indicateOptimisticFixpoint();
|
||||
return ChangeStatus::UNCHANGED;
|
||||
}
|
||||
|
||||
// If the above check does not hold anymore we look at the calls.
|
||||
auto CheckForNoRecurse = [&](Instruction &I) {
|
||||
ImmutableCallSite ICS(&I);
|
||||
if (ICS.hasFnAttr(Attribute::NoRecurse))
|
||||
|
|
|
@ -30,7 +30,7 @@ define void @caller(i32** %Y, %struct.pair* %P) {
|
|||
; CHECK-LABEL: define {{[^@]+}}@caller
|
||||
; CHECK-SAME: (i32** nocapture readonly [[Y:%.*]], %struct.pair* nocapture nofree readonly [[P:%.*]])
|
||||
; CHECK-NEXT: call void @test(i32** nocapture readonly align 8 [[Y]]), !dbg !4
|
||||
; CHECK-NEXT: call void @test_byval(), !dbg !5
|
||||
; CHECK-NEXT: call void @test_byval() #1, !dbg !5
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @test(i32** %Y), !dbg !1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
|
||||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 < %s | FileCheck %s
|
||||
|
||||
; ArgumentPromotion should preserve the default function address space
|
||||
; from the data layout.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
|
||||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=1 < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s
|
||||
;
|
||||
;
|
||||
; /---------------------------------------|
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 < %s | FileCheck %s
|
||||
; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 < %s | FileCheck %s
|
||||
|
||||
define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 {
|
||||
entry:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR
|
||||
; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR
|
||||
; Copied from Transforms/FunctoinAttrs/norecurse.ll
|
||||
|
||||
; ATTRIBUTOR: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
|
@ -59,8 +59,7 @@ define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
|
|||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
|
||||
|
||||
; ATTRIBUTOR: Function Attrs
|
||||
; FIXME: missing "norecurse"
|
||||
; ATTRIBUTOR-SAME: nosync readnone
|
||||
; ATTRIBUTOR-SAME: norecurse nosync readnone
|
||||
define internal i32 @called_by_norecurse() {
|
||||
%a = call i32 @k()
|
||||
ret i32 %a
|
||||
|
@ -73,19 +72,22 @@ define void @m() norecurse {
|
|||
}
|
||||
|
||||
; ATTRIBUTOR: Function Attrs
|
||||
; FIXME: missing "norecurse"
|
||||
; ATTRIBUTOR-SAME: nosync
|
||||
; ATTRIBUTOR-SAME: norecurse nosync readnone
|
||||
; ATTRIBUTOR-NEXT: @called_by_norecurse_indirectly
|
||||
define internal i32 @called_by_norecurse_indirectly() {
|
||||
%a = call i32 @k()
|
||||
ret i32 %a
|
||||
}
|
||||
define internal void @o() {
|
||||
; ATTRIBUTOR: Function Attrs
|
||||
; ATTRIBUTOR-SAME: norecurse nosync readnone
|
||||
; ATTRIBUTOR-NEXT: @o
|
||||
define internal i32 @o() {
|
||||
%a = call i32 @called_by_norecurse_indirectly()
|
||||
ret void
|
||||
ret i32 %a
|
||||
}
|
||||
define void @p() norecurse {
|
||||
call void @o()
|
||||
ret void
|
||||
define i32 @p() norecurse {
|
||||
%a = call i32 @o()
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
; ATTRIBUTOR: Function Attrs: nofree nosync nounwind
|
||||
|
|
Loading…
Reference in New Issue