xref: /llvm-project/mlir/unittests/Debug/FileLineColLocBreakpointManagerTest.cpp (revision 1893a3743eb971f0ea7657dc119b642a12870a1e)
17f069f5eSMehdi Amini //===- FileLineColLocBreakpointManagerTest.cpp - --------------------------===//
27f069f5eSMehdi Amini //
37f069f5eSMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47f069f5eSMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
57f069f5eSMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67f069f5eSMehdi Amini //
77f069f5eSMehdi Amini //===----------------------------------------------------------------------===//
87f069f5eSMehdi Amini 
97f069f5eSMehdi Amini #include "mlir/Debug/BreakpointManagers/FileLineColLocBreakpointManager.h"
107f069f5eSMehdi Amini #include "mlir/Debug/ExecutionContext.h"
117f069f5eSMehdi Amini #include "mlir/IR/Builders.h"
127f069f5eSMehdi Amini #include "mlir/IR/BuiltinAttributes.h"
137f069f5eSMehdi Amini #include "mlir/IR/BuiltinTypes.h"
147f069f5eSMehdi Amini #include "mlir/IR/Location.h"
157f069f5eSMehdi Amini #include "mlir/IR/OperationSupport.h"
167f069f5eSMehdi Amini #include "llvm/ADT/STLExtras.h"
177f069f5eSMehdi Amini #include "gtest/gtest.h"
187f069f5eSMehdi Amini 
197f069f5eSMehdi Amini using namespace mlir;
207f069f5eSMehdi Amini using namespace mlir::tracing;
217f069f5eSMehdi Amini 
createOp(MLIRContext * context,Location loc,StringRef operationName,unsigned int numRegions=0)227f069f5eSMehdi Amini static Operation *createOp(MLIRContext *context, Location loc,
237f069f5eSMehdi Amini                            StringRef operationName,
247f069f5eSMehdi Amini                            unsigned int numRegions = 0) {
257f069f5eSMehdi Amini   context->allowUnregisteredDialects();
267f069f5eSMehdi Amini   return Operation::create(loc, OperationName(operationName, context),
277f069f5eSMehdi Amini                            std::nullopt, std::nullopt, std::nullopt,
285e118f93SMehdi Amini                            OpaqueProperties(nullptr), std::nullopt, numRegions);
297f069f5eSMehdi Amini }
307f069f5eSMehdi Amini 
317f069f5eSMehdi Amini namespace {
327f069f5eSMehdi Amini struct FileLineColLocTestingAction
337f069f5eSMehdi Amini     : public ActionImpl<FileLineColLocTestingAction> {
347f069f5eSMehdi Amini   MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(FileLineColLocTestingAction)
357f069f5eSMehdi Amini   static constexpr StringLiteral tag = "file-line-col-loc-testing-action";
FileLineColLocTestingAction__anon99b9193c0111::FileLineColLocTestingAction367f069f5eSMehdi Amini   FileLineColLocTestingAction(ArrayRef<IRUnit> irUnits)
377f069f5eSMehdi Amini       : ActionImpl<FileLineColLocTestingAction>(irUnits) {}
387f069f5eSMehdi Amini };
397f069f5eSMehdi Amini 
TEST(FileLineColLocBreakpointManager,OperationMatch)407f069f5eSMehdi Amini TEST(FileLineColLocBreakpointManager, OperationMatch) {
417f069f5eSMehdi Amini   // This test will process a sequence of operation and check various situation
427f069f5eSMehdi Amini   // with a breakpoint hitting or not based on the location attached to the
437f069f5eSMehdi Amini   // operation. When a breakpoint hits, the action is skipped and the counter is
447f069f5eSMehdi Amini   // not incremented.
457f069f5eSMehdi Amini   ExecutionContext executionCtx(
467f069f5eSMehdi Amini       [](const ActionActiveStack *) { return ExecutionContext::Skip; });
477f069f5eSMehdi Amini   int counter = 0;
487f069f5eSMehdi Amini   auto counterInc = [&]() { counter++; };
497f069f5eSMehdi Amini 
507f069f5eSMehdi Amini   // Setup
517f069f5eSMehdi Amini 
527f069f5eSMehdi Amini   MLIRContext context;
537f069f5eSMehdi Amini   // Miscellaneous information to define operations
547f069f5eSMehdi Amini   std::vector<StringRef> fileNames = {
557f069f5eSMehdi Amini       StringRef("foo.bar"), StringRef("baz.qux"), StringRef("quux.corge")};
567f069f5eSMehdi Amini   std::vector<std::pair<unsigned, unsigned>> lineColLoc = {{42, 7}, {24, 3}};
577f069f5eSMehdi Amini   Location callee = UnknownLoc::get(&context),
587f069f5eSMehdi Amini            caller = UnknownLoc::get(&context), loc = UnknownLoc::get(&context);
597f069f5eSMehdi Amini 
607f069f5eSMehdi Amini   // Set of operations over where we are going to be testing the functionality
617f069f5eSMehdi Amini   std::vector<Operation *> operations = {
627f069f5eSMehdi Amini       createOp(&context, CallSiteLoc::get(callee, caller),
637f069f5eSMehdi Amini                "callSiteLocOperation"),
647f069f5eSMehdi Amini       createOp(&context,
657f069f5eSMehdi Amini                FileLineColLoc::get(&context, fileNames[0], lineColLoc[0].first,
667f069f5eSMehdi Amini                                    lineColLoc[0].second),
677f069f5eSMehdi Amini                "fileLineColLocOperation"),
687f069f5eSMehdi Amini       createOp(&context, FusedLoc::get(&context, {}, Attribute()),
697f069f5eSMehdi Amini                "fusedLocOperation"),
707f069f5eSMehdi Amini       createOp(&context, NameLoc::get(StringAttr::get(&context, fileNames[2])),
717f069f5eSMehdi Amini                "nameLocOperation"),
727f069f5eSMehdi Amini       createOp(&context, OpaqueLoc::get<void *>(nullptr, loc),
737f069f5eSMehdi Amini                "opaqueLocOperation"),
747f069f5eSMehdi Amini       createOp(&context,
757f069f5eSMehdi Amini                FileLineColLoc::get(&context, fileNames[1], lineColLoc[1].first,
767f069f5eSMehdi Amini                                    lineColLoc[1].second),
777f069f5eSMehdi Amini                "anotherFileLineColLocOperation"),
787f069f5eSMehdi Amini       createOp(&context, UnknownLoc::get(&context), "unknownLocOperation"),
797f069f5eSMehdi Amini   };
807f069f5eSMehdi Amini 
817f069f5eSMehdi Amini   FileLineColLocBreakpointManager breakpointManager;
827f069f5eSMehdi Amini   executionCtx.addBreakpointManager(&breakpointManager);
837f069f5eSMehdi Amini 
847f069f5eSMehdi Amini   // Test
857f069f5eSMehdi Amini 
867f069f5eSMehdi Amini   // Basic case is that no breakpoint is set and the counter is incremented for
877f069f5eSMehdi Amini   // every op.
887f069f5eSMehdi Amini   auto checkNoMatch = [&]() {
897f069f5eSMehdi Amini     counter = 0;
907f069f5eSMehdi Amini     for (auto enumeratedOp : llvm::enumerate(operations)) {
917f069f5eSMehdi Amini       executionCtx(counterInc,
927f069f5eSMehdi Amini                    FileLineColLocTestingAction({enumeratedOp.value()}));
937f069f5eSMehdi Amini       EXPECT_EQ(counter, static_cast<int>(enumeratedOp.index() + 1));
947f069f5eSMehdi Amini     }
957f069f5eSMehdi Amini   };
967f069f5eSMehdi Amini   checkNoMatch();
977f069f5eSMehdi Amini 
987f069f5eSMehdi Amini   // Set a breakpoint matching only the second operation in the list.
997f069f5eSMehdi Amini   auto *breakpoint = breakpointManager.addBreakpoint(
1007f069f5eSMehdi Amini       fileNames[0], lineColLoc[0].first, lineColLoc[0].second);
101*1893a374SMehdi Amini   auto checkMatchIdxs = [&](const DenseSet<int> &idxs) {
1027f069f5eSMehdi Amini     counter = 0;
1037f069f5eSMehdi Amini     int reference = 0;
1047f069f5eSMehdi Amini     for (int i = 0; i < (int)operations.size(); ++i) {
1057f069f5eSMehdi Amini       executionCtx(counterInc, FileLineColLocTestingAction({operations[i]}));
1067f069f5eSMehdi Amini       if (!idxs.contains(i))
1077f069f5eSMehdi Amini         reference++;
1087f069f5eSMehdi Amini       EXPECT_EQ(counter, reference);
1097f069f5eSMehdi Amini     }
1107f069f5eSMehdi Amini   };
1117f069f5eSMehdi Amini   checkMatchIdxs({1});
1127f069f5eSMehdi Amini 
1137f069f5eSMehdi Amini   // Check that disabling the breakpoing brings us back to the original
1147f069f5eSMehdi Amini   // behavior.
1157f069f5eSMehdi Amini   breakpoint->disable();
1167f069f5eSMehdi Amini   checkNoMatch();
1177f069f5eSMehdi Amini 
1187f069f5eSMehdi Amini   // Adding a breakpoint that won't match any location shouldn't affect the
1197f069f5eSMehdi Amini   // behavior.
1207f069f5eSMehdi Amini   breakpointManager.addBreakpoint(StringRef("random.file"), 3, 14);
1217f069f5eSMehdi Amini   checkNoMatch();
1227f069f5eSMehdi Amini 
1237f069f5eSMehdi Amini   // Set a breakpoint matching only the fifth operation in the list.
1247f069f5eSMehdi Amini   breakpointManager.addBreakpoint(fileNames[1], lineColLoc[1].first,
1257f069f5eSMehdi Amini                                   lineColLoc[1].second);
1267f069f5eSMehdi Amini   counter = 0;
1277f069f5eSMehdi Amini   checkMatchIdxs({5});
1287f069f5eSMehdi Amini 
1297f069f5eSMehdi Amini   // Re-enable the breakpoint matching only the second operation in the list.
1307f069f5eSMehdi Amini   // We now expect matching of operations 1 and 5.
1317f069f5eSMehdi Amini   breakpoint->enable();
1327f069f5eSMehdi Amini   checkMatchIdxs({1, 5});
1337f069f5eSMehdi Amini 
1347f069f5eSMehdi Amini   for (auto *op : operations) {
1357f069f5eSMehdi Amini     op->destroy();
1367f069f5eSMehdi Amini   }
1377f069f5eSMehdi Amini }
1387f069f5eSMehdi Amini 
TEST(FileLineColLocBreakpointManager,BlockMatch)1397f069f5eSMehdi Amini TEST(FileLineColLocBreakpointManager, BlockMatch) {
1407f069f5eSMehdi Amini   // This test will process a block and check various situation with
1417f069f5eSMehdi Amini   // a breakpoint hitting or not based on the location attached.
1427f069f5eSMehdi Amini   // When a breakpoint hits, the action is skipped and the counter is not
1437f069f5eSMehdi Amini   // incremented.
1447f069f5eSMehdi Amini   ExecutionContext executionCtx(
1457f069f5eSMehdi Amini       [](const ActionActiveStack *) { return ExecutionContext::Skip; });
1467f069f5eSMehdi Amini   int counter = 0;
1477f069f5eSMehdi Amini   auto counterInc = [&]() { counter++; };
1487f069f5eSMehdi Amini 
1497f069f5eSMehdi Amini   // Setup
1507f069f5eSMehdi Amini 
1517f069f5eSMehdi Amini   MLIRContext context;
1527f069f5eSMehdi Amini   std::vector<StringRef> fileNames = {StringRef("grault.garply"),
1537f069f5eSMehdi Amini                                       StringRef("waldo.fred")};
1547f069f5eSMehdi Amini   std::vector<std::pair<unsigned, unsigned>> lineColLoc = {{42, 7}, {24, 3}};
1557f069f5eSMehdi Amini   Operation *frontOp = createOp(&context,
1567f069f5eSMehdi Amini                                 FileLineColLoc::get(&context, fileNames.front(),
1577f069f5eSMehdi Amini                                                     lineColLoc.front().first,
1587f069f5eSMehdi Amini                                                     lineColLoc.front().second),
1597f069f5eSMehdi Amini                                 "firstOperation");
1607f069f5eSMehdi Amini   Operation *backOp = createOp(&context,
1617f069f5eSMehdi Amini                                FileLineColLoc::get(&context, fileNames.back(),
1627f069f5eSMehdi Amini                                                    lineColLoc.back().first,
1637f069f5eSMehdi Amini                                                    lineColLoc.back().second),
1647f069f5eSMehdi Amini                                "secondOperation");
1657f069f5eSMehdi Amini   Block block;
1667f069f5eSMehdi Amini   block.push_back(frontOp);
1677f069f5eSMehdi Amini   block.push_back(backOp);
1687f069f5eSMehdi Amini 
1697f069f5eSMehdi Amini   FileLineColLocBreakpointManager breakpointManager;
1707f069f5eSMehdi Amini   executionCtx.addBreakpointManager(&breakpointManager);
1717f069f5eSMehdi Amini 
1727f069f5eSMehdi Amini   // Test
1737f069f5eSMehdi Amini 
1747f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&block}));
1757f069f5eSMehdi Amini   EXPECT_EQ(counter, 1);
1767f069f5eSMehdi Amini 
1777f069f5eSMehdi Amini   auto *breakpoint = breakpointManager.addBreakpoint(
1787f069f5eSMehdi Amini       fileNames.front(), lineColLoc.front().first, lineColLoc.front().second);
1797f069f5eSMehdi Amini   counter = 0;
1807f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&block}));
1817f069f5eSMehdi Amini   EXPECT_EQ(counter, 0);
1827f069f5eSMehdi Amini   breakpoint->disable();
1837f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&block}));
1847f069f5eSMehdi Amini   EXPECT_EQ(counter, 1);
1857f069f5eSMehdi Amini 
1867f069f5eSMehdi Amini   breakpoint = breakpointManager.addBreakpoint(
1877f069f5eSMehdi Amini       fileNames.back(), lineColLoc.back().first, lineColLoc.back().second);
1887f069f5eSMehdi Amini   counter = 0;
1897f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&block}));
1907f069f5eSMehdi Amini   EXPECT_EQ(counter, 0);
1917f069f5eSMehdi Amini   breakpoint->disable();
1927f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&block}));
1937f069f5eSMehdi Amini   EXPECT_EQ(counter, 1);
1947f069f5eSMehdi Amini }
1957f069f5eSMehdi Amini 
TEST(FileLineColLocBreakpointManager,RegionMatch)1967f069f5eSMehdi Amini TEST(FileLineColLocBreakpointManager, RegionMatch) {
1977f069f5eSMehdi Amini   // This test will process a region and check various situation with
1987f069f5eSMehdi Amini   // a breakpoint hitting or not based on the location attached.
1997f069f5eSMehdi Amini   // When a breakpoint hits, the action is skipped and the counter is not
2007f069f5eSMehdi Amini   // incremented.
2017f069f5eSMehdi Amini   ExecutionContext executionCtx(
2027f069f5eSMehdi Amini       [](const ActionActiveStack *) { return ExecutionContext::Skip; });
2037f069f5eSMehdi Amini   int counter = 0;
2047f069f5eSMehdi Amini   auto counterInc = [&]() { counter++; };
2057f069f5eSMehdi Amini 
2067f069f5eSMehdi Amini   // Setup
2077f069f5eSMehdi Amini 
2087f069f5eSMehdi Amini   MLIRContext context;
2097f069f5eSMehdi Amini   StringRef fileName("plugh.xyzzy");
2107f069f5eSMehdi Amini   unsigned line = 42, col = 7;
2117f069f5eSMehdi Amini   Operation *containerOp =
2127f069f5eSMehdi Amini       createOp(&context, FileLineColLoc::get(&context, fileName, line, col),
2137f069f5eSMehdi Amini                "containerOperation", 1);
2147f069f5eSMehdi Amini   Region &region = containerOp->getRegion(0);
2157f069f5eSMehdi Amini 
2167f069f5eSMehdi Amini   FileLineColLocBreakpointManager breakpointManager;
2177f069f5eSMehdi Amini   executionCtx.addBreakpointManager(&breakpointManager);
2187f069f5eSMehdi Amini 
2197f069f5eSMehdi Amini   // Test
2207f069f5eSMehdi Amini   counter = 0;
2217f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&region}));
2227f069f5eSMehdi Amini   EXPECT_EQ(counter, 1);
2237f069f5eSMehdi Amini   auto *breakpoint = breakpointManager.addBreakpoint(fileName, line, col);
2247f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&region}));
2257f069f5eSMehdi Amini   EXPECT_EQ(counter, 1);
2267f069f5eSMehdi Amini   breakpoint->disable();
2277f069f5eSMehdi Amini   executionCtx(counterInc, FileLineColLocTestingAction({&region}));
2287f069f5eSMehdi Amini   EXPECT_EQ(counter, 2);
2297f069f5eSMehdi Amini 
2307f069f5eSMehdi Amini   containerOp->destroy();
2317f069f5eSMehdi Amini }
2327f069f5eSMehdi Amini } // namespace
233