forked from OSchip/llvm-project
83 lines
2.8 KiB
C++
83 lines
2.8 KiB
C++
//===- Tester.cpp ---------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the Tester class used in the MLIR Reduce tool.
|
|
//
|
|
// A Tester object is passed as an argument to the reduction passes and it is
|
|
// used to run the interestingness testing script on the different generated
|
|
// reduced variants of the test case.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Reducer/Tester.h"
|
|
#include "mlir/IR/Verifier.h"
|
|
#include "llvm/Support/ToolOutputFile.h"
|
|
|
|
using namespace mlir;
|
|
|
|
Tester::Tester(StringRef scriptName, ArrayRef<std::string> scriptArgs)
|
|
: testScript(scriptName), testScriptArgs(scriptArgs) {}
|
|
|
|
std::pair<Tester::Interestingness, size_t>
|
|
Tester::isInteresting(ModuleOp module) const {
|
|
// The reduced module should always be vaild, or we may end up retaining the
|
|
// error message by an invalid case. Besides, an invalid module may not be
|
|
// able to print properly.
|
|
if (failed(verify(module)))
|
|
return std::make_pair(Interestingness::False, /*size=*/0);
|
|
|
|
SmallString<128> filepath;
|
|
int fd;
|
|
|
|
// Print module to temporary file.
|
|
std::error_code ec =
|
|
llvm::sys::fs::createTemporaryFile("mlir-reduce", "mlir", fd, filepath);
|
|
|
|
if (ec)
|
|
llvm::report_fatal_error(llvm::Twine("Error making unique filename: ") +
|
|
ec.message());
|
|
|
|
llvm::ToolOutputFile out(filepath, fd);
|
|
module.print(out.os());
|
|
out.os().close();
|
|
|
|
if (out.os().has_error())
|
|
llvm::report_fatal_error(llvm::Twine("Error emitting the IR to file '") +
|
|
filepath);
|
|
|
|
size_t size = out.os().tell();
|
|
return std::make_pair(isInteresting(filepath), size);
|
|
}
|
|
|
|
/// Runs the interestingness testing script on a MLIR test case file. Returns
|
|
/// true if the interesting behavior is present in the test case or false
|
|
/// otherwise.
|
|
Tester::Interestingness Tester::isInteresting(StringRef testCase) const {
|
|
std::vector<StringRef> testerArgs;
|
|
testerArgs.push_back(testCase);
|
|
|
|
for (const std::string &arg : testScriptArgs)
|
|
testerArgs.emplace_back(arg);
|
|
|
|
testerArgs.push_back(testCase);
|
|
|
|
std::string errMsg;
|
|
int result = llvm::sys::ExecuteAndWait(
|
|
testScript, testerArgs, /*Env=*/None, /*Redirects=*/None,
|
|
/*SecondsToWait=*/0, /*MemoryLimit=*/0, &errMsg);
|
|
|
|
if (result < 0)
|
|
llvm::report_fatal_error(
|
|
llvm::Twine("Error running interestingness test: ") + errMsg, false);
|
|
|
|
if (!result)
|
|
return Interestingness::False;
|
|
|
|
return Interestingness::True;
|
|
}
|