[Attributor] Ignore read accesses to constant memory
authorJohannes Doerfert <johannes@jdoerfert.de>
Wed, 9 Sep 2020 05:41:46 +0000 (00:41 -0500)
committerJohannes Doerfert <johannes@jdoerfert.de>
Wed, 7 Oct 2020 00:31:07 +0000 (19:31 -0500)
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
llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll
llvm/test/Transforms/Attributor/readattrs.ll

index 1472542..2e0f034 100644 (file)
@@ -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<GEPOperator>(V) && "GEPs should have been stripped.");
     if (isa<UndefValue>(V))
@@ -6615,6 +6616,13 @@ void AAMemoryLocationImpl::categorizePtrValue(
       else
         MLK = NO_ARGUMENT_MEM;
     } else if (auto *GV = dyn_cast<GlobalValue>(&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<GlobalVariable>(GV))
+        if (GVar->isConstant())
+          return true;
+
       if (GV->hasLocalLinkage())
         MLK = NO_GLOBAL_INTERNAL_MEM;
       else
index 8c87bd0..8dd54ce 100644 (file)
@@ -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:
index 095981a..ffd40da 100644 (file)
@@ -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:
index 570ebd7..ef77796 100644 (file)
@@ -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
+}