//===- mlir-src-sharder.cpp - A tool for sharder generated source files ---===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "mlir/Support/FileUtilities.h" #include "mlir/Support/LLVM.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/ToolOutputFile.h" using namespace mlir; /// Create a dependency file for `-d` option. /// /// This functionality is generally only for the benefit of the build system, /// and is modeled after the same option in TableGen. static LogicalResult createDependencyFile(StringRef outputFilename, StringRef dependencyFile) { if (outputFilename == "-") { llvm::errs() << "error: the option -d must be used together with -o\n"; return failure(); } std::string errorMessage; std::unique_ptr outputFile = openOutputFile(dependencyFile, &errorMessage); if (!outputFile) { llvm::errs() << errorMessage << "\n"; return failure(); } outputFile->os() << outputFilename << ":\n"; outputFile->keep(); return success(); } int main(int argc, char **argv) { // FIXME: This is necessary because we link in TableGen, which defines its // options as static variables.. some of which overlap with our options. llvm::cl::ResetCommandLineParser(); llvm::cl::opt opShardIndex( "op-shard-index", llvm::cl::desc("The current shard index")); llvm::cl::opt inputFilename(llvm::cl::Positional, llvm::cl::desc(""), llvm::cl::init("-")); llvm::cl::opt outputFilename( "o", llvm::cl::desc("Output filename"), llvm::cl::value_desc("filename"), llvm::cl::init("-")); llvm::cl::list includeDirs( "I", llvm::cl::desc("Directory of include files"), llvm::cl::value_desc("directory"), llvm::cl::Prefix); llvm::cl::opt dependencyFilename( "d", llvm::cl::desc("Dependency filename"), llvm::cl::value_desc("filename"), llvm::cl::init("")); llvm::cl::opt writeIfChanged( "write-if-changed", llvm::cl::desc("Only write to the output file if it changed")); // `ResetCommandLineParser` at the above unregistered the "D" option // of `llvm-tblgen`, which caused `TestOps.cpp` to fail due to // "Unknnown command line argument '-D...`" when a macros name is // present. The following is a workaround to re-register it again. llvm::cl::list macroNames( "D", llvm::cl::desc( "Name of the macro to be defined -- ignored by mlir-src-sharder"), llvm::cl::value_desc("macro name"), llvm::cl::Prefix); llvm::InitLLVM y(argc, argv); llvm::cl::ParseCommandLineOptions(argc, argv); // Open the input file. std::string errorMessage; std::unique_ptr inputFile = openInputFile(inputFilename, &errorMessage); if (!inputFile) { llvm::errs() << errorMessage << "\n"; return 1; } // Write the output to a buffer. std::string outputStr; llvm::raw_string_ostream os(outputStr); os << "#define GET_OP_DEFS_" << opShardIndex << "\n" << inputFile->getBuffer(); // Determine whether we need to write the output file. bool shouldWriteOutput = true; if (writeIfChanged) { // Only update the real output file if there are any differences. This // prevents recompilation of all the files depending on it if there aren't // any. if (auto existingOrErr = llvm::MemoryBuffer::getFile(outputFilename, /*IsText=*/true)) if (std::move(existingOrErr.get())->getBuffer() == outputStr) shouldWriteOutput = false; } // Populate the output file if necessary. if (shouldWriteOutput) { std::unique_ptr outputFile = openOutputFile(outputFilename, &errorMessage); if (!outputFile) { llvm::errs() << errorMessage << "\n"; return 1; } outputFile->os() << os.str(); outputFile->keep(); } // Always write the depfile, even if the main output hasn't changed. If it's // missing, Ninja considers the output dirty. if (!dependencyFilename.empty()) if (failed(createDependencyFile(outputFilename, dependencyFilename))) return 1; return 0; }