From cc48854d5d51a2d7557f1040a61f160ad86c9729 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 24 Sep 2013 23:52:22 +0000 Subject: Move LTO support library to a component, allowing it to be tested more reliably across platforms. Patch by Tom Roeder! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191343 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/LTO/LTOCodeGenerator.h | 130 ++++++++++++++++++++++++ include/llvm/LTO/LTOModule.h | 196 ++++++++++++++++++++++++++++++++++++ 2 files changed, 326 insertions(+) create mode 100644 include/llvm/LTO/LTOCodeGenerator.h create mode 100644 include/llvm/LTO/LTOModule.h (limited to 'include/llvm/LTO') diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h new file mode 100644 index 0000000..3d151b9 --- /dev/null +++ b/include/llvm/LTO/LTOCodeGenerator.h @@ -0,0 +1,130 @@ +//===-LTOCodeGenerator.h - LLVM Link Time Optimizer -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the LTOCodeGenerator class. +// +// LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO. +// +// The Pre-IPO phase compiles source code into bitcode file. The resulting +// bitcode files, along with object files and libraries, will be fed to the +// linker to through the IPO and Post-IPO phases. By using obj-file extension, +// the resulting bitcode file disguises itself as an object file, and therefore +// obviates the need of writing a special set of the make-rules only for LTO +// compilation. +// +// The IPO phase perform inter-procedural analyses and optimizations, and +// the Post-IPO consists two sub-phases: intra-procedural scalar optimizations +// (SOPT), and intra-procedural target-dependent code generator (CG). +// +// As of this writing, we don't separate IPO and the Post-IPO SOPT. They +// are intermingled together, and are driven by a single pass manager (see +// PassManagerBuilder::populateLTOPassManager()). +// +// The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages. +// The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator" +// with the machine specific code generator. +// +//===----------------------------------------------------------------------===// + +#ifndef LTO_CODE_GENERATOR_H +#define LTO_CODE_GENERATOR_H + +#include "llvm-c/lto.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Linker.h" +#include +#include + +namespace llvm { + class LLVMContext; + class GlobalValue; + class Mangler; + class MemoryBuffer; + class TargetMachine; + class raw_ostream; +} + +//===----------------------------------------------------------------------===// +/// LTOCodeGenerator - C++ class which implements the opaque lto_code_gen_t +/// type. +/// +struct LTOCodeGenerator { + static const char *getVersionString(); + + LTOCodeGenerator(); + ~LTOCodeGenerator(); + + // Merge given module, return true on success. + bool addModule(struct LTOModule*, std::string &errMsg); + + void setDebugInfo(lto_debug_model); + void setCodePICModel(lto_codegen_model); + + void setCpu(const char *mCpu) { MCpu = mCpu; } + + void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; } + + // To pass options to the driver and optimization passes. These options are + // not necessarily for debugging purpose (The function name is misleading). + // This function should be called before LTOCodeGenerator::compilexxx(), + // and LTOCodeGenerator::writeMergedModules(). + // + void setCodeGenDebugOptions(const char *opts); + + // Write the merged module to the file specified by the given path. + // Return true on success. + bool writeMergedModules(const char *path, std::string &errMsg); + + // Compile the merged module into a *single* object file; the path to object + // file is returned to the caller via argument "name". Return true on + // success. + // + // NOTE that it is up to the linker to remove the intermediate object file. + // Do not try to remove the object file in LTOCodeGenerator's destructor + // as we don't who (LTOCodeGenerator or the obj file) will last longer. + // + bool compile_to_file(const char **name, std::string &errMsg); + + // As with compile_to_file(), this function compiles the merged module into + // single object file. Instead of returning the object-file-path to the caller + // (linker), it brings the object to a buffer, and return the buffer to the + // caller. This function should delete intermediate object file once its content + // is brought to memory. Return NULL if the compilation was not successful. + // + const void *compile(size_t *length, std::string &errMsg); + +private: + void initializeLTOPasses(); + + bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg); + void applyScopeRestrictions(); + void applyRestriction(llvm::GlobalValue &GV, + std::vector &MustPreserveList, + llvm::SmallPtrSet &AsmUsed, + llvm::Mangler &Mangler); + bool determineTarget(std::string &errMsg); + + typedef llvm::StringMap StringSet; + + llvm::LLVMContext &Context; + llvm::Linker Linker; + llvm::TargetMachine *TargetMach; + bool EmitDwarfDebugInfo; + bool ScopeRestrictionsDone; + lto_codegen_model CodeModel; + StringSet MustPreserveSymbols; + StringSet AsmUndefinedRefs; + llvm::MemoryBuffer *NativeObjectFile; + std::vector CodegenOptions; + std::string MCpu; + std::string NativeObjectPath; +}; + +#endif // LTO_CODE_GENERATOR_H diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h new file mode 100644 index 0000000..973466c --- /dev/null +++ b/include/llvm/LTO/LTOModule.h @@ -0,0 +1,196 @@ +//===-LTOModule.h - LLVM Link Time Optimizer ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the LTOModule class. +// +//===----------------------------------------------------------------------===// + +#ifndef LTO_MODULE_H +#define LTO_MODULE_H + +#include "llvm-c/lto.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/MCContext.h" +#include "llvm/Target/Mangler.h" +#include "llvm/Target/TargetMachine.h" +#include +#include + +// Forward references to llvm classes. +namespace llvm { + class Function; + class GlobalValue; + class MemoryBuffer; + class TargetOptions; + class Value; +} + +//===----------------------------------------------------------------------===// +/// LTOModule - C++ class which implements the opaque lto_module_t type. +/// +struct LTOModule { +private: + typedef llvm::StringMap StringSet; + + struct NameAndAttributes { + const char *name; + uint32_t attributes; + bool isFunction; + const llvm::GlobalValue *symbol; + }; + + llvm::OwningPtr _module; + llvm::OwningPtr _target; + std::vector _symbols; + + // _defines and _undefines only needed to disambiguate tentative definitions + StringSet _defines; + llvm::StringMap _undefines; + std::vector _asm_undefines; + llvm::MCContext _context; + + // Use mangler to add GlobalPrefix to names to match linker names. + llvm::Mangler _mangler; + + LTOModule(llvm::Module *m, llvm::TargetMachine *t); +public: + /// isBitcodeFile - Returns 'true' if the file or memory contents is LLVM + /// bitcode. + static bool isBitcodeFile(const void *mem, size_t length); + static bool isBitcodeFile(const char *path); + + /// isBitcodeFileForTarget - Returns 'true' if the file or memory contents + /// is LLVM bitcode for the specified triple. + static bool isBitcodeFileForTarget(const void *mem, + size_t length, + const char *triplePrefix); + static bool isBitcodeFileForTarget(const char *path, + const char *triplePrefix); + + /// makeLTOModule - Create an LTOModule. N.B. These methods take ownership + /// of the buffer. The caller must have initialized the Targets, the + /// TargetMCs, the AsmPrinters, and the AsmParsers by calling: + /// + /// InitializeAllTargets(); + /// InitializeAllTargetMCs(); + /// InitializeAllAsmPrinters(); + /// InitializeAllAsmParsers(); + static LTOModule *makeLTOModule(const char* path, + std::string &errMsg); + static LTOModule *makeLTOModule(int fd, const char *path, + size_t size, std::string &errMsg); + static LTOModule *makeLTOModule(int fd, const char *path, + size_t map_size, + off_t offset, + std::string& errMsg); + static LTOModule *makeLTOModule(const void *mem, size_t length, + std::string &errMsg); + + /// getTargetTriple - Return the Module's target triple. + const char *getTargetTriple() { + return _module->getTargetTriple().c_str(); + } + + /// setTargetTriple - Set the Module's target triple. + void setTargetTriple(const char *triple) { + _module->setTargetTriple(triple); + } + + /// getSymbolCount - Get the number of symbols + uint32_t getSymbolCount() { + return _symbols.size(); + } + + /// getSymbolAttributes - Get the attributes for a symbol at the specified + /// index. + lto_symbol_attributes getSymbolAttributes(uint32_t index) { + if (index < _symbols.size()) + return lto_symbol_attributes(_symbols[index].attributes); + return lto_symbol_attributes(0); + } + + /// getSymbolName - Get the name of the symbol at the specified index. + const char *getSymbolName(uint32_t index) { + if (index < _symbols.size()) + return _symbols[index].name; + return NULL; + } + + /// getLLVVMModule - Return the Module. + llvm::Module *getLLVVMModule() { return _module.get(); } + + /// getAsmUndefinedRefs - + const std::vector &getAsmUndefinedRefs() { + return _asm_undefines; + } + + /// getTargetOptions - Fill the TargetOptions object with the options + /// specified on the command line. + static void getTargetOptions(llvm::TargetOptions &Options); + +private: + /// parseSymbols - Parse the symbols from the module and model-level ASM and + /// add them to either the defined or undefined lists. + bool parseSymbols(std::string &errMsg); + + /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet + /// to a list to be resolved later. + void addPotentialUndefinedSymbol(const llvm::GlobalValue *dcl, bool isFunc); + + /// addDefinedSymbol - Add a defined symbol to the list. + void addDefinedSymbol(const llvm::GlobalValue *def, bool isFunction); + + /// addDefinedFunctionSymbol - Add a function symbol as defined to the list. + void addDefinedFunctionSymbol(const llvm::Function *f); + + /// addDefinedDataSymbol - Add a data symbol as defined to the list. + void addDefinedDataSymbol(const llvm::GlobalValue *v); + + /// addAsmGlobalSymbols - Add global symbols from module-level ASM to the + /// defined or undefined lists. + bool addAsmGlobalSymbols(std::string &errMsg); + + /// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the + /// defined list. + void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope); + + /// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to + /// the undefined list. + void addAsmGlobalSymbolUndef(const char *); + + /// addObjCClass - Parse i386/ppc ObjC class data structure. + void addObjCClass(const llvm::GlobalVariable *clgv); + + /// addObjCCategory - Parse i386/ppc ObjC category data structure. + void addObjCCategory(const llvm::GlobalVariable *clgv); + + /// addObjCClassRef - Parse i386/ppc ObjC class list data structure. + void addObjCClassRef(const llvm::GlobalVariable *clgv); + + /// objcClassNameFromExpression - Get string that the data pointer points + /// to. + bool objcClassNameFromExpression(const llvm::Constant* c, std::string &name); + + /// isTargetMatch - Returns 'true' if the memory buffer is for the specified + /// target triple. + static bool isTargetMatch(llvm::MemoryBuffer *memBuffer, + const char *triplePrefix); + + /// makeLTOModule - Create an LTOModule (private version). N.B. This + /// method takes ownership of the buffer. + static LTOModule *makeLTOModule(llvm::MemoryBuffer *buffer, + std::string &errMsg); + + /// makeBuffer - Create a MemoryBuffer from a memory range. + static llvm::MemoryBuffer *makeBuffer(const void *mem, size_t length); +}; + +#endif // LTO_MODULE_H -- cgit v1.1