[mlir][Rewrite] Add support for using an operation with no results as location

Prior to this patch, using an operation without any results as the location would result in the generation of invalid C++ code. It'd try to format using the result values, which would would end up being an empty string for an operation without any.
This patch fixes that issue by instead using getValueAndRangeUse which handles both ranges as well as the case for an op without any results.

Differential Revision: https://reviews.llvm.org/D118885
This commit is contained in:
Markus Böck 2022-02-03 15:07:46 +01:00
parent e7361469bb
commit 7b196f1b09
4 changed files with 20 additions and 3 deletions

View File

@ -324,7 +324,7 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
// means we want to capture the op itself. // means we want to capture the op itself.
if (op->getNumResults() == 0) { if (op->getNumResults() == 0) {
LLVM_DEBUG(llvm::dbgs() << name << " (Op)\n"); LLVM_DEBUG(llvm::dbgs() << name << " (Op)\n");
return std::string(name); return formatv(fmt, name);
} }
// We are referencing all results of the multi-result op. A specific result // We are referencing all results of the multi-result op. A specific result

View File

@ -690,6 +690,16 @@ def TestLocationDstOp : TEST_Op<"loc_dst", [SameOperandsAndResultType]> {
let results = (outs I32:$output); let results = (outs I32:$output);
} }
def TestLocationSrcNoResOp : TEST_Op<"loc_src_no_res"> {
let arguments = (ins I32:$input);
let results = (outs);
}
def TestLocationDstNoResOp : TEST_Op<"loc_dst_no_res"> {
let arguments = (ins I32:$input);
let results = (outs);
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Test Patterns // Test Patterns
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -1375,6 +1385,11 @@ def : Pat<(TestLocationSrcOp:$res1
(location "named")), (location "named")),
(location "fused", $res2, $res3))>; (location "fused", $res2, $res3))>;
// Test that we can use the location of an op without results
def : Pat<(TestLocationSrcNoResOp:$loc
(TestLocationSrcOp (TestLocationSrcOp $input))),
(TestLocationDstNoResOp $input, (location $loc))>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Test Patterns (Type Builders) // Test Patterns (Type Builders)

View File

@ -15,10 +15,12 @@ func @verifyDesignatedLoc(%arg0 : i32) -> i32 {
%0 = "test.loc_src"(%arg0) : (i32) -> i32 loc("loc3") %0 = "test.loc_src"(%arg0) : (i32) -> i32 loc("loc3")
%1 = "test.loc_src"(%0) : (i32) -> i32 loc("loc2") %1 = "test.loc_src"(%0) : (i32) -> i32 loc("loc2")
%2 = "test.loc_src"(%1) : (i32) -> i32 loc("loc1") %2 = "test.loc_src"(%1) : (i32) -> i32 loc("loc1")
"test.loc_src_no_res"(%2) : (i32) -> () loc("loc4")
// CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("loc1") // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("loc1")
// CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("named") // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc("named")
// CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc(fused<"fused">["loc2", "loc3"]) // CHECK: "test.loc_dst"({{.*}}) : (i32) -> i32 loc(fused<"fused">["loc2", "loc3"])
// CHECK: "test.loc_dst_no_res"({{.*}}) : (i32) -> () loc("loc4")
return %1 : i32 return %1 : i32
} }

View File

@ -1148,8 +1148,8 @@ StringRef PatternEmitter::handleReplaceWithValue(DagNode tree) {
std::string PatternEmitter::handleLocationDirective(DagNode tree) { std::string PatternEmitter::handleLocationDirective(DagNode tree) {
assert(tree.isLocationDirective()); assert(tree.isLocationDirective());
auto lookUpArgLoc = [this, &tree](int idx) { auto lookUpArgLoc = [this, &tree](int idx) {
const auto *const lookupFmt = "(*{0}.begin()).getLoc()"; const auto *const lookupFmt = "{0}.getLoc()";
return symbolInfoMap.getAllRangeUse(tree.getArgName(idx), lookupFmt); return symbolInfoMap.getValueAndRangeUse(tree.getArgName(idx), lookupFmt);
}; };
if (tree.getNumArgs() == 0) if (tree.getNumArgs() == 0)