//===- Miscompilation.cpp - Debug program miscompilations -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
//
// This file implements program miscompilation debugging support.
//
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "Support/FileUtilities.h"
+using namespace llvm;
-class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
- BugDriver &BD;
-public:
- ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
+namespace llvm {
- virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
- std::vector<const PassInfo*> &Suffix);
-};
+ class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
+ BugDriver &BD;
+ public:
+ ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
+
+ virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
+ std::vector<const PassInfo*> &Suffix);
+ };
+}
ReduceMiscompilingPasses::TestResult
ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
<< " on the input program!\n";
BD.setPassesToRun(Suffix);
BD.EmitProgressBytecode("pass-error", false);
- exit(1);
+ exit(BD.debugOptimizerCrash());
}
// Check to see if the finished program matches the reference output...
<< " on the input program!\n";
BD.setPassesToRun(Prefix);
BD.EmitProgressBytecode("pass-error", false);
- exit(1);
+ exit(BD.debugOptimizerCrash());
}
// If the prefix maintains the predicate by itself, only keep the prefix!
<< " on the input program!\n";
BD.setPassesToRun(Suffix);
BD.EmitProgressBytecode("pass-error", false);
- exit(1);
+ exit(BD.debugOptimizerCrash());
}
// Run the result...
return NoFailure;
}
-class ReduceMiscompilingFunctions : public ListReducer<Function*> {
- BugDriver &BD;
-public:
- ReduceMiscompilingFunctions(BugDriver &bd) : BD(bd) {}
-
- virtual TestResult doTest(std::vector<Function*> &Prefix,
- std::vector<Function*> &Suffix) {
- if (!Suffix.empty() && TestFuncs(Suffix, false))
- return KeepSuffix;
- if (!Prefix.empty() && TestFuncs(Prefix, false))
- return KeepPrefix;
- return NoFailure;
- }
-
- bool TestFuncs(const std::vector<Function*> &Prefix, bool EmitBytecode);
-};
+namespace llvm {
+ class ReduceMiscompilingFunctions : public ListReducer<Function*> {
+ BugDriver &BD;
+ public:
+ ReduceMiscompilingFunctions(BugDriver &bd) : BD(bd) {}
+
+ virtual TestResult doTest(std::vector<Function*> &Prefix,
+ std::vector<Function*> &Suffix) {
+ if (!Suffix.empty() && TestFuncs(Suffix, false))
+ return KeepSuffix;
+ if (!Prefix.empty() && TestFuncs(Prefix, false))
+ return KeepPrefix;
+ return NoFailure;
+ }
+
+ bool TestFuncs(const std::vector<Function*> &Prefix, bool EmitBytecode);
+ };
+}
bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
bool EmitBytecode) {
// Test to see if the function is misoptimized if we ONLY run it on the
// functions listed in Funcs.
if (!EmitBytecode) {
- std::cout << "Checking to see if the program is misoptimized when these "
- << "functions are run\nthrough the passes: ";
+ std::cout << "Checking to see if the program is misoptimized when "
+ << (Funcs.size()==1 ? "this function is" : "these functions are")
+ << " run through the pass"
+ << (BD.PassesToRun.size() == 1 ? "" : "es") << ": ";
BD.PrintFunctionList(Funcs);
std::cout << "\n";
} else {
}
// First step: clone the module for the two halves of the program we want.
- Module *ToOptimize = CloneModule(BD.Program);
+ Module *ToOptimize = CloneModule(BD.getProgram());
// Second step: Make sure functions & globals are all external so that linkage
// between the two modules will work.
std::cerr << " Error running this sequence of passes"
<< " on the input program!\n";
BD.EmitProgressBytecode("pass-error", false);
- exit(1);
+ exit(BD.debugOptimizerCrash());
}
if (!EmitBytecode)
std::cout << "done.\n";
- delete BD.Program; // Delete the old "ToOptimize" module
+ delete BD.getProgram(); // Delete the old "ToOptimize" module
BD.Program = BD.ParseInputFile(BytecodeResult);
if (EmitBytecode) {
// output, then 'Funcs' are being misoptimized!
bool Broken = BD.diffProgram();
- delete BD.Program; // Delete the hacked up program
+ delete BD.Program; // Delete the hacked up program
BD.Program = OldProgram; // Restore the original
- std::cout << (Broken ? "nope.\n" : "yup.\n");
+ std::cout << (Broken ? " nope.\n" : " yup.\n");
return Broken;
}
// Do the reduction...
ReduceMiscompilingFunctions(*this).reduceList(MiscompiledFunctions);
- std::cout << "\n*** The following functions are being miscompiled: ";
+ std::cout << "\n*** The following function"
+ << (MiscompiledFunctions.size() == 1 ? " is" : "s are")
+ << " being miscompiled: ";
PrintFunctionList(MiscompiledFunctions);
std::cout << "\n";
return false;
}
+