1 //===- mlir-src-sharder.cpp - A tool for sharder generated source files ---===//
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
7 //===----------------------------------------------------------------------===//
9 #include "mlir/Support/FileUtilities.h"
10 #include "mlir/Support/LLVM.h"
11 #include "llvm/Support/CommandLine.h"
12 #include "llvm/Support/InitLLVM.h"
13 #include "llvm/Support/MemoryBuffer.h"
14 #include "llvm/Support/ToolOutputFile.h"
18 /// Create a dependency file for `-d` option.
20 /// This functionality is generally only for the benefit of the build system,
21 /// and is modeled after the same option in TableGen.
22 static LogicalResult
createDependencyFile(StringRef outputFilename
,
23 StringRef dependencyFile
) {
24 if (outputFilename
== "-") {
25 llvm::errs() << "error: the option -d must be used together with -o\n";
29 std::string errorMessage
;
30 std::unique_ptr
<llvm::ToolOutputFile
> outputFile
=
31 openOutputFile(dependencyFile
, &errorMessage
);
33 llvm::errs() << errorMessage
<< "\n";
37 outputFile
->os() << outputFilename
<< ":\n";
42 int main(int argc
, char **argv
) {
43 // FIXME: This is necessary because we link in TableGen, which defines its
44 // options as static variables.. some of which overlap with our options.
45 llvm::cl::ResetCommandLineParser();
47 llvm::cl::opt
<unsigned> opShardIndex(
48 "op-shard-index", llvm::cl::desc("The current shard index"));
49 llvm::cl::opt
<std::string
> inputFilename(llvm::cl::Positional
,
50 llvm::cl::desc("<input file>"),
52 llvm::cl::opt
<std::string
> outputFilename(
53 "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"),
55 llvm::cl::list
<std::string
> includeDirs(
56 "I", llvm::cl::desc("Directory of include files"),
57 llvm::cl::value_desc("directory"), llvm::cl::Prefix
);
58 llvm::cl::opt
<std::string
> dependencyFilename(
59 "d", llvm::cl::desc("Dependency filename"),
60 llvm::cl::value_desc("filename"), llvm::cl::init(""));
61 llvm::cl::opt
<bool> writeIfChanged(
63 llvm::cl::desc("Only write to the output file if it changed"));
65 // `ResetCommandLineParser` at the above unregistered the "D" option
66 // of `llvm-tblgen`, which caused `TestOps.cpp` to fail due to
67 // "Unknnown command line argument '-D...`" when a macros name is
68 // present. The following is a workaround to re-register it again.
69 llvm::cl::list
<std::string
> macroNames(
72 "Name of the macro to be defined -- ignored by mlir-src-sharder"),
73 llvm::cl::value_desc("macro name"), llvm::cl::Prefix
);
75 llvm::InitLLVM
y(argc
, argv
);
76 llvm::cl::ParseCommandLineOptions(argc
, argv
);
78 // Open the input file.
79 std::string errorMessage
;
80 std::unique_ptr
<llvm::MemoryBuffer
> inputFile
=
81 openInputFile(inputFilename
, &errorMessage
);
83 llvm::errs() << errorMessage
<< "\n";
87 // Write the output to a buffer.
88 std::string outputStr
;
89 llvm::raw_string_ostream
os(outputStr
);
90 os
<< "#define GET_OP_DEFS_" << opShardIndex
<< "\n"
91 << inputFile
->getBuffer();
93 // Determine whether we need to write the output file.
94 bool shouldWriteOutput
= true;
96 // Only update the real output file if there are any differences. This
97 // prevents recompilation of all the files depending on it if there aren't
99 if (auto existingOrErr
=
100 llvm::MemoryBuffer::getFile(outputFilename
, /*IsText=*/true))
101 if (std::move(existingOrErr
.get())->getBuffer() == outputStr
)
102 shouldWriteOutput
= false;
105 // Populate the output file if necessary.
106 if (shouldWriteOutput
) {
107 std::unique_ptr
<llvm::ToolOutputFile
> outputFile
=
108 openOutputFile(outputFilename
, &errorMessage
);
110 llvm::errs() << errorMessage
<< "\n";
113 outputFile
->os() << os
.str();
117 // Always write the depfile, even if the main output hasn't changed. If it's
118 // missing, Ninja considers the output dirty.
119 if (!dependencyFilename
.empty())
120 if (failed(createDependencyFile(outputFilename
, dependencyFilename
)))