From 6f092e501b715332263987f86e9a0f26a50524cb Mon Sep 17 00:00:00 2001 From: Christian Ulmann Date: Mon, 26 Aug 2024 15:23:39 +0200 Subject: [PATCH] [MLIR][Transforms] Update block arg locations during inlining (#106064) This commit changes the inlining to also update the locations of block arguments. Not updating these locations leads to LLVM IR verification issues when exporting converted block arguments to phi nodes. This lack of location update was not visible due to ignoring the argument locations until recently. Relevant change: https://github.com/llvm/llvm-project/pull/105534 --- mlir/lib/Transforms/Utils/InliningUtils.cpp | 37 +++++++++++++++------ mlir/test/Transforms/inlining.mlir | 4 +-- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/mlir/lib/Transforms/Utils/InliningUtils.cpp b/mlir/lib/Transforms/Utils/InliningUtils.cpp index ba146920fae2..0db097d14cd3 100644 --- a/mlir/lib/Transforms/Utils/InliningUtils.cpp +++ b/mlir/lib/Transforms/Utils/InliningUtils.cpp @@ -25,22 +25,37 @@ using namespace mlir; -/// Remap locations from the inlined blocks with CallSiteLoc locations with the -/// provided caller location. +/// Remap all locations reachable from the inlined blocks with CallSiteLoc +/// locations with the provided caller location. static void remapInlinedLocations(iterator_range inlinedBlocks, Location callerLoc) { - DenseMap mappedLocations; - auto remapOpLoc = [&](Operation *op) { - auto it = mappedLocations.find(op->getLoc()); - if (it == mappedLocations.end()) { - auto newLoc = CallSiteLoc::get(op->getLoc(), callerLoc); - it = mappedLocations.try_emplace(op->getLoc(), newLoc).first; + DenseMap mappedLocations; + auto remapLoc = [&](Location loc) { + auto [it, inserted] = mappedLocations.try_emplace(loc); + // Only query the attribute uniquer once per callsite attribute. + if (inserted) { + auto newLoc = CallSiteLoc::get(loc, callerLoc); + it->getSecond() = newLoc; } - op->setLoc(it->second); + return it->second; }; - for (auto &block : inlinedBlocks) - block.walk(remapOpLoc); + + AttrTypeReplacer attrReplacer; + attrReplacer.addReplacement( + [&](LocationAttr loc) -> std::pair { + return {remapLoc(loc), WalkResult::skip()}; + }); + + for (Block &block : inlinedBlocks) { + for (BlockArgument &arg : block.getArguments()) + if (LocationAttr newLoc = remapLoc(arg.getLoc())) + arg.setLoc(newLoc); + + for (Operation &op : block) + attrReplacer.recursivelyReplaceElementsIn(&op, /*replaceAttrs=*/false, + /*replaceLocs=*/true); + } } static void remapInlinedOperands(iterator_range inlinedBlocks, diff --git a/mlir/test/Transforms/inlining.mlir b/mlir/test/Transforms/inlining.mlir index 2a08e625ba79..79a2936b104f 100644 --- a/mlir/test/Transforms/inlining.mlir +++ b/mlir/test/Transforms/inlining.mlir @@ -215,9 +215,9 @@ func.func @func_with_block_args_location(%arg0 : i32) { // INLINE-LOC-LABEL: func @func_with_block_args_location_callee1 // INLINE-LOC: cf.br -// INLINE-LOC: ^bb{{[0-9]+}}(%{{.*}}: i32 loc("foo") +// INLINE-LOC: ^bb{{[0-9]+}}(%{{.*}}: i32 loc(callsite("foo" at "bar")) func.func @func_with_block_args_location_callee1(%arg0 : i32) { - call @func_with_block_args_location(%arg0) : (i32) -> () + call @func_with_block_args_location(%arg0) : (i32) -> () loc("bar") return }