Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
//===- CodeGeneratorBug.cpp - Debug code generation bugs ------------------===//
|
|
|
|
//
|
|
|
|
// This file implements program code generation debugging support.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "BugDriver.h"
|
|
|
|
#include "SystemUtils.h"
|
|
|
|
#include "ListReducer.h"
|
|
|
|
#include "llvm/Pass.h"
|
|
|
|
#include "llvm/Module.h"
|
|
|
|
#include "llvm/Transforms/Utils/Cloning.h"
|
|
|
|
#include "llvm/Transforms/Utils/Linker.h"
|
|
|
|
#include "Support/CommandLine.h"
|
|
|
|
#include "Support/Statistic.h"
|
|
|
|
#include "Support/StringExtras.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <set>
|
|
|
|
|
|
|
|
class ReduceMisCodegenFunctions : public ListReducer<Function*> {
|
|
|
|
BugDriver &BD;
|
|
|
|
public:
|
|
|
|
ReduceMisCodegenFunctions(BugDriver &bd) : BD(bd) {}
|
|
|
|
|
|
|
|
virtual TestResult doTest(std::vector<Function*> &Prefix,
|
|
|
|
std::vector<Function*> &Suffix) {
|
|
|
|
if (!Prefix.empty() && TestFuncs(Prefix))
|
|
|
|
return KeepPrefix;
|
|
|
|
if (!Suffix.empty() && TestFuncs(Suffix))
|
|
|
|
return KeepSuffix;
|
|
|
|
return NoFailure;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TestFuncs(const std::vector<Function*> &CodegenTest);
|
|
|
|
|
|
|
|
void DisambiguateGlobalSymbols(Module *M);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
bool ReduceMisCodegenFunctions::TestFuncs(const std::vector<Function*> &Funcs)
|
|
|
|
{
|
|
|
|
// Clone the module for the two halves of the program we want.
|
|
|
|
Module *SafeModule = CloneModule(BD.Program);
|
|
|
|
|
|
|
|
// Make sure functions & globals are all external so that linkage
|
|
|
|
// between the two modules will work.
|
|
|
|
for (Module::iterator I = SafeModule->begin(), E = SafeModule->end();I!=E;++I)
|
|
|
|
I->setLinkage(GlobalValue::ExternalLinkage);
|
|
|
|
for (Module::giterator I=SafeModule->gbegin(),E = SafeModule->gend();I!=E;++I)
|
|
|
|
I->setLinkage(GlobalValue::ExternalLinkage);
|
|
|
|
|
|
|
|
DisambiguateGlobalSymbols(SafeModule);
|
|
|
|
Module *TestModule = CloneModule(SafeModule);
|
|
|
|
|
|
|
|
// Make sure global initializers exist only in the safe module (CBE->.so)
|
|
|
|
for (Module::giterator I=TestModule->gbegin(),E = TestModule->gend();I!=E;++I)
|
|
|
|
I->setInitializer(0); // Delete the initializer to make it external
|
|
|
|
|
2003-07-24 21:59:10 +00:00
|
|
|
// Remove the Test functions from the Safe module
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
|
|
|
|
Function *TNOF = SafeModule->getFunction(Funcs[i]->getName(),
|
|
|
|
Funcs[i]->getFunctionType());
|
|
|
|
assert(TNOF && "Function doesn't exist in module!");
|
|
|
|
DeleteFunctionBody(TNOF); // Function is now external in this module!
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write out the bytecode to be sent to CBE
|
|
|
|
std::string SafeModuleBC = "bugpoint.safe.bc";
|
|
|
|
if (BD.writeProgramToFile(SafeModuleBC, SafeModule)) {
|
|
|
|
std::cerr << "Error writing bytecode to `" << SafeModuleBC << "'\nExiting.";
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make a shared library
|
|
|
|
std::string SharedObject;
|
|
|
|
BD.compileSharedObject(SafeModuleBC, SharedObject);
|
|
|
|
|
|
|
|
// Remove all functions from the Test module EXCEPT for the ones specified in
|
|
|
|
// Funcs. We know which ones these are because they are non-external in
|
|
|
|
// ToOptimize, but external in ToNotOptimize.
|
|
|
|
//
|
|
|
|
for (Module::iterator I = TestModule->begin(), E = TestModule->end();I!=E;++I)
|
|
|
|
if (!I->isExternal()) {
|
|
|
|
Function *TNOF = SafeModule->getFunction(I->getName(),
|
|
|
|
I->getFunctionType());
|
|
|
|
assert(TNOF && "Function doesn't exist in ToNotOptimize module??");
|
|
|
|
if (!TNOF->isExternal())
|
|
|
|
DeleteFunctionBody(I);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string TestModuleBC = "bugpoint.test.bc";
|
|
|
|
if (BD.writeProgramToFile(TestModuleBC, TestModule)) {
|
|
|
|
std::cerr << "Error writing bytecode to `" << SafeModuleBC << "'\nExiting.";
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run the code generator on the `Test' code, loading the shared library.
|
|
|
|
// The function returns whether or not the new output differs from reference.
|
2003-07-24 21:59:10 +00:00
|
|
|
int Result = BD.diffProgram(TestModuleBC, SharedObject, false);
|
|
|
|
removeFile(SharedObject);
|
|
|
|
return Result;
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
2003-07-24 21:59:10 +00:00
|
|
|
struct Disambiguator {
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
std::set<std::string> SymbolNames;
|
|
|
|
uint64_t uniqueCounter;
|
|
|
|
bool externalOnly;
|
2003-07-24 21:59:10 +00:00
|
|
|
public:
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
Disambiguator() : uniqueCounter(0), externalOnly(true) {}
|
|
|
|
void setExternalOnly(bool value) { externalOnly = value; }
|
2003-07-24 21:59:10 +00:00
|
|
|
void add(GlobalValue &V) {
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
if (externalOnly && !V.isExternal()) return;
|
|
|
|
|
|
|
|
if (SymbolNames.count(V.getName()) == 0) {
|
|
|
|
DEBUG(std::cerr << "Disambiguator: adding " << V.getName()
|
|
|
|
<< ", no conflicts.\n");
|
|
|
|
SymbolNames.insert(V.getName());
|
|
|
|
} else {
|
|
|
|
// Mangle name before adding
|
|
|
|
std::string newName;
|
|
|
|
do {
|
|
|
|
newName = V.getName() + "_" + utostr(uniqueCounter);
|
|
|
|
if (SymbolNames.count(newName) == 0) break;
|
|
|
|
else ++uniqueCounter;
|
|
|
|
} while (1);
|
|
|
|
//while (SymbolNames.count(V->getName()+utostr(uniqueCounter++))==0);
|
|
|
|
DEBUG(std::cerr << "Disambiguator: conflict: " << V.getName()
|
|
|
|
<< ", adding: " << newName << "\n");
|
|
|
|
V.setName(newName);
|
|
|
|
SymbolNames.insert(newName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReduceMisCodegenFunctions::DisambiguateGlobalSymbols(Module *M) {
|
|
|
|
// First, try not to cause collisions by minimizing chances of renaming an
|
|
|
|
// already-external symbol, so take in external globals and functions as-is.
|
2003-07-24 21:59:10 +00:00
|
|
|
Disambiguator D;
|
|
|
|
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) D.add(*I);
|
|
|
|
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) D.add(*I);
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
|
|
|
|
// Now just rename functions and globals as necessary, keeping what's already
|
|
|
|
// in the set unique.
|
|
|
|
D.setExternalOnly(false);
|
2003-07-24 21:59:10 +00:00
|
|
|
for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) D.add(*I);
|
|
|
|
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) D.add(*I);
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool BugDriver::debugCodeGenerator() {
|
|
|
|
// See if we can pin down which functions are being miscompiled...
|
|
|
|
//First, build a list of all of the non-external functions in the program.
|
|
|
|
std::vector<Function*> MisCodegenFunctions;
|
|
|
|
for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I)
|
|
|
|
if (!I->isExternal())
|
|
|
|
MisCodegenFunctions.push_back(I);
|
|
|
|
|
|
|
|
// Do the reduction...
|
|
|
|
ReduceMisCodegenFunctions(*this).reduceList(MisCodegenFunctions);
|
|
|
|
|
|
|
|
std::cout << "\n*** The following functions are being miscompiled: ";
|
|
|
|
PrintFunctionList(MisCodegenFunctions);
|
|
|
|
std::cout << "\n";
|
|
|
|
|
|
|
|
// Output a bunch of bytecode files for the user...
|
2003-07-24 21:59:10 +00:00
|
|
|
// ReduceMisCodegenFunctions(*this).TestFuncs(MisCodegenFunctions);
|
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.
LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.
Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.
ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.
If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.
llvm-svn: 7293
2003-07-24 18:17:43 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|