diff options
author | Devang Patel <dpatel@apple.com> | 2008-07-24 00:34:11 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2008-07-24 00:34:11 +0000 |
commit | 9d76c73d9c0ecd38ea88bb192c48f153b7bb9af7 (patch) | |
tree | f2651ba9eac92ab65fcf242a639bc86e572160fe | |
parent | 2d58bfac5931e61a4010e3e464e89e0b21fa4abe (diff) | |
download | external_llvm-9d76c73d9c0ecd38ea88bb192c48f153b7bb9af7.zip external_llvm-9d76c73d9c0ecd38ea88bb192c48f153b7bb9af7.tar.gz external_llvm-9d76c73d9c0ecd38ea88bb192c48f153b7bb9af7.tar.bz2 |
Identify llvm bit-code file that is causing linking failure in LTO mode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53972 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | tools/lto-bugpoint/LTOBugPoint.cpp | 138 | ||||
-rw-r--r-- | tools/lto-bugpoint/LTOBugPoint.h | 24 |
2 files changed, 144 insertions, 18 deletions
diff --git a/tools/lto-bugpoint/LTOBugPoint.cpp b/tools/lto-bugpoint/LTOBugPoint.cpp index d54b28d..587e360 100644 --- a/tools/lto-bugpoint/LTOBugPoint.cpp +++ b/tools/lto-bugpoint/LTOBugPoint.cpp @@ -31,6 +31,27 @@ using namespace llvm; using namespace Reloc; + +/// printBitVector - Helper function. +static void printBitVector(BitVector &BV, const char *Title) { + std::cerr << Title; + for (unsigned i = 0, e = BV.size(); i < e; i++) { + if (BV[i]) + std::cerr << " " << i; + } + std::cerr << "\n"; +} + +/// printBitVector - Helper function. +static void printBitVectorFiles(BitVector &BV, const char *Title, + SmallVector<std::string, 16> &InFiles) { + std::cerr << Title << "\n"; + for (unsigned i = 0, e = BV.size(); i < e; i++) { + if (BV[i]) + std::cerr << "\t" << InFiles[i] << "\n"; + } +} + /// LTOBugPoint -- Constructor. Popuate list of linker options and /// list of linker input files. LTOBugPoint::LTOBugPoint(std::istream &args, std::istream &ins) { @@ -46,6 +67,9 @@ LTOBugPoint::LTOBugPoint(std::istream &args, std::istream &ins) { LinkerInputFiles.push_back(inFile); TempDir = sys::Path::GetTemporaryDirectory(); + + // FIXME - Use command line option to set this. + findLinkingFailure = true; } LTOBugPoint::~LTOBugPoint() { @@ -59,48 +83,62 @@ LTOBugPoint::findTroubleMakers(SmallVector<std::string, 4> &TroubleMakers, std::string &Script) { // Reproduce original error. - if (!relinkProgram(LinkerInputFiles) || !reproduceProgramError(Script)) { - ErrMsg += " Unable to reproduce original error!"; + if (!relinkProgram(LinkerInputFiles) && !findLinkingFailure) { + ErrMsg = " Unable to reproduce original error!"; + return false; + } + + if (!findLinkingFailure && !reproduceProgramError(Script)) { + ErrMsg = " Unable to reproduce original error!"; return false; } // Build native object files set. - bool bitcodeFileSeen = false; unsigned Size = LinkerInputFiles.size(); + BCFiles.resize(Size); + ConfirmedClean.resize(Size); + ConfirmedGuilty.resize(Size); for (unsigned I = 0; I < Size; ++I) { std::string &FileName = LinkerInputFiles[I]; sys::Path InputFile(FileName.c_str()); if (InputFile.isDynamicLibrary() || InputFile.isArchive()) { - ErrMsg = "Unable to handle input file "; - ErrMsg += FileName; + ErrMsg = "Unable to handle input file " + FileName; return false; } else if (InputFile.isBitcodeFile()) { - bitcodeFileSeen = true; + BCFiles.set(I); if (getNativeObjectFile(FileName) == false) return false; } - else + else { + // Original native object input files are always clean. + ConfirmedClean.set(I); NativeInputFiles.push_back(FileName); + } } - if (!bitcodeFileSeen) { + if (BCFiles.none()) { ErrMsg = "Unable to help!"; - ErrMsg += " Need at least one input file that contains llvm bitcode"; + ErrMsg = " Need at least one input file that contains llvm bitcode"; return false; } // Try to reproduce error using native object files first. If the error // occurs then this is not a LTO error. if (!relinkProgram(NativeInputFiles)) { - ErrMsg += " Unable to link the program using all native object files!"; + ErrMsg = " Unable to link the program using all native object files!"; return false; } - if (reproduceProgramError(Script) == true) { - ErrMsg += " Unable to fix program error using all native object files!"; + if (!findLinkingFailure && reproduceProgramError(Script) == true) { + ErrMsg = " Unable to fix program error using all native object files!"; return false; } + printBitVector(BCFiles, "Initial set of llvm bitcode files"); + identifyTroubleMakers(BCFiles); + printBitVectorFiles(ConfirmedGuilty, + "Identified minimal set of bitcode files!", + LinkerInputFiles); return true; } @@ -192,8 +230,7 @@ bool LTOBugPoint::getNativeObjectFile(std::string &FileName) { MemoryBuffer *Buffer = MemoryBuffer::getFile(FileName.c_str(), &ErrMsg); if (!Buffer) { - ErrMsg = "Unable to read "; - ErrMsg += FileName; + ErrMsg = "Unable to read " + FileName; return false; } M.reset(ParseBitcodeFile(Buffer, &ErrMsg)); @@ -261,6 +298,7 @@ bool LTOBugPoint::getNativeObjectFile(std::string &FileName) { } AsmFile.eraseFromDisk(); + NativeInputFiles.push_back(NativeFile.c_str()); return true; } @@ -289,10 +327,9 @@ bool LTOBugPoint::relinkProgram(llvm::SmallVector<std::string, 16> &InFiles) { Args.push_back(0); if (sys::Program::ExecuteAndWait(linker, &Args[0], 0, 0, 0, 0, &ErrMsg)) { - ErrMsg += "error while linking program"; - return false; + ErrMsg = "error while linking program"; + return false; } - return true; } @@ -325,3 +362,70 @@ bool LTOBugPoint::reproduceProgramError(std::string &Script) { return false; } + +/// identifyTroubleMakers - Identify set of bit code files that are causing +/// the error. This is a recursive function. +void LTOBugPoint::identifyTroubleMakers(llvm::BitVector &In) { + + assert (In.size() == LinkerInputFiles.size() + && "Invalid identifyTroubleMakers input!\n"); + + printBitVector(In, "Processing files "); + BitVector CandidateVector; + CandidateVector.resize(LinkerInputFiles.size()); + + // Process first half + unsigned count = 0; + for (unsigned i = 0, e = In.size(); i < e; ++i) { + if (!ConfirmedClean[i]) { + count++; + CandidateVector.set(i); + } + if (count >= In.count()/2) + break; + } + + if (CandidateVector.none()) + return; + + printBitVector(CandidateVector, "Candidate vector "); + + // Reproduce the error using native object files for candidate files. + SmallVector<std::string, 16> CandidateFiles; + for (unsigned i = 0, e = CandidateVector.size(); i < e; ++i) { + if (CandidateVector[i] || ConfirmedClean[i]) + CandidateFiles.push_back(NativeInputFiles[i]); + else + CandidateFiles.push_back(LinkerInputFiles[i]); + } + + bool result = relinkProgram(CandidateFiles); + if (findLinkingFailure) { + if (result == true) { + // Candidate files are suspected. + if (CandidateVector.count() == 1) { + ConfirmedGuilty.set(CandidateVector.find_first()); + return; + } + else + identifyTroubleMakers(CandidateVector); + } else { + // Candidate files are not causing this error. + for (unsigned i = 0, e = CandidateVector.size(); i < e; ++i) { + if (CandidateVector[i]) + ConfirmedClean.set(i); + } + } + } else { + std::cerr << "FIXME : Not yet implemented!\n"; + } + + // Process remaining cadidates + CandidateVector.clear(); + CandidateVector.resize(LinkerInputFiles.size()); + for (unsigned i = 0, e = LinkerInputFiles.size(); i < e; ++i) { + if (!ConfirmedClean[i] && !ConfirmedGuilty[i]) + CandidateVector.set(i); + } + identifyTroubleMakers(CandidateVector); +} diff --git a/tools/lto-bugpoint/LTOBugPoint.h b/tools/lto-bugpoint/LTOBugPoint.h index 5f1b5cc..4179124 100644 --- a/tools/lto-bugpoint/LTOBugPoint.h +++ b/tools/lto-bugpoint/LTOBugPoint.h @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/BitVector.h" #include "llvm/Module.h" #include "llvm/System/Path.h" #include <string> @@ -30,7 +31,8 @@ class LTOBugPoint { std::string &Script); /// getNativeObjectFile - Generate native object file based from llvm - /// bitcode file. Return false in case of an error. + /// bitcode file. Return false in case of an error. Generated native + /// object file is inserted in to the NativeInputFiles list. bool getNativeObjectFile(std::string &FileName); std::string &getErrMsg() { return ErrMsg; } @@ -49,10 +51,26 @@ class LTOBugPoint { /// at index 4 in NativeInputFiles is corresponding native object file. llvm::SmallVector<std::string, 16> NativeInputFiles; + /// BCFiles - This bit vector tracks input bitcode files. + llvm::BitVector BCFiles; + + /// ConfirmedClean - This bit vector tracks input files that are confirmed + /// to be clean. + llvm::BitVector ConfirmedClean; + + /// ConfirmedGuilty - This bit vector tracks input files that are confirmed + /// to contribute to the bug being investigated. + llvm::BitVector ConfirmedGuilty; std::string getFeatureString(const char *TargetTriple); std::string ErrMsg; llvm::sys::Path TempDir; + + /// findLinkingFailure - If true, investigate link failure bugs when + /// one or more linker input files are llvm bitcode files. If false, + /// investigate optimization or code generation bugs in LTO mode. + bool findLinkingFailure; + private: /// assembleBitcode - Generate assembly code from the module. Return false /// in case of an error. @@ -63,4 +81,8 @@ private: /// reproduceProgramError - Validate program using user provided script. bool reproduceProgramError(std::string &Script); + + /// identifyTroubleMakers - Identify set of inputs from the given + /// bitvector that are causing the bug under investigation. + void identifyTroubleMakers(llvm::BitVector &In); }; |