233 lines · cpp
1//===- FileLineColLocBreakpointManagerTest.cpp - --------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "mlir/Debug/BreakpointManagers/FileLineColLocBreakpointManager.h"10#include "mlir/Debug/ExecutionContext.h"11#include "mlir/IR/Builders.h"12#include "mlir/IR/BuiltinAttributes.h"13#include "mlir/IR/BuiltinTypes.h"14#include "mlir/IR/Location.h"15#include "mlir/IR/OperationSupport.h"16#include "llvm/ADT/STLExtras.h"17#include "gtest/gtest.h"18 19using namespace mlir;20using namespace mlir::tracing;21 22static Operation *createOp(MLIRContext *context, Location loc,23 StringRef operationName,24 unsigned int numRegions = 0) {25 context->allowUnregisteredDialects();26 return Operation::create(loc, OperationName(operationName, context), {}, {},27 NamedAttrList(), OpaqueProperties(nullptr), {},28 numRegions);29}30 31namespace {32struct FileLineColLocTestingAction33 : public ActionImpl<FileLineColLocTestingAction> {34 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(FileLineColLocTestingAction)35 static constexpr StringLiteral tag = "file-line-col-loc-testing-action";36 FileLineColLocTestingAction(ArrayRef<IRUnit> irUnits)37 : ActionImpl<FileLineColLocTestingAction>(irUnits) {}38};39 40TEST(FileLineColLocBreakpointManager, OperationMatch) {41 // This test will process a sequence of operation and check various situation42 // with a breakpoint hitting or not based on the location attached to the43 // operation. When a breakpoint hits, the action is skipped and the counter is44 // not incremented.45 ExecutionContext executionCtx(46 [](const ActionActiveStack *) { return ExecutionContext::Skip; });47 int counter = 0;48 auto counterInc = [&]() { counter++; };49 50 // Setup51 52 MLIRContext context;53 // Miscellaneous information to define operations54 std::vector<StringRef> fileNames = {55 StringRef("foo.bar"), StringRef("baz.qux"), StringRef("quux.corge")};56 std::vector<std::pair<unsigned, unsigned>> lineColLoc = {{42, 7}, {24, 3}};57 Location callee = UnknownLoc::get(&context),58 caller = UnknownLoc::get(&context), loc = UnknownLoc::get(&context);59 60 // Set of operations over where we are going to be testing the functionality61 std::vector<Operation *> operations = {62 createOp(&context, CallSiteLoc::get(callee, caller),63 "callSiteLocOperation"),64 createOp(&context,65 FileLineColLoc::get(&context, fileNames[0], lineColLoc[0].first,66 lineColLoc[0].second),67 "fileLineColLocOperation"),68 createOp(&context, FusedLoc::get(&context, {}, Attribute()),69 "fusedLocOperation"),70 createOp(&context, NameLoc::get(StringAttr::get(&context, fileNames[2])),71 "nameLocOperation"),72 createOp(&context, OpaqueLoc::get<void *>(nullptr, loc),73 "opaqueLocOperation"),74 createOp(&context,75 FileLineColLoc::get(&context, fileNames[1], lineColLoc[1].first,76 lineColLoc[1].second),77 "anotherFileLineColLocOperation"),78 createOp(&context, UnknownLoc::get(&context), "unknownLocOperation"),79 };80 81 FileLineColLocBreakpointManager breakpointManager;82 executionCtx.addBreakpointManager(&breakpointManager);83 84 // Test85 86 // Basic case is that no breakpoint is set and the counter is incremented for87 // every op.88 auto checkNoMatch = [&]() {89 counter = 0;90 for (auto enumeratedOp : llvm::enumerate(operations)) {91 executionCtx(counterInc,92 FileLineColLocTestingAction({enumeratedOp.value()}));93 EXPECT_EQ(counter, static_cast<int>(enumeratedOp.index() + 1));94 }95 };96 checkNoMatch();97 98 // Set a breakpoint matching only the second operation in the list.99 auto *breakpoint = breakpointManager.addBreakpoint(100 fileNames[0], lineColLoc[0].first, lineColLoc[0].second);101 auto checkMatchIdxs = [&](const DenseSet<int> &idxs) {102 counter = 0;103 int reference = 0;104 for (int i = 0; i < (int)operations.size(); ++i) {105 executionCtx(counterInc, FileLineColLocTestingAction({operations[i]}));106 if (!idxs.contains(i))107 reference++;108 EXPECT_EQ(counter, reference);109 }110 };111 checkMatchIdxs({1});112 113 // Check that disabling the breakpoing brings us back to the original114 // behavior.115 breakpoint->disable();116 checkNoMatch();117 118 // Adding a breakpoint that won't match any location shouldn't affect the119 // behavior.120 breakpointManager.addBreakpoint(StringRef("random.file"), 3, 14);121 checkNoMatch();122 123 // Set a breakpoint matching only the fifth operation in the list.124 breakpointManager.addBreakpoint(fileNames[1], lineColLoc[1].first,125 lineColLoc[1].second);126 counter = 0;127 checkMatchIdxs({5});128 129 // Re-enable the breakpoint matching only the second operation in the list.130 // We now expect matching of operations 1 and 5.131 breakpoint->enable();132 checkMatchIdxs({1, 5});133 134 for (auto *op : operations) {135 op->destroy();136 }137}138 139TEST(FileLineColLocBreakpointManager, BlockMatch) {140 // This test will process a block and check various situation with141 // a breakpoint hitting or not based on the location attached.142 // When a breakpoint hits, the action is skipped and the counter is not143 // incremented.144 ExecutionContext executionCtx(145 [](const ActionActiveStack *) { return ExecutionContext::Skip; });146 int counter = 0;147 auto counterInc = [&]() { counter++; };148 149 // Setup150 151 MLIRContext context;152 std::vector<StringRef> fileNames = {StringRef("grault.garply"),153 StringRef("waldo.fred")};154 std::vector<std::pair<unsigned, unsigned>> lineColLoc = {{42, 7}, {24, 3}};155 Operation *frontOp = createOp(&context,156 FileLineColLoc::get(&context, fileNames.front(),157 lineColLoc.front().first,158 lineColLoc.front().second),159 "firstOperation");160 Operation *backOp = createOp(&context,161 FileLineColLoc::get(&context, fileNames.back(),162 lineColLoc.back().first,163 lineColLoc.back().second),164 "secondOperation");165 Block block;166 block.push_back(frontOp);167 block.push_back(backOp);168 169 FileLineColLocBreakpointManager breakpointManager;170 executionCtx.addBreakpointManager(&breakpointManager);171 172 // Test173 174 executionCtx(counterInc, FileLineColLocTestingAction({&block}));175 EXPECT_EQ(counter, 1);176 177 auto *breakpoint = breakpointManager.addBreakpoint(178 fileNames.front(), lineColLoc.front().first, lineColLoc.front().second);179 counter = 0;180 executionCtx(counterInc, FileLineColLocTestingAction({&block}));181 EXPECT_EQ(counter, 0);182 breakpoint->disable();183 executionCtx(counterInc, FileLineColLocTestingAction({&block}));184 EXPECT_EQ(counter, 1);185 186 breakpoint = breakpointManager.addBreakpoint(187 fileNames.back(), lineColLoc.back().first, lineColLoc.back().second);188 counter = 0;189 executionCtx(counterInc, FileLineColLocTestingAction({&block}));190 EXPECT_EQ(counter, 0);191 breakpoint->disable();192 executionCtx(counterInc, FileLineColLocTestingAction({&block}));193 EXPECT_EQ(counter, 1);194}195 196TEST(FileLineColLocBreakpointManager, RegionMatch) {197 // This test will process a region and check various situation with198 // a breakpoint hitting or not based on the location attached.199 // When a breakpoint hits, the action is skipped and the counter is not200 // incremented.201 ExecutionContext executionCtx(202 [](const ActionActiveStack *) { return ExecutionContext::Skip; });203 int counter = 0;204 auto counterInc = [&]() { counter++; };205 206 // Setup207 208 MLIRContext context;209 StringRef fileName("plugh.xyzzy");210 unsigned line = 42, col = 7;211 Operation *containerOp =212 createOp(&context, FileLineColLoc::get(&context, fileName, line, col),213 "containerOperation", 1);214 Region ®ion = containerOp->getRegion(0);215 216 FileLineColLocBreakpointManager breakpointManager;217 executionCtx.addBreakpointManager(&breakpointManager);218 219 // Test220 counter = 0;221 executionCtx(counterInc, FileLineColLocTestingAction({®ion}));222 EXPECT_EQ(counter, 1);223 auto *breakpoint = breakpointManager.addBreakpoint(fileName, line, col);224 executionCtx(counterInc, FileLineColLocTestingAction({®ion}));225 EXPECT_EQ(counter, 1);226 breakpoint->disable();227 executionCtx(counterInc, FileLineColLocTestingAction({®ion}));228 EXPECT_EQ(counter, 2);229 230 containerOp->destroy();231}232} // namespace233