From c4cfe7a43512c8fadb2aa207f6d914858e2cc50e Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Wed, 9 Sep 2020 00:41:46 -0500 Subject: [PATCH] [Attributor] Ignore read accesses to constant memory The old function attribute deduction pass ignores reads of constant memory and we need to copy this behavior to replace the pass completely. First step are constant globals. TBAA can also describe constant accesses and there are other possibilities. We might want to consider asking the alias analyses that are available but for now this is simpler and cheaper. --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp | 8 ++++++++ .../Attributor/ArgumentPromotion/aggregate-promote.ll | 8 ++++---- .../Attributor/ArgumentPromotion/invalidation.ll | 6 +++--- llvm/test/Transforms/Attributor/readattrs.ll | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 1472542..2e0f034 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -6605,6 +6605,7 @@ void AAMemoryLocationImpl::categorizePtrValue( auto VisitValueCB = [&](Value &V, const Instruction *, AAMemoryLocation::StateType &T, bool Stripped) -> bool { + // TODO: recognize the TBAA used for constant accesses. MemoryLocationsKind MLK = NO_LOCATIONS; assert(!isa(V) && "GEPs should have been stripped."); if (isa(V)) @@ -6615,6 +6616,13 @@ void AAMemoryLocationImpl::categorizePtrValue( else MLK = NO_ARGUMENT_MEM; } else if (auto *GV = dyn_cast(&V)) { + // Reading constant memory is not treated as a read "effect" by the + // function attr pass so we won't neither. Constants defined by TBAA are + // similar. (We know we do not write it because it is constant.) + if (auto *GVar = dyn_cast(GV)) + if (GVar->isConstant()) + return true; + if (GV->hasLocalLinkage()) MLK = NO_GLOBAL_INTERNAL_MEM; else diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll index 8c87bd0..8dd54ce 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll @@ -8,7 +8,7 @@ @G = constant %T { i32 0, i32 0, i32 17, i32 25 } define internal i32 @test(%T* %p) { -; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn +; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@test ; IS__TUNIT____-SAME: () [[ATTR0:#.*]] { ; IS__TUNIT____-NEXT: entry: @@ -19,7 +19,7 @@ define internal i32 @test(%T* %p) { ; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]] ; IS__TUNIT____-NEXT: ret i32 [[V]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@test ; IS__CGSCC____-SAME: () [[ATTR0:#.*]] { ; IS__CGSCC____-NEXT: entry: @@ -40,14 +40,14 @@ entry: } define i32 @caller() { -; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn +; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@caller ; IS__TUNIT____-SAME: () [[ATTR0]] { ; IS__TUNIT____-NEXT: entry: ; IS__TUNIT____-NEXT: [[V:%.*]] = call i32 @test() [[ATTR0]] ; IS__TUNIT____-NEXT: ret i32 [[V]] ; -; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@caller ; IS__CGSCC____-SAME: () [[ATTR0]] { ; IS__CGSCC____-NEXT: entry: diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll index 095981a..ffd40da 100644 --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll @@ -12,7 +12,7 @@ @G = constant i32 0 define internal i32 @a(i32* %x) { -; CHECK: Function Attrs: nofree nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@a ; CHECK-SAME: () [[ATTR0:#.*]] { ; CHECK-NEXT: entry: @@ -25,7 +25,7 @@ entry: } define i32 @b() { -; CHECK: Function Attrs: nofree nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@b ; CHECK-SAME: () [[ATTR0]] { ; CHECK-NEXT: entry: @@ -38,7 +38,7 @@ entry: } define i32 @c() { -; CHECK: Function Attrs: nofree nosync nounwind readonly willreturn +; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn ; CHECK-LABEL: define {{[^@]+}}@c ; CHECK-SAME: () [[ATTR0]] { ; CHECK-NEXT: entry: diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll index 570ebd7..ef777960 100644 --- a/llvm/test/Transforms/Attributor/readattrs.ll +++ b/llvm/test/Transforms/Attributor/readattrs.ll @@ -449,3 +449,21 @@ define void @ptr_use_chain(i8* %ptr) { call void @escape_i8(i8* %abc9) ret void } + +@constant_mem = external dso_local constant i32, align 4 +define i32 @read_only_constant_mem() { +; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@read_only_constant_mem +; IS__TUNIT____-SAME: () [[ATTR1]] { +; IS__TUNIT____-NEXT: [[L:%.*]] = load i32, i32* @constant_mem, align 4 +; IS__TUNIT____-NEXT: ret i32 [[L]] +; +; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@read_only_constant_mem +; IS__CGSCC____-SAME: () [[ATTR1]] { +; IS__CGSCC____-NEXT: [[L:%.*]] = load i32, i32* @constant_mem, align 4 +; IS__CGSCC____-NEXT: ret i32 [[L]] +; + %l = load i32, i32* @constant_mem + ret i32 %l +} -- 2.7.4