We required the test and input arguments for --print-delta-passes which is unhelpful. Also, start printing the help output if no arguments were supplied. It looks like there's more sophisticated ways to accomplish this with the opt library, but it was less work to manually emit these errors.
116 lines
4.0 KiB
C++
116 lines
4.0 KiB
C++
//===-- TestRunner.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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "TestRunner.h"
|
|
#include "ReducerWorkItem.h"
|
|
#include "deltas/Utils.h"
|
|
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
|
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
|
#include "llvm/Bitcode/BitcodeReader.h"
|
|
#include "llvm/Bitcode/BitcodeWriter.h"
|
|
#include "llvm/Passes/PassBuilder.h"
|
|
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
|
|
|
|
using namespace llvm;
|
|
|
|
TestRunner::TestRunner(StringRef TestName,
|
|
const std::vector<std::string> &TestArgs,
|
|
std::unique_ptr<ReducerWorkItem> Program,
|
|
std::unique_ptr<TargetMachine> TM, StringRef ToolName,
|
|
StringRef OutputName, bool InputIsBitcode,
|
|
bool OutputBitcode)
|
|
: TestName(TestName), ToolName(ToolName), TestArgs(TestArgs),
|
|
Program(std::move(Program)), TM(std::move(TM)),
|
|
OutputFilename(OutputName), InputIsBitcode(InputIsBitcode),
|
|
EmitBitcode(OutputBitcode) {
|
|
assert(this->Program && "Initialized with null program?");
|
|
}
|
|
|
|
static constexpr std::array<std::optional<StringRef>, 3> DefaultRedirects = {
|
|
StringRef()};
|
|
static constexpr std::array<std::optional<StringRef>, 3> NullRedirects;
|
|
|
|
/// Runs the interestingness test, passes file to be tested as first argument
|
|
/// and other specified test arguments after that.
|
|
int TestRunner::run(StringRef Filename) const {
|
|
std::vector<StringRef> ProgramArgs;
|
|
ProgramArgs.push_back(TestName);
|
|
|
|
for (const auto &Arg : TestArgs)
|
|
ProgramArgs.push_back(Arg);
|
|
|
|
ProgramArgs.push_back(Filename);
|
|
|
|
std::string ErrMsg;
|
|
|
|
int Result =
|
|
sys::ExecuteAndWait(TestName, ProgramArgs, /*Env=*/std::nullopt,
|
|
Verbose ? DefaultRedirects : NullRedirects,
|
|
/*SecondsToWait=*/0, /*MemoryLimit=*/0, &ErrMsg);
|
|
|
|
if (Result < 0) {
|
|
Error E = make_error<StringError>("Error running interesting-ness test: " +
|
|
ErrMsg,
|
|
inconvertibleErrorCode());
|
|
errs() << toString(std::move(E)) << '\n';
|
|
exit(1);
|
|
}
|
|
|
|
return !Result;
|
|
}
|
|
|
|
void TestRunner::setProgram(std::unique_ptr<ReducerWorkItem> P) {
|
|
assert(P && "Setting null program?");
|
|
Program = std::move(P);
|
|
}
|
|
|
|
void writeBitcode(ReducerWorkItem &M, raw_ostream &OutStream) {
|
|
if (M.LTOInfo && M.LTOInfo->IsThinLTO && M.LTOInfo->EnableSplitLTOUnit) {
|
|
PassBuilder PB;
|
|
LoopAnalysisManager LAM;
|
|
FunctionAnalysisManager FAM;
|
|
CGSCCAnalysisManager CGAM;
|
|
ModuleAnalysisManager MAM;
|
|
PB.registerModuleAnalyses(MAM);
|
|
PB.registerCGSCCAnalyses(CGAM);
|
|
PB.registerFunctionAnalyses(FAM);
|
|
PB.registerLoopAnalyses(LAM);
|
|
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
|
|
ModulePassManager MPM;
|
|
MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr));
|
|
MPM.run(*M.M, MAM);
|
|
} else {
|
|
std::unique_ptr<ModuleSummaryIndex> Index;
|
|
if (M.LTOInfo && M.LTOInfo->HasSummary) {
|
|
ProfileSummaryInfo PSI(M);
|
|
Index = std::make_unique<ModuleSummaryIndex>(
|
|
buildModuleSummaryIndex(M, nullptr, &PSI));
|
|
}
|
|
WriteBitcodeToFile(M, OutStream, Index.get());
|
|
}
|
|
}
|
|
|
|
void TestRunner::writeOutput(StringRef Message) {
|
|
std::error_code EC;
|
|
raw_fd_ostream Out(OutputFilename, EC,
|
|
EmitBitcode && !Program->isMIR() ? sys::fs::OF_None
|
|
: sys::fs::OF_Text);
|
|
if (EC) {
|
|
errs() << "Error opening output file: " << EC.message() << "!\n";
|
|
exit(1);
|
|
}
|
|
|
|
// Requesting bitcode emission with mir is nonsense, so just ignore it.
|
|
if (EmitBitcode && !Program->isMIR())
|
|
writeBitcode(*Program, Out);
|
|
else
|
|
Program->print(Out, /*AnnotationWriter=*/nullptr);
|
|
|
|
errs() << Message << OutputFilename << '\n';
|
|
}
|