Use Module& wherever possible.
Since every reduction immediately turns Chunks into an Oracle, directly pass Oracle instead.
Reviewed By: hans
Differential Revision: https://reviews.llvm.org/D111122
using namespace llvm;
-TestRunner::TestRunner(StringRef TestName, const std::vector<std::string> &TestArgs)
- : TestName(TestName), TestArgs(TestArgs) {
+TestRunner::TestRunner(StringRef TestName,
+ const std::vector<std::string> &TestArgs,
+ std::unique_ptr<Module> Program)
+ : TestName(TestName), TestArgs(TestArgs), Program(std::move(Program)) {
+ assert(this->Program && "Initialized with null program?");
}
/// Runs the interestingness test, passes file to be tested as first argument
// respective filename.
class TestRunner {
public:
- TestRunner(StringRef TestName, const std::vector<std::string> &TestArgs);
+ TestRunner(StringRef TestName, const std::vector<std::string> &TestArgs,
+ std::unique_ptr<Module> Program);
/// Runs the interesting-ness test for the specified file
/// @returns 0 if test was successful, 1 if otherwise
int run(StringRef Filename);
/// Returns the most reduced version of the original testcase
- Module *getProgram() const { return Program.get(); }
+ Module &getProgram() const { return *Program; }
- void setProgram(std::unique_ptr<Module> P) { Program = std::move(P); }
+ void setProgram(std::unique_ptr<Module> P) {
+ assert(P && "Setting null program?");
+ Program = std::move(P);
+ }
private:
StringRef TestName;
"abort-on-invalid-reduction",
cl::desc("Abort if any reduction results in invalid IR"));
-void writeOutput(llvm::Module *M, llvm::StringRef Message);
+void writeOutput(llvm::Module &M, llvm::StringRef Message);
bool isReduced(Module &M, TestRunner &Test, SmallString<128> &CurrentFilepath) {
// Write Module to tmp file
/// given test.
void llvm::runDeltaPass(
TestRunner &Test, int Targets,
- std::function<void(const std::vector<Chunk> &, Module *)>
- ExtractChunksFromModule) {
+ function_ref<void(Oracle &, Module &)> ExtractChunksFromModule) {
assert(Targets >= 0);
if (!Targets) {
errs() << "\nNothing to reduce\n";
return;
}
- 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);
- }
-
- assert(!verifyModule(*Program, &errs()) &&
- "input module is broken before making changes");
+ SmallString<128> CurrentFilepath;
+ if (!isReduced(Test.getProgram(), Test, CurrentFilepath)) {
+ errs() << "\nInput isn't interesting! Verify interesting-ness test\n";
+ exit(1);
}
+ assert(!verifyModule(Test.getProgram(), &errs()) &&
+ "input module is broken before making changes");
+
std::vector<Chunk> ChunksStillConsideredInteresting = {{1, Targets}};
std::unique_ptr<Module> ReducedProgram;
});
// Clone module before hacking it up..
- std::unique_ptr<Module> Clone = CloneModule(*Test.getProgram());
+ std::unique_ptr<Module> Clone = CloneModule(Test.getProgram());
// Generate Module with only Targets inside Current Chunks
- ExtractChunksFromModule(CurrentChunks, Clone.get());
+ Oracle O(CurrentChunks);
+ ExtractChunksFromModule(O, *Clone);
// Some reductions may result in invalid IR. Skip such reductions.
- if (verifyModule(*Clone.get(), &errs())) {
+ if (verifyModule(*Clone, &errs())) {
if (AbortOnInvalidReduction) {
errs() << "Invalid reduction\n";
exit(1);
UninterestingChunks.insert(ChunkToCheckForUninterestingness);
ReducedProgram = std::move(Clone);
errs() << " **** SUCCESS | lines: " << getLines(CurrentFilepath) << "\n";
- writeOutput(ReducedProgram.get(), "Saved new best reduction to ");
+ writeOutput(*ReducedProgram, "Saved new best reduction to ");
}
// Delete uninteresting chunks
erase_if(ChunksStillConsideredInteresting,
///
/// Other implementations of the Delta Debugging algorithm can also be found in
/// the CReduce, Delta, and Lithium projects.
-void runDeltaPass(TestRunner &Test, int Targets,
- std::function<void(const std::vector<Chunk> &, Module *)>
- ExtractChunksFromModule);
+void runDeltaPass(
+ TestRunner &Test, int Targets,
+ function_ref<void(Oracle &, Module &)> ExtractChunksFromModule);
} // namespace llvm
#endif
/// Removes all aliases aren't inside any of the
/// desired Chunks.
-static void extractAliasesFromModule(const std::vector<Chunk> &ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
- for (auto &GA : make_early_inc_range(Program->aliases())) {
+static void extractAliasesFromModule(Oracle &O, Module &Program) {
+ for (auto &GA : make_early_inc_range(Program.aliases())) {
if (!O.shouldKeep()) {
GA.replaceAllUsesWith(GA.getAliasee());
GA.eraseFromParent();
}
/// Counts the amount of aliases and prints their respective name & index.
-static int countAliases(Module *Program) {
+static int countAliases(Module &Program) {
// TODO: Silence index with --quiet flag
errs() << "----------------------------\n";
errs() << "Aliases Index Reference:\n";
int Count = 0;
- for (auto &GA : Program->aliases())
+ for (auto &GA : Program.aliases())
errs() << "\t" << ++Count << ": " << GA.getName() << "\n";
errs() << "----------------------------\n";
/// Removes out-of-chunk arguments from functions, and modifies their calls
/// accordingly. It also removes allocations of out-of-chunk arguments.
-static void extractArgumentsFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractArgumentsFromModule(Oracle &O, Module &Program) {
std::set<Argument *> ArgsToKeep;
std::vector<Function *> Funcs;
// Get inside-chunk arguments, as well as their parent function
- for (auto &F : *Program)
+ for (auto &F : Program)
if (shouldRemoveArguments(F)) {
Funcs.push_back(&F);
for (auto &A : F.args())
auto *ClonedFunc = CloneFunction(F, VMap);
// In order to preserve function order, we move Clone after old Function
ClonedFunc->removeFromParent();
- Program->getFunctionList().insertAfter(F->getIterator(), ClonedFunc);
+ Program.getFunctionList().insertAfter(F->getIterator(), ClonedFunc);
replaceFunctionCalls(*F, *ClonedFunc, ArgIndexesToKeep);
// Rename Cloned Function to Old's name
/// Counts the amount of arguments in functions and prints their respective
/// name, index, and parent function name
-static int countArguments(Module *Program) {
+static int countArguments(Module &Program) {
// TODO: Silence index with --quiet flag
outs() << "----------------------------\n";
outs() << "Param Index Reference:\n";
int ArgsCount = 0;
- for (auto &F : *Program)
+ for (auto &F : Program)
if (shouldRemoveArguments(F)) {
outs() << " " << F.getName() << "\n";
for (auto &A : F.args())
/// Given ChunksToKeep, produce a map of global variables/functions/calls
/// and indexes of attributes to be preserved for each of them.
class AttributeRemapper : public InstVisitor<AttributeRemapper> {
- Oracle O;
+ Oracle &O;
public:
DenseMap<GlobalVariable *, AttrPtrVecTy> GlobalVariablesToRefine;
DenseMap<Function *, AttrPtrVecVecTy> FunctionsToRefine;
DenseMap<CallBase *, AttrPtrVecVecTy> CallsToRefine;
- explicit AttributeRemapper(ArrayRef<Chunk> ChunksToKeep) : O(ChunksToKeep) {}
+ explicit AttributeRemapper(Oracle &O) : O(O) {}
void visitModule(Module &M) {
for (GlobalVariable &GV : M.getGlobalList())
}
/// Removes out-of-chunk attributes from module.
-static void extractAttributesFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- AttributeRemapper R(ChunksToKeep);
+static void extractAttributesFromModule(Oracle &O, Module &Program) {
+ AttributeRemapper R(O);
R.visit(Program);
- LLVMContext &C = Program->getContext();
+ LLVMContext &C = Program.getContext();
for (const auto &I : R.GlobalVariablesToRefine)
I.first->setAttributes(convertAttributeRefToAttributeSet(C, I.second));
for (const auto &I : R.FunctionsToRefine)
}
/// Counts the amount of attributes.
-static int countAttributes(Module *Program) {
+static int countAttributes(Module &Program) {
AttributeCounter C;
// TODO: Silence index with --quiet flag
/// Removes out-of-chunk arguments from functions, and modifies their calls
/// accordingly. It also removes allocations of out-of-chunk arguments.
-static void extractBasicBlocksFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractBasicBlocksFromModule(Oracle &O, Module &Program) {
std::set<BasicBlock *> BBsToKeep;
- for (auto &F : *Program)
+ for (auto &F : Program)
for (auto &BB : F)
if (O.shouldKeep())
BBsToKeep.insert(&BB);
std::vector<BasicBlock *> BBsToDelete;
- for (auto &F : *Program)
+ for (auto &F : Program)
for (auto &BB : F) {
if (!BBsToKeep.count(&BB)) {
BBsToDelete.push_back(&BB);
}
// Replace terminators that reference out-of-chunk BBs
- for (auto &F : *Program)
+ for (auto &F : Program)
for (auto &BB : F) {
if (auto *SwInst = dyn_cast<SwitchInst>(BB.getTerminator()))
removeUninterestingBBsFromSwitch(*SwInst, BBsToKeep);
}
/// Counts the amount of basic blocks and prints their name & respective index
-static int countBasicBlocks(Module *Program) {
+static int countBasicBlocks(Module &Program) {
// TODO: Silence index with --quiet flag
outs() << "----------------------------\n";
int BBCount = 0;
- for (auto &F : *Program)
+ for (auto &F : Program)
for (auto &BB : F) {
if (BB.hasName())
outs() << "\t" << ++BBCount << ": " << BB.getName() << "\n";
/// Removes all the bodies of defined functions that aren't inside any of the
/// desired Chunks.
-static void
-extractFunctionBodiesFromModule(const std::vector<Chunk> &ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractFunctionBodiesFromModule(Oracle &O, Module &Program) {
// Delete out-of-chunk function bodies
std::vector<Function *> FuncDefsToReduce;
- for (auto &F : *Program)
+ for (auto &F : Program)
if (!F.isDeclaration() && !O.shouldKeep()) {
F.deleteBody();
F.setComdat(nullptr);
/// Counts the amount of non-declaration functions and prints their
/// respective name & index
-static int countFunctionDefinitions(Module *Program) {
+static int countFunctionDefinitions(Module &Program) {
// TODO: Silence index with --quiet flag
errs() << "----------------------------\n";
errs() << "Function Definition Index Reference:\n";
int FunctionDefinitionCount = 0;
- for (auto &F : *Program)
+ for (auto &F : Program)
if (!F.isDeclaration())
errs() << "\t" << ++FunctionDefinitionCount << ": " << F.getName()
<< "\n";
/// Removes all the Defined Functions
/// that aren't inside any of the desired Chunks.
-static void extractFunctionsFromModule(const std::vector<Chunk> &ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractFunctionsFromModule(Oracle &O, Module &Program) {
// Record all out-of-chunk functions.
std::vector<std::reference_wrapper<Function>> FuncsToRemove;
- copy_if(Program->functions(), std::back_inserter(FuncsToRemove),
+ copy_if(Program.functions(), std::back_inserter(FuncsToRemove),
[&O](Function &F) {
// Intrinsics don't have function bodies that are useful to
// reduce. Additionally, intrinsics may have additional operand
/// Counts the amount of functions and prints their
/// respective name & index
-static int countFunctions(Module *Program) {
+static int countFunctions(Module &Program) {
// TODO: Silence index with --quiet flag
errs() << "----------------------------\n";
errs() << "Function Index Reference:\n";
int FunctionCount = 0;
- for (auto &F : *Program) {
+ for (auto &F : Program) {
if (F.isIntrinsic() && !F.use_empty())
continue;
}
/// Sets dso_local to false for all global values.
-static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractGVsFromModule(Oracle &O, Module &Program) {
// remove dso_local from global values
- for (auto &GV : Program->global_values())
+ for (auto &GV : Program.global_values())
if (isValidDSOLocalReductionGV(GV) && !O.shouldKeep()) {
GV.setDSOLocal(false);
}
/// Counts the amount of global values with dso_local and displays their
/// respective name & index
-static int countGVs(Module *Program) {
+static int countGVs(Module &Program) {
// TODO: Silence index with --quiet flag
outs() << "----------------------------\n";
outs() << "GlobalValue Index Reference:\n";
int GVCount = 0;
- for (auto &GV : Program->global_values())
+ for (auto &GV : Program.global_values())
if (isValidDSOLocalReductionGV(GV))
outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n";
outs() << "----------------------------\n";
using namespace llvm;
/// Removes all the Initialized GVs that aren't inside the desired Chunks.
-static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractGVsFromModule(Oracle &O, Module &Program) {
// Drop initializers of out-of-chunk GVs
- for (auto &GV : Program->globals())
+ for (auto &GV : Program.globals())
if (GV.hasInitializer() && !O.shouldKeep()) {
GV.setInitializer(nullptr);
GV.setLinkage(GlobalValue::LinkageTypes::ExternalLinkage);
/// Counts the amount of initialized GVs and displays their
/// respective name & index
-static int countGVs(Module *Program) {
+static int countGVs(Module &Program) {
// TODO: Silence index with --quiet flag
outs() << "----------------------------\n";
outs() << "GlobalVariable Index Reference:\n";
int GVCount = 0;
- for (auto &GV : Program->globals())
+ for (auto &GV : Program.globals())
if (GV.hasInitializer())
outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n";
outs() << "----------------------------\n";
using namespace llvm;
/// Removes all the GVs that aren't inside the desired Chunks.
-static void extractGVsFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractGVsFromModule(Oracle &O, Module &Program) {
// Get GVs inside desired chunks
std::set<GlobalVariable *> GVsToKeep;
- for (auto &GV : Program->globals())
+ for (auto &GV : Program.globals())
if (O.shouldKeep())
GVsToKeep.insert(&GV);
// Delete out-of-chunk GVs and their uses
std::vector<GlobalVariable *> ToRemove;
std::vector<WeakVH> InstToRemove;
- for (auto &GV : Program->globals())
+ for (auto &GV : Program.globals())
if (!GVsToKeep.count(&GV)) {
for (auto *U : GV.users())
if (auto *Inst = dyn_cast<Instruction>(U))
/// Counts the amount of GVs and displays their
/// respective name & index
-static int countGVs(Module *Program) {
+static int countGVs(Module &Program) {
// TODO: Silence index with --quiet flag
outs() << "----------------------------\n";
outs() << "GlobalVariable Index Reference:\n";
int GVCount = 0;
- for (auto &GV : Program->globals())
+ for (auto &GV : Program.globals())
outs() << "\t" << ++GVCount << ": " << GV.getName() << "\n";
outs() << "----------------------------\n";
return GVCount;
/// Removes out-of-chunk arguments from functions, and modifies their calls
/// accordingly. It also removes allocations of out-of-chunk arguments.
-static void extractInstrFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractInstrFromModule(Oracle &O, Module &Program) {
std::set<Instruction *> InstToKeep;
- for (auto &F : *Program)
+ for (auto &F : Program)
for (auto &BB : F) {
// Removing the terminator would make the block invalid. Only iterate over
// instructions before the terminator.
}
std::vector<Instruction *> InstToDelete;
- for (auto &F : *Program)
+ for (auto &F : Program)
for (auto &BB : F)
for (auto &Inst : BB)
if (!InstToKeep.count(&Inst)) {
}
/// Counts the amount of basic blocks and prints their name & respective index
-static unsigned countInstructions(Module *Program) {
+static unsigned countInstructions(Module &Program) {
// TODO: Silence index with --quiet flag
outs() << "----------------------------\n";
int InstCount = 0;
- for (auto &F : *Program)
+ for (auto &F : Program)
for (auto &BB : F)
// Well-formed blocks have terminators, which we cannot remove.
InstCount += BB.getInstList().size() - 1;
/// Removes all the Named and Unnamed Metadata Nodes, as well as any debug
/// functions that aren't inside the desired Chunks.
-static void extractMetadataFromModule(const std::vector<Chunk> &ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractMetadataFromModule(Oracle &O, Module &Program) {
// Get out-of-chunk Named metadata nodes
SmallVector<NamedMDNode *> NamedNodesToDelete;
- for (NamedMDNode &MD : Program->named_metadata())
+ for (NamedMDNode &MD : Program.named_metadata())
if (!O.shouldKeep())
NamedNodesToDelete.push_back(&MD);
// Delete out-of-chunk metadata attached to globals.
SmallVector<std::pair<unsigned, MDNode *>> MDs;
- for (GlobalVariable &GV : Program->globals()) {
+ for (GlobalVariable &GV : Program.globals()) {
GV.getAllMetadata(MDs);
for (std::pair<unsigned, MDNode *> &MD : MDs)
if (!O.shouldKeep())
GV.setMetadata(MD.first, NULL);
}
- for (Function &F : *Program) {
+ for (Function &F : Program) {
// Delete out-of-chunk metadata attached to functions.
F.getAllMetadata(MDs);
for (std::pair<unsigned, MDNode *> &MD : MDs)
}
}
-static int countMetadataTargets(Module *Program) {
- int NamedMetadataNodes = Program->named_metadata_size();
+static int countMetadataTargets(Module &Program) {
+ int NamedMetadataNodes = Program.named_metadata_size();
// Get metadata attached to globals.
int GlobalMetadataArgs = 0;
SmallVector<std::pair<unsigned, MDNode *>> MDs;
- for (GlobalVariable &GV : Program->globals()) {
+ for (GlobalVariable &GV : Program.globals()) {
GV.getAllMetadata(MDs);
GlobalMetadataArgs += MDs.size();
}
// Get metadata attached to functions & instructions.
int FunctionMetadataArgs = 0;
int InstructionMetadataArgs = 0;
- for (Function &F : *Program) {
+ for (Function &F : Program) {
F.getAllMetadata(MDs);
FunctionMetadataArgs += MDs.size();
using namespace llvm;
-static void clearModuleData(std::vector<Chunk> ChunksToKeep, Module *Program) {
- Oracle O(ChunksToKeep);
-
- if (!Program->getModuleIdentifier().empty() && !O.shouldKeep())
- Program->setModuleIdentifier("");
- if (!Program->getSourceFileName().empty() && !O.shouldKeep())
- Program->setSourceFileName("");
- if (!Program->getDataLayoutStr().empty() && !O.shouldKeep())
- Program->setDataLayout("");
- if (!Program->getTargetTriple().empty() && !O.shouldKeep())
- Program->setTargetTriple("");
+static void clearModuleData(Oracle &O, Module &Program) {
+ if (!Program.getModuleIdentifier().empty() && !O.shouldKeep())
+ Program.setModuleIdentifier("");
+ if (!Program.getSourceFileName().empty() && !O.shouldKeep())
+ Program.setSourceFileName("");
+ if (!Program.getDataLayoutStr().empty() && !O.shouldKeep())
+ Program.setDataLayout("");
+ if (!Program.getTargetTriple().empty() && !O.shouldKeep())
+ Program.setTargetTriple("");
// TODO: clear line by line rather than all at once
- if (!Program->getModuleInlineAsm().empty() && !O.shouldKeep())
- Program->setModuleInlineAsm("");
+ if (!Program.getModuleInlineAsm().empty() && !O.shouldKeep())
+ Program.setModuleInlineAsm("");
}
-static int countModuleData(Module *M) {
+static int countModuleData(Module &M) {
int Count = 0;
- if (!M->getModuleIdentifier().empty())
+ if (!M.getModuleIdentifier().empty())
++Count;
- if (!M->getSourceFileName().empty())
+ if (!M.getSourceFileName().empty())
++Count;
- if (!M->getDataLayoutStr().empty())
+ if (!M.getDataLayoutStr().empty())
++Count;
- if (!M->getTargetTriple().empty())
+ if (!M.getTargetTriple().empty())
++Count;
- if (!M->getModuleInlineAsm().empty())
+ if (!M.getModuleInlineAsm().empty())
++Count;
return Count;
}
/// Given ChunksToKeep, produce a map of calls and indexes of operand bundles
/// to be preserved for each call.
class OperandBundleRemapper : public InstVisitor<OperandBundleRemapper> {
- Oracle O;
+ Oracle &O;
public:
DenseMap<CallBase *, std::vector<unsigned>> CallsToRefine;
- explicit OperandBundleRemapper(ArrayRef<Chunk> ChunksToKeep)
- : O(ChunksToKeep) {}
+ explicit OperandBundleRemapper(Oracle &O) : O(O) {}
/// So far only CallBase sub-classes can have operand bundles.
/// Let's see which of the operand bundles of this call are to be kept.
}
/// Removes out-of-chunk operand bundles from calls.
-static void extractOperandBundesFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- OperandBundleRemapper R(ChunksToKeep);
+static void extractOperandBundesFromModule(Oracle &O, Module &Program) {
+ OperandBundleRemapper R(O);
R.visit(Program);
for (const auto &I : R.CallsToRefine)
}
/// Counts the amount of operand bundles.
-static int countOperandBundes(Module *Program) {
+static int countOperandBundes(Module &Program) {
OperandBundleCounter C;
// TODO: Silence index with --quiet flag
}
/// Sets Operands to undef.
-static void extractOperandsFromModule(std::vector<Chunk> ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractOperandsFromModule(Oracle &O, Module &Program) {
// Extract Operands from the module.
- for (auto &F : Program->functions()) {
+ for (auto &F : Program.functions()) {
for (auto &I : instructions(&F)) {
for (auto &Op : I.operands()) {
// Filter Operands then set to undef.
}
/// Counts the amount of operands in the module that can be reduced.
-static int countOperands(Module *Program) {
+static int countOperands(Module &Program) {
int Count = 0;
- for (auto &F : Program->functions()) {
+ for (auto &F : Program.functions()) {
for (auto &I : instructions(&F)) {
for (auto &Op : I.operands()) {
if (canReduceOperand(Op)) {
/// Removes all special globals aren't inside any of the
/// desired Chunks.
-static void
-extractSpecialGlobalsFromModule(const std::vector<Chunk> &ChunksToKeep,
- Module *Program) {
- Oracle O(ChunksToKeep);
-
+static void extractSpecialGlobalsFromModule(Oracle &O, Module &Program) {
for (StringRef Name : SpecialGlobalNames) {
- if (auto *Used = Program->getNamedGlobal(Name)) {
+ if (auto *Used = Program.getNamedGlobal(Name)) {
Used->replaceAllUsesWith(UndefValue::get(Used->getType()));
Used->eraseFromParent();
}
/// Counts the amount of special globals and prints their
/// respective name & index
-static int countSpecialGlobals(Module *Program) {
+static int countSpecialGlobals(Module &Program) {
// TODO: Silence index with --quiet flag
errs() << "----------------------------\n";
errs() << "Special Globals Index Reference:\n";
int Count = 0;
for (StringRef Name : SpecialGlobalNames) {
- if (auto *Used = Program->getNamedGlobal(Name))
+ if (auto *Used = Program.getNamedGlobal(Name))
errs() << "\t" << ++Count << ": " << Used->getName() << "\n";
}
errs() << "----------------------------\n";
return Result;
}
-void writeOutput(Module *M, StringRef Message) {
+void writeOutput(Module &M, StringRef Message) {
if (ReplaceInput) // In-place
OutputFilename = InputFilename.c_str();
else if (OutputFilename.empty() || OutputFilename == "-")
errs() << "Error opening output file: " << EC.message() << "!\n";
exit(1);
}
- M->print(Out, /*AnnotationWriter=*/nullptr);
+ M.print(Out, /*AnnotationWriter=*/nullptr);
errs() << Message << OutputFilename << "\n";
}
}
// Initialize test environment
- TestRunner Tester(TestFilename, TestArguments);
- Tester.setProgram(std::move(OriginalProgram));
+ TestRunner Tester(TestFilename, TestArguments, std::move(OriginalProgram));
// Try to reduce code
runDeltaPasses(Tester);
- if (!Tester.getProgram()) {
- errs() << "\nCouldnt reduce input :/\n";
- } else {
- // Print reduced file to STDOUT
- if (OutputFilename == "-")
- Tester.getProgram()->print(outs(), nullptr);
- else
- writeOutput(Tester.getProgram(), "\nDone reducing! Reduced testcase: ");
- }
+ // Print reduced file to STDOUT
+ if (OutputFilename == "-")
+ Tester.getProgram().print(outs(), nullptr);
+ else
+ writeOutput(Tester.getProgram(), "\nDone reducing! Reduced testcase: ");
return 0;
}