83 lines · cpp
1//===- Tester.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// This file defines the Tester class used in the MLIR Reduce tool.10//11// A Tester object is passed as an argument to the reduction passes and it is12// used to run the interestingness testing script on the different generated13// reduced variants of the test case.14//15//===----------------------------------------------------------------------===//16 17#include "mlir/Reducer/Tester.h"18#include "mlir/IR/Verifier.h"19#include "llvm/Support/ToolOutputFile.h"20 21using namespace mlir;22 23Tester::Tester(StringRef scriptName, ArrayRef<std::string> scriptArgs)24 : testScript(scriptName), testScriptArgs(scriptArgs) {}25 26std::pair<Tester::Interestingness, size_t>27Tester::isInteresting(ModuleOp module) const {28 // The reduced module should always be vaild, or we may end up retaining the29 // error message by an invalid case. Besides, an invalid module may not be30 // able to print properly.31 if (failed(verify(module)))32 return std::make_pair(Interestingness::False, /*size=*/0);33 34 SmallString<128> filepath;35 int fd;36 37 // Print module to temporary file.38 std::error_code ec =39 llvm::sys::fs::createTemporaryFile("mlir-reduce", "mlir", fd, filepath);40 41 if (ec)42 llvm::report_fatal_error(llvm::Twine("Error making unique filename: ") +43 ec.message());44 45 llvm::ToolOutputFile out(filepath, fd);46 module.print(out.os());47 out.os().close();48 49 if (out.os().has_error())50 llvm::report_fatal_error(llvm::Twine("Error emitting the IR to file '") +51 filepath);52 53 size_t size = out.os().tell();54 return std::make_pair(isInteresting(filepath), size);55}56 57/// Runs the interestingness testing script on a MLIR test case file. Returns58/// true if the interesting behavior is present in the test case or false59/// otherwise.60Tester::Interestingness Tester::isInteresting(StringRef testCase) const {61 std::vector<StringRef> testerArgs;62 testerArgs.push_back(testCase);63 64 for (const std::string &arg : testScriptArgs)65 testerArgs.emplace_back(arg);66 67 testerArgs.push_back(testCase);68 69 std::string errMsg;70 int result = llvm::sys::ExecuteAndWait(71 testScript, testerArgs, /*Env=*/std::nullopt, /*Redirects=*/{},72 /*SecondsToWait=*/0, /*MemoryLimit=*/0, &errMsg);73 74 if (result < 0)75 llvm::report_fatal_error(76 llvm::Twine("Error running interestingness test: ") + errMsg, false);77 78 if (!result)79 return Interestingness::False;80 81 return Interestingness::True;82}83