Skip to content

Commit 76672e3

Browse files
kartcqMeinersbur
andauthored
[Polly] Add vectorize metadata to loops identified as vectorizable by polly (llvm#113994)
This patch introduces the initial implementation for annotating loops created by Polly. Polly generates RunTimeChecks (RTCs), which result in loop versioning. Specifically, the loop created by Polly is executed when the RTCs pass, otherwise, the original loop is executed. This patch adds the "llvm.loop.vectorize.enable" metadata, setting it to true for loops created by Polly. Disabling vectorization for the original fallback loop is already merged in llvm#119188. This behavior is controlled by the 'polly-annotate-metadata-vectorize' flag, and the annotations are applied only when this flag is enabled. This flag is set to false by default. NOTE: This commit is initial patch in effort to make polly interact with Loop Vectorizer via metadata. --------- Co-authored-by: Michael Kruse <[email protected]>
1 parent 7bb949e commit 76672e3

File tree

4 files changed

+109
-20
lines changed

4 files changed

+109
-20
lines changed

polly/include/polly/CodeGen/IRBuilder.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@ class ScopAnnotator {
5858
/// Annotate the new instruction @p I for all parallel loops.
5959
void annotate(llvm::Instruction *I);
6060

61-
/// Annotate the loop latch @p B wrt. @p L.
62-
void annotateLoopLatch(llvm::BranchInst *B, llvm::Loop *L, bool IsParallel,
63-
bool IsLoopVectorizerDisabled) const;
61+
/// Annotate the loop latch @p B.
62+
/// Last argument is optional, if no value is passed, we don't annotate
63+
/// any vectorize metadata.
64+
void annotateLoopLatch(
65+
llvm::BranchInst *B, bool IsParallel,
66+
std::optional<bool> EnableVectorizeMetadata = std::nullopt) const;
6467

6568
/// Add alternative alias based pointers
6669
///

polly/lib/CodeGen/IRBuilder.cpp

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,26 @@ void ScopAnnotator::popLoop(bool IsParallel) {
128128
LoopAttrEnv.pop_back();
129129
}
130130

131-
void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L, bool IsParallel,
132-
bool IsLoopVectorizerDisabled) const {
131+
static void addVectorizeMetadata(LLVMContext &Ctx,
132+
SmallVector<Metadata *, 3> *Args,
133+
bool EnableLoopVectorizer) {
134+
MDString *PropName = MDString::get(Ctx, "llvm.loop.vectorize.enable");
135+
ConstantInt *Value =
136+
ConstantInt::get(Type::getInt1Ty(Ctx), EnableLoopVectorizer);
137+
ValueAsMetadata *PropValue = ValueAsMetadata::get(Value);
138+
Args->push_back(MDNode::get(Ctx, {PropName, PropValue}));
139+
}
140+
141+
void addParallelMetadata(LLVMContext &Ctx, SmallVector<Metadata *, 3> *Args,
142+
llvm::SmallVector<llvm::MDNode *, 8> ParallelLoops) {
143+
MDString *PropName = MDString::get(Ctx, "llvm.loop.parallel_accesses");
144+
MDNode *AccGroup = ParallelLoops.back();
145+
Args->push_back(MDNode::get(Ctx, {PropName, AccGroup}));
146+
}
147+
148+
void ScopAnnotator::annotateLoopLatch(
149+
BranchInst *B, bool IsParallel,
150+
std::optional<bool> EnableVectorizeMetadata) const {
133151
LLVMContext &Ctx = SE->getContext();
134152
SmallVector<Metadata *, 3> Args;
135153

@@ -145,19 +163,10 @@ void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L, bool IsParallel,
145163
if (MData)
146164
llvm::append_range(Args, drop_begin(MData->operands(), 1));
147165
}
148-
149-
if (IsLoopVectorizerDisabled) {
150-
MDString *PropName = MDString::get(Ctx, "llvm.loop.vectorize.enable");
151-
ConstantInt *FalseValue = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
152-
ValueAsMetadata *PropValue = ValueAsMetadata::get(FalseValue);
153-
Args.push_back(MDNode::get(Ctx, {PropName, PropValue}));
154-
}
155-
156-
if (IsParallel) {
157-
MDString *PropName = MDString::get(Ctx, "llvm.loop.parallel_accesses");
158-
MDNode *AccGroup = ParallelLoops.back();
159-
Args.push_back(MDNode::get(Ctx, {PropName, AccGroup}));
160-
}
166+
if (IsParallel)
167+
addParallelMetadata(Ctx, &Args, ParallelLoops);
168+
if (EnableVectorizeMetadata.has_value())
169+
addVectorizeMetadata(Ctx, &Args, *EnableVectorizeMetadata);
161170

162171
// No metadata to annotate.
163172
if (!MData && Args.size() <= 1)

polly/lib/CodeGen/LoopGenerators.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ static cl::opt<int, true>
3535
cl::Hidden, cl::location(polly::PollyNumThreads),
3636
cl::init(0), cl::cat(PollyCategory));
3737

38+
cl::opt<bool> PollyVectorizeMetadata(
39+
"polly-annotate-metadata-vectorize",
40+
cl::desc("Append vectorize enable/disable metadata from polly"),
41+
cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
42+
3843
static cl::opt<OMPGeneralSchedulingType, true> XPollyScheduling(
3944
"polly-scheduling",
4045
cl::desc("Scheduling type of parallel OpenMP for loops"),
@@ -159,8 +164,19 @@ Value *polly::createLoop(Value *LB, Value *UB, Value *Stride,
159164

160165
// Create the loop latch and annotate it as such.
161166
BranchInst *B = Builder.CreateCondBr(LoopCondition, HeaderBB, ExitBB);
162-
if (Annotator)
163-
Annotator->annotateLoopLatch(B, NewLoop, Parallel, LoopVectDisabled);
167+
168+
// Don't annotate vectorize metadata when both LoopVectDisabled and
169+
// PollyVectorizeMetadata are disabled. Annotate vectorize metadata to false
170+
// when LoopVectDisabled is true. Otherwise we annotate the vectorize metadata
171+
// to true.
172+
if (Annotator) {
173+
std::optional<bool> EnableVectorizeMetadata;
174+
if (LoopVectDisabled)
175+
EnableVectorizeMetadata = false;
176+
else if (PollyVectorizeMetadata)
177+
EnableVectorizeMetadata = true;
178+
Annotator->annotateLoopLatch(B, Parallel, EnableVectorizeMetadata);
179+
}
164180

165181
IV->addIncoming(IncrementedIV, HeaderBB);
166182
if (GuardBB)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
; RUN: opt %loadNPMPolly -S -passes=polly-codegen -polly-annotate-metadata-vectorize < %s | FileCheck %s
2+
3+
; Basic verification of vectorize metadata getting added when "-polly-vectorize-metadata" is
4+
; passed.
5+
6+
; void add(int *A, int *B, int *C,int n) {
7+
; for(int i=0; i<n; i++)
8+
; C[i] += A[i] + B[i];
9+
; }
10+
11+
; CHECK: for.body:
12+
; CHECK: br {{.*}} !llvm.loop [[LOOP:![0-9]+]]
13+
; CHECK: polly.stmt.for.body:
14+
; CHECK: br {{.*}} !llvm.loop [[POLLY_LOOP:![0-9]+]]
15+
; CHECK: [[LOOP]] = distinct !{[[LOOP]], [[META2:![0-9]+]], [[META3:![0-9]+]]}
16+
; CHECK: [[META3]] = !{!"llvm.loop.vectorize.enable", i32 0}
17+
; CHECK: [[POLLY_LOOP]] = distinct !{[[POLLY_LOOP]], [[META2:![0-9]+]], [[META3:![0-9]+]]}
18+
; CHECK: [[META3]] = !{!"llvm.loop.vectorize.enable", i1 true}
19+
20+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
21+
target triple = "aarch64-unknown-linux-gnu"
22+
23+
; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite) uwtable
24+
define dso_local void @add(ptr nocapture noundef readonly %A, ptr nocapture noundef readonly %B, ptr nocapture noundef %C, i32 noundef %n) local_unnamed_addr #0 {
25+
entry:
26+
br label %entry.split
27+
28+
entry.split: ; preds = %entry
29+
%cmp10 = icmp sgt i32 %n, 0
30+
br i1 %cmp10, label %for.body.preheader, label %for.cond.cleanup
31+
32+
for.body.preheader: ; preds = %entry.split
33+
%wide.trip.count = zext nneg i32 %n to i64
34+
br label %for.body
35+
36+
for.cond.cleanup.loopexit: ; preds = %for.body
37+
br label %for.cond.cleanup
38+
39+
for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry.split
40+
ret void
41+
42+
for.body: ; preds = %for.body.preheader, %for.body
43+
%indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
44+
%arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
45+
%0 = load i32, ptr %arrayidx, align 4
46+
%arrayidx2 = getelementptr inbounds i32, ptr %B, i64 %indvars.iv
47+
%1 = load i32, ptr %arrayidx2, align 4
48+
%add = add nsw i32 %1, %0
49+
%arrayidx4 = getelementptr inbounds i32, ptr %C, i64 %indvars.iv
50+
%2 = load i32, ptr %arrayidx4, align 4
51+
%add5 = add nsw i32 %add, %2
52+
store i32 %add5, ptr %arrayidx4, align 4
53+
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
54+
%exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
55+
br i1 %exitcond.not, label %for.cond.cleanup.loopexit, label %for.body, !llvm.loop !0
56+
}
57+
58+
attributes #0 = { nofree norecurse nosync nounwind memory(argmem: readwrite) uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a57" "target-features"="+aes,+crc,+fp-armv8,+neon,+outline-atomics,+perfmon,+sha2,+v8a,-fmv" }
59+
60+
!0 = distinct !{!0, !1}
61+
!1 = !{!"llvm.loop.mustprogress"}

0 commit comments

Comments
 (0)