mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Implement LTOModule on top of IRObjectFile.
IRObjectFile provides all the logic for producing mangled names and getting symbols from inline assembly. LTOModule then adds logic for linking specific tasks, like constructing llvm.compiler_user or extracting linker options from the bitcode. The rule of the thumb is that IRObjectFile has the functionality that is needed by both LTO and llvm-ar. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2291f8cf89
commit
1c9687eed2
@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
#include "llvm-c/lto.h"
|
#include "llvm-c/lto.h"
|
||||||
#include "llvm/ADT/StringMap.h"
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include "llvm/IR/Mangler.h"
|
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/MC/MCContext.h"
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/MC/MCObjectFileInfo.h"
|
#include "llvm/MC/MCObjectFileInfo.h"
|
||||||
|
#include "llvm/Object/IRObjectFile.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -46,9 +46,8 @@ private:
|
|||||||
const GlobalValue *symbol;
|
const GlobalValue *symbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Module> _module;
|
std::unique_ptr<object::IRObjectFile> IRFile;
|
||||||
std::unique_ptr<TargetMachine> _target;
|
std::unique_ptr<TargetMachine> _target;
|
||||||
MCObjectFileInfo ObjFileInfo;
|
|
||||||
StringSet _linkeropt_strings;
|
StringSet _linkeropt_strings;
|
||||||
std::vector<const char *> _deplibs;
|
std::vector<const char *> _deplibs;
|
||||||
std::vector<const char *> _linkeropts;
|
std::vector<const char *> _linkeropts;
|
||||||
@ -58,12 +57,8 @@ private:
|
|||||||
StringSet _defines;
|
StringSet _defines;
|
||||||
StringMap<NameAndAttributes> _undefines;
|
StringMap<NameAndAttributes> _undefines;
|
||||||
std::vector<const char*> _asm_undefines;
|
std::vector<const char*> _asm_undefines;
|
||||||
MCContext _context;
|
|
||||||
|
|
||||||
// Use mangler to add GlobalPrefix to names to match linker names.
|
LTOModule(std::unique_ptr<object::IRObjectFile> Obj, TargetMachine *TM);
|
||||||
Mangler _mangler;
|
|
||||||
|
|
||||||
LTOModule(std::unique_ptr<Module> M, TargetMachine *TM);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Returns 'true' if the file or memory contents is LLVM bitcode.
|
/// Returns 'true' if the file or memory contents is LLVM bitcode.
|
||||||
@ -100,14 +95,21 @@ public:
|
|||||||
TargetOptions options, std::string &errMsg,
|
TargetOptions options, std::string &errMsg,
|
||||||
StringRef path = "");
|
StringRef path = "");
|
||||||
|
|
||||||
|
const Module &getModule() const {
|
||||||
|
return const_cast<LTOModule*>(this)->getModule();
|
||||||
|
}
|
||||||
|
Module &getModule() {
|
||||||
|
return IRFile->getModule();
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the Module's target triple.
|
/// Return the Module's target triple.
|
||||||
const std::string &getTargetTriple() {
|
const std::string &getTargetTriple() {
|
||||||
return _module->getTargetTriple();
|
return getModule().getTargetTriple();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the Module's target triple.
|
/// Set the Module's target triple.
|
||||||
void setTargetTriple(StringRef Triple) {
|
void setTargetTriple(StringRef Triple) {
|
||||||
_module->setTargetTriple(Triple);
|
getModule().setTargetTriple(Triple);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of symbols
|
/// Get the number of symbols
|
||||||
@ -153,9 +155,6 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the Module.
|
|
||||||
Module *getLLVVMModule() { return _module.get(); }
|
|
||||||
|
|
||||||
const std::vector<const char*> &getAsmUndefinedRefs() {
|
const std::vector<const char*> &getAsmUndefinedRefs() {
|
||||||
return _asm_undefines;
|
return _asm_undefines;
|
||||||
}
|
}
|
||||||
@ -170,23 +169,20 @@ private:
|
|||||||
bool parseSymbols(std::string &errMsg);
|
bool parseSymbols(std::string &errMsg);
|
||||||
|
|
||||||
/// Add a symbol which isn't defined just yet to a list to be resolved later.
|
/// Add a symbol which isn't defined just yet to a list to be resolved later.
|
||||||
void addPotentialUndefinedSymbol(const GlobalValue *dcl, bool isFunc);
|
void addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym,
|
||||||
|
bool isFunc);
|
||||||
|
|
||||||
/// Add a defined symbol to the list.
|
/// Add a defined symbol to the list.
|
||||||
void addDefinedSymbol(const char *Name, const GlobalValue *Def,
|
void addDefinedSymbol(const char *Name, const GlobalValue *def,
|
||||||
bool IsFunction);
|
bool isFunction);
|
||||||
|
|
||||||
/// Add a function symbol as defined to the list.
|
|
||||||
void addDefinedFunctionSymbol(const Function *f);
|
|
||||||
void addDefinedFunctionSymbol(const char *Name, const Function *F);
|
|
||||||
|
|
||||||
/// Add a data symbol as defined to the list.
|
/// Add a data symbol as defined to the list.
|
||||||
void addDefinedDataSymbol(const GlobalValue *v);
|
void addDefinedDataSymbol(const object::BasicSymbolRef &Sym);
|
||||||
void addDefinedDataSymbol(const char *Name, const GlobalValue *V);
|
void addDefinedDataSymbol(const char*Name, const GlobalValue *v);
|
||||||
|
|
||||||
/// Add global symbols from module-level ASM to the defined or undefined
|
/// Add a function symbol as defined to the list.
|
||||||
/// lists.
|
void addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym);
|
||||||
bool addAsmGlobalSymbols(std::string &errMsg);
|
void addDefinedFunctionSymbol(const char *Name, const Function *F);
|
||||||
|
|
||||||
/// Add a global symbol from module-level ASM to the defined list.
|
/// Add a global symbol from module-level ASM to the defined list.
|
||||||
void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope);
|
void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope);
|
||||||
|
@ -28,8 +28,7 @@ class IRObjectFile : public SymbolicFile {
|
|||||||
std::vector<std::pair<std::string, uint32_t>> AsmSymbols;
|
std::vector<std::pair<std::string, uint32_t>> AsmSymbols;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IRObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC,
|
IRObjectFile(std::unique_ptr<MemoryBuffer> Object, std::unique_ptr<Module> M);
|
||||||
LLVMContext &Context);
|
|
||||||
~IRObjectFile();
|
~IRObjectFile();
|
||||||
void moveSymbolNext(DataRefImpl &Symb) const override;
|
void moveSymbolNext(DataRefImpl &Symb) const override;
|
||||||
std::error_code printSymbolName(raw_ostream &OS,
|
std::error_code printSymbolName(raw_ostream &OS,
|
||||||
@ -39,6 +38,13 @@ public:
|
|||||||
basic_symbol_iterator symbol_begin_impl() const override;
|
basic_symbol_iterator symbol_begin_impl() const override;
|
||||||
basic_symbol_iterator symbol_end_impl() const override;
|
basic_symbol_iterator symbol_end_impl() const override;
|
||||||
|
|
||||||
|
const Module &getModule() const {
|
||||||
|
return const_cast<IRObjectFile*>(this)->getModule();
|
||||||
|
}
|
||||||
|
Module &getModule() {
|
||||||
|
return *M;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool classof(const Binary *v) {
|
static inline bool classof(const Binary *v) {
|
||||||
return v->isIR();
|
return v->isIR();
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ void LTOCodeGenerator::initializeLTOPasses() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) {
|
bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) {
|
||||||
bool ret = IRLinker.linkInModule(mod->getLLVVMModule(), &errMsg);
|
bool ret = IRLinker.linkInModule(&mod->getModule(), &errMsg);
|
||||||
|
|
||||||
const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
|
const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
|
||||||
for (int i = 0, e = undefs.size(); i != e; ++i)
|
for (int i = 0, e = undefs.size(); i != e; ++i)
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "llvm/MC/MCSymbol.h"
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/MC/MCTargetAsmParser.h"
|
#include "llvm/MC/MCTargetAsmParser.h"
|
||||||
#include "llvm/MC/SubtargetFeature.h"
|
#include "llvm/MC/SubtargetFeature.h"
|
||||||
#include "llvm/Object/RecordStreamer.h"
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
#include "llvm/Support/Host.h"
|
#include "llvm/Support/Host.h"
|
||||||
@ -44,15 +43,9 @@
|
|||||||
#include <system_error>
|
#include <system_error>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
LTOModule::LTOModule(std::unique_ptr<Module> M, TargetMachine *TM)
|
LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
|
||||||
: _module(std::move(M)), _target(TM),
|
llvm::TargetMachine *TM)
|
||||||
_context(_target->getMCAsmInfo(), _target->getRegisterInfo(),
|
: IRFile(std::move(Obj)), _target(TM) {}
|
||||||
&ObjFileInfo),
|
|
||||||
_mangler(TM->getDataLayout()) {
|
|
||||||
ObjFileInfo.InitMCObjectFileInfo(TM->getTargetTriple(),
|
|
||||||
TM->getRelocationModel(), TM->getCodeModel(),
|
|
||||||
_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
|
/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
|
||||||
/// bitcode.
|
/// bitcode.
|
||||||
@ -115,17 +108,15 @@ LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length,
|
|||||||
LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
|
LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
|
||||||
TargetOptions options,
|
TargetOptions options,
|
||||||
std::string &errMsg) {
|
std::string &errMsg) {
|
||||||
// parse bitcode buffer
|
ErrorOr<Module *> MOrErr =
|
||||||
ErrorOr<Module *> ModuleOrErr =
|
|
||||||
getLazyBitcodeModule(Buffer.get(), getGlobalContext());
|
getLazyBitcodeModule(Buffer.get(), getGlobalContext());
|
||||||
if (std::error_code EC = ModuleOrErr.getError()) {
|
if (std::error_code EC = MOrErr.getError()) {
|
||||||
errMsg = EC.message();
|
errMsg = EC.message();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Buffer.release();
|
std::unique_ptr<Module> M(MOrErr.get());
|
||||||
std::unique_ptr<Module> m(ModuleOrErr.get());
|
|
||||||
|
|
||||||
std::string TripleStr = m->getTargetTriple();
|
std::string TripleStr = M->getTargetTriple();
|
||||||
if (TripleStr.empty())
|
if (TripleStr.empty())
|
||||||
TripleStr = sys::getDefaultTargetTriple();
|
TripleStr = sys::getDefaultTargetTriple();
|
||||||
llvm::Triple Triple(TripleStr);
|
llvm::Triple Triple(TripleStr);
|
||||||
@ -153,18 +144,13 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
|
|||||||
|
|
||||||
TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr,
|
TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr,
|
||||||
options);
|
options);
|
||||||
m->materializeAllPermanently();
|
M->materializeAllPermanently(true);
|
||||||
|
M->setDataLayout(target->getDataLayout());
|
||||||
|
|
||||||
LTOModule *Ret = new LTOModule(std::move(m), target);
|
std::unique_ptr<object::IRObjectFile> IRObj(
|
||||||
|
new object::IRObjectFile(std::move(Buffer), std::move(M)));
|
||||||
|
|
||||||
// We need a MCContext set up in order to get mangled names of private
|
LTOModule *Ret = new LTOModule(std::move(IRObj), target);
|
||||||
// symbols. It is a bit odd that we need to report uses and definitions
|
|
||||||
// of private symbols, but it does look like ld64 expects to be informed
|
|
||||||
// of at least the ones with an 'l' prefix.
|
|
||||||
MCContext &Context = Ret->_context;
|
|
||||||
const TargetLoweringObjectFile &TLOF =
|
|
||||||
target->getTargetLowering()->getObjFileLowering();
|
|
||||||
const_cast<TargetLoweringObjectFile &>(TLOF).Initialize(Context, *target);
|
|
||||||
|
|
||||||
if (Ret->parseSymbols(errMsg)) {
|
if (Ret->parseSymbols(errMsg)) {
|
||||||
delete Ret;
|
delete Ret;
|
||||||
@ -283,9 +269,14 @@ void LTOModule::addObjCClassRef(const GlobalVariable *clgv) {
|
|||||||
entry.setValue(info);
|
entry.setValue(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LTOModule::addDefinedDataSymbol(const GlobalValue *V) {
|
void LTOModule::addDefinedDataSymbol(const object::BasicSymbolRef &Sym) {
|
||||||
SmallString<64> Buffer;
|
SmallString<64> Buffer;
|
||||||
_target->getNameWithPrefix(Buffer, V, _mangler);
|
{
|
||||||
|
raw_svector_ostream OS(Buffer);
|
||||||
|
Sym.printName(OS);
|
||||||
|
}
|
||||||
|
|
||||||
|
const GlobalValue *V = IRFile->getSymbolGV(Sym.getRawDataRefImpl());
|
||||||
addDefinedDataSymbol(Buffer.c_str(), V);
|
addDefinedDataSymbol(Buffer.c_str(), V);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,9 +330,15 @@ void LTOModule::addDefinedDataSymbol(const char *Name, const GlobalValue *v) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LTOModule::addDefinedFunctionSymbol(const Function *F) {
|
void LTOModule::addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym) {
|
||||||
SmallString<64> Buffer;
|
SmallString<64> Buffer;
|
||||||
_target->getNameWithPrefix(Buffer, F, _mangler);
|
{
|
||||||
|
raw_svector_ostream OS(Buffer);
|
||||||
|
Sym.printName(OS);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Function *F =
|
||||||
|
cast<Function>(IRFile->getSymbolGV(Sym.getRawDataRefImpl()));
|
||||||
addDefinedFunctionSymbol(Buffer.c_str(), F);
|
addDefinedFunctionSymbol(Buffer.c_str(), F);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,10 +373,6 @@ static bool canBeHidden(const GlobalValue *GV) {
|
|||||||
|
|
||||||
void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def,
|
void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def,
|
||||||
bool isFunction) {
|
bool isFunction) {
|
||||||
// ignore all llvm.* symbols
|
|
||||||
if (def->getName().startswith("llvm."))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// set alignment part log2() can have rounding errors
|
// set alignment part log2() can have rounding errors
|
||||||
uint32_t align = def->getAlignment();
|
uint32_t align = def->getAlignment();
|
||||||
uint32_t attr = align ? countTrailingZeros(align) : 0;
|
uint32_t attr = align ? countTrailingZeros(align) : 0;
|
||||||
@ -499,20 +492,14 @@ void LTOModule::addAsmGlobalSymbolUndef(const char *name) {
|
|||||||
entry.setValue(info);
|
entry.setValue(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a
|
/// Add a symbol which isn't defined just yet to a list to be resolved later.
|
||||||
/// list to be resolved later.
|
void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym,
|
||||||
void
|
bool isFunc) {
|
||||||
LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) {
|
|
||||||
// ignore all llvm.* symbols
|
|
||||||
if (decl->getName().startswith("llvm."))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// ignore all aliases
|
|
||||||
if (isa<GlobalAlias>(decl))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SmallString<64> name;
|
SmallString<64> name;
|
||||||
_target->getNameWithPrefix(name, decl, _mangler);
|
{
|
||||||
|
raw_svector_ostream OS(name);
|
||||||
|
Sym.printName(OS);
|
||||||
|
}
|
||||||
|
|
||||||
StringMap<NameAndAttributes>::value_type &entry =
|
StringMap<NameAndAttributes>::value_type &entry =
|
||||||
_undefines.GetOrCreateValue(name);
|
_undefines.GetOrCreateValue(name);
|
||||||
@ -525,6 +512,8 @@ LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) {
|
|||||||
|
|
||||||
info.name = entry.getKey().data();
|
info.name = entry.getKey().data();
|
||||||
|
|
||||||
|
const GlobalValue *decl = IRFile->getSymbolGV(Sym.getRawDataRefImpl());
|
||||||
|
|
||||||
if (decl->hasExternalWeakLinkage())
|
if (decl->hasExternalWeakLinkage())
|
||||||
info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF;
|
info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF;
|
||||||
else
|
else
|
||||||
@ -536,90 +525,50 @@ LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) {
|
|||||||
entry.setValue(info);
|
entry.setValue(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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;
|
|
||||||
|
|
||||||
std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(_context));
|
|
||||||
MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm);
|
|
||||||
SourceMgr SrcMgr;
|
|
||||||
SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
|
|
||||||
std::unique_ptr<MCAsmParser> Parser(
|
|
||||||
createMCAsmParser(SrcMgr, _context, *Streamer, *_target->getMCAsmInfo()));
|
|
||||||
const Target &T = _target->getTarget();
|
|
||||||
std::unique_ptr<MCInstrInfo> MCII(T.createMCInstrInfo());
|
|
||||||
std::unique_ptr<MCSubtargetInfo> STI(T.createMCSubtargetInfo(
|
|
||||||
_target->getTargetTriple(), _target->getTargetCPU(),
|
|
||||||
_target->getTargetFeatureString()));
|
|
||||||
std::unique_ptr<MCTargetAsmParser> TAP(
|
|
||||||
T.createMCAsmParser(*STI, *Parser.get(), *MCII,
|
|
||||||
_target->Options.MCOptions));
|
|
||||||
if (!TAP) {
|
|
||||||
errMsg = "target " + std::string(T.getName()) +
|
|
||||||
" does not define AsmParser.";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Parser->setTargetParser(*TAP);
|
|
||||||
if (Parser->Run(false))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto &KV : *Streamer) {
|
|
||||||
StringRef Key = KV.first();
|
|
||||||
RecordStreamer::State Value = KV.second;
|
|
||||||
if (Value == RecordStreamer::DefinedGlobal)
|
|
||||||
addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_DEFAULT);
|
|
||||||
else if (Value == RecordStreamer::Defined)
|
|
||||||
addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_INTERNAL);
|
|
||||||
else if (Value == RecordStreamer::Global ||
|
|
||||||
Value == RecordStreamer::Used)
|
|
||||||
addAsmGlobalSymbolUndef(Key.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// isDeclaration - Return 'true' if the global value is a declaration.
|
|
||||||
static bool isDeclaration(const GlobalValue &V) {
|
|
||||||
if (V.hasAvailableExternallyLinkage())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (V.isMaterializable())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return V.isDeclaration();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// parseSymbols - Parse the symbols from the module and model-level ASM and add
|
/// parseSymbols - Parse the symbols from the module and model-level ASM and add
|
||||||
/// them to either the defined or undefined lists.
|
/// them to either the defined or undefined lists.
|
||||||
bool LTOModule::parseSymbols(std::string &errMsg) {
|
bool LTOModule::parseSymbols(std::string &errMsg) {
|
||||||
// add functions
|
for (auto &Sym : IRFile->symbols()) {
|
||||||
for (Module::iterator f = _module->begin(), e = _module->end(); f != e; ++f) {
|
const GlobalValue *GV = IRFile->getSymbolGV(Sym.getRawDataRefImpl());
|
||||||
if (isDeclaration(*f))
|
uint32_t Flags = Sym.getFlags();
|
||||||
addPotentialUndefinedSymbol(f, true);
|
bool IsUndefined = Flags & object::BasicSymbolRef::SF_Undefined;
|
||||||
|
|
||||||
|
if (!GV) {
|
||||||
|
SmallString<64> Buffer;
|
||||||
|
{
|
||||||
|
raw_svector_ostream OS(Buffer);
|
||||||
|
Sym.printName(OS);
|
||||||
|
}
|
||||||
|
const char *Name = Buffer.c_str();
|
||||||
|
|
||||||
|
if (IsUndefined)
|
||||||
|
addAsmGlobalSymbolUndef(Name);
|
||||||
|
else if (Flags & object::BasicSymbolRef::SF_Global)
|
||||||
|
addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_DEFAULT);
|
||||||
else
|
else
|
||||||
addDefinedFunctionSymbol(f);
|
addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_INTERNAL);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add data
|
auto *F = dyn_cast<Function>(GV);
|
||||||
for (Module::global_iterator v = _module->global_begin(),
|
if (IsUndefined) {
|
||||||
e = _module->global_end(); v != e; ++v) {
|
addPotentialUndefinedSymbol(Sym, F != nullptr);
|
||||||
if (isDeclaration(*v))
|
continue;
|
||||||
addPotentialUndefinedSymbol(v, false);
|
|
||||||
else
|
|
||||||
addDefinedDataSymbol(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add asm globals
|
if (F) {
|
||||||
if (addAsmGlobalSymbols(errMsg))
|
addDefinedFunctionSymbol(Sym);
|
||||||
return true;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// add aliases
|
if (isa<GlobalVariable>(GV)) {
|
||||||
for (const auto &Alias : _module->aliases())
|
addDefinedDataSymbol(Sym);
|
||||||
addDefinedDataSymbol(&Alias);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(isa<GlobalAlias>(GV));
|
||||||
|
addDefinedDataSymbol(Sym);
|
||||||
|
}
|
||||||
|
|
||||||
// make symbols for all undefines
|
// make symbols for all undefines
|
||||||
for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(),
|
for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(),
|
||||||
@ -637,7 +586,7 @@ bool LTOModule::parseSymbols(std::string &errMsg) {
|
|||||||
/// parseMetadata - Parse metadata from the module
|
/// parseMetadata - Parse metadata from the module
|
||||||
void LTOModule::parseMetadata() {
|
void LTOModule::parseMetadata() {
|
||||||
// Linker Options
|
// Linker Options
|
||||||
if (Value *Val = _module->getModuleFlag("Linker Options")) {
|
if (Value *Val = getModule().getModuleFlag("Linker Options")) {
|
||||||
MDNode *LinkerOptions = cast<MDNode>(Val);
|
MDNode *LinkerOptions = cast<MDNode>(Val);
|
||||||
for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
|
||||||
MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
|
MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
|
||||||
|
@ -33,14 +33,8 @@ using namespace llvm;
|
|||||||
using namespace object;
|
using namespace object;
|
||||||
|
|
||||||
IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object,
|
IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object,
|
||||||
std::error_code &EC, LLVMContext &Context)
|
std::unique_ptr<Module> Mod)
|
||||||
: SymbolicFile(Binary::ID_IR, std::move(Object)) {
|
: SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) {
|
||||||
ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Data.get(), Context);
|
|
||||||
if ((EC = MOrErr.getError()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
M.reset(MOrErr.get());
|
|
||||||
|
|
||||||
// If we have a DataLayout, setup a mangler.
|
// If we have a DataLayout, setup a mangler.
|
||||||
const DataLayout *DL = M->getDataLayout();
|
const DataLayout *DL = M->getDataLayout();
|
||||||
if (!DL)
|
if (!DL)
|
||||||
@ -119,7 +113,11 @@ IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IRObjectFile::~IRObjectFile() { M->getMaterializer()->releaseBuffer(); }
|
IRObjectFile::~IRObjectFile() {
|
||||||
|
GVMaterializer *GVM = M->getMaterializer();
|
||||||
|
if (GVM)
|
||||||
|
GVM->releaseBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
static const GlobalValue *getGV(DataRefImpl &Symb) {
|
static const GlobalValue *getGV(DataRefImpl &Symb) {
|
||||||
if ((Symb.p & 3) == 3)
|
if ((Symb.p & 3) == 3)
|
||||||
@ -275,10 +273,10 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const {
|
|||||||
|
|
||||||
ErrorOr<IRObjectFile *> llvm::object::IRObjectFile::createIRObjectFile(
|
ErrorOr<IRObjectFile *> llvm::object::IRObjectFile::createIRObjectFile(
|
||||||
std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context) {
|
std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context) {
|
||||||
std::error_code EC;
|
ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Object.get(), Context);
|
||||||
std::unique_ptr<IRObjectFile> Ret(
|
if (std::error_code EC = MOrErr.getError())
|
||||||
new IRObjectFile(std::move(Object), EC, Context));
|
|
||||||
if (EC)
|
|
||||||
return EC;
|
return EC;
|
||||||
return Ret.release();
|
|
||||||
|
std::unique_ptr<Module> M(MOrErr.get());
|
||||||
|
return new IRObjectFile(std::move(Object), std::move(M));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user