1 //===- Tester.cpp ---------------------------------------------------------===//
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 // This file defines the Tester class used in the MLIR Reduce tool.
11 // A Tester object is passed as an argument to the reduction passes and it is
12 // used to run the interestingness testing script on the different generated
13 // reduced variants of the test case.
15 //===----------------------------------------------------------------------===//
17 #include "mlir/Reducer/Tester.h"
18 #include "mlir/IR/Verifier.h"
19 #include "llvm/Support/ToolOutputFile.h"
23 Tester::Tester(StringRef scriptName
, ArrayRef
<std::string
> scriptArgs
)
24 : testScript(scriptName
), testScriptArgs(scriptArgs
) {}
26 std::pair
<Tester::Interestingness
, size_t>
27 Tester::isInteresting(ModuleOp module
) const {
28 // The reduced module should always be vaild, or we may end up retaining the
29 // error message by an invalid case. Besides, an invalid module may not be
30 // able to print properly.
31 if (failed(verify(module
)))
32 return std::make_pair(Interestingness::False
, /*size=*/0);
34 SmallString
<128> filepath
;
37 // Print module to temporary file.
39 llvm::sys::fs::createTemporaryFile("mlir-reduce", "mlir", fd
, filepath
);
42 llvm::report_fatal_error(llvm::Twine("Error making unique filename: ") +
45 llvm::ToolOutputFile
out(filepath
, fd
);
46 module
.print(out
.os());
49 if (out
.os().has_error())
50 llvm::report_fatal_error(llvm::Twine("Error emitting the IR to file '") +
53 size_t size
= out
.os().tell();
54 return std::make_pair(isInteresting(filepath
), size
);
57 /// Runs the interestingness testing script on a MLIR test case file. Returns
58 /// true if the interesting behavior is present in the test case or false
60 Tester::Interestingness
Tester::isInteresting(StringRef testCase
) const {
61 std::vector
<StringRef
> testerArgs
;
62 testerArgs
.push_back(testCase
);
64 for (const std::string
&arg
: testScriptArgs
)
65 testerArgs
.emplace_back(arg
);
67 testerArgs
.push_back(testCase
);
70 int result
= llvm::sys::ExecuteAndWait(
71 testScript
, testerArgs
, /*Env=*/std::nullopt
, /*Redirects=*/std::nullopt
,
72 /*SecondsToWait=*/0, /*MemoryLimit=*/0, &errMsg
);
75 llvm::report_fatal_error(
76 llvm::Twine("Error running interestingness test: ") + errMsg
, false);
79 return Interestingness::False
;
81 return Interestingness::True
;