1 //===- TestOpaqueLoc.cpp - Pass to test opaque locations ------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "mlir/Dialect/StandardOps/IR/Ops.h" 10 #include "mlir/IR/Builders.h" 11 #include "mlir/Pass/Pass.h" 12 13 using namespace mlir; 14 15 namespace { 16 /// Pass that changes locations to opaque locations for each operation. 17 /// It also takes all operations that are not function operations or 18 /// terminators and clones them with opaque locations which store the initial 19 /// locations. 20 struct TestOpaqueLoc 21 : public PassWrapper<TestOpaqueLoc, OperationPass<ModuleOp>> { 22 23 /// A simple structure which is used for testing as an underlying location in 24 /// OpaqueLoc. 25 struct MyLocation { MyLocation__anoncc17faef0111::TestOpaqueLoc::MyLocation26 MyLocation() : id(42) {} MyLocation__anoncc17faef0111::TestOpaqueLoc::MyLocation27 MyLocation(int id) : id(id) {} getId__anoncc17faef0111::TestOpaqueLoc::MyLocation28 int getId() { return id; } 29 30 int id; 31 }; 32 runOnOperation__anoncc17faef0111::TestOpaqueLoc33 void runOnOperation() override { 34 std::vector<std::unique_ptr<MyLocation>> myLocs; 35 int last_it = 0; 36 37 getOperation().walk([&](Operation *op) { 38 myLocs.push_back(std::make_unique<MyLocation>(last_it++)); 39 40 Location loc = op->getLoc(); 41 42 /// Set opaque location without fallback location to test the 43 /// corresponding get method. 44 op->setLoc( 45 OpaqueLoc::get<MyLocation *>(myLocs.back().get(), &getContext())); 46 47 if (isa<FuncOp>(op) || op->isKnownTerminator()) 48 return; 49 50 OpBuilder builder(op); 51 52 /// Add the same operation but with fallback location to test the 53 /// corresponding get method and serialization. 54 Operation *op_cloned_1 = builder.clone(*op); 55 op_cloned_1->setLoc( 56 OpaqueLoc::get<MyLocation *>(myLocs.back().get(), loc)); 57 58 /// Add the same operation but with void* instead of MyLocation* to test 59 /// getUnderlyingLocationOrNull method. 60 Operation *op_cloned_2 = builder.clone(*op); 61 op_cloned_2->setLoc(OpaqueLoc::get<void *>(nullptr, loc)); 62 }); 63 64 ScopedDiagnosticHandler diagHandler(&getContext(), [](Diagnostic &diag) { 65 auto &os = llvm::outs(); 66 if (diag.getLocation().isa<OpaqueLoc>()) { 67 MyLocation *loc = OpaqueLoc::getUnderlyingLocationOrNull<MyLocation *>( 68 diag.getLocation()); 69 if (loc) 70 os << "MyLocation: " << loc->id; 71 else 72 os << "nullptr"; 73 } 74 os << ": " << diag << '\n'; 75 os.flush(); 76 }); 77 78 getOperation().walk([&](Operation *op) { op->emitOpError(); }); 79 } 80 }; 81 82 } // end anonymous namespace 83 84 namespace mlir { 85 namespace test { registerTestOpaqueLoc()86void registerTestOpaqueLoc() { 87 PassRegistration<TestOpaqueLoc> pass( 88 "test-opaque-loc", "Changes all leaf locations to opaque locations"); 89 } 90 } // namespace test 91 } // namespace mlir 92