166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===-LTOModule.h - LLVM Link Time Optimizer ------------------------------===//
266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//                     The LLVM Compiler Infrastructure
466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This file is distributed under the University of Illinois Open Source
666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// License. See LICENSE.TXT for details.
766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===//
966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
1066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This file declares the LTOModule class.
1166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
1266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===//
1366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#ifndef LTO_MODULE_H
1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#define LTO_MODULE_H
1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Module.h"
1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/OwningPtr.h"
1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Target/TargetMachine.h"
2066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/StringMap.h"
2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm-c/lto.h"
2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <vector>
2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <string>
2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// forward references to llvm classes
2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace llvm {
3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    class Mangler;
3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    class MemoryBuffer;
3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    class GlobalValue;
3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    class Value;
3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    class Function;
3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
3866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
3966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// C++ class which implements the opaque lto_module_t
4066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
4166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstruct LTOModule {
4266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
4366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static bool              isBitcodeFile(const void* mem, size_t length);
4466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static bool              isBitcodeFile(const char* path);
4566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
4666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static bool              isBitcodeFileForTarget(const void* mem,
4766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    size_t length, const char* triplePrefix);
4866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
4966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static bool              isBitcodeFileForTarget(const char* path,
5066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                    const char* triplePrefix);
5166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
5266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static LTOModule*        makeLTOModule(const char* path,
5366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                          std::string& errMsg);
5466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static LTOModule*        makeLTOModule(int fd, const char *path,
5566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           size_t size,
5666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           std::string& errMsg);
5766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static LTOModule*        makeLTOModule(int fd, const char *path,
5866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           size_t file_size,
5966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           size_t map_size,
6066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           off_t offset,
6166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           std::string& errMsg);
6266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static LTOModule*        makeLTOModule(const void* mem, size_t length,
6366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           std::string& errMsg);
6466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
6566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    const char*              getTargetTriple();
6666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                     setTargetTriple(const char*);
6766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    uint32_t                 getSymbolCount();
6866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    lto_symbol_attributes    getSymbolAttributes(uint32_t index);
6966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    const char*              getSymbolName(uint32_t index);
7066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
7166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    llvm::Module *           getLLVVMModule() { return _module.get(); }
7266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    const std::vector<const char*> &getAsmUndefinedRefs() {
7366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman            return _asm_undefines;
7466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
7566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
7666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanprivate:
7766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                            LTOModule(llvm::Module* m, llvm::TargetMachine* t);
7866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
7966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    bool                    ParseSymbols(std::string &errMsg);
8066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addDefinedSymbol(llvm::GlobalValue* def,
8166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                    llvm::Mangler& mangler,
8266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                    bool isFunction);
8366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addPotentialUndefinedSymbol(llvm::GlobalValue* decl,
8466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                        llvm::Mangler &mangler);
8566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addDefinedFunctionSymbol(llvm::Function* f,
8666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                        llvm::Mangler &mangler);
8766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addDefinedDataSymbol(llvm::GlobalValue* v,
8866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                        llvm::Mangler &mangler);
8966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    bool                    addAsmGlobalSymbols(llvm::MCContext &Context,
9066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                std::string &errMsg);
9166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addAsmGlobalSymbol(const char *,
9266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                               lto_symbol_attributes scope);
9366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addAsmGlobalSymbolUndef(const char *);
9466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addObjCClass(llvm::GlobalVariable* clgv);
9566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addObjCCategory(llvm::GlobalVariable* clgv);
9666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void                    addObjCClassRef(llvm::GlobalVariable* clgv);
9766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    bool                    objcClassNameFromExpression(llvm::Constant* c,
9866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                    std::string& name);
9966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
10066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static bool             isTargetMatch(llvm::MemoryBuffer* memBuffer,
10166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                    const char* triplePrefix);
10266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
10366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static LTOModule*       makeLTOModule(llvm::MemoryBuffer* buffer,
10466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                        std::string& errMsg);
10566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    static llvm::MemoryBuffer* makeBuffer(const void* mem, size_t length);
10666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
10766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    typedef llvm::StringMap<uint8_t> StringSet;
10866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
10966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    struct NameAndAttributes {
11066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        const char*            name;
11166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        lto_symbol_attributes  attributes;
11266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    };
11366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
11466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    llvm::OwningPtr<llvm::Module>           _module;
11566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    llvm::OwningPtr<llvm::TargetMachine>    _target;
11666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<NameAndAttributes>          _symbols;
11766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // _defines and _undefines only needed to disambiguate tentative definitions
11866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    StringSet                               _defines;
11966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    llvm::StringMap<NameAndAttributes>      _undefines;
12066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<const char*>                _asm_undefines;
12166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman};
12266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
12366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif // LTO_MODULE_H
12466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
125