Skip to content

Commit

Permalink
Revert r299168 and r299169 due to library dependency issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
pcc committed Mar 31, 2017
1 parent 0c34fa1 commit bfb6d1a
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 659 deletions.
207 changes: 162 additions & 45 deletions include/llvm/LTO/LTO.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/LTO/Config.h"
#include "llvm/Linker/IRMover.h"
#include "llvm/Object/IRSymtab.h"
#include "llvm/Object/ModuleSymbolTable.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/thread.h"
Expand Down Expand Up @@ -79,75 +79,192 @@ class LTO;
struct SymbolResolution;
class ThinBackendProc;

/// An input file. This is a symbol table wrapper that only exposes the
/// An input file. This is a wrapper for ModuleSymbolTable that exposes only the
/// information that an LTO client should need in order to do symbol resolution.
class InputFile {
public:
class Symbol;

private:
// FIXME: Remove LTO class friendship once we have bitcode symbol tables.
friend LTO;
InputFile() = default;

std::vector<BitcodeModule> Mods;
SmallVector<char, 0> Strtab;
std::vector<Symbol> Symbols;

// [begin, end) for each module
std::vector<std::pair<size_t, size_t>> ModuleSymIndices;
// FIXME: Remove the LLVMContext once we have bitcode symbol tables.
LLVMContext Ctx;
struct InputModule;
std::vector<InputModule> Mods;
ModuleSymbolTable SymTab;

StringRef SourceFileName, COFFLinkerOpts;
std::vector<StringRef> ComdatTable;
std::vector<StringRef> Comdats;
DenseMap<const Comdat *, unsigned> ComdatMap;

public:
~InputFile();

/// Create an InputFile.
static Expected<std::unique_ptr<InputFile>> create(MemoryBufferRef Object);

/// The purpose of this class is to only expose the symbol information that an
/// LTO client should need in order to do symbol resolution.
class Symbol : irsymtab::Symbol {
class symbol_iterator;

/// This is a wrapper for ArrayRef<ModuleSymbolTable::Symbol>::iterator that
/// exposes only the information that an LTO client should need in order to do
/// symbol resolution.
///
/// This object is ephemeral; it is only valid as long as an iterator obtained
/// from symbols() refers to it.
class Symbol {
friend symbol_iterator;
friend LTO;

ArrayRef<ModuleSymbolTable::Symbol>::iterator I;
const ModuleSymbolTable &SymTab;
const InputFile *File;
uint32_t Flags;
SmallString<64> Name;

bool shouldSkip() {
return !(Flags & object::BasicSymbolRef::SF_Global) ||
(Flags & object::BasicSymbolRef::SF_FormatSpecific);
}

void skip() {
ArrayRef<ModuleSymbolTable::Symbol>::iterator E = SymTab.symbols().end();
while (I != E) {
Flags = SymTab.getSymbolFlags(*I);
if (!shouldSkip())
break;
++I;
}
if (I == E)
return;

Name.clear();
{
raw_svector_ostream OS(Name);
SymTab.printSymbolName(OS, *I);
}
}

bool isGV() const { return I->is<GlobalValue *>(); }
GlobalValue *getGV() const { return I->get<GlobalValue *>(); }

public:
Symbol(const irsymtab::Symbol &S) : irsymtab::Symbol(S) {}

using irsymtab::Symbol::isUndefined;
using irsymtab::Symbol::isCommon;
using irsymtab::Symbol::isWeak;
using irsymtab::Symbol::isIndirect;
using irsymtab::Symbol::getName;
using irsymtab::Symbol::getVisibility;
using irsymtab::Symbol::canBeOmittedFromSymbolTable;
using irsymtab::Symbol::isTLS;
using irsymtab::Symbol::getComdatIndex;
using irsymtab::Symbol::getCommonSize;
using irsymtab::Symbol::getCommonAlignment;
using irsymtab::Symbol::getCOFFWeakExternalFallback;
Symbol(ArrayRef<ModuleSymbolTable::Symbol>::iterator I,
const ModuleSymbolTable &SymTab, const InputFile *File)
: I(I), SymTab(SymTab), File(File) {
skip();
}

bool isUndefined() const {
return Flags & object::BasicSymbolRef::SF_Undefined;
}
bool isCommon() const { return Flags & object::BasicSymbolRef::SF_Common; }
bool isWeak() const { return Flags & object::BasicSymbolRef::SF_Weak; }
bool isIndirect() const {
return Flags & object::BasicSymbolRef::SF_Indirect;
}

/// For COFF weak externals, returns the name of the symbol that is used
/// as a fallback if the weak external remains undefined.
std::string getCOFFWeakExternalFallback() const {
assert((Flags & object::BasicSymbolRef::SF_Weak) &&
(Flags & object::BasicSymbolRef::SF_Indirect) &&
"symbol is not a weak external");
std::string Name;
raw_string_ostream OS(Name);
SymTab.printSymbolName(
OS,
cast<GlobalValue>(
cast<GlobalAlias>(getGV())->getAliasee()->stripPointerCasts()));
OS.flush();
return Name;
}

/// Returns the mangled name of the global.
StringRef getName() const { return Name; }

GlobalValue::VisibilityTypes getVisibility() const {
if (isGV())
return getGV()->getVisibility();
return GlobalValue::DefaultVisibility;
}
bool canBeOmittedFromSymbolTable() const {
return isGV() && llvm::canBeOmittedFromSymbolTable(getGV());
}
bool isTLS() const {
// FIXME: Expose a thread-local flag for module asm symbols.
return isGV() && getGV()->isThreadLocal();
}

// Returns the index of the comdat this symbol is in or -1 if the symbol
// is not in a comdat.
// FIXME: We have to return Expected<int> because aliases point to an
// arbitrary ConstantExpr and that might not actually be a constant. That
// means we might not be able to find what an alias is aliased to and
// so find its comdat.
Expected<int> getComdatIndex() const;

uint64_t getCommonSize() const {
assert(Flags & object::BasicSymbolRef::SF_Common);
if (!isGV())
return 0;
return getGV()->getParent()->getDataLayout().getTypeAllocSize(
getGV()->getType()->getElementType());
}
unsigned getCommonAlignment() const {
assert(Flags & object::BasicSymbolRef::SF_Common);
if (!isGV())
return 0;
return getGV()->getAlignment();
}
};

class symbol_iterator {
Symbol Sym;

public:
symbol_iterator(ArrayRef<ModuleSymbolTable::Symbol>::iterator I,
const ModuleSymbolTable &SymTab, const InputFile *File)
: Sym(I, SymTab, File) {}

symbol_iterator &operator++() {
++Sym.I;
Sym.skip();
return *this;
}

symbol_iterator operator++(int) {
symbol_iterator I = *this;
++*this;
return I;
}

const Symbol &operator*() const { return Sym; }
const Symbol *operator->() const { return &Sym; }

bool operator!=(const symbol_iterator &Other) const {
return Sym.I != Other.Sym.I;
}
};

/// A range over the symbols in this InputFile.
ArrayRef<Symbol> symbols() const { return Symbols; }
iterator_range<symbol_iterator> symbols() {
return llvm::make_range(
symbol_iterator(SymTab.symbols().begin(), SymTab, this),
symbol_iterator(SymTab.symbols().end(), SymTab, this));
}

/// Returns linker options specified in the input file.
StringRef getCOFFLinkerOpts() const { return COFFLinkerOpts; }
Expected<std::string> getLinkerOpts();

/// Returns the path to the InputFile.
StringRef getName() const;

/// Returns the source file path specified at compile time.
StringRef getSourceFileName() const { return SourceFileName; }
StringRef getSourceFileName() const;

// Returns a table with all the comdats used by this file.
ArrayRef<StringRef> getComdatTable() const { return ComdatTable; }
ArrayRef<StringRef> getComdatTable() const { return Comdats; }

private:
ArrayRef<Symbol> module_symbols(unsigned I) const {
const auto &Indices = ModuleSymIndices[I];
return {Symbols.data() + Indices.first, Symbols.data() + Indices.second};
}
iterator_range<symbol_iterator> module_symbols(InputModule &IM);
};

/// This class wraps an output stream for a native object. Most clients should
Expand Down Expand Up @@ -335,20 +452,20 @@ class LTO {
// Global mapping from mangled symbol names to resolutions.
StringMap<GlobalResolution> GlobalResolutions;

void addSymbolToGlobalRes(const InputFile::Symbol &Sym, SymbolResolution Res,
void addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used,
const InputFile::Symbol &Sym, SymbolResolution Res,
unsigned Partition);

// These functions take a range of symbol resolutions [ResI, ResE) and consume
// the resolutions used by a single input module by incrementing ResI. After
// these functions return, [ResI, ResE) will refer to the resolution range for
// the remaining modules in the InputFile.
Error addModule(InputFile &Input, unsigned ModI,
Error addModule(InputFile &Input, InputFile::InputModule &IM,
const SymbolResolution *&ResI, const SymbolResolution *ResE);
Error addRegularLTO(BitcodeModule BM,
ArrayRef<InputFile::Symbol> Syms,
const SymbolResolution *&ResI,
Error addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
const SymbolResolution *ResE);
Error addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms,
Error addThinLTO(BitcodeModule BM, Module &M,
iterator_range<InputFile::symbol_iterator> Syms,
const SymbolResolution *&ResI, const SymbolResolution *ResE);

Error runRegularLTO(AddStreamFn AddStream);
Expand Down
Loading

0 comments on commit bfb6d1a

Please sign in to comment.