; then include the rest of the test script
; RUN: cat %p/Inputs/remove-funcs.py >> %t/test.py
-; UN: llvm-reduce --test %t/test.py %s -o %t/out.ll
-; UN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
+; RUN: llvm-reduce --test %t/test.py %s -o %t/out.ll
+; RUN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
; REQUIRES: plugins
define i32 @uninteresting1() {
; then include the rest of the test script
; RUN: cat %p/Inputs/remove-global-vars.py >> %t/test.py
-; UN: llvm-reduce --test %t/test.py %s -o %t/out.ll
-; UN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
+; RUN: llvm-reduce --test %t/test.py %s -o %t/out.ll
+; RUN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
; REQUIRES: plugins
; CHECK: @interesting = global
; then include the rest of the test script
; RUN: cat %p/Inputs/remove-metadata.py >> %t/test.py
-; UN: llvm-reduce --test %t/test.py %s -o %t/out.ll
-; UN: cat %t/out.ll | FileCheck -implicit-check-not=! %s
+; RUN: llvm-reduce --test %t/test.py %s -o %t/out.ll
+; RUN: cat %t/out.ll | FileCheck -implicit-check-not=! %s
; REQUIRES: plugins
@global = global i32 0, !dbg !0
return TmpDirectory;
}
-TestRunner::TestRunner(StringRef TestName, std::vector<std::string> TestArgs,
- StringRef ReducedFilepath)
- : TestName(TestName), TestArgs(std::move(TestArgs)),
- ReducedFilepath(ReducedFilepath) {
+TestRunner::TestRunner(StringRef TestName, std::vector<std::string> TestArgs)
+ : TestName(TestName), TestArgs(std::move(TestArgs)) {
TmpDirectory = initializeTmpDirectory();
}
// respective filename.
class TestRunner {
public:
- TestRunner(StringRef TestName, std::vector<std::string> TestArgs,
- StringRef ReducedFilepath);
+ TestRunner(StringRef TestName, std::vector<std::string> TestArgs);
/// Runs the interesting-ness test for the specified file
/// @returns 0 if test was successful, 1 if otherwise
int run(StringRef Filename);
- /// Filename to the most reduced testcase
- StringRef getReducedFilepath() const { return ReducedFilepath; }
/// Directory where tmp files are created
StringRef getTmpDir() const { return TmpDirectory; }
/// Returns the most reduced version of the original testcase
Module *getProgram() const { return Program.get(); }
- void setReducedFilepath(SmallString<128> F) {
- ReducedFilepath = std::move(F);
- }
void setProgram(std::unique_ptr<Module> P) { Program = std::move(P); }
private:
SmallString<128> TestName;
std::vector<std::string> TestArgs;
- SmallString<128> ReducedFilepath;
SmallString<128> TmpDirectory;
std::unique_ptr<Module> Program;
};
using namespace llvm;
-/// Writes IR code to the given Filepath
-static bool writeProgramToFile(StringRef Filepath, int FD, const Module &M) {
- ToolOutputFile Out(Filepath, FD);
- M.print(Out.os(), /*AnnotationWriter=*/nullptr);
- Out.os().close();
-
- if (!Out.os().has_error()) {
- Out.keep();
- return false;
- }
- return true;
-}
-
-/// Creates a temporary (and unique) file inside the tmp folder and writes
-/// the given module IR.
-static SmallString<128> createTmpFile(Module *M, StringRef TmpDir) {
- SmallString<128> UniqueFilepath;
- int UniqueFD;
-
- SmallString<128> TmpFilepath;
- sys::path::append(TmpFilepath, TmpDir, "tmp-%%%.ll");
+bool IsReduced(Module &M, TestRunner &Test, SmallString<128> &CurrentFilepath) {
+ // Write Module to tmp file
+ int FD;
std::error_code EC =
- sys::fs::createUniqueFile(TmpFilepath, UniqueFD, UniqueFilepath);
+ sys::fs::createTemporaryFile("llvm-reduce", "ll", FD, CurrentFilepath);
if (EC) {
errs() << "Error making unique filename: " << EC.message() << "!\n";
exit(1);
}
- if (writeProgramToFile(UniqueFilepath, UniqueFD, *M)) {
- errs() << "Error emitting bitcode to file '" << UniqueFilepath << "'!\n";
+ ToolOutputFile Out(CurrentFilepath, FD);
+ M.print(Out.os(), /*AnnotationWriter=*/nullptr);
+ Out.os().close();
+ if (Out.os().has_error()) {
+ errs() << "Error emitting bitcode to file '" << CurrentFilepath << "'!\n";
exit(1);
}
- return UniqueFilepath;
+
+ // Current Chunks aren't interesting
+ return Test.run(CurrentFilepath);
}
/// Counts the amount of lines for a given file
errs() << "\nNothing to reduce\n";
return;
}
- if (!Test.run(Test.getReducedFilepath())) {
- errs() << "\nInput isn't interesting! Verify interesting-ness test\n";
- exit(1);
+
+ if (Module *Program = Test.getProgram()) {
+ SmallString<128> CurrentFilepath;
+ if (!IsReduced(*Program, Test, CurrentFilepath)) {
+ errs() << "\nInput isn't interesting! Verify interesting-ness test\n";
+ exit(1);
+ }
}
std::vector<Chunk> Chunks = {{1, Targets}};
std::unique_ptr<Module> Clone = CloneModule(*Test.getProgram());
// Generate Module with only Targets inside Current Chunks
ExtractChunksFromModule(CurrentChunks, Clone.get());
- // Write Module to tmp file
- SmallString<128> CurrentFilepath =
- createTmpFile(Clone.get(), Test.getTmpDir());
errs() << "Ignoring: ";
Chunks[I].print();
for (auto C : UninterestingChunks)
C.print();
- errs() << " | " << sys::path::filename(CurrentFilepath);
- // Current Chunks aren't interesting
- if (!Test.run(CurrentFilepath)) {
+
+ SmallString<128> CurrentFilepath;
+ if (!IsReduced(*Clone, Test, CurrentFilepath)) {
errs() << "\n";
continue;
}
UninterestingChunks.insert(Chunks[I]);
- Test.setReducedFilepath(CurrentFilepath);
ReducedProgram = std::move(Clone);
errs() << " **** SUCCESS | lines: " << getLines(CurrentFilepath) << "\n";
}
parseInputFile(InputFilename, Context);
// Initialize test environment
- TestRunner Tester(TestFilename, TestArguments, InputFilename);
+ TestRunner Tester(TestFilename, TestArguments);
Tester.setProgram(std::move(OriginalProgram));
// Try to reduce code
runDeltaPasses(Tester);
- StringRef ReducedFilename = sys::path::filename(Tester.getReducedFilepath());
- if (ReducedFilename == sys::path::filename(InputFilename)) {
+ if (!Tester.getProgram()) {
errs() << "\nCouldnt reduce input :/\n";
} else {
// Print reduced file to STDOUT
else if (OutputFilename.empty())
OutputFilename = "reduced.ll";
- sys::fs::copy_file(Tester.getReducedFilepath(), OutputFilename);
+ std::error_code EC;
+ raw_fd_ostream Out(OutputFilename, EC);
+ if (EC) {
+ errs() << "Error opening output file: " << EC.message() << "!\n";
+ exit(1);
+ }
+ Tester.getProgram()->print(Out, /*AnnotationWriter=*/nullptr);
errs() << "\nDone reducing! Reduced testcase: " << OutputFilename << "\n";
}
}