mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-02 15:51:54 +00:00
PR43278: llvm-reduce: Use temporary file names (and ToolOutputFile) rather than unique ones - to ensure they're cleaned up
This modifies the tool somewhat to only create files when about to run the "interestingness" test, and delete them immediately after - this means some more files will be created sometimes (when "double checking" work - which should probably be fixed/avoided anyway). This now creates temporary files, rather than only unique ones, and also uses ToolOutputFile (without ever calling "keep") to ensure the files are deleted as soon as the interestingness test is run. llvm-svn: 371696
This commit is contained in:
parent
f9ccef34dc
commit
bcb0f91086
@ -10,8 +10,8 @@
|
|||||||
; then include the rest of the test script
|
; then include the rest of the test script
|
||||||
; RUN: cat %p/Inputs/remove-funcs.py >> %t/test.py
|
; RUN: cat %p/Inputs/remove-funcs.py >> %t/test.py
|
||||||
|
|
||||||
; UN: llvm-reduce --test %t/test.py %s -o %t/out.ll
|
; RUN: llvm-reduce --test %t/test.py %s -o %t/out.ll
|
||||||
; UN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
|
; RUN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
|
||||||
; REQUIRES: plugins
|
; REQUIRES: plugins
|
||||||
|
|
||||||
define i32 @uninteresting1() {
|
define i32 @uninteresting1() {
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
; then include the rest of the test script
|
; then include the rest of the test script
|
||||||
; RUN: cat %p/Inputs/remove-global-vars.py >> %t/test.py
|
; RUN: cat %p/Inputs/remove-global-vars.py >> %t/test.py
|
||||||
|
|
||||||
; UN: llvm-reduce --test %t/test.py %s -o %t/out.ll
|
; RUN: llvm-reduce --test %t/test.py %s -o %t/out.ll
|
||||||
; UN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
|
; RUN: cat %t/out.ll | FileCheck -implicit-check-not=uninteresting %s
|
||||||
; REQUIRES: plugins
|
; REQUIRES: plugins
|
||||||
|
|
||||||
; CHECK: @interesting = global
|
; CHECK: @interesting = global
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
; then include the rest of the test script
|
; then include the rest of the test script
|
||||||
; RUN: cat %p/Inputs/remove-metadata.py >> %t/test.py
|
; RUN: cat %p/Inputs/remove-metadata.py >> %t/test.py
|
||||||
|
|
||||||
; UN: llvm-reduce --test %t/test.py %s -o %t/out.ll
|
; RUN: llvm-reduce --test %t/test.py %s -o %t/out.ll
|
||||||
; UN: cat %t/out.ll | FileCheck -implicit-check-not=! %s
|
; RUN: cat %t/out.ll | FileCheck -implicit-check-not=! %s
|
||||||
; REQUIRES: plugins
|
; REQUIRES: plugins
|
||||||
|
|
||||||
@global = global i32 0, !dbg !0
|
@global = global i32 0, !dbg !0
|
||||||
|
@ -26,10 +26,8 @@ static SmallString<128> initializeTmpDirectory() {
|
|||||||
return TmpDirectory;
|
return TmpDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestRunner::TestRunner(StringRef TestName, std::vector<std::string> TestArgs,
|
TestRunner::TestRunner(StringRef TestName, std::vector<std::string> TestArgs)
|
||||||
StringRef ReducedFilepath)
|
: TestName(TestName), TestArgs(std::move(TestArgs)) {
|
||||||
: TestName(TestName), TestArgs(std::move(TestArgs)),
|
|
||||||
ReducedFilepath(ReducedFilepath) {
|
|
||||||
TmpDirectory = initializeTmpDirectory();
|
TmpDirectory = initializeTmpDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,29 +24,22 @@ namespace llvm {
|
|||||||
// respective filename.
|
// respective filename.
|
||||||
class TestRunner {
|
class TestRunner {
|
||||||
public:
|
public:
|
||||||
TestRunner(StringRef TestName, std::vector<std::string> TestArgs,
|
TestRunner(StringRef TestName, std::vector<std::string> TestArgs);
|
||||||
StringRef ReducedFilepath);
|
|
||||||
|
|
||||||
/// Runs the interesting-ness test for the specified file
|
/// Runs the interesting-ness test for the specified file
|
||||||
/// @returns 0 if test was successful, 1 if otherwise
|
/// @returns 0 if test was successful, 1 if otherwise
|
||||||
int run(StringRef Filename);
|
int run(StringRef Filename);
|
||||||
|
|
||||||
/// Filename to the most reduced testcase
|
|
||||||
StringRef getReducedFilepath() const { return ReducedFilepath; }
|
|
||||||
/// Directory where tmp files are created
|
/// Directory where tmp files are created
|
||||||
StringRef getTmpDir() const { return TmpDirectory; }
|
StringRef getTmpDir() const { return TmpDirectory; }
|
||||||
/// Returns the most reduced version of the original testcase
|
/// Returns the most reduced version of the original testcase
|
||||||
Module *getProgram() const { return Program.get(); }
|
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); }
|
void setProgram(std::unique_ptr<Module> P) { Program = std::move(P); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SmallString<128> TestName;
|
SmallString<128> TestName;
|
||||||
std::vector<std::string> TestArgs;
|
std::vector<std::string> TestArgs;
|
||||||
SmallString<128> ReducedFilepath;
|
|
||||||
SmallString<128> TmpDirectory;
|
SmallString<128> TmpDirectory;
|
||||||
std::unique_ptr<Module> Program;
|
std::unique_ptr<Module> Program;
|
||||||
};
|
};
|
||||||
|
@ -21,39 +21,26 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
/// Writes IR code to the given Filepath
|
bool IsReduced(Module &M, TestRunner &Test, SmallString<128> &CurrentFilepath) {
|
||||||
static bool writeProgramToFile(StringRef Filepath, int FD, const Module &M) {
|
// Write Module to tmp file
|
||||||
ToolOutputFile Out(Filepath, FD);
|
int 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");
|
|
||||||
std::error_code EC =
|
std::error_code EC =
|
||||||
sys::fs::createUniqueFile(TmpFilepath, UniqueFD, UniqueFilepath);
|
sys::fs::createTemporaryFile("llvm-reduce", "ll", FD, CurrentFilepath);
|
||||||
if (EC) {
|
if (EC) {
|
||||||
errs() << "Error making unique filename: " << EC.message() << "!\n";
|
errs() << "Error making unique filename: " << EC.message() << "!\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writeProgramToFile(UniqueFilepath, UniqueFD, *M)) {
|
ToolOutputFile Out(CurrentFilepath, FD);
|
||||||
errs() << "Error emitting bitcode to file '" << UniqueFilepath << "'!\n";
|
M.print(Out.os(), /*AnnotationWriter=*/nullptr);
|
||||||
|
Out.os().close();
|
||||||
|
if (Out.os().has_error()) {
|
||||||
|
errs() << "Error emitting bitcode to file '" << CurrentFilepath << "'!\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
return UniqueFilepath;
|
|
||||||
|
// Current Chunks aren't interesting
|
||||||
|
return Test.run(CurrentFilepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Counts the amount of lines for a given file
|
/// Counts the amount of lines for a given file
|
||||||
@ -108,9 +95,13 @@ void llvm::runDeltaPass(
|
|||||||
errs() << "\nNothing to reduce\n";
|
errs() << "\nNothing to reduce\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Test.run(Test.getReducedFilepath())) {
|
|
||||||
errs() << "\nInput isn't interesting! Verify interesting-ness test\n";
|
if (Module *Program = Test.getProgram()) {
|
||||||
exit(1);
|
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::vector<Chunk> Chunks = {{1, Targets}};
|
||||||
@ -138,25 +129,21 @@ void llvm::runDeltaPass(
|
|||||||
std::unique_ptr<Module> Clone = CloneModule(*Test.getProgram());
|
std::unique_ptr<Module> Clone = CloneModule(*Test.getProgram());
|
||||||
// Generate Module with only Targets inside Current Chunks
|
// Generate Module with only Targets inside Current Chunks
|
||||||
ExtractChunksFromModule(CurrentChunks, Clone.get());
|
ExtractChunksFromModule(CurrentChunks, Clone.get());
|
||||||
// Write Module to tmp file
|
|
||||||
SmallString<128> CurrentFilepath =
|
|
||||||
createTmpFile(Clone.get(), Test.getTmpDir());
|
|
||||||
|
|
||||||
errs() << "Ignoring: ";
|
errs() << "Ignoring: ";
|
||||||
Chunks[I].print();
|
Chunks[I].print();
|
||||||
for (auto C : UninterestingChunks)
|
for (auto C : UninterestingChunks)
|
||||||
C.print();
|
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";
|
errs() << "\n";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
UninterestingChunks.insert(Chunks[I]);
|
UninterestingChunks.insert(Chunks[I]);
|
||||||
Test.setReducedFilepath(CurrentFilepath);
|
|
||||||
ReducedProgram = std::move(Clone);
|
ReducedProgram = std::move(Clone);
|
||||||
errs() << " **** SUCCESS | lines: " << getLines(CurrentFilepath) << "\n";
|
errs() << " **** SUCCESS | lines: " << getLines(CurrentFilepath) << "\n";
|
||||||
}
|
}
|
||||||
|
@ -81,14 +81,13 @@ int main(int argc, char **argv) {
|
|||||||
parseInputFile(InputFilename, Context);
|
parseInputFile(InputFilename, Context);
|
||||||
|
|
||||||
// Initialize test environment
|
// Initialize test environment
|
||||||
TestRunner Tester(TestFilename, TestArguments, InputFilename);
|
TestRunner Tester(TestFilename, TestArguments);
|
||||||
Tester.setProgram(std::move(OriginalProgram));
|
Tester.setProgram(std::move(OriginalProgram));
|
||||||
|
|
||||||
// Try to reduce code
|
// Try to reduce code
|
||||||
runDeltaPasses(Tester);
|
runDeltaPasses(Tester);
|
||||||
StringRef ReducedFilename = sys::path::filename(Tester.getReducedFilepath());
|
|
||||||
|
|
||||||
if (ReducedFilename == sys::path::filename(InputFilename)) {
|
if (!Tester.getProgram()) {
|
||||||
errs() << "\nCouldnt reduce input :/\n";
|
errs() << "\nCouldnt reduce input :/\n";
|
||||||
} else {
|
} else {
|
||||||
// Print reduced file to STDOUT
|
// Print reduced file to STDOUT
|
||||||
@ -100,7 +99,13 @@ int main(int argc, char **argv) {
|
|||||||
else if (OutputFilename.empty())
|
else if (OutputFilename.empty())
|
||||||
OutputFilename = "reduced.ll";
|
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";
|
errs() << "\nDone reducing! Reduced testcase: " << OutputFilename << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user