llvm.org GIT mirror llvm / 788923e
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369804 91177308-0d34-0410-b5e6-96231b3b80d8 Johannes Doerfert 27 days ago
2 changed file(s) with 105 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
21122112 takeKnownMaximum(Attr.getValueAsInt());
21132113 }
21142114
2115 // TODO: Provide a helper to determine the implied ABI alignment and check in
2116 // the existing manifest method and a new one for AAAlignImpl that value
2117 // to avoid making the alignment explicit if it did not improve.
2118
21152119 /// See AbstractAttribute::getDeducedAttributes
21162120 virtual void
21172121 getDeducedAttributes(LLVMContext &Ctx,
21312135 /// Align attribute for a floating value.
21322136 struct AAAlignFloating : AAAlignImpl {
21332137 AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2138
2139 /// See AbstractAttribute::manifest(...).
2140 ChangeStatus manifest(Attributor &A) override {
2141 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2142
2143 // Check for users that allow alignment annotations.
2144 Value &AnchorVal = getIRPosition().getAnchorValue();
2145 for (const Use &U : AnchorVal.uses()) {
2146 if (auto *SI = dyn_cast(U.getUser())) {
2147 if (SI->getPointerOperand() == &AnchorVal)
2148 if (SI->getAlignment() < getAssumedAlign()) {
2149 STATS_DECLTRACK(AAAlign, Store,
2150 "Number of times alignemnt added to a store");
2151 SI->setAlignment(getAssumedAlign());
2152 Changed = ChangeStatus::CHANGED;
2153 }
2154 } else if (auto *LI = dyn_cast(U.getUser())) {
2155 if (LI->getPointerOperand() == &AnchorVal)
2156 if (LI->getAlignment() < getAssumedAlign()) {
2157 LI->setAlignment(getAssumedAlign());
2158 STATS_DECLTRACK(AAAlign, Load,
2159 "Number of times alignemnt added to a load");
2160 Changed = ChangeStatus::CHANGED;
2161 }
2162 }
2163 }
2164
2165 return AAAlignImpl::manifest(A) | Changed;
2166 }
21342167
21352168 /// See AbstractAttribute::updateImpl(...).
21362169 ChangeStatus updateImpl(Attributor &A) override {
21882221
21892222 struct AAAlignCallSiteArgument final : AAAlignFloating {
21902223 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
2224
2225 /// See AbstractAttribute::manifest(...).
2226 ChangeStatus manifest(Attributor &A) override {
2227 return AAAlignImpl::manifest(A);
2228 }
21912229
21922230 /// See AbstractAttribute::trackStatistics()
21932231 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
26632701 assert((!ImmutableCallSite(&I)) && (!isa(&I)) &&
26642702 "New call site/base instruction type needs to be known int the "
26652703 "attributor.");
2704 break;
2705 case Instruction::Load:
2706 // The alignment of a pointer is interesting for loads.
2707 checkAndRegisterAA(
2708 IRPosition::value(*cast(I).getPointerOperand()), *this,
2709 Whitelist);
2710 break;
2711 case Instruction::Store:
2712 // The alignment of a pointer is interesting for stores.
2713 checkAndRegisterAA(
2714 IRPosition::value(*cast(I).getPointerOperand()), *this,
2715 Whitelist);
26662716 break;
26672717 case Instruction::Call:
26682718 case Instruction::CallBr:
170170 ret void
171171 }
172172
173 ; FIXME: This will work with an upcoming patch (D66618 or similar)
174 ; define align 32 i32* @test10a(i32* align 32 %p)
175 ; ATTRIBUTOR: define i32* @test10a(i32* align 32 %p)
176 define i32* @test10a(i32* align 32 %p) {
177 ; ATTRIBUTOR: %l = load i32, i32* %p, align 32
178 %l = load i32, i32* %p
179 %c = icmp eq i32 %l, 0
180 br i1 %c, label %t, label %f
181 t:
182 %r = call i32* @test10a(i32* %p)
183 ; FIXME: This will work with an upcoming patch (D66618 or similar)
184 ; store i32 1, i32* %r, align 32
185 ; ATTRIBUTOR: store i32 1, i32* %r
186 store i32 1, i32* %r
187 %g0 = getelementptr i32, i32* %p, i32 8
188 br label %e
189 f:
190 %g1 = getelementptr i32, i32* %p, i32 8
191 ; FIXME: This will work with an upcoming patch (D66618 or similar)
192 ; store i32 -1, i32* %g1, align 32
193 ; ATTRIBUTOR: store i32 -1, i32* %g1
194 store i32 -1, i32* %g1
195 br label %e
196 e:
197 %phi = phi i32* [%g0, %t], [%g1, %f]
198 ret i32* %phi
199 }
200
201 ; FIXME: This will work with an upcoming patch (D66618 or similar)
202 ; define align 32 i32* @test10b(i32* align 32 %p)
203 ; ATTRIBUTOR: define i32* @test10b(i32* align 32 %p)
204 define i32* @test10b(i32* align 32 %p) {
205 ; ATTRIBUTOR: %l = load i32, i32* %p, align 32
206 %l = load i32, i32* %p
207 %c = icmp eq i32 %l, 0
208 br i1 %c, label %t, label %f
209 t:
210 %r = call i32* @test10b(i32* %p)
211 ; FIXME: This will work with an upcoming patch (D66618 or similar)
212 ; store i32 1, i32* %r, align 32
213 ; ATTRIBUTOR: store i32 1, i32* %r
214 store i32 1, i32* %r
215 %g0 = getelementptr i32, i32* %p, i32 8
216 br label %e
217 f:
218 %g1 = getelementptr i32, i32* %p, i32 -8
219 ; FIXME: This will work with an upcoming patch (D66618 or similar)
220 ; store i32 -1, i32* %g1, align 32
221 ; ATTRIBUTOR: store i32 -1, i32* %g1
222 store i32 -1, i32* %g1
223 br label %e
224 e:
225 %phi = phi i32* [%g0, %t], [%g1, %f]
226 ret i32* %phi
227 }
173228
174229 attributes #0 = { nounwind uwtable noinline }
175230 attributes #1 = { uwtable noinline }