Skip to content

Commit 62d7d94

Browse files
committed
[mlir][LLVM] Support locations in loop annotation
This commit introduces support for locations as part of the loop annotation attribute. These locations indicate the start and the end of the loop. Reviewed By: gysit Differential Revision: https://reviews.llvm.org/D149858
1 parent 81cb43f commit 62d7d94

File tree

10 files changed

+171
-14
lines changed

10 files changed

+171
-14
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ def LoopAnnotationAttr : LLVM_Attr<"LoopAnnotation", "loop_annotation"> {
206206
OptionalParameter<"LoopUnswitchAttr">:$unswitch,
207207
OptionalParameter<"BoolAttr">:$mustProgress,
208208
OptionalParameter<"BoolAttr">:$isVectorized,
209-
OptionalArrayRefParameter<"SymbolRefAttr">:$parallelAccesses
209+
OptionalArrayRefParameter<"SymbolRefAttr">:$parallelAccesses,
210+
OptionalParameter<"FusedLoc">:$startLoc,
211+
OptionalParameter<"FusedLoc">:$endLoc
210212
);
211213

212214
let assemblyFormat = "`<` struct(params) `>`";

mlir/lib/Target/LLVMIR/LoopAnnotationImporter.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ struct LoopMetadataConversion {
2323
/// Converts this structs loop metadata node into a LoopAnnotationAttr.
2424
LoopAnnotationAttr convert();
2525

26-
LogicalResult initPropertyMap();
26+
/// Initializes the shared state for the conversion member functions.
27+
LogicalResult initConversionState();
2728

2829
/// Helper function to get and erase a property.
2930
const llvm::MDNode *lookupAndEraseProperty(StringRef name);
@@ -53,7 +54,10 @@ struct LoopMetadataConversion {
5354
FailureOr<LoopPeeledAttr> convertPeeledAttr();
5455
FailureOr<LoopUnswitchAttr> convertUnswitchAttr();
5556
FailureOr<SmallVector<SymbolRefAttr>> convertParallelAccesses();
57+
FusedLoc convertStartLoc();
58+
FailureOr<FusedLoc> convertEndLoc();
5659

60+
llvm::SmallVector<llvm::DILocation *, 2> locations;
5761
llvm::StringMap<const llvm::MDNode *> propertyMap;
5862
const llvm::MDNode *node;
5963
Location loc;
@@ -62,16 +66,17 @@ struct LoopMetadataConversion {
6266
};
6367
} // namespace
6468

65-
LogicalResult LoopMetadataConversion::initPropertyMap() {
69+
LogicalResult LoopMetadataConversion::initConversionState() {
6670
// Check if it's a valid node.
6771
if (node->getNumOperands() == 0 ||
6872
dyn_cast<llvm::MDNode>(node->getOperand(0)) != node)
6973
return emitWarning(loc) << "invalid loop node";
7074

7175
for (const llvm::MDOperand &operand : llvm::drop_begin(node->operands())) {
72-
// Skip over DILocations.
73-
if (isa<llvm::DILocation>(operand))
76+
if (auto *diLoc = dyn_cast<llvm::DILocation>(operand)) {
77+
locations.push_back(diLoc);
7478
continue;
79+
}
7580

7681
auto *property = dyn_cast<llvm::MDNode>(operand);
7782
if (!property)
@@ -405,8 +410,25 @@ LoopMetadataConversion::convertParallelAccesses() {
405410
return refs;
406411
}
407412

413+
FusedLoc LoopMetadataConversion::convertStartLoc() {
414+
if (locations.empty())
415+
return {};
416+
return dyn_cast<FusedLoc>(
417+
loopAnnotationImporter.moduleImport.translateLoc(locations[0]));
418+
}
419+
420+
FailureOr<FusedLoc> LoopMetadataConversion::convertEndLoc() {
421+
if (locations.size() < 2)
422+
return FusedLoc();
423+
if (locations.size() > 2)
424+
return emitError(loc)
425+
<< "expected loop metadata to have at most two DILocations";
426+
return dyn_cast<FusedLoc>(
427+
loopAnnotationImporter.moduleImport.translateLoc(locations[1]));
428+
}
429+
408430
LoopAnnotationAttr LoopMetadataConversion::convert() {
409-
if (failed(initPropertyMap()))
431+
if (failed(initConversionState()))
410432
return {};
411433

412434
FailureOr<BoolAttr> disableNonForced =
@@ -433,10 +455,14 @@ LoopAnnotationAttr LoopMetadataConversion::convert() {
433455
return {};
434456
}
435457

458+
FailureOr<FusedLoc> startLoc = convertStartLoc();
459+
FailureOr<FusedLoc> endLoc = convertEndLoc();
460+
436461
return createIfNonNull<LoopAnnotationAttr>(
437462
ctx, disableNonForced, vecAttr, interleaveAttr, unrollAttr,
438463
unrollAndJamAttr, licmAttr, distributeAttr, pipelineAttr, peeledAttr,
439-
unswitchAttr, mustProgress, isVectorized, parallelAccesses);
464+
unswitchAttr, mustProgress, isVectorized, parallelAccesses, startLoc,
465+
endLoc);
440466
}
441467

442468
LoopAnnotationAttr

mlir/lib/Target/LLVMIR/LoopAnnotationImporter.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ namespace detail {
2626
/// AccessGroupMetadataOps.
2727
class LoopAnnotationImporter {
2828
public:
29-
explicit LoopAnnotationImporter(OpBuilder &builder) : builder(builder) {}
29+
LoopAnnotationImporter(ModuleImport &moduleImport, OpBuilder &builder)
30+
: moduleImport(moduleImport), builder(builder) {}
3031
LoopAnnotationAttr translateLoopAnnotation(const llvm::MDNode *node,
3132
Location loc);
3233

@@ -44,6 +45,9 @@ class LoopAnnotationImporter {
4445
FailureOr<SmallVector<SymbolRefAttr>>
4546
lookupAccessGroupAttrs(const llvm::MDNode *node) const;
4647

48+
/// The ModuleImport owning this instance.
49+
ModuleImport &moduleImport;
50+
4751
private:
4852
/// Returns the LLVM metadata corresponding to a llvm loop metadata attribute.
4953
LoopAnnotationAttr lookupLoopMetadata(const llvm::MDNode *node) const {

mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "LoopAnnotationTranslation.h"
10+
#include "llvm/IR/DebugInfoMetadata.h"
1011

1112
using namespace mlir;
1213
using namespace mlir::LLVM;
@@ -32,6 +33,7 @@ struct LoopAnnotationConversion {
3233
void convertBoolNode(StringRef name, BoolAttr attr, bool negated = false);
3334
void convertI32Node(StringRef name, IntegerAttr attr);
3435
void convertFollowupNode(StringRef name, LoopAnnotationAttr attr);
36+
void convertLocation(FusedLoc attr);
3537

3638
/// Conversion functions for each for each loop annotation sub-attribute.
3739
void convertLoopOptions(LoopVectorizeAttr options);
@@ -186,12 +188,33 @@ void LoopAnnotationConversion::convertLoopOptions(LoopUnswitchAttr options) {
186188
options.getPartialDisable());
187189
}
188190

189-
llvm::MDNode *LoopAnnotationConversion::convert() {
191+
void LoopAnnotationConversion::convertLocation(FusedLoc location) {
192+
auto localScopeAttr =
193+
location.getMetadata().dyn_cast_or_null<DILocalScopeAttr>();
194+
if (!localScopeAttr)
195+
return;
196+
auto *localScope = dyn_cast<llvm::DILocalScope>(
197+
loopAnnotationTranslation.moduleTranslation.translateDebugInfo(
198+
localScopeAttr));
199+
if (!localScope)
200+
return;
201+
const llvm::Metadata *loc =
202+
loopAnnotationTranslation.moduleTranslation.translateLoc(location,
203+
localScope);
204+
metadataNodes.push_back(const_cast<llvm::Metadata *>(loc));
205+
}
190206

207+
llvm::MDNode *LoopAnnotationConversion::convert() {
191208
// Reserve operand 0 for loop id self reference.
192209
auto dummy = llvm::MDNode::getTemporary(ctx, std::nullopt);
193210
metadataNodes.push_back(dummy.get());
194211

212+
if (FusedLoc startLoc = attr.getStartLoc())
213+
convertLocation(startLoc);
214+
215+
if (FusedLoc endLoc = attr.getEndLoc())
216+
convertLocation(endLoc);
217+
195218
addUnitNode("llvm.loop.disable_nonforced", attr.getDisableNonforced());
196219
addUnitNode("llvm.loop.mustprogress", attr.getMustProgress());
197220
// "isvectorized" is encoded as an i32 value.

mlir/lib/Target/LLVMIR/LoopAnnotationTranslation.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ namespace detail {
2525
/// into a corresponding llvm::MDNodes.
2626
class LoopAnnotationTranslation {
2727
public:
28-
LoopAnnotationTranslation(Operation *mlirModule, llvm::Module &llvmModule)
29-
: mlirModule(mlirModule), llvmModule(llvmModule) {}
28+
LoopAnnotationTranslation(ModuleTranslation &moduleTranslation,
29+
Operation *mlirModule, llvm::Module &llvmModule)
30+
: moduleTranslation(moduleTranslation), mlirModule(mlirModule),
31+
llvmModule(llvmModule) {}
3032

3133
llvm::MDNode *translateLoopAnnotation(LoopAnnotationAttr attr, Operation *op);
3234

@@ -43,6 +45,9 @@ class LoopAnnotationTranslation {
4345
/// referenced by the AccessGroupOpInterface or null if there are none.
4446
llvm::MDNode *getAccessGroups(AccessGroupOpInterface op) const;
4547

48+
/// The ModuleTranslation owning this instance.
49+
ModuleTranslation &moduleTranslation;
50+
4651
private:
4752
/// Returns the LLVM metadata corresponding to a llvm loop metadata attribute.
4853
llvm::MDNode *lookupLoopMetadata(Attribute options) const {

mlir/lib/Target/LLVMIR/ModuleImport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ ModuleImport::ModuleImport(ModuleOp mlirModule,
153153
typeTranslator(*mlirModule->getContext()),
154154
debugImporter(std::make_unique<DebugImporter>(mlirModule)),
155155
loopAnnotationImporter(
156-
std::make_unique<LoopAnnotationImporter>(builder)) {
156+
std::make_unique<LoopAnnotationImporter>(*this, builder)) {
157157
builder.setInsertionPointToStart(mlirModule.getBody());
158158
}
159159

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ ModuleTranslation::ModuleTranslation(Operation *module,
444444
debugTranslation(
445445
std::make_unique<DebugTranslation>(module, *this->llvmModule)),
446446
loopAnnotationTranslation(std::make_unique<LoopAnnotationTranslation>(
447-
module, *this->llvmModule)),
447+
*this, module, *this->llvmModule)),
448448
typeTranslator(this->llvmModule->getContext()),
449449
iface(module->getContext()) {
450450
assert(satisfiesLLVMModule(mlirModule) &&

mlir/test/Dialect/LLVMIR/loop-metadata.mlir

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: mlir-opt %s | mlir-opt | FileCheck %s
1+
// RUN: mlir-opt %s --split-input-file | mlir-opt --split-input-file | FileCheck %s
22

33
// CHECK-DAG: #[[FOLLOWUP:.*]] = #llvm.loop_annotation<disableNonforced = true>
44
#followup = #llvm.loop_annotation<disableNonforced = true>
@@ -80,3 +80,38 @@ llvm.metadata @metadata {
8080
llvm.access_group @group1
8181
llvm.access_group @group2
8282
}
83+
84+
// -----
85+
86+
#di_file = #llvm.di_file<"metadata-loop.ll" in "/">
87+
88+
// CHECK: #[[START_LOC:.*]] = loc("loop-metadata.mlir":42:4)
89+
#loc1 = loc("loop-metadata.mlir":42:4)
90+
// CHECK: #[[END_LOC:.*]] = loc("loop-metadata.mlir":52:4)
91+
#loc2 = loc("loop-metadata.mlir":52:4)
92+
93+
#di_compile_unit = #llvm.di_compile_unit<sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = None>
94+
// CHECK: #[[SUBPROGRAM:.*]] = #llvm.di_subprogram<
95+
#di_subprogram = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "loop_locs", file = #di_file, subprogramFlags = Definition>
96+
97+
// CHECK: #[[START_LOC_FUSED:.*]] = loc(fused<#[[SUBPROGRAM]]>[#[[START_LOC]]]
98+
#start_loc_fused = loc(fused<#di_subprogram>[#loc1])
99+
// CHECK: #[[END_LOC_FUSED:.*]] = loc(fused<#[[SUBPROGRAM]]>[#[[END_LOC]]]
100+
#end_loc_fused= loc(fused<#di_subprogram>[#loc2])
101+
102+
// CHECK: #[[LOOP_ANNOT:.*]] = #llvm.loop_annotation<
103+
// CHECK-DAG: disableNonforced = false
104+
// CHECK-DAG: startLoc = #[[START_LOC_FUSED]]
105+
// CHECK-DAG: endLoc = #[[END_LOC_FUSED]]
106+
#loopMD = #llvm.loop_annotation<disableNonforced = false,
107+
mustProgress = true,
108+
startLoc = #start_loc_fused,
109+
endLoc = #end_loc_fused>
110+
111+
// CHECK: llvm.func @loop_annotation_with_locs
112+
llvm.func @loop_annotation_with_locs() {
113+
// CHECK: llvm.br ^bb1 {loop_annotation = #[[LOOP_ANNOT]]
114+
llvm.br ^bb1 {loop_annotation = #loopMD}
115+
^bb1:
116+
llvm.return
117+
}

mlir/test/Target/LLVMIR/Import/metadata-loop.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,36 @@ end:
343343
!1 = distinct !{!1, !2}
344344
!2 = !{!"llvm.loop.parallel_accesses", !0, !3}
345345
!3 = distinct !{}
346+
347+
; // -----
348+
349+
; CHECK: #[[start_loc:.*]] = loc("metadata-loop.ll":1:2)
350+
; CHECK: #[[end_loc:.*]] = loc("metadata-loop.ll":2:2)
351+
; CHECK: #[[SUBPROGRAM:.*]] = #llvm.di_subprogram<
352+
; CHECK: #[[start_loc_fused:.*]] = loc(fused<#[[SUBPROGRAM]]>[#[[start_loc]]])
353+
; CHECK: #[[end_loc_fused:.*]] = loc(fused<#[[SUBPROGRAM]]>[#[[end_loc]]])
354+
; CHECK: #[[$ANNOT_ATTR:.*]] = #llvm.loop_annotation<
355+
; CHECK-SAME: mustProgress = true
356+
; CHECK-SAME: startLoc = #[[start_loc_fused]]
357+
; CHECK-SAME: endLoc = #[[end_loc_fused]]
358+
359+
; CHECK-LABEL: @loop_locs
360+
define void @loop_locs(i64 %n, ptr %A) {
361+
entry:
362+
; CHECK: llvm.br ^{{.*}} {loop_annotation = #[[$ANNOT_ATTR]]}
363+
br label %end, !llvm.loop !6
364+
end:
365+
ret void
366+
}
367+
368+
!llvm.dbg.cu = !{!1}
369+
!llvm.module.flags = !{!0}
370+
!0 = !{i32 2, !"Debug Info Version", i32 3}
371+
!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
372+
!2 = !DIFile(filename: "metadata-loop.ll", directory: "/")
373+
!3 = distinct !DISubprogram(name: "loop_locs", scope: !2, file: !2, spFlags: DISPFlagDefinition, unit: !1)
374+
!4 = !DILocation(line: 1, column: 2, scope: !3)
375+
!5 = !DILocation(line: 2, column: 2, scope: !3)
376+
377+
!6 = distinct !{!6, !4, !5, !7}
378+
!7 = !{!"llvm.loop.mustprogress"}

mlir/test/Target/LLVMIR/loop-metadata.mlir

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,32 @@ llvm.metadata @metadata {
288288
// CHECK-DAG: ![[PIPELINE_DISABLE_NODE:[0-9]+]] = !{!"llvm.loop.pipeline.disable", i1 true}
289289
// CHECK-DAG: ![[II_NODE:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 2}
290290
// CHECK-DAG: ![[ACCESS_GROUPS_NODE:[0-9]+]] = !{![[GROUP_NODE1]], ![[GROUP_NODE2]]}
291+
292+
// -----
293+
294+
#di_file = #llvm.di_file<"metadata-loop.ll" in "/">
295+
296+
#loc1 = loc("loop-metadata.mlir":42:4)
297+
#loc2 = loc("loop-metadata.mlir":52:4)
298+
299+
#di_compile_unit = #llvm.di_compile_unit<sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = None>
300+
#di_subprogram = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "loop_locs", file = #di_file, subprogramFlags = Definition>
301+
302+
#start_loc_fused = loc(fused<#di_subprogram>[#loc1])
303+
#end_loc_fused= loc(fused<#di_subprogram>[#loc2])
304+
305+
#loopMD = #llvm.loop_annotation<disableNonforced = false,
306+
startLoc = #start_loc_fused,
307+
endLoc = #end_loc_fused>
308+
309+
// CHECK-LABEL: @loop_annotation_with_locs
310+
llvm.func @loop_annotation_with_locs() {
311+
// CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
312+
llvm.br ^bb1 {loop_annotation = #loopMD}
313+
^bb1:
314+
llvm.return
315+
}
316+
317+
// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], ![[START_LOC:.*]], ![[END_LOC:.*]]}
318+
// CHECK: ![[START_LOC]] = !DILocation(line: 42, column: 4, scope:
319+
// CHECK: ![[END_LOC]] = !DILocation(line: 52, column: 4, scope:

0 commit comments

Comments
 (0)