#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Transforms/Utils/GlobalStatus.h"
using namespace llvm;
LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t)
: _module(m), _target(t),
- _context(_target->getMCAsmInfo(), _target->getRegisterInfo(), NULL),
- _mangler(_context, t) {}
+ _context(_target->getMCAsmInfo(), _target->getRegisterInfo(), &ObjFileInfo),
+ _mangler(t->getDataLayout()) {
+ ObjFileInfo.InitMCObjectFileInfo(t->getTargetTriple(),
+ t->getRelocationModel(), t->getCodeModel(),
+ _context);
+}
/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
/// bitcode.
TargetOptions options,
std::string &errMsg) {
// parse bitcode buffer
- OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext(),
- &errMsg));
- if (!m) {
+ ErrorOr<Module *> ModuleOrErr =
+ getLazyBitcodeModule(buffer, getGlobalContext());
+ if (error_code EC = ModuleOrErr.getError()) {
+ errMsg = EC.message();
delete buffer;
return NULL;
}
+ OwningPtr<Module> m(ModuleOrErr.get());
std::string TripleStr = m->getTargetTriple();
if (TripleStr.empty())
TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr,
options);
+ m->materializeAllPermanently();
+
LTOModule *Ret = new LTOModule(m.take(), target);
if (Ret->parseSymbols(errMsg)) {
delete Ret;
return NULL;
}
+ Ret->parseMetadata();
+
return Ret;
}
addDefinedSymbol(f, true);
}
+static bool canBeHidden(const GlobalValue *GV) {
+ GlobalValue::LinkageTypes L = GV->getLinkage();
+
+ if (L != GlobalValue::LinkOnceODRLinkage)
+ return false;
+
+ if (GV->hasUnnamedAddr())
+ return true;
+
+ GlobalStatus GS;
+ if (GlobalStatus::analyzeGlobal(GV, GS))
+ return false;
+
+ return !GS.IsCompared;
+}
+
/// addDefinedSymbol - Add a defined symbol to the list.
void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) {
// ignore all llvm.* symbols
// string is owned by _defines
SmallString<64> Buffer;
- _mangler.getNameWithPrefix(Buffer, def, false);
+ _mangler.getNameWithPrefix(Buffer, def);
// set alignment part log2() can have rounding errors
uint32_t align = def->getAlignment();
attr |= LTO_SYMBOL_SCOPE_HIDDEN;
else if (def->hasProtectedVisibility())
attr |= LTO_SYMBOL_SCOPE_PROTECTED;
+ else if (canBeHidden(def))
+ attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
else if (def->hasExternalLinkage() || def->hasWeakLinkage() ||
def->hasLinkOnceLinkage() || def->hasCommonLinkage() ||
def->hasLinkerPrivateWeakLinkage())
attr |= LTO_SYMBOL_SCOPE_DEFAULT;
- else if (def->hasLinkOnceODRAutoHideLinkage())
- attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN;
else
attr |= LTO_SYMBOL_SCOPE_INTERNAL;
return;
SmallString<64> name;
- _mangler.getNameWithPrefix(name, decl, false);
+ _mangler.getNameWithPrefix(name, decl);
StringMap<NameAndAttributes>::value_type &entry =
_undefines.GetOrCreateValue(name);
}
namespace {
+
+// Common infrastructure is allowed to assume the existence of a current
+// section. Since this streamer doesn't need one itself, we just provide
+// a dummy one.
+class DummySection : public MCSection {
+public:
+ DummySection() : MCSection(SV_ELF, SectionKind::getText()) {}
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const {}
+
+ virtual std::string getLabelBeginName() const { return ""; }
+
+ virtual std::string getLabelEndName() const { return ""; }
+
+ virtual bool UseCodeAlign() const { return false; }
+
+ virtual bool isVirtualSection() const { return false; }
+};
+
class RecordStreamer : public MCStreamer {
public:
enum State { NeverSeen, Global, Defined, DefinedGlobal, Used };
+ DummySection TheSection;
+
private:
StringMap<State> Symbols;
return Symbols.end();
}
- RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
+ RecordStreamer(MCContext &Context) : MCStreamer(Context, 0) {
+ SwitchSection(&TheSection);
+ }
virtual void EmitInstruction(const MCInst &Inst) {
// Scan for values.
// Noop calls.
virtual void ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {}
- virtual void InitToTextSection() {}
virtual void InitSections() {}
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
virtual void EmitThumbFunc(MCSymbol *Func) {}
return false;
}
+
+/// parseMetadata - Parse metadata from the module
+void LTOModule::parseMetadata() {
+ // Linker Options
+ if (Value *Val = _module->getModuleFlag("Linker Options")) {
+ MDNode *LinkerOptions = cast<MDNode>(Val);
+ for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) {
+ 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);
+ if (!DepLibName.empty())
+ _deplibs.push_back(DepLibName.data());
+ else if (!Op.empty())
+ _linkeropts.push_back(Op.data());
+ }
+ }
+ }
+
+ // Add other interesting metadata here.
+}