[llvm] r369804 - [Attributor] Manifest alignment in load and store instructions

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 23 13:20:10 PDT 2019


Author: jdoerfert
Date: Fri Aug 23 13:20:10 2019
New Revision: 369804

URL: http://llvm.org/viewvc/llvm-project?rev=369804&view=rev
Log:
[Attributor] Manifest alignment in load and store instructions

Summary:
We can now manifest alignment information in load/store instructions if
the pointer is known to have a better alignment.

Reviewers: uenoku, sstefan1, lebedev.ri

Subscribers: hiraditya, bollu, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66567

Modified:
    llvm/trunk/lib/Transforms/IPO/Attributor.cpp
    llvm/trunk/test/Transforms/FunctionAttrs/align.ll

Modified: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Attributor.cpp?rev=369804&r1=369803&r2=369804&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp Fri Aug 23 13:20:10 2019
@@ -2113,6 +2113,10 @@ struct AAAlignImpl : AAAlign {
       takeKnownMaximum(Attr.getValueAsInt());
   }
 
+  // TODO: Provide a helper to determine the implied ABI alignment and check in
+  //       the existing manifest method and a new one for AAAlignImpl that value
+  //       to avoid making the alignment explicit if it did not improve.
+
   /// See AbstractAttribute::getDeducedAttributes
   virtual void
   getDeducedAttributes(LLVMContext &Ctx,
@@ -2133,6 +2137,35 @@ struct AAAlignImpl : AAAlign {
 struct AAAlignFloating : AAAlignImpl {
   AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
 
+  /// See AbstractAttribute::manifest(...).
+  ChangeStatus manifest(Attributor &A) override {
+    ChangeStatus Changed = ChangeStatus::UNCHANGED;
+
+    // Check for users that allow alignment annotations.
+    Value &AnchorVal = getIRPosition().getAnchorValue();
+    for (const Use &U : AnchorVal.uses()) {
+      if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
+        if (SI->getPointerOperand() == &AnchorVal)
+          if (SI->getAlignment() < getAssumedAlign()) {
+            STATS_DECLTRACK(AAAlign, Store,
+                            "Number of times alignemnt added to a store");
+            SI->setAlignment(getAssumedAlign());
+            Changed = ChangeStatus::CHANGED;
+          }
+      } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
+        if (LI->getPointerOperand() == &AnchorVal)
+          if (LI->getAlignment() < getAssumedAlign()) {
+            LI->setAlignment(getAssumedAlign());
+            STATS_DECLTRACK(AAAlign, Load,
+                            "Number of times alignemnt added to a load");
+            Changed = ChangeStatus::CHANGED;
+          }
+      }
+    }
+
+    return AAAlignImpl::manifest(A) | Changed;
+  }
+
   /// See AbstractAttribute::updateImpl(...).
   ChangeStatus updateImpl(Attributor &A) override {
     const DataLayout &DL = A.getDataLayout();
@@ -2190,6 +2223,11 @@ struct AAAlignArgument final
 struct AAAlignCallSiteArgument final : AAAlignFloating {
   AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
 
+  /// See AbstractAttribute::manifest(...).
+  ChangeStatus manifest(Attributor &A) override {
+    return AAAlignImpl::manifest(A);
+  }
+
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
 };
@@ -2665,6 +2703,18 @@ void Attributor::identifyDefaultAbstract
              "New call site/base instruction type needs to be known int the "
              "attributor.");
       break;
+    case Instruction::Load:
+      // The alignment of a pointer is interesting for loads.
+      checkAndRegisterAA<AAAlignFloating>(
+          IRPosition::value(*cast<LoadInst>(I).getPointerOperand()), *this,
+          Whitelist);
+      break;
+    case Instruction::Store:
+      // The alignment of a pointer is interesting for stores.
+      checkAndRegisterAA<AAAlignFloating>(
+          IRPosition::value(*cast<StoreInst>(I).getPointerOperand()), *this,
+          Whitelist);
+      break;
     case Instruction::Call:
     case Instruction::CallBr:
     case Instruction::Invoke:

Modified: llvm/trunk/test/Transforms/FunctionAttrs/align.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/align.ll?rev=369804&r1=369803&r2=369804&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/align.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/align.ll Fri Aug 23 13:20:10 2019
@@ -171,6 +171,61 @@ define void @test9_traversal(i1 %c, i32*
   ret void
 }
 
+; FIXME: This will work with an upcoming patch (D66618 or similar)
+;             define align 32 i32* @test10a(i32* align 32 %p)
+; ATTRIBUTOR: define i32* @test10a(i32* align 32 %p)
+define i32* @test10a(i32* align 32 %p) {
+; ATTRIBUTOR: %l = load i32, i32* %p, align 32
+  %l = load i32, i32* %p
+  %c = icmp eq i32 %l, 0
+  br i1 %c, label %t, label %f
+t:
+  %r = call i32* @test10a(i32* %p)
+; FIXME: This will work with an upcoming patch (D66618 or similar)
+;             store i32 1, i32* %r, align 32
+; ATTRIBUTOR: store i32 1, i32* %r
+  store i32 1, i32* %r
+  %g0 = getelementptr i32, i32* %p, i32 8
+  br label %e
+f:
+  %g1 = getelementptr i32, i32* %p, i32 8
+; FIXME: This will work with an upcoming patch (D66618 or similar)
+;             store i32 -1, i32* %g1, align 32
+; ATTRIBUTOR: store i32 -1, i32* %g1
+  store i32 -1, i32* %g1
+  br label %e
+e:
+  %phi = phi i32* [%g0, %t], [%g1, %f]
+  ret i32* %phi
+}
+
+; FIXME: This will work with an upcoming patch (D66618 or similar)
+;             define align 32 i32* @test10b(i32* align 32 %p)
+; ATTRIBUTOR: define i32* @test10b(i32* align 32 %p)
+define i32* @test10b(i32* align 32 %p) {
+; ATTRIBUTOR: %l = load i32, i32* %p, align 32
+  %l = load i32, i32* %p
+  %c = icmp eq i32 %l, 0
+  br i1 %c, label %t, label %f
+t:
+  %r = call i32* @test10b(i32* %p)
+; FIXME: This will work with an upcoming patch (D66618 or similar)
+;             store i32 1, i32* %r, align 32
+; ATTRIBUTOR: store i32 1, i32* %r
+  store i32 1, i32* %r
+  %g0 = getelementptr i32, i32* %p, i32 8
+  br label %e
+f:
+  %g1 = getelementptr i32, i32* %p, i32 -8
+; FIXME: This will work with an upcoming patch (D66618 or similar)
+;             store i32 -1, i32* %g1, align 32
+; ATTRIBUTOR: store i32 -1, i32* %g1
+  store i32 -1, i32* %g1
+  br label %e
+e:
+  %phi = phi i32* [%g0, %t], [%g1, %f]
+  ret i32* %phi
+}
 
 attributes #0 = { nounwind uwtable noinline }
 attributes #1 = { uwtable noinline }




More information about the llvm-commits mailing list