summaryrefslogtreecommitdiffstats
path: root/lib/LTO/LTOModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/LTO/LTOModule.cpp')
-rw-r--r--lib/LTO/LTOModule.cpp233
1 files changed, 126 insertions, 107 deletions
diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp
index 844c0f2..4108ef2 100644
--- a/lib/LTO/LTOModule.cpp
+++ b/lib/LTO/LTOModule.cpp
@@ -15,6 +15,7 @@
#include "llvm/LTO/LTOModule.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/CodeGen/Analysis.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
@@ -28,6 +29,8 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
@@ -39,32 +42,51 @@
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Transforms/Utils/GlobalStatus.h"
#include <system_error>
using namespace llvm;
+using namespace llvm::object;
LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
llvm::TargetMachine *TM)
: IRFile(std::move(Obj)), _target(TM) {}
+LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
+ llvm::TargetMachine *TM,
+ std::unique_ptr<LLVMContext> Context)
+ : OwnedContext(std::move(Context)), IRFile(std::move(Obj)), _target(TM) {}
+
+LTOModule::~LTOModule() {}
+
/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
/// bitcode.
-bool LTOModule::isBitcodeFile(const void *mem, size_t length) {
- return sys::fs::identify_magic(StringRef((const char *)mem, length)) ==
- sys::fs::file_magic::bitcode;
+bool LTOModule::isBitcodeFile(const void *Mem, size_t Length) {
+ ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer(
+ MemoryBufferRef(StringRef((const char *)Mem, Length), "<mem>"));
+ return bool(BCData);
}
-bool LTOModule::isBitcodeFile(const char *path) {
- sys::fs::file_magic type;
- if (sys::fs::identify_magic(path, type))
+bool LTOModule::isBitcodeFile(const char *Path) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
+ MemoryBuffer::getFile(Path);
+ if (!BufferOrErr)
return false;
- return type == sys::fs::file_magic::bitcode;
+
+ ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInMemBuffer(
+ BufferOrErr.get()->getMemBufferRef());
+ return bool(BCData);
}
-bool LTOModule::isBitcodeForTarget(MemoryBuffer *buffer,
- StringRef triplePrefix) {
- std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext());
- return StringRef(Triple).startswith(triplePrefix);
+bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer,
+ StringRef TriplePrefix) {
+ ErrorOr<MemoryBufferRef> BCOrErr =
+ IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef());
+ if (!BCOrErr)
+ return false;
+ LLVMContext Context;
+ std::string Triple = getBitcodeTargetTriple(*BCOrErr, Context);
+ return StringRef(Triple).startswith(TriplePrefix);
}
LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options,
@@ -75,7 +97,9 @@ LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options,
errMsg = EC.message();
return nullptr;
}
- return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg);
+ std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
+ return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg,
+ &getGlobalContext());
}
LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size,
@@ -94,23 +118,50 @@ LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path,
errMsg = EC.message();
return nullptr;
}
- return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg);
+ std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
+ return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg,
+ &getGlobalContext());
}
LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length,
TargetOptions options,
std::string &errMsg, StringRef path) {
- std::unique_ptr<MemoryBuffer> buffer(makeBuffer(mem, length, path));
- if (!buffer)
- return nullptr;
- return makeLTOModule(std::move(buffer), options, errMsg);
+ return createInContext(mem, length, options, errMsg, path,
+ &getGlobalContext());
+}
+
+LTOModule *LTOModule::createInLocalContext(const void *mem, size_t length,
+ TargetOptions options,
+ std::string &errMsg,
+ StringRef path) {
+ return createInContext(mem, length, options, errMsg, path, nullptr);
}
-LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
- TargetOptions options,
- std::string &errMsg) {
- ErrorOr<Module *> MOrErr =
- getLazyBitcodeModule(Buffer.get(), getGlobalContext());
+LTOModule *LTOModule::createInContext(const void *mem, size_t length,
+ TargetOptions options,
+ std::string &errMsg, StringRef path,
+ LLVMContext *Context) {
+ StringRef Data((const char *)mem, length);
+ MemoryBufferRef Buffer(Data, path);
+ return makeLTOModule(Buffer, options, errMsg, Context);
+}
+
+LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer,
+ TargetOptions options, std::string &errMsg,
+ LLVMContext *Context) {
+ std::unique_ptr<LLVMContext> OwnedContext;
+ if (!Context) {
+ OwnedContext = llvm::make_unique<LLVMContext>();
+ Context = OwnedContext.get();
+ }
+
+ ErrorOr<MemoryBufferRef> MBOrErr =
+ IRObjectFile::findBitcodeInMemBuffer(Buffer);
+ if (std::error_code EC = MBOrErr.getError()) {
+ errMsg = EC.message();
+ return nullptr;
+ }
+ ErrorOr<Module *> MOrErr = parseBitcodeFile(*MBOrErr, *Context);
if (std::error_code EC = MOrErr.getError()) {
errMsg = EC.message();
return nullptr;
@@ -138,20 +189,22 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
CPU = "core2";
else if (Triple.getArch() == llvm::Triple::x86)
CPU = "yonah";
- else if (Triple.getArch() == llvm::Triple::arm64 ||
- Triple.getArch() == llvm::Triple::aarch64)
+ else if (Triple.getArch() == llvm::Triple::aarch64)
CPU = "cyclone";
}
TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr,
options);
- M->materializeAllPermanently(true);
- M->setDataLayout(target->getDataLayout());
+ M->setDataLayout(target->getSubtargetImpl()->getDataLayout());
std::unique_ptr<object::IRObjectFile> IRObj(
- new object::IRObjectFile(std::move(Buffer), std::move(M)));
+ new object::IRObjectFile(Buffer, std::move(M)));
- LTOModule *Ret = new LTOModule(std::move(IRObj), target);
+ LTOModule *Ret;
+ if (OwnedContext)
+ Ret = new LTOModule(std::move(IRObj), target, std::move(OwnedContext));
+ else
+ Ret = new LTOModule(std::move(IRObj), target);
if (Ret->parseSymbols(errMsg)) {
delete Ret;
@@ -164,8 +217,8 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr<MemoryBuffer> Buffer,
}
/// Create a MemoryBuffer from a memory range with an optional name.
-MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length,
- StringRef name) {
+std::unique_ptr<MemoryBuffer>
+LTOModule::makeBuffer(const void *mem, size_t length, StringRef name) {
const char *startPtr = (const char*)mem;
return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false);
}
@@ -196,27 +249,24 @@ void LTOModule::addObjCClass(const GlobalVariable *clgv) {
// second slot in __OBJC,__class is pointer to superclass name
std::string superclassName;
if (objcClassNameFromExpression(c->getOperand(1), superclassName)) {
- NameAndAttributes info;
- StringMap<NameAndAttributes>::value_type &entry =
- _undefines.GetOrCreateValue(superclassName);
- if (!entry.getValue().name) {
- const char *symbolName = entry.getKey().data();
- info.name = symbolName;
+ auto IterBool =
+ _undefines.insert(std::make_pair(superclassName, NameAndAttributes()));
+ if (IterBool.second) {
+ NameAndAttributes &info = IterBool.first->second;
+ info.name = IterBool.first->first().data();
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
info.isFunction = false;
info.symbol = clgv;
- entry.setValue(info);
}
}
// third slot in __OBJC,__class is pointer to class name
std::string className;
if (objcClassNameFromExpression(c->getOperand(2), className)) {
- StringSet::value_type &entry = _defines.GetOrCreateValue(className);
- entry.setValue(1);
+ auto Iter = _defines.insert(className).first;
NameAndAttributes info;
- info.name = entry.getKey().data();
+ info.name = Iter->first().data();
info.attributes = LTO_SYMBOL_PERMISSIONS_DATA |
LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT;
info.isFunction = false;
@@ -235,19 +285,17 @@ void LTOModule::addObjCCategory(const GlobalVariable *clgv) {
if (!objcClassNameFromExpression(c->getOperand(1), targetclassName))
return;
- NameAndAttributes info;
- StringMap<NameAndAttributes>::value_type &entry =
- _undefines.GetOrCreateValue(targetclassName);
+ auto IterBool =
+ _undefines.insert(std::make_pair(targetclassName, NameAndAttributes()));
- if (entry.getValue().name)
+ if (!IterBool.second)
return;
- const char *symbolName = entry.getKey().data();
- info.name = symbolName;
+ NameAndAttributes &info = IterBool.first->second;
+ info.name = IterBool.first->first().data();
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
info.isFunction = false;
info.symbol = clgv;
- entry.setValue(info);
}
/// addObjCClassRef - Parse i386/ppc ObjC class list data structure.
@@ -256,18 +304,17 @@ void LTOModule::addObjCClassRef(const GlobalVariable *clgv) {
if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName))
return;
- NameAndAttributes info;
- StringMap<NameAndAttributes>::value_type &entry =
- _undefines.GetOrCreateValue(targetclassName);
- if (entry.getValue().name)
+ auto IterBool =
+ _undefines.insert(std::make_pair(targetclassName, NameAndAttributes()));
+
+ if (!IterBool.second)
return;
- const char *symbolName = entry.getKey().data();
- info.name = symbolName;
+ NameAndAttributes &info = IterBool.first->second;
+ info.name = IterBool.first->first().data();
info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED;
info.isFunction = false;
info.symbol = clgv;
- entry.setValue(info);
}
void LTOModule::addDefinedDataSymbol(const object::BasicSymbolRef &Sym) {
@@ -348,30 +395,6 @@ void LTOModule::addDefinedFunctionSymbol(const char *Name, const Function *F) {
addDefinedSymbol(Name, F, true);
}
-static bool canBeHidden(const GlobalValue *GV) {
- // FIXME: this is duplicated with another static function in AsmPrinter.cpp
- GlobalValue::LinkageTypes L = GV->getLinkage();
-
- if (L != GlobalValue::LinkOnceODRLinkage)
- return false;
-
- if (GV->hasUnnamedAddr())
- return true;
-
- // If it is a non constant variable, it needs to be uniqued across shared
- // objects.
- if (const GlobalVariable *Var = dyn_cast<GlobalVariable>(GV)) {
- if (!Var->isConstant())
- return false;
- }
-
- GlobalStatus GS;
- if (GlobalStatus::analyzeGlobal(GV, GS))
- return false;
-
- return !GS.IsCompared;
-}
-
void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def,
bool isFunction) {
// set alignment part log2() can have rounding errors
@@ -405,17 +428,16 @@ void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def,
attr |= LTO_SYMBOL_SCOPE_HIDDEN;
else if (def->hasProtectedVisibility())
attr |= LTO_SYMBOL_SCOPE_PROTECTED;
- else if (canBeHidden(def))
+ else if (canBeOmittedFromSymbolTable(def))
attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
else
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
- StringSet::value_type &entry = _defines.GetOrCreateValue(Name);
- entry.setValue(1);
+ auto Iter = _defines.insert(Name).first;
// fill information structure
NameAndAttributes info;
- StringRef NameRef = entry.getKey();
+ StringRef NameRef = Iter->first();
info.name = NameRef.data();
assert(info.name[NameRef.size()] == '\0');
info.attributes = attr;
@@ -430,15 +452,13 @@ void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def,
/// defined list.
void LTOModule::addAsmGlobalSymbol(const char *name,
lto_symbol_attributes scope) {
- StringSet::value_type &entry = _defines.GetOrCreateValue(name);
+ auto IterBool = _defines.insert(name);
// only add new define if not already defined
- if (entry.getValue())
+ if (!IterBool.second)
return;
- entry.setValue(1);
-
- NameAndAttributes &info = _undefines[entry.getKey().data()];
+ NameAndAttributes &info = _undefines[IterBool.first->first().data()];
if (info.symbol == nullptr) {
// FIXME: This is trying to take care of module ASM like this:
@@ -450,7 +470,7 @@ void LTOModule::addAsmGlobalSymbol(const char *name,
// much.
// fill information structure
- info.name = entry.getKey().data();
+ info.name = IterBool.first->first().data();
info.attributes =
LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope;
info.isFunction = false;
@@ -473,24 +493,21 @@ void LTOModule::addAsmGlobalSymbol(const char *name,
/// 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);
+ auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes()));
- _asm_undefines.push_back(entry.getKey().data());
+ _asm_undefines.push_back(IterBool.first->first().data());
// we already have the symbol
- if (entry.getValue().name)
+ if (!IterBool.second)
return;
uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED;
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
- NameAndAttributes info;
- info.name = entry.getKey().data();
+ NameAndAttributes &info = IterBool.first->second;
+ info.name = IterBool.first->first().data();
info.attributes = attr;
info.isFunction = false;
info.symbol = nullptr;
-
- entry.setValue(info);
}
/// Add a symbol which isn't defined just yet to a list to be resolved later.
@@ -502,16 +519,15 @@ void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym,
Sym.printName(OS);
}
- StringMap<NameAndAttributes>::value_type &entry =
- _undefines.GetOrCreateValue(name);
+ auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes()));
// we already have the symbol
- if (entry.getValue().name)
+ if (!IterBool.second)
return;
- NameAndAttributes info;
+ NameAndAttributes &info = IterBool.first->second;
- info.name = entry.getKey().data();
+ info.name = IterBool.first->first().data();
const GlobalValue *decl = IRFile->getSymbolGV(Sym.getRawDataRefImpl());
@@ -522,8 +538,6 @@ void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym,
info.isFunction = isFunc;
info.symbol = decl;
-
- entry.setValue(info);
}
/// parseSymbols - Parse the symbols from the module and model-level ASM and add
@@ -596,10 +610,15 @@ void LTOModule::parseMetadata() {
MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i));
for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) {
MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii));
- StringRef Op = _linkeropt_strings.
- GetOrCreateValue(MDOption->getString()).getKey();
- StringRef DepLibName = _target->getTargetLowering()->
- getObjFileLowering().getDepLibFromLinkerOpt(Op);
+ // FIXME: Make StringSet::insert match Self-Associative Container
+ // requirements, returning <iter,bool> rather than bool, and use that
+ // here.
+ StringRef Op =
+ _linkeropt_strings.insert(MDOption->getString()).first->first();
+ StringRef DepLibName = _target->getSubtargetImpl()
+ ->getTargetLowering()
+ ->getObjFileLowering()
+ .getDepLibFromLinkerOpt(Op);
if (!DepLibName.empty())
_deplibs.push_back(DepLibName.data());
else if (!Op.empty())