//===----------------------------------------------------------------------===//
#include "LTOModule.h"
-
#include "llvm/Constants.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
-
using namespace llvm;
+LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t)
+ : _module(m), _target(t),
+ _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL),
+ _mangler(_context, *_target->getTargetData()) {}
+
+/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
+/// bitcode.
bool LTOModule::isBitcodeFile(const void *mem, size_t length) {
return llvm::sys::IdentifyFileType((char*)mem, length)
== llvm::sys::Bitcode_FileType;
return llvm::sys::Path(path).isBitcodeFile();
}
+/// isBitcodeFileForTarget - Returns 'true' if the file (or memory contents) is
+/// LLVM bitcode for the specified triple.
bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length,
const char *triplePrefix) {
MemoryBuffer *buffer = makeBuffer(mem, length);
return isTargetMatch(buffer.take(), triplePrefix);
}
-// Takes ownership of buffer.
+/// isTargetMatch - Returns 'true' if the memory buffer is for the specified
+/// target triple.
bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) {
std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext());
delete buffer;
return strncmp(Triple.c_str(), triplePrefix, strlen(triplePrefix)) == 0;
}
-
-LTOModule::LTOModule(Module *m, TargetMachine *t)
- : _module(m), _target(t),
- _context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL),
- _mangler(_context, *_target->getTargetData())
-{
-}
-
-LTOModule *LTOModule::makeLTOModule(const char *path,
- std::string &errMsg) {
+/// makeLTOModule - Create an LTOModule. N.B. These methods take ownership of
+/// the buffer.
+LTOModule *LTOModule::makeLTOModule(const char *path, std::string &errMsg) {
OwningPtr<MemoryBuffer> buffer;
if (error_code ec = MemoryBuffer::getFile(path, buffer)) {
errMsg = ec.message();
return makeLTOModule(buffer.take(), errMsg);
}
-/// makeBuffer - Create a MemoryBuffer from a memory range.
-MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) {
- const char *startPtr = (char*)mem;
- return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false);
-}
-
LTOModule *LTOModule::makeLTOModule(const void *mem, size_t length,
std::string &errMsg) {
OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length));
return Ret;
}
-const char *LTOModule::getTargetTriple() {
- return _module->getTargetTriple().c_str();
-}
-
-void LTOModule::setTargetTriple(const char *triple) {
- _module->setTargetTriple(triple);
-}
-
-void LTOModule::addDefinedFunctionSymbol(Function *f) {
- // add to list of defined symbols
- addDefinedSymbol(f, true);
+/// makeBuffer - Create a MemoryBuffer from a memory range.
+MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) {
+ const char *startPtr = (char*)mem;
+ return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false);
}
-// Get string that data pointer points to.
+/// objcClassNameFromExpression - Get string that the data pointer points to.
bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) {
if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) {
Constant *op = ce->getOperand(0);
return false;
}
-// Parse i386/ppc ObjC class data structure.
+/// addObjCClass - Parse i386/ppc ObjC class data structure.
void LTOModule::addObjCClass(GlobalVariable *clgv) {
ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
if (!c) return;
}
}
-
-// Parse i386/ppc ObjC category data structure.
+/// addObjCCategory - Parse i386/ppc ObjC category data structure.
void LTOModule::addObjCCategory(GlobalVariable *clgv) {
ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer());
if (!c) return;
entry.setValue(info);
}
-
-// Parse i386/ppc ObjC class list data structure.
+/// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
void LTOModule::addObjCClassRef(GlobalVariable *clgv) {
std::string targetclassName;
if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName))
entry.setValue(info);
}
-
+/// addDefinedDataSymbol - Add a data symbol as defined to the list.
void LTOModule::addDefinedDataSymbol(GlobalValue *v) {
// Add to list of defined symbols.
addDefinedSymbol(v, false);
}
}
+/// addDefinedFunctionSymbol - Add a function symbol as defined to the list.
+void LTOModule::addDefinedFunctionSymbol(Function *f) {
+ // add to list of defined symbols
+ addDefinedSymbol(f, true);
+}
+
+/// addDefinedSymbol - Add a defined symbol to the list.
void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) {
// ignore all llvm.* symbols
if (def->getName().startswith("llvm."))
_symbols.push_back(info);
}
+/// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the
+/// defined list.
void LTOModule::addAsmGlobalSymbol(const char *name,
lto_symbol_attributes scope) {
StringSet::value_type &entry = _defines.GetOrCreateValue(name);
_symbols.push_back(info);
}
+/// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the
+/// undefined list.
void LTOModule::addAsmGlobalSymbolUndef(const char *name) {
StringMap<NameAndAttributes>::value_type &entry =
_undefines.GetOrCreateValue(name);
entry.setValue(info);
}
+/// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a
+/// list to be resolved later.
void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl) {
// ignore all llvm.* symbols
if (decl->getName().startswith("llvm."))
NameAndAttributes info;
info.name = entry.getKey().data();
+
if (decl->hasExternalWeakLinkage())
info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF;
else
};
}
+/// addAsmGlobalSymbols - Add global symbols from module-level ASM to the
+/// defined or undefined lists.
bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) {
const std::string &inlineAsm = _module->getModuleInlineAsm();
if (inlineAsm.empty())
return false;
}
+/// isDeclaration - Return 'true' if the global value is a declaration.
static bool isDeclaration(const GlobalValue &V) {
if (V.hasAvailableExternallyLinkage())
return true;
return V.isDeclaration();
}
+/// isAliasToDeclaration - Return 'true' if the global value is an alias to a
+/// declaration.
static bool isAliasToDeclaration(const GlobalAlias &V) {
return isDeclaration(*V.getAliasedGlobal());
}
+/// ParseSymbols - Parse the symbols from the module and model-level ASM and add
+/// them to either the defined or undefined lists.
bool LTOModule::ParseSymbols(std::string &errMsg) {
// add functions
for (Module::iterator f = _module->begin(); f != _module->end(); ++f) {
}
return false;
}
-
-uint32_t LTOModule::getSymbolCount() {
- return _symbols.size();
-}
-
-lto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) {
- if (index < _symbols.size())
- return _symbols[index].attributes;
- else
- return lto_symbol_attributes(0);
-}
-
-const char *LTOModule::getSymbolName(uint32_t index) {
- if (index < _symbols.size())
- return _symbols[index].name;
- else
- return NULL;
-}
// forward references to llvm classes
namespace llvm {
- class MemoryBuffer;
+ class Function;
class GlobalValue;
+ class MemoryBuffer;
class Value;
- class Function;
}
//
// C++ class which implements the opaque lto_module_t
//
struct LTOModule {
+private:
+ typedef llvm::StringMap<uint8_t> StringSet;
+
+ struct NameAndAttributes {
+ enum name_type { IsFunction, IsData };
+ const char* name;
+ lto_symbol_attributes attributes;
+ };
+
+ llvm::OwningPtr<llvm::Module> _module;
+ llvm::OwningPtr<llvm::TargetMachine> _target;
+ std::vector<NameAndAttributes> _symbols;
+
+ // _defines and _undefines only needed to disambiguate tentative definitions
+ StringSet _defines;
+ llvm::StringMap<NameAndAttributes> _undefines;
+ std::vector<const char*> _asm_undefines;
+ llvm::MCContext _context;
+
+ // Use mangler to add GlobalPrefix to names to match linker names.
+ llvm::Mangler _mangler;
- static bool isBitcodeFile(const void* mem, size_t length);
- static bool isBitcodeFile(const char* path);
- static bool isBitcodeFileForTarget(const void* mem,
+ 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);
+ 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.
static LTOModule* makeLTOModule(const char* path,
- std::string& errMsg);
+ std::string &errMsg);
static LTOModule* makeLTOModule(int fd, const char *path,
size_t size,
- std::string& errMsg);
+ std::string &errMsg);
static LTOModule* makeLTOModule(int fd, const char *path,
size_t file_size,
size_t map_size,
off_t offset,
std::string& errMsg);
- static LTOModule* makeLTOModule(const void* mem, size_t length,
- std::string& errMsg);
- const char* getTargetTriple();
- void setTargetTriple(const char*);
- uint32_t getSymbolCount();
- lto_symbol_attributes getSymbolAttributes(uint32_t index);
- const char* getSymbolName(uint32_t index);
+ 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 _symbols[index].attributes;
+ else
+ 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;
+ else
+ return NULL;
+ }
+
+ /// getLLVVMModule - Return the Module.
llvm::Module * getLLVVMModule() { return _module.get(); }
+
+ /// getAsmUndefinedRefs -
const std::vector<const char*> &getAsmUndefinedRefs() {
return _asm_undefines;
}
private:
- LTOModule(llvm::Module* m, llvm::TargetMachine* t);
-
+ /// 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);
- void addDefinedSymbol(llvm::GlobalValue* def,
+
+ /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet
+ /// to a list to be resolved later.
+ void addPotentialUndefinedSymbol(llvm::GlobalValue *dcl);
+
+ /// addDefinedSymbol - Add a defined symbol to the list.
+ void addDefinedSymbol(llvm::GlobalValue *def,
bool isFunction);
- void addPotentialUndefinedSymbol(llvm::GlobalValue* decl);
- void addDefinedFunctionSymbol(llvm::Function* f);
- void addDefinedDataSymbol(llvm::GlobalValue* v);
+
+ /// addDefinedFunctionSymbol - Add a function symbol as defined to the list.
+ void addDefinedFunctionSymbol(llvm::Function *f);
+
+ /// addDefinedDataSymbol - Add a data symbol as defined to the list.
+ void addDefinedDataSymbol(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 *);
- void addObjCClass(llvm::GlobalVariable* clgv);
- void addObjCCategory(llvm::GlobalVariable* clgv);
- void addObjCClassRef(llvm::GlobalVariable* clgv);
- bool objcClassNameFromExpression(llvm::Constant* c,
- std::string& name);
-
- static bool isTargetMatch(llvm::MemoryBuffer* memBuffer,
- const char* triplePrefix);
- static LTOModule* makeLTOModule(llvm::MemoryBuffer* buffer,
- std::string& errMsg);
- static llvm::MemoryBuffer* makeBuffer(const void* mem, size_t length);
- typedef llvm::StringMap<uint8_t> StringSet;
-
- struct NameAndAttributes {
- const char* name;
- lto_symbol_attributes attributes;
- };
+ /// addObjCClass - Parse i386/ppc ObjC class data structure.
+ void addObjCClass(llvm::GlobalVariable *clgv);
- llvm::OwningPtr<llvm::Module> _module;
- llvm::OwningPtr<llvm::TargetMachine> _target;
- std::vector<NameAndAttributes> _symbols;
+ /// addObjCCategory - Parse i386/ppc ObjC category data structure.
+ void addObjCCategory(llvm::GlobalVariable *clgv);
- // _defines and _undefines only needed to disambiguate tentative definitions
- StringSet _defines;
- llvm::StringMap<NameAndAttributes> _undefines;
- std::vector<const char*> _asm_undefines;
- llvm::MCContext _context;
+ /// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
+ void addObjCClassRef(llvm::GlobalVariable *clgv);
- // Use mangler to add GlobalPrefix to names to match linker names.
- llvm::Mangler _mangler;
+ /// objcClassNameFromExpression - Get string that the data pointer points
+ /// to.
+ bool objcClassNameFromExpression(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