MLIR  19.0.0git
ToolUtilities.cpp
Go to the documentation of this file.
1 //===- ToolUtilities.cpp - MLIR Tool Utilities ----------------------------===//
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 // This file defines common utilities for implementing MLIR tools.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "mlir/Support/LLVM.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "llvm/Support/raw_ostream.h"
18 
19 using namespace mlir;
20 
22 mlir::splitAndProcessBuffer(std::unique_ptr<llvm::MemoryBuffer> originalBuffer,
23  ChunkBufferHandler processChunkBuffer,
24  raw_ostream &os, llvm::StringRef inputSplitMarker,
25  llvm::StringRef outputSplitMarker) {
26  // If splitting is disabled, we process the full input buffer.
27  if (inputSplitMarker.empty())
28  return processChunkBuffer(std::move(originalBuffer), os);
29 
30  const int inputSplitMarkerLen = inputSplitMarker.size();
31 
32  auto *origMemBuffer = originalBuffer.get();
33  SmallVector<StringRef, 8> rawSourceBuffers;
34  const int checkLen = 2;
35  // Split dropping the last checkLen chars to enable flagging near misses.
36  origMemBuffer->getBuffer().split(rawSourceBuffers,
37  inputSplitMarker.drop_back(checkLen));
38  if (rawSourceBuffers.empty())
39  return success();
40 
41  // Add the original buffer to the source manager.
42  llvm::SourceMgr fileSourceMgr;
43  fileSourceMgr.AddNewSourceBuffer(std::move(originalBuffer), SMLoc());
44 
45  // Flag near misses by iterating over all the sub-buffers found when splitting
46  // with the prefix of the splitMarker. Use a sliding window where we only add
47  // a buffer as a sourceBuffer if terminated by a full match of the
48  // splitMarker, else flag a warning (if near miss) and extend the size of the
49  // buffer under consideration.
50  SmallVector<StringRef, 8> sourceBuffers;
51  StringRef prev;
52  for (auto buffer : rawSourceBuffers) {
53  if (prev.empty()) {
54  prev = buffer;
55  continue;
56  }
57 
58  // Check that suffix is as expected and doesn't have any dash post.
59  bool expectedSuffix =
60  buffer.starts_with(inputSplitMarker.take_back(checkLen)) &&
61  buffer.size() > checkLen && buffer[checkLen] != '0';
62  if (expectedSuffix) {
63  sourceBuffers.push_back(prev);
64  prev = buffer.drop_front(checkLen);
65  } else {
66  // TODO: Consider making this a failure.
67  auto splitLoc = SMLoc::getFromPointer(buffer.data());
68  fileSourceMgr.PrintMessage(llvm::errs(), splitLoc,
69  llvm::SourceMgr::DK_Warning,
70  "near miss with file split marker");
71  prev = StringRef(prev.data(), prev.size() + inputSplitMarkerLen -
72  checkLen + buffer.size());
73  }
74  }
75  if (!prev.empty())
76  sourceBuffers.push_back(prev);
77 
78  // Process each chunk in turn.
79  bool hadFailure = false;
80  auto interleaveFn = [&](StringRef subBuffer) {
81  auto splitLoc = SMLoc::getFromPointer(subBuffer.data());
82  unsigned splitLine = fileSourceMgr.getLineAndColumn(splitLoc).first;
83  auto subMemBuffer = llvm::MemoryBuffer::getMemBufferCopy(
84  subBuffer, Twine("within split at ") +
85  origMemBuffer->getBufferIdentifier() + ":" +
86  Twine(splitLine) + " offset ");
87  if (failed(processChunkBuffer(std::move(subMemBuffer), os)))
88  hadFailure = true;
89  };
90  llvm::interleave(sourceBuffers, os, interleaveFn,
91  (llvm::Twine(outputSplitMarker) + "\n").str());
92 
93  // If any fails, then return a failure of the tool.
94  return failure(hadFailure);
95 }
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
LogicalResult splitAndProcessBuffer(std::unique_ptr< llvm::MemoryBuffer > originalBuffer, ChunkBufferHandler processChunkBuffer, raw_ostream &os, llvm::StringRef inputSplitMarker=kDefaultSplitMarker, llvm::StringRef outputSplitMarker="")
Splits the specified buffer on a marker (// ----- by default), processes each chunk independently acc...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26