diff options
author | Johannes Doerfert <jdoerfert@anl.gov> | 2019-08-23 20:20:10 +0000 |
---|---|---|
committer | Johannes Doerfert <jdoerfert@anl.gov> | 2019-08-23 20:20:10 +0000 |
commit | 5a5a139917593409f1dc6af0b0e10caedf091fcb (patch) | |
tree | 2f0894f1c3cda20894fcbd76997c2911b87bc65c | |
parent | dc5f805d31f62e094bd3eb105b47620633f65e5b (diff) | |
download | bcm5719-llvm-5a5a139917593409f1dc6af0b0e10caedf091fcb.tar.gz bcm5719-llvm-5a5a139917593409f1dc6af0b0e10caedf091fcb.zip |
[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
llvm-svn: 369804
-rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 50 | ||||
-rw-r--r-- | llvm/test/Transforms/FunctionAttrs/align.ll | 55 |
2 files changed, 105 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index f75fc2c3ee6..029017a5690 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -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::identifyDefaultAbstractAttributes( "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: diff --git a/llvm/test/Transforms/FunctionAttrs/align.ll b/llvm/test/Transforms/FunctionAttrs/align.ll index eb13728764b..76ebf9632af 100644 --- a/llvm/test/Transforms/FunctionAttrs/align.ll +++ b/llvm/test/Transforms/FunctionAttrs/align.ll @@ -171,6 +171,61 @@ define void @test9_traversal(i1 %c, i32* align 4 %B, i32* align 8 %C) { 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 } |