From 1a7354082ad62d9e31faf3d6ad15c39debc94fd6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 6 May 2007 04:55:19 +0000 Subject: add bitcode reading support. Remove EH cruft. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36839 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llc/Makefile | 3 +- tools/llc/llc.cpp | 250 ++++++++++++++++++++++++++++------------------------- 2 files changed, 131 insertions(+), 122 deletions(-) (limited to 'tools') diff --git a/tools/llc/Makefile b/tools/llc/Makefile index 847a175d25..fa7a1b482f 100644 --- a/tools/llc/Makefile +++ b/tools/llc/Makefile @@ -9,14 +9,13 @@ LEVEL = ../.. TOOLNAME = llc -REQUIRES_EH := 1 # 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) bcreader +LINK_COMPONENTS := $(TARGETS_TO_BUILD) bcreader bitreader include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index a6e718707e..fd0109543a 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -13,6 +13,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Bytecode/Reader.h" #include "llvm/CodeGen/FileWriters.h" #include "llvm/CodeGen/LinkAllCodegenComponents.h" @@ -27,6 +28,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compressor.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Analysis/Verifier.h" @@ -36,9 +38,11 @@ #include #include #include - using namespace llvm; +cl::opt Bitcode("bitcode"); + + // General options for llc. Other pass-specific options are specified // within the corresponding llc passes, and target-specific options // and back-end code generation options are specified with the target machine. @@ -172,137 +176,143 @@ static std::ostream *GetOutputStream(const char *ProgName) { // int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - try { - cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); - sys::PrintStackTraceOnErrorSignal(); - - // Load the module to be compiled... - std::string errmsg; - std::auto_ptr M(ParseBytecodeFile(InputFilename, - Compressor::decompressToNewBuffer, - &errmsg)); - if (M.get() == 0) { - std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; - std::cerr << "Reason: " << errmsg << "\n"; - return 1; - } - Module &mod = *M.get(); + cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); + sys::PrintStackTraceOnErrorSignal(); - // If we are supposed to override the target triple, do so now. - if (!TargetTriple.empty()) - mod.setTargetTriple(TargetTriple); + // Load the module to be compiled... + std::string ErrorMessage; + std::auto_ptr M; + + if (Bitcode) { + MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(&InputFilename[0], + InputFilename.size()); + if (Buffer == 0) + ErrorMessage = "Error reading file '" + InputFilename + "'"; + else + M.reset(ParseBitcodeFile(Buffer, &ErrorMessage)); + delete Buffer; - // Allocate target machine. First, check whether the user has - // explicitly specified an architecture to compile for. + } else { + M.reset(ParseBytecodeFile(InputFilename, + Compressor::decompressToNewBuffer, + &ErrorMessage)); + } + if (M.get() == 0) { + std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; + std::cerr << "Reason: " << ErrorMessage << "\n"; + return 1; + } + Module &mod = *M.get(); + + // If we are supposed to override the target triple, do so now. + if (!TargetTriple.empty()) + mod.setTargetTriple(TargetTriple); + + // Allocate target machine. First, check whether the user has + // explicitly specified an architecture to compile for. + if (MArch == 0) { + std::string Err; + MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err); if (MArch == 0) { - std::string Err; - MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err); - if (MArch == 0) { - std::cerr << argv[0] << ": error auto-selecting target for module '" - << Err << "'. Please use the -march option to explicitly " - << "pick a target.\n"; - return 1; - } - } - - // Package up features to be passed to target/subtarget - std::string FeaturesStr; - if (MCPU.size() || MAttrs.size()) { - SubtargetFeatures Features; - Features.setCPU(MCPU); - for (unsigned i = 0; i != MAttrs.size(); ++i) - Features.AddFeature(MAttrs[i]); - FeaturesStr = Features.getString(); + std::cerr << argv[0] << ": error auto-selecting target for module '" + << Err << "'. Please use the -march option to explicitly " + << "pick a target.\n"; + return 1; } + } - std::auto_ptr target(MArch->CtorFn(mod, FeaturesStr)); - assert(target.get() && "Could not allocate target machine!"); - TargetMachine &Target = *target.get(); + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + if (MCPU.size() || MAttrs.size()) { + SubtargetFeatures Features; + Features.setCPU(MCPU); + for (unsigned i = 0; i != MAttrs.size(); ++i) + Features.AddFeature(MAttrs[i]); + FeaturesStr = Features.getString(); + } + + std::auto_ptr target(MArch->CtorFn(mod, FeaturesStr)); + assert(target.get() && "Could not allocate target machine!"); + TargetMachine &Target = *target.get(); - // Figure out where we are going to send the output... - std::ostream *Out = GetOutputStream(argv[0]); - if (Out == 0) return 1; + // Figure out where we are going to send the output... + std::ostream *Out = GetOutputStream(argv[0]); + if (Out == 0) return 1; + + // If this target requires addPassesToEmitWholeFile, do it now. This is + // used by strange things like the C backend. + if (Target.WantsWholeFile()) { + PassManager PM; + PM.add(new TargetData(*Target.getTargetData())); + if (!NoVerify) + PM.add(createVerifierPass()); + + // Ask the target to add backend passes as necessary. + if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) { + std::cerr << argv[0] << ": target does not support generation of this" + << " file type!\n"; + if (Out != &std::cout) delete Out; + // And the Out file is empty and useless, so remove it now. + sys::Path(OutputFilename).eraseFromDisk(); + return 1; + } + PM.run(mod); + } else { + // Build up all of the passes that we want to do to the module. + FunctionPassManager Passes(new ExistingModuleProvider(M.get())); + Passes.add(new TargetData(*Target.getTargetData())); - // If this target requires addPassesToEmitWholeFile, do it now. This is - // used by strange things like the C backend. - if (Target.WantsWholeFile()) { - PassManager PM; - PM.add(new TargetData(*Target.getTargetData())); - if (!NoVerify) - PM.add(createVerifierPass()); - - // Ask the target to add backend passes as necessary. - if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) { - std::cerr << argv[0] << ": target does not support generation of this" - << " file type!\n"; - if (Out != &std::cout) delete Out; - // And the Out file is empty and useless, so remove it now. - sys::Path(OutputFilename).eraseFromDisk(); - return 1; - } - PM.run(mod); - } else { - // Build up all of the passes that we want to do to the module. - FunctionPassManager Passes(new ExistingModuleProvider(M.get())); - Passes.add(new TargetData(*Target.getTargetData())); - #ifndef NDEBUG - if (!NoVerify) - Passes.add(createVerifierPass()); + if (!NoVerify) + Passes.add(createVerifierPass()); #endif - - // Ask the target to add backend passes as necessary. - MachineCodeEmitter *MCE = 0; + + // Ask the target to add backend passes as necessary. + MachineCodeEmitter *MCE = 0; - switch (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) { - default: - assert(0 && "Invalid file model!"); - return 1; - case FileModel::Error: - std::cerr << argv[0] << ": target does not support generation of this" - << " file type!\n"; - if (Out != &std::cout) delete Out; - // And the Out file is empty and useless, so remove it now. - sys::Path(OutputFilename).eraseFromDisk(); - return 1; - case FileModel::AsmFile: - break; - case FileModel::MachOFile: - MCE = AddMachOWriter(Passes, *Out, Target); - break; - case FileModel::ElfFile: - MCE = AddELFWriter(Passes, *Out, Target); - break; - } + switch (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) { + default: + assert(0 && "Invalid file model!"); + return 1; + case FileModel::Error: + std::cerr << argv[0] << ": target does not support generation of this" + << " file type!\n"; + if (Out != &std::cout) delete Out; + // And the Out file is empty and useless, so remove it now. + sys::Path(OutputFilename).eraseFromDisk(); + return 1; + case FileModel::AsmFile: + break; + case FileModel::MachOFile: + MCE = AddMachOWriter(Passes, *Out, Target); + break; + case FileModel::ElfFile: + MCE = AddELFWriter(Passes, *Out, Target); + break; + } - if (Target.addPassesToEmitFileFinish(Passes, MCE, Fast)) { - std::cerr << argv[0] << ": target does not support generation of this" - << " file type!\n"; - if (Out != &std::cout) delete Out; - // And the Out file is empty and useless, so remove it now. - sys::Path(OutputFilename).eraseFromDisk(); - return 1; - } + if (Target.addPassesToEmitFileFinish(Passes, MCE, Fast)) { + std::cerr << argv[0] << ": target does not support generation of this" + << " file type!\n"; + if (Out != &std::cout) delete Out; + // And the Out file is empty and useless, so remove it now. + sys::Path(OutputFilename).eraseFromDisk(); + return 1; + } + + Passes.doInitialization(); + + // Run our queue of passes all at once now, efficiently. + // TODO: this could lazily stream functions out of the module. + for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) + if (!I->isDeclaration()) + Passes.run(*I); - Passes.doInitialization(); + Passes.doFinalization(); + } - // Run our queue of passes all at once now, efficiently. - // TODO: this could lazily stream functions out of the module. - for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) - if (!I->isDeclaration()) - Passes.run(*I); - - Passes.doFinalization(); - } - - // Delete the ostream if it's not a stdout stream - if (Out != &std::cout) delete Out; + // Delete the ostream if it's not a stdout stream + if (Out != &std::cout) delete Out; - return 0; - } catch (const std::string& msg) { - std::cerr << argv[0] << ": " << msg << "\n"; - } catch (...) { - std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; - } - return 1; + return 0; } -- cgit v1.2.3