X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fbugpoint%2FCodeGeneratorBug.cpp;h=8569bb9337d92c1fe1dd0bf5fa6f39d4c09c5e77;hb=91ef460285021b5bf43b3850f0f8958a09b8939c;hp=b24620ea140b1403c056fb3f146c9c06415d035c;hpb=d0fde30ce850b78371fd1386338350591f9ff494;p=oota-llvm.git diff --git a/tools/bugpoint/CodeGeneratorBug.cpp b/tools/bugpoint/CodeGeneratorBug.cpp index b24620ea140..8569bb9337d 100644 --- a/tools/bugpoint/CodeGeneratorBug.cpp +++ b/tools/bugpoint/CodeGeneratorBug.cpp @@ -32,71 +32,46 @@ #include "Support/FileUtilities.h" #include #include +using namespace llvm; namespace llvm { + extern cl::list InputArgv; -extern cl::list InputArgv; - -class ReduceMisCodegenFunctions : public ListReducer { - BugDriver &BD; -public: - ReduceMisCodegenFunctions(BugDriver &bd) : BD(bd) {} - - virtual TestResult doTest(std::vector &Prefix, - std::vector &Suffix) { - if (!Prefix.empty() && TestFuncs(Prefix)) - return KeepPrefix; - if (!Suffix.empty() && TestFuncs(Suffix)) - return KeepSuffix; - return NoFailure; - } - - bool TestFuncs(const std::vector &CodegenTest, - bool KeepFiles = false); -}; - + class ReduceMisCodegenFunctions : public ListReducer { + BugDriver &BD; + public: + ReduceMisCodegenFunctions(BugDriver &bd) : BD(bd) {} + + virtual TestResult doTest(std::vector &Prefix, + std::vector &Suffix) { + if (!Prefix.empty() && TestFuncs(Prefix)) + return KeepPrefix; + if (!Suffix.empty() && TestFuncs(Suffix)) + return KeepSuffix; + return NoFailure; + } + + bool TestFuncs(const std::vector &CodegenTest, + bool KeepFiles = false); + }; +} bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, bool KeepFiles) { std::cout << "Testing functions: "; - BD.PrintFunctionList(Funcs); + PrintFunctionList(Funcs); std::cout << "\t"; // 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); - - 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 - - // Remove the Test functions from the Safe module - for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { - Function *TNOF = SafeModule->getFunction(Funcs[i]->getName(), - Funcs[i]->getFunctionType()); - DEBUG(std::cerr << "Removing function " << Funcs[i]->getName() << "\n"); - assert(TNOF && "Function doesn't exist in module!"); - DeleteFunctionBody(TNOF); // Function is now external in this module! - } + Module *SafeModule = CloneModule(BD.getProgram()); - // Remove the Safe functions from the Test module - for (Module::iterator I=TestModule->begin(),E=TestModule->end(); I!=E; ++I) { - bool funcFound = false; - for (std::vector::const_iterator F=Funcs.begin(),Fe=Funcs.end(); - F != Fe; ++F) - if (I->getName() == (*F)->getName()) funcFound = true; - - if (!funcFound && !(BD.isExecutingJIT() && I->getName() == "main")) - DeleteFunctionBody(I); + // The JIT must extract the 'main' function. + std::vector RealFuncs(Funcs); + if (BD.isExecutingJIT()) { + if (Function *F = BD.Program->getMainFunction()) + RealFuncs.push_back(F); } + Module *TestModule = SplitFunctionsOutOfModule(SafeModule, RealFuncs); // This is only applicable if we are debugging the JIT: // Find all external functions in the Safe modules that are actually used @@ -167,10 +142,11 @@ bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, // actually use the resolved function Inst->replaceUsesOfWith(F, castResolver); } else { - // FIXME: need to take care of cases where a function is used that - // is not an instruction, e.g. global variable initializer... - std::cerr << - "UNSUPPORTED: External function used as global initializer!\n"; + // FIXME: need to take care of cases where a function is used by + // something other than an instruction; e.g., global variable + // initializers and constant expressions. + std::cerr << "UNSUPPORTED: Non-instruction is using an external " + << "function, " << F->getName() << "().\n"; abort(); } } @@ -262,7 +238,7 @@ bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, for (unsigned i=0, e = InputArgv.size(); i != e; ++i) std::cout << " " << InputArgv[i]; std::cout << "\n"; - std::cout << "The shared object was created with:\n llvm-dis -c " + std::cout << "The shared object was created with:\n llc -march=c " << SafeModuleBC << " -o temporary.c\n" << " gcc -xc temporary.c -O2 -o " << SharedObject #if defined(sparc) || defined(__sparc__) || defined(__sparcv9) @@ -328,7 +304,7 @@ namespace { }; } -void DisambiguateGlobalSymbols(Module *M) { +static void 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. Disambiguator D; @@ -348,8 +324,19 @@ void DisambiguateGlobalSymbols(Module *M) { bool BugDriver::debugCodeGenerator() { + if ((void*)cbe == (void*)Interpreter) { + std::string Result = executeProgramWithCBE("bugpoint.cbe.out"); + std::cout << "\n*** The C backend cannot match the reference diff, but it " + << "is used as the 'known good'\n code generator, so I can't" + << " debug it. Perhaps you have a front-end problem?\n As a" + << " sanity check, I left the result of executing the program " + << "with the C backend\n in this file for you: '" + << Result << "'.\n"; + return true; + } + // 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. + // First, build a list of all of the non-external functions in the program. std::vector MisCodegenFunctions; for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I) if (!I->isExternal()) @@ -381,15 +368,11 @@ bool BugDriver::debugCodeGenerator() { BB->getInstList().push_back(call); // if the type of old function wasn't void, return value of call - ReturnInst *ret; if (oldMain->getReturnType() != Type::VoidTy) { - ret = new ReturnInst(call); + new ReturnInst(call, BB); } else { - ret = new ReturnInst(); + new ReturnInst(0, BB); } - - // Add the return instruction to the BasicBlock - BB->getInstList().push_back(ret); } DisambiguateGlobalSymbols(Program); @@ -410,5 +393,3 @@ bool BugDriver::debugCodeGenerator() { return false; } - -} // End llvm namespace