@@ -511,6 +511,57 @@ static void handleAccessGroups(Operation *call,
511
511
accessGroupOpInterface.getAccessGroupsOrNull (), accessGroups));
512
512
}
513
513
514
+ // / Updates locations inside loop annotations to reflect that they were inlined.
515
+ static void
516
+ handleLoopAnnotations (Operation *call,
517
+ iterator_range<Region::iterator> inlinedBlocks) {
518
+ // Attempt to extract a DISubprogram from the callee.
519
+ auto func = call->getParentOfType <FunctionOpInterface>();
520
+ if (!func)
521
+ return ;
522
+ LocationAttr funcLoc = func->getLoc ();
523
+ auto fusedLoc = dyn_cast_if_present<FusedLoc>(funcLoc);
524
+ if (!fusedLoc)
525
+ return ;
526
+ auto scope =
527
+ dyn_cast_if_present<LLVM::DISubprogramAttr>(fusedLoc.getMetadata ());
528
+ if (!scope)
529
+ return ;
530
+
531
+ // Helper to build a new fused location that reflects the inlining of the loop
532
+ // annotation.
533
+ auto updateLoc = [&](FusedLoc loc) -> FusedLoc {
534
+ if (!loc)
535
+ return {};
536
+ Location callSiteLoc = CallSiteLoc::get (loc, call->getLoc ());
537
+ return FusedLoc::get (loc.getContext (), callSiteLoc, scope);
538
+ };
539
+
540
+ AttrTypeReplacer replacer;
541
+ replacer.addReplacement ([&](LLVM::LoopAnnotationAttr loopAnnotation)
542
+ -> std::pair<Attribute, WalkResult> {
543
+ FusedLoc newStartLoc = updateLoc (loopAnnotation.getStartLoc ());
544
+ FusedLoc newEndLoc = updateLoc (loopAnnotation.getEndLoc ());
545
+ if (!newStartLoc && !newEndLoc)
546
+ return {loopAnnotation, WalkResult::advance ()};
547
+ auto newLoopAnnotation = LLVM::LoopAnnotationAttr::get (
548
+ loopAnnotation.getContext (), loopAnnotation.getDisableNonforced (),
549
+ loopAnnotation.getVectorize (), loopAnnotation.getInterleave (),
550
+ loopAnnotation.getUnroll (), loopAnnotation.getUnrollAndJam (),
551
+ loopAnnotation.getLicm (), loopAnnotation.getDistribute (),
552
+ loopAnnotation.getPipeline (), loopAnnotation.getPeeled (),
553
+ loopAnnotation.getUnswitch (), loopAnnotation.getMustProgress (),
554
+ loopAnnotation.getIsVectorized (), newStartLoc, newEndLoc,
555
+ loopAnnotation.getParallelAccesses ());
556
+ // Needs to advance, as loop annotations can be nested.
557
+ return {newLoopAnnotation, WalkResult::advance ()};
558
+ });
559
+
560
+ for (Block &block : inlinedBlocks)
561
+ for (Operation &op : block)
562
+ replacer.recursivelyReplaceElementsIn (&op);
563
+ }
564
+
514
565
// / If `requestedAlignment` is higher than the alignment specified on `alloca`,
515
566
// / realigns `alloca` if this does not exceed the natural stack alignment.
516
567
// / Returns the post-alignment of `alloca`, whether it was realigned or not.
@@ -784,6 +835,7 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
784
835
handleInlinedAllocas (call, inlinedBlocks);
785
836
handleAliasScopes (call, inlinedBlocks);
786
837
handleAccessGroups (call, inlinedBlocks);
838
+ handleLoopAnnotations (call, inlinedBlocks);
787
839
}
788
840
789
841
// Keeping this (immutable) state on the interface allows us to look up
0 commit comments