X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fbugpoint%2FCodeGeneratorBug.cpp;h=4da709a3f8cd8790bc5dfd0f490b905a2ecec6ae;hb=744b5fb93f86e35093ea6379ae3b9c3f9cac75a9;hp=72ea91a4e274ac5939ea1d7b613138b771fdaa6b;hpb=57e5a702d0e3c49c67208bf07212c878d34e73ca;p=oota-llvm.git diff --git a/tools/bugpoint/CodeGeneratorBug.cpp b/tools/bugpoint/CodeGeneratorBug.cpp index 72ea91a4e27..4da709a3f8c 100644 --- a/tools/bugpoint/CodeGeneratorBug.cpp +++ b/tools/bugpoint/CodeGeneratorBug.cpp @@ -1,4 +1,11 @@ //===- CodeGeneratorBug.cpp - Debug code generation bugs ------------------===// +// +// 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 code generation debugging support. // @@ -25,31 +32,32 @@ #include "Support/FileUtilities.h" #include #include +using namespace llvm; -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); -}; +namespace llvm { + 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); + }; +} bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, - bool KeepFiles) -{ + bool KeepFiles) { std::cout << "Testing functions: "; BD.PrintFunctionList(Funcs); std::cout << "\t"; @@ -113,8 +121,10 @@ bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, // Use the function we just added to get addresses of functions we need // Iterate over the global declarations in the Safe module for (Module::iterator F=SafeModule->begin(),E=SafeModule->end(); F!=E; ++F){ - if (F->isExternal() && !F->use_empty() && &(*F) != resolverFunc && - F->getIntrinsicID() == 0 /* ignore intrinsics */) { + if (F->isExternal() && !F->use_empty() && &*F != resolverFunc && + F->getIntrinsicID() == 0 /* ignore intrinsics */ && + // Don't forward functions which are external in the test module too. + !TestModule->getNamedFunction(F->getName())->isExternal()) { // If it has a non-zero use list, // 1. Add a string constant with its name to the global file // The correct type is `const [ NUM x sbyte ]' where NUM is length of @@ -145,8 +155,8 @@ bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, ResolverArgs.push_back(GEP); // Insert code at the beginning of the function - for (Value::use_iterator i=F->use_begin(), e=F->use_end(); i!=e; ++i) { - if (Instruction* Inst = dyn_cast(*i)) { + while (!F->use_empty()) + if (Instruction *Inst = dyn_cast(F->use_back())) { // call resolver(GetElementPtr...) CallInst *resolve = new CallInst(resolverFunc, ResolverArgs, "resolver", Inst); @@ -157,12 +167,13 @@ 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 << "Non-instruction is using an external function!\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(); } - } } } } @@ -225,8 +236,7 @@ bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, } // Make a shared library - std::string SharedObject; - BD.compileSharedObject(SafeModuleBC, SharedObject); + std::string SharedObject = BD.compileSharedObject(SafeModuleBC); delete SafeModule; delete TestModule; @@ -247,15 +257,21 @@ bool ReduceMisCodegenFunctions::TestFuncs(const std::vector &Funcs, } else { std::cout << " llc " << TestModuleBC << " -o " << TestModuleBC << ".s\n"; std::cout << " gcc " << SharedObject << " " << TestModuleBC - << ".s -o " << TestModuleBC << ".exe\n"; + << ".s -o " << TestModuleBC << ".exe -Wl,-R.\n"; std::cout << " " << TestModuleBC << ".exe"; } 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 dis -c " + std::cout << "The shared object was created with:\n llc -march=c " << SafeModuleBC << " -o temporary.c\n" - << " gcc -shared temporary.c -o " << SharedObject << "\n"; + << " gcc -xc temporary.c -O2 -o " << SharedObject +#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) + << " -G" // Compile a shared library, `-G' for Sparc +#else + << " -shared" // `-shared' for Linux/X86, maybe others +#endif + << " -fno-strict-aliasing\n"; } else { removeFile(TestModuleBC); removeFile(SafeModuleBC); @@ -313,7 +329,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; @@ -333,8 +349,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()) @@ -366,15 +393,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);