aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2008-07-21 23:04:39 +0000
committerDevang Patel <dpatel@apple.com>2008-07-21 23:04:39 +0000
commit6e7775f732b4695dd049389238689415bdc99835 (patch)
treead937ec5365638cb383a716cf067b35d5191add4 /tools
parent79acd2b51ff81db67d8383ec117039cb99fdc04d (diff)
downloadexternal_llvm-6e7775f732b4695dd049389238689415bdc99835.zip
external_llvm-6e7775f732b4695dd049389238689415bdc99835.tar.gz
external_llvm-6e7775f732b4695dd049389238689415bdc99835.tar.bz2
Provide llvm bitcode file to native object file interface.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53886 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/lto-bugpoint/LTOBugPoint.cpp191
-rw-r--r--tools/lto-bugpoint/LTOBugPoint.h15
-rw-r--r--tools/lto-bugpoint/Makefile7
-rw-r--r--tools/lto-bugpoint/lto-bugpoint.cpp4
4 files changed, 208 insertions, 9 deletions
diff --git a/tools/lto-bugpoint/LTOBugPoint.cpp b/tools/lto-bugpoint/LTOBugPoint.cpp
index 925ab9e..a855a0b 100644
--- a/tools/lto-bugpoint/LTOBugPoint.cpp
+++ b/tools/lto-bugpoint/LTOBugPoint.cpp
@@ -13,10 +13,26 @@
//===----------------------------------------------------------------------===//
#include "LTOBugPoint.h"
+#include "llvm/PassManager.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/CodeGen/FileWriters.h"
+#include "llvm/Target/SubtargetFeature.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/System/Path.h"
+#include "llvm/Config/config.h"
+#include <fstream>
#include <iostream>
+using namespace llvm;
+using namespace Reloc;
/// LTOBugPoint -- Constructor. Popuate list of linker options and
/// list of linker input files.
LTOBugPoint::LTOBugPoint(std::istream &args, std::istream &ins) {
@@ -35,23 +51,184 @@ LTOBugPoint::LTOBugPoint(std::istream &args, std::istream &ins) {
/// findTroubleMakers - Find minimum set of input files that causes error
/// identified by the script.
bool
-LTOBugPoint::findTroubleMakers(llvm::SmallVector<std::string, 4> &TroubleMakers,
+LTOBugPoint::findTroubleMakers(SmallVector<std::string, 4> &TroubleMakers,
std::string &Script) {
// First, build native object files set.
bool bitcodeFileSeen = false;
- for(llvm::SmallVector<std::string, 16>::iterator I = LinkerInputFiles.begin(),
- E = LinkerInputFiles.end(); I != E; ++I) {
- std::string &path = *I;
- if (llvm::sys::Path(path.c_str()).isBitcodeFile())
+ unsigned Size = LinkerInputFiles.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;
+ return false;
+ }
+ else if (InputFile.isBitcodeFile()) {
bitcodeFileSeen = true;
+ if (getNativeObjectFile(FileName) == false)
+ return false;
+ }
+ else
+ NativeInputFiles.push_back(FileName);
}
if (!bitcodeFileSeen) {
- std::cerr << "lto-bugpoint: Error: Unable to help!";
- std::cerr << " Need at least one input file that contains llvm bitcode\n";
+ ErrMsg = "Unable to help!";
+ ErrMsg += " Need at least one input file that contains llvm bitcode";
return false;
}
return true;
}
+
+/// getFeatureString - Return a string listing the features associated with the
+/// target triple.
+///
+/// FIXME: This is an inelegant way of specifying the features of a
+/// subtarget. It would be better if we could encode this information into the
+/// IR.
+std::string LTOBugPoint::getFeatureString(const char *TargetTriple) {
+ SubtargetFeatures Features;
+
+ if (strncmp(TargetTriple, "powerpc-apple-", 14) == 0) {
+ Features.AddFeature("altivec", true);
+ } else if (strncmp(TargetTriple, "powerpc64-apple-", 16) == 0) {
+ Features.AddFeature("64bit", true);
+ Features.AddFeature("altivec", true);
+ }
+
+ return Features.getString();
+}
+
+/// assembleBitcode - Generate assembly code from the module. Return false
+/// in case of an error.
+bool LTOBugPoint::assembleBitcode(llvm::Module *M, const char *AsmFileName) {
+ std::string TargetTriple = M->getTargetTriple();
+ std::string FeatureStr =
+ getFeatureString(TargetTriple.c_str());
+
+ const TargetMachineRegistry::entry* Registry =
+ TargetMachineRegistry::getClosestStaticTargetForModule(
+ *M, ErrMsg);
+ if ( Registry == NULL )
+ return false;
+
+ TargetMachine *Target = Registry->CtorFn(*M, FeatureStr.c_str());
+
+ // If target supports exception handling then enable it now.
+ if (Target->getTargetAsmInfo()->doesSupportExceptionHandling())
+ ExceptionHandling = true;
+
+ // FIXME
+ Target->setRelocationModel(Reloc::PIC_);
+
+ FunctionPassManager* CGPasses =
+ new FunctionPassManager(new ExistingModuleProvider(M));
+
+ CGPasses->add(new TargetData(*Target->getTargetData()));
+ MachineCodeEmitter* mce = NULL;
+
+ std::ofstream *Out = new std::ofstream(AsmFileName, std::ios::out);
+
+ switch (Target->addPassesToEmitFile(*CGPasses, *Out,
+ TargetMachine::AssemblyFile, true)) {
+ case FileModel::MachOFile:
+ mce = AddMachOWriter(*CGPasses, *Out, *Target);
+ break;
+ case FileModel::ElfFile:
+ mce = AddELFWriter(*CGPasses, *Out, *Target);
+ break;
+ case FileModel::AsmFile:
+ break;
+ case FileModel::Error:
+ case FileModel::None:
+ ErrMsg = "target file type not supported";
+ return false;
+ }
+
+ if (Target->addPassesToEmitFileFinish(*CGPasses, mce, true)) {
+ ErrMsg = "target does not support generation of this file type";
+ return false;
+ }
+
+ CGPasses->doInitialization();
+ for (Module::iterator
+ it = M->begin(), e = M->end(); it != e; ++it)
+ if (!it->isDeclaration())
+ CGPasses->run(*it);
+ CGPasses->doFinalization();
+ delete Out;
+ return true;
+}
+
+/// getNativeObjectFile - Generate native object file based from llvm
+/// bitcode file. Return false in case of an error.
+bool LTOBugPoint::getNativeObjectFile(std::string &FileName) {
+
+ std::auto_ptr<Module> M;
+ MemoryBuffer *Buffer
+ = MemoryBuffer::getFile(FileName.c_str(), &ErrMsg);
+ if (!Buffer) {
+ ErrMsg = "Unable to read ";
+ ErrMsg += FileName;
+ return false;
+ }
+ M.reset(ParseBitcodeFile(Buffer, &ErrMsg));
+ std::string TargetTriple = M->getTargetTriple();
+
+ sys::Path AsmFile(sys::Path::GetTemporaryDirectory());
+ if(AsmFile.createTemporaryFileOnDisk(false, &ErrMsg))
+ return false;
+
+ if (assembleBitcode(M.get(), AsmFile.c_str()) == false)
+ return false;
+
+ sys::Path NativeFile(sys::Path::GetTemporaryDirectory());
+ if(NativeFile.createTemporaryFileOnDisk(false, &ErrMsg))
+ return false;
+
+ // find compiler driver
+ const sys::Path gcc = sys::Program::FindProgramByName("gcc");
+ if ( gcc.isEmpty() ) {
+ ErrMsg = "can't locate gcc";
+ return false;
+ }
+
+ // build argument list
+ std::vector<const char*> args;
+ args.push_back(gcc.c_str());
+ if ( TargetTriple.find("darwin") != TargetTriple.size() ) {
+ if (strncmp(TargetTriple.c_str(), "i686-apple-", 11) == 0) {
+ args.push_back("-arch");
+ args.push_back("i386");
+ }
+ else if (strncmp(TargetTriple.c_str(), "x86_64-apple-", 13) == 0) {
+ args.push_back("-arch");
+ args.push_back("x86_64");
+ }
+ else if (strncmp(TargetTriple.c_str(), "powerpc-apple-", 14) == 0) {
+ args.push_back("-arch");
+ args.push_back("ppc");
+ }
+ else if (strncmp(TargetTriple.c_str(), "powerpc64-apple-", 16) == 0) {
+ args.push_back("-arch");
+ args.push_back("ppc64");
+ }
+ }
+ args.push_back("-c");
+ args.push_back("-x");
+ args.push_back("assembler");
+ args.push_back("-o");
+ args.push_back(NativeFile.c_str());
+ args.push_back(AsmFile.c_str());
+ args.push_back(0);
+
+ // invoke assembler
+ if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 0, 0, &ErrMsg)) {
+ ErrMsg = "error in assembly";
+ return false;
+ }
+ return true;
+}
diff --git a/tools/lto-bugpoint/LTOBugPoint.h b/tools/lto-bugpoint/LTOBugPoint.h
index b73b267..c63a272 100644
--- a/tools/lto-bugpoint/LTOBugPoint.h
+++ b/tools/lto-bugpoint/LTOBugPoint.h
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Module.h"
#include <string>
#include <fstream>
@@ -25,6 +26,13 @@ class LTOBugPoint {
/// identified by the script.
bool findTroubleMakers(llvm::SmallVector<std::string, 4> &TroubleMakers,
std::string &Script);
+
+ /// getNativeObjectFile - Generate native object file based from llvm
+ /// bitcode file. Return false in case of an error.
+ bool getNativeObjectFile(std::string &FileName);
+
+ std::string &getErrMsg() { return ErrMsg; }
+
private:
/// LinkerInputFiles - This is a list of linker input files. Once populated
/// this list is not modified.
@@ -39,4 +47,11 @@ class LTOBugPoint {
/// at index 4 in NativeInputFiles is corresponding native object file.
llvm::SmallVector<std::string, 16> NativeInputFiles;
+ std::string getFeatureString(const char *TargetTriple);
+ std::string ErrMsg;
+
+private:
+ /// assembleBitcode - Generate assembly code from the module. Return false
+ /// in case of an error.
+ bool assembleBitcode(llvm::Module *M, const char *AsmFileName);
};
diff --git a/tools/lto-bugpoint/Makefile b/tools/lto-bugpoint/Makefile
index c63eb6b..6a08c91 100644
--- a/tools/lto-bugpoint/Makefile
+++ b/tools/lto-bugpoint/Makefile
@@ -10,7 +10,12 @@ LEVEL = ../..
TOOLNAME = lto-bugpoint
-LINK_COMPONENTS := system
+# Include this here so we can get the configuration of the targets
+# that have been configured for construction. We have to do this
+# early so we can set up LINK_COMPONENTS before including Makefile.rules
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader
REQUIRES_EH := 1
diff --git a/tools/lto-bugpoint/lto-bugpoint.cpp b/tools/lto-bugpoint/lto-bugpoint.cpp
index 01adb57..230d3eb 100644
--- a/tools/lto-bugpoint/lto-bugpoint.cpp
+++ b/tools/lto-bugpoint/lto-bugpoint.cpp
@@ -51,8 +51,10 @@ int main(int argc, char **argv) {
LTOBugPoint bugFinder(*LinkerArgsFile, *LinkerInputsFile);
llvm::SmallVector<std::string, 4> TroubleMakers;
- if (!bugFinder.findTroubleMakers(TroubleMakers, ValidationScript))
+ if (!bugFinder.findTroubleMakers(TroubleMakers, ValidationScript)) {
+ std::cerr << "lto-bugpoint:" << bugFinder.getErrMsg() << "\n";
return 1;
+ }
return 0;
} catch (const std::string& msg) {