[lld] r325150 - [WebAssembly] Use a Symbol class heirarchy. NFC.
Sam Clegg via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 14 14:00:31 PST 2018
Works for me too. I added this assert to the other backends yesterday
without issue. Strange...
On Wed, Feb 14, 2018 at 1:15 PM, Rui Ueyama <ruiu at google.com> wrote:
> It compiles on my machine. What is "T" when it fails on the assertion?
>
> On Wed, Feb 14, 2018 at 1:10 PM, Michael Spencer via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
>>
>> This doesn't build for me.
>>
>> /home/michael/llvm-project/lld/wasm/Symbols.h:240:3: error: static
>> assertion failed: Symbol types must be trivially destructible
>> │
>> static_assert(std::is_trivially_destructible<T>(),
>> │
>> ^~~~~~~~~~~~~
>>
>> - Michael Spencer
>>
>> On Wed, Feb 14, 2018 at 10:27 AM, Sam Clegg via llvm-commits
>> <llvm-commits at lists.llvm.org> wrote:
>>>
>>> Author: sbc
>>> Date: Wed Feb 14 10:27:59 2018
>>> New Revision: 325150
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=325150&view=rev
>>> Log:
>>> [WebAssembly] Use a Symbol class heirarchy. NFC.
>>>
>>> This brings wasm into line with ELF and COFF in terms of
>>> symbol types are represented.
>>>
>>> Differential Revision: https://reviews.llvm.org/D43112
>>>
>>> Modified:
>>> lld/trunk/wasm/InputFiles.cpp
>>> lld/trunk/wasm/InputFiles.h
>>> lld/trunk/wasm/SymbolTable.cpp
>>> lld/trunk/wasm/SymbolTable.h
>>> lld/trunk/wasm/Symbols.cpp
>>> lld/trunk/wasm/Symbols.h
>>> lld/trunk/wasm/Writer.cpp
>>>
>>> Modified: lld/trunk/wasm/InputFiles.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=325150&r1=325149&r2=325150&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/wasm/InputFiles.cpp (original)
>>> +++ lld/trunk/wasm/InputFiles.cpp Wed Feb 14 10:27:59 2018
>>> @@ -51,11 +51,14 @@ void ObjFile::dumpInfo() const {
>>> }
>>>
>>> uint32_t ObjFile::relocateVirtualAddress(uint32_t GlobalIndex) const {
>>> - return getGlobalSymbol(GlobalIndex)->getVirtualAddress();
>>> + if (auto *DG = dyn_cast<DefinedGlobal>(getGlobalSymbol(GlobalIndex)))
>>> + return DG->getVirtualAddress();
>>> + else
>>> + return 0;
>>> }
>>>
>>> uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const {
>>> - const Symbol *Sym = getFunctionSymbol(Original);
>>> + const FunctionSymbol *Sym = getFunctionSymbol(Original);
>>> uint32_t Index = Sym->getOutputIndex();
>>> DEBUG(dbgs() << "relocateFunctionIndex: " << toString(*Sym) << ": "
>>> << Original << " -> " << Index << "\n");
>>> @@ -68,7 +71,7 @@ uint32_t ObjFile::relocateTypeIndex(uint
>>> }
>>>
>>> uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
>>> - const Symbol *Sym = getFunctionSymbol(Original);
>>> + const FunctionSymbol *Sym = getFunctionSymbol(Original);
>>> uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
>>> DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " <<
>>> Original
>>> << " -> " << Index << "\n");
>>> @@ -249,7 +252,7 @@ void ObjFile::initializeSymbols() {
>>> case WasmSymbol::SymbolType::FUNCTION_EXPORT: {
>>> InputFunction *Function = getFunction(WasmSym);
>>> if (!isExcludedByComdat(Function)) {
>>> - S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind,
>>> Function);
>>> + S = createDefinedFunction(WasmSym, Function);
>>> break;
>>> } else {
>>> Function->Live = false;
>>> @@ -263,8 +266,7 @@ void ObjFile::initializeSymbols() {
>>> case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
>>> InputSegment *Segment = getSegment(WasmSym);
>>> if (!isExcludedByComdat(Segment)) {
>>> - S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind,
>>> Segment,
>>> - getGlobalValue(WasmSym));
>>> + S = createDefinedGlobal(WasmSym, Segment,
>>> getGlobalValue(WasmSym));
>>> break;
>>> } else {
>>> Segment->Live = false;
>>> @@ -302,15 +304,18 @@ Symbol *ObjFile::createUndefined(const W
>>> return Symtab->addUndefined(Sym.Name, Kind, Sym.Flags, this,
>>> Signature);
>>> }
>>>
>>> -Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
>>> - InputChunk *Chunk, uint32_t Address) {
>>> - Symbol *S;
>>> - if (Sym.isBindingLocal()) {
>>> - S = make<Symbol>(Sym.Name, true);
>>> - S->update(Kind, this, Sym.Flags, Chunk, Address);
>>> - return S;
>>> - }
>>> - return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Chunk,
>>> Address);
>>> +Symbol *ObjFile::createDefinedFunction(const WasmSymbol &Sym,
>>> + InputChunk *Chunk) {
>>> + if (Sym.isBindingLocal())
>>> + return make<DefinedFunction>(Sym.Name, Sym.Flags, this, Chunk);
>>> + return Symtab->addDefined(true, Sym.Name, Sym.Flags, this, Chunk);
>>> +}
>>> +
>>> +Symbol *ObjFile::createDefinedGlobal(const WasmSymbol &Sym, InputChunk
>>> *Chunk,
>>> + uint32_t Address) {
>>> + if (Sym.isBindingLocal())
>>> + return make<DefinedGlobal>(Sym.Name, Sym.Flags, this, Chunk,
>>> Address);
>>> + return Symtab->addDefined(false, Sym.Name, Sym.Flags, this, Chunk,
>>> Address);
>>> }
>>>
>>> void ArchiveFile::parse() {
>>>
>>> Modified: lld/trunk/wasm/InputFiles.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=325150&r1=325149&r2=325150&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/wasm/InputFiles.h (original)
>>> +++ lld/trunk/wasm/InputFiles.h Wed Feb 14 10:27:59 2018
>>> @@ -107,11 +107,13 @@ public:
>>>
>>> ArrayRef<Symbol *> getSymbols() const { return Symbols; }
>>>
>>> - Symbol *getFunctionSymbol(uint32_t Index) const {
>>> - return FunctionSymbols[Index];
>>> + FunctionSymbol *getFunctionSymbol(uint32_t Index) const {
>>> + return cast<FunctionSymbol>(FunctionSymbols[Index]);
>>> }
>>>
>>> - Symbol *getGlobalSymbol(uint32_t Index) const { return
>>> GlobalSymbols[Index]; }
>>> + GlobalSymbol *getGlobalSymbol(uint32_t Index) const {
>>> + return cast<GlobalSymbol>(GlobalSymbols[Index]);
>>> + }
>>>
>>> private:
>>> uint32_t relocateVirtualAddress(uint32_t Index) const;
>>> @@ -119,9 +121,9 @@ private:
>>> uint32_t relocateGlobalIndex(uint32_t Original) const;
>>> uint32_t relocateTableIndex(uint32_t Original) const;
>>>
>>> - Symbol *createDefined(const WasmSymbol &Sym, Symbol::Kind Kind,
>>> - InputChunk *Chunk = nullptr,
>>> - uint32_t Address = UINT32_MAX);
>>> + Symbol *createDefinedGlobal(const WasmSymbol &Sym, InputChunk *Chunk,
>>> + uint32_t Address);
>>> + Symbol *createDefinedFunction(const WasmSymbol &Sym, InputChunk
>>> *Chunk);
>>> Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind,
>>> const WasmSignature *Signature = nullptr);
>>> void initializeSymbols();
>>>
>>> Modified: lld/trunk/wasm/SymbolTable.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=325150&r1=325149&r2=325150&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/wasm/SymbolTable.cpp (original)
>>> +++ lld/trunk/wasm/SymbolTable.cpp Wed Feb 14 10:27:59 2018
>>> @@ -66,7 +66,7 @@ std::pair<Symbol *, bool> SymbolTable::i
>>> Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
>>> if (Sym)
>>> return {Sym, false};
>>> - Sym = make<Symbol>(Name, false);
>>> + Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
>>> SymVector.emplace_back(Sym);
>>> return {Sym, true};
>>> }
>>> @@ -80,13 +80,10 @@ void SymbolTable::reportDuplicate(Symbol
>>> // Check the type of new symbol matches that of the symbol is replacing.
>>> // For functions this can also involve verifying that the signatures
>>> match.
>>> static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,
>>> - Symbol::Kind Kind, const WasmSignature
>>> *NewSig) {
>>> + bool NewIsFunction, const WasmSignature
>>> *NewSig) {
>>> if (Existing.isLazy())
>>> return;
>>>
>>> - bool NewIsFunction = Kind == Symbol::Kind::UndefinedFunctionKind ||
>>> - Kind == Symbol::Kind::DefinedFunctionKind;
>>> -
>>> // First check the symbol types match (i.e. either both are function
>>> // symbols or both are data symbols).
>>> if (Existing.isFunction() != NewIsFunction) {
>>> @@ -98,105 +95,102 @@ static void checkSymbolTypes(const Symbo
>>> }
>>>
>>> // For function symbols, optionally check the function signature
>>> matches too.
>>> - if (!NewIsFunction || !Config->CheckSignatures)
>>> + auto *ExistingFunc = dyn_cast<FunctionSymbol>(&Existing);
>>> + if (!ExistingFunc || !Config->CheckSignatures)
>>> return;
>>> +
>>> // Skip the signature check if the existing function has no signature
>>> (e.g.
>>> // if it is an undefined symbol generated by --undefined command line
>>> flag).
>>> - if (!Existing.hasFunctionType())
>>> + if (!ExistingFunc->hasFunctionType())
>>> return;
>>>
>>> - DEBUG(dbgs() << "checkSymbolTypes: " << Existing.getName() << "\n");
>>> + DEBUG(dbgs() << "checkSymbolTypes: " << ExistingFunc->getName() <<
>>> "\n");
>>> assert(NewSig);
>>>
>>> - const WasmSignature &OldSig = Existing.getFunctionType();
>>> + const WasmSignature &OldSig = ExistingFunc->getFunctionType();
>>> if (*NewSig == OldSig)
>>> return;
>>>
>>> - error("function signature mismatch: " + Existing.getName() +
>>> + error("function signature mismatch: " + ExistingFunc->getName() +
>>> "\n>>> defined as " + toString(OldSig) + " in " +
>>> - toString(Existing.getFile()) + "\n>>> defined as " +
>>> toString(*NewSig) +
>>> - " in " + F.getName());
>>> + toString(ExistingFunc->getFile()) + "\n>>> defined as " +
>>> + toString(*NewSig) + " in " + F.getName());
>>> }
>>>
>>> static void checkSymbolTypes(const Symbol &Existing, const InputFile &F,
>>> - Symbol::Kind Kind, const InputChunk *Chunk)
>>> {
>>> + bool IsFunction, const InputChunk *Chunk) {
>>> const WasmSignature *Sig = nullptr;
>>> if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
>>> Sig = &F->Signature;
>>> - return checkSymbolTypes(Existing, F, Kind, Sig);
>>> + return checkSymbolTypes(Existing, F, IsFunction, Sig);
>>> }
>>>
>>> -Symbol *SymbolTable::addSyntheticFunction(StringRef Name,
>>> - const WasmSignature *Type,
>>> - uint32_t Flags) {
>>> +DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name,
>>> + const WasmSignature
>>> *Type,
>>> + uint32_t Flags) {
>>> DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n");
>>> Symbol *S;
>>> bool WasInserted;
>>> std::tie(S, WasInserted) = insert(Name);
>>> assert(WasInserted);
>>> - S->update(Symbol::DefinedFunctionKind, nullptr, Flags);
>>> - S->setFunctionType(Type);
>>> - return S;
>>> + return replaceSymbol<DefinedFunction>(S, Name, Flags, Type);
>>> }
>>>
>>> -Symbol *SymbolTable::addSyntheticGlobal(StringRef Name) {
>>> +DefinedGlobal *SymbolTable::addSyntheticGlobal(StringRef Name, uint32_t
>>> Flags) {
>>> DEBUG(dbgs() << "addSyntheticGlobal: " << Name << "\n");
>>> Symbol *S;
>>> bool WasInserted;
>>> std::tie(S, WasInserted) = insert(Name);
>>> assert(WasInserted);
>>> - S->update(Symbol::DefinedGlobalKind);
>>> - return S;
>>> + return replaceSymbol<DefinedGlobal>(S, Name, Flags);
>>> }
>>>
>>> -Symbol *SymbolTable::addDefined(StringRef Name, Symbol::Kind Kind,
>>> - uint32_t Flags, InputFile *F, InputChunk
>>> *Chunk,
>>> +Symbol *SymbolTable::addDefined(bool IsFunction, StringRef Name,
>>> uint32_t Flags,
>>> + InputFile *F, InputChunk *Chunk,
>>> uint32_t Address) {
>>> - DEBUG(dbgs() << "addDefined: " << Name << " addr:" << Address <<
>>> "\n");
>>> + if (IsFunction)
>>> + DEBUG(dbgs() << "addDefined: func:" << Name << "\n");
>>> + else
>>> + DEBUG(dbgs() << "addDefined: global:" << Name << " addr:" << Address
>>> + << "\n");
>>> Symbol *S;
>>> bool WasInserted;
>>> + bool Replace = false;
>>> + bool CheckTypes = false;
>>>
>>> std::tie(S, WasInserted) = insert(Name);
>>> if (WasInserted) {
>>> - S->update(Kind, F, Flags, Chunk, Address);
>>> + Replace = true;
>>> } else if (S->isLazy()) {
>>> - // The existing symbol is lazy. Replace it without checking types
>>> since
>>> + // Existing symbol is lazy. Replace it without checking types since
>>> // lazy symbols don't have any type information.
>>> DEBUG(dbgs() << "replacing existing lazy symbol: " << Name << "\n");
>>> - S->update(Kind, F, Flags, Chunk, Address);
>>> + Replace = true;
>>> } else if (!S->isDefined()) {
>>> - // The existing symbol table entry is undefined. The new symbol
>>> replaces
>>> - // it, after checking the type matches
>>> + // Existing symbol is undefined: replace it, while check types.
>>> DEBUG(dbgs() << "resolving existing undefined symbol: " << Name <<
>>> "\n");
>>> - checkSymbolTypes(*S, *F, Kind, Chunk);
>>> - S->update(Kind, F, Flags, Chunk, Address);
>>> + Replace = true;
>>> + CheckTypes = true;
>>> } else if ((Flags & WASM_SYMBOL_BINDING_MASK) ==
>>> WASM_SYMBOL_BINDING_WEAK) {
>>> // the new symbol is weak we can ignore it
>>> DEBUG(dbgs() << "existing symbol takes precedence\n");
>>> } else if (S->isWeak()) {
>>> - // the new symbol is not weak and the existing symbol is, so we
>>> replace
>>> - // it
>>> + // the existing symbol is, so we replace it
>>> DEBUG(dbgs() << "replacing existing weak symbol\n");
>>> - checkSymbolTypes(*S, *F, Kind, Chunk);
>>> - S->update(Kind, F, Flags, Chunk, Address);
>>> + Replace = true;
>>> + CheckTypes = true;
>>> } else {
>>> // neither symbol is week. They conflict.
>>> reportDuplicate(S, F);
>>> }
>>> - return S;
>>> -}
>>>
>>> -Symbol *SymbolTable::addUndefinedFunction(StringRef Name,
>>> - const WasmSignature *Type) {
>>> - DEBUG(dbgs() << "addUndefinedFunction: " << Name << "\n");
>>> - Symbol *S;
>>> - bool WasInserted;
>>> - std::tie(S, WasInserted) = insert(Name);
>>> - if (WasInserted) {
>>> - S->update(Symbol::UndefinedFunctionKind);
>>> - S->setFunctionType(Type);
>>> - } else if (!S->isFunction()) {
>>> - error("symbol type mismatch: " + Name);
>>> + if (Replace) {
>>> + if (CheckTypes)
>>> + checkSymbolTypes(*S, *F, IsFunction, Chunk);
>>> + if (IsFunction)
>>> + replaceSymbol<DefinedFunction>(S, Name, Flags, F, Chunk);
>>> + else
>>> + replaceSymbol<DefinedGlobal>(S, Name, Flags, F, Chunk, Address);
>>> }
>>> return S;
>>> }
>>> @@ -208,17 +202,19 @@ Symbol *SymbolTable::addUndefined(String
>>> Symbol *S;
>>> bool WasInserted;
>>> std::tie(S, WasInserted) = insert(Name);
>>> + bool IsFunction = Kind == Symbol::UndefinedFunctionKind;
>>> if (WasInserted) {
>>> - S->update(Kind, F, Flags);
>>> - if (Type)
>>> - S->setFunctionType(Type);
>>> - } else if (S->isLazy()) {
>>> + if (IsFunction)
>>> + replaceSymbol<UndefinedFunction>(S, Name, Flags, F, Type);
>>> + else
>>> + replaceSymbol<UndefinedGlobal>(S, Name, Flags, F);
>>> + } else if (auto *LazySym = dyn_cast<LazySymbol>(S)) {
>>> DEBUG(dbgs() << "resolved by existing lazy\n");
>>> - auto *AF = cast<ArchiveFile>(S->getFile());
>>> - AF->addMember(&S->getArchiveSymbol());
>>> + auto *AF = cast<ArchiveFile>(LazySym->getFile());
>>> + AF->addMember(&LazySym->getArchiveSymbol());
>>> } else if (S->isDefined()) {
>>> DEBUG(dbgs() << "resolved by existing\n");
>>> - checkSymbolTypes(*S, *F, Kind, Type);
>>> + checkSymbolTypes(*S, *F, IsFunction, Type);
>>> }
>>> return S;
>>> }
>>> @@ -230,8 +226,7 @@ void SymbolTable::addLazy(ArchiveFile *F
>>> bool WasInserted;
>>> std::tie(S, WasInserted) = insert(Name);
>>> if (WasInserted) {
>>> - S->update(Symbol::LazyKind, F);
>>> - S->setArchiveSymbol(*Sym);
>>> + replaceSymbol<LazySymbol>(S, Name, F, *Sym);
>>> } else if (S->isUndefined()) {
>>> // There is an existing undefined symbol. The can load from the
>>> // archive.
>>>
>>> Modified: lld/trunk/wasm/SymbolTable.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.h?rev=325150&r1=325149&r2=325150&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/wasm/SymbolTable.h (original)
>>> +++ lld/trunk/wasm/SymbolTable.h Wed Feb 14 10:27:59 2018
>>> @@ -49,7 +49,7 @@ public:
>>> Symbol *find(StringRef Name);
>>> ObjFile *findComdat(StringRef Name) const;
>>>
>>> - Symbol *addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags,
>>> + Symbol *addDefined(bool IsFunction, StringRef Name, uint32_t Flags,
>>> InputFile *F, InputChunk *Chunk = nullptr,
>>> uint32_t Address = 0);
>>> Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t
>>> Flags,
>>> @@ -58,9 +58,10 @@ public:
>>> void addLazy(ArchiveFile *F, const Archive::Symbol *Sym);
>>> bool addComdat(StringRef Name, ObjFile *);
>>>
>>> - Symbol *addSyntheticGlobal(StringRef Name);
>>> - Symbol *addSyntheticFunction(StringRef Name, const WasmSignature
>>> *Type,
>>> - uint32_t Flags);
>>> + DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags = 0);
>>> + DefinedFunction *addSyntheticFunction(StringRef Name,
>>> + const WasmSignature *Type,
>>> + uint32_t Flags = 0);
>>> private:
>>> std::pair<Symbol *, bool> insert(StringRef Name);
>>>
>>>
>>> Modified: lld/trunk/wasm/Symbols.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=325150&r1=325149&r2=325150&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/wasm/Symbols.cpp (original)
>>> +++ lld/trunk/wasm/Symbols.cpp Wed Feb 14 10:27:59 2018
>>> @@ -22,32 +22,11 @@ using namespace llvm::wasm;
>>> using namespace lld;
>>> using namespace lld::wasm;
>>>
>>> -Symbol *WasmSym::CallCtors;
>>> -Symbol *WasmSym::DsoHandle;
>>> -Symbol *WasmSym::DataEnd;
>>> -Symbol *WasmSym::HeapBase;
>>> -Symbol *WasmSym::StackPointer;
>>> -
>>> -const WasmSignature &Symbol::getFunctionType() const {
>>> - if (Chunk != nullptr)
>>> - return dyn_cast<InputFunction>(Chunk)->Signature;
>>> -
>>> - assert(FunctionType != nullptr);
>>> - return *FunctionType;
>>> -}
>>> -
>>> -void Symbol::setFunctionType(const WasmSignature *Type) {
>>> - assert(FunctionType == nullptr);
>>> - assert(!Chunk);
>>> - FunctionType = Type;
>>> -}
>>> -
>>> -uint32_t Symbol::getVirtualAddress() const {
>>> - assert(isGlobal());
>>> - DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
>>> - return Chunk ?
>>> dyn_cast<InputSegment>(Chunk)->translateVA(VirtualAddress)
>>> - : VirtualAddress;
>>> -}
>>> +DefinedFunction *WasmSym::CallCtors;
>>> +DefinedGlobal *WasmSym::DsoHandle;
>>> +DefinedGlobal *WasmSym::DataEnd;
>>> +DefinedGlobal *WasmSym::HeapBase;
>>> +DefinedGlobal *WasmSym::StackPointer;
>>>
>>> bool Symbol::hasOutputIndex() const {
>>> if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
>>> @@ -61,12 +40,6 @@ uint32_t Symbol::getOutputIndex() const
>>> return OutputIndex.getValue();
>>> }
>>>
>>> -void Symbol::setVirtualAddress(uint32_t Value) {
>>> - DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value <<
>>> "\n");
>>> - assert(isGlobal());
>>> - VirtualAddress = Value;
>>> -}
>>> -
>>> void Symbol::setOutputIndex(uint32_t Index) {
>>> DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n");
>>> assert(!dyn_cast_or_null<InputFunction>(Chunk));
>>> @@ -74,19 +47,54 @@ void Symbol::setOutputIndex(uint32_t Ind
>>> OutputIndex = Index;
>>> }
>>>
>>> -uint32_t Symbol::getTableIndex() const {
>>> +bool Symbol::isWeak() const {
>>> + return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
>>> +}
>>> +
>>> +bool Symbol::isLocal() const {
>>> + return (Flags & WASM_SYMBOL_BINDING_MASK) ==
>>> WASM_SYMBOL_BINDING_LOCAL;
>>> +}
>>> +
>>> +bool Symbol::isHidden() const {
>>> + return (Flags & WASM_SYMBOL_VISIBILITY_MASK) ==
>>> WASM_SYMBOL_VISIBILITY_HIDDEN;
>>> +}
>>> +
>>> +void Symbol::setHidden(bool IsHidden) {
>>> + DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
>>> + Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
>>> + if (IsHidden)
>>> + Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
>>> + else
>>> + Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
>>> +}
>>> +
>>> +const WasmSignature &FunctionSymbol::getFunctionType() const {
>>> + if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
>>> + return F->Signature;
>>> +
>>> + assert(FunctionType != nullptr);
>>> + return *FunctionType;
>>> +}
>>> +
>>> +void FunctionSymbol::setFunctionType(const WasmSignature *Type) {
>>> + assert(FunctionType == nullptr);
>>> + assert(!Chunk);
>>> + FunctionType = Type;
>>> +}
>>> +
>>> +uint32_t FunctionSymbol::getTableIndex() const {
>>> if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
>>> return F->getTableIndex();
>>> return TableIndex.getValue();
>>> }
>>>
>>> -bool Symbol::hasTableIndex() const {
>>> +bool FunctionSymbol::hasTableIndex() const {
>>> if (auto *F = dyn_cast_or_null<InputFunction>(Chunk))
>>> return F->hasTableIndex();
>>> return TableIndex.hasValue();
>>> }
>>>
>>> -void Symbol::setTableIndex(uint32_t Index) {
>>> +void FunctionSymbol::setTableIndex(uint32_t Index) {
>>> // For imports, we set the table index here on the Symbol; for defined
>>> // functions we set the index on the InputFunction so that we don't
>>> export
>>> // the same thing twice (keeps the table size down).
>>> @@ -99,35 +107,17 @@ void Symbol::setTableIndex(uint32_t Inde
>>> TableIndex = Index;
>>> }
>>>
>>> -void Symbol::update(Kind K, InputFile *F, uint32_t Flags_, InputChunk
>>> *Chunk_,
>>> - uint32_t Address) {
>>> - SymbolKind = K;
>>> - File = F;
>>> - Flags = Flags_;
>>> - Chunk = Chunk_;
>>> - if (Address != UINT32_MAX)
>>> - setVirtualAddress(Address);
>>> -}
>>> -
>>> -bool Symbol::isWeak() const {
>>> - return (Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK;
>>> -}
>>> -
>>> -bool Symbol::isLocal() const {
>>> - return (Flags & WASM_SYMBOL_BINDING_MASK) ==
>>> WASM_SYMBOL_BINDING_LOCAL;
>>> -}
>>> -
>>> -bool Symbol::isHidden() const {
>>> - return (Flags & WASM_SYMBOL_VISIBILITY_MASK) ==
>>> WASM_SYMBOL_VISIBILITY_HIDDEN;
>>> +uint32_t DefinedGlobal::getVirtualAddress() const {
>>> + assert(isGlobal());
>>> + DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
>>> + return Chunk ?
>>> dyn_cast<InputSegment>(Chunk)->translateVA(VirtualAddress)
>>> + : VirtualAddress;
>>> }
>>>
>>> -void Symbol::setHidden(bool IsHidden) {
>>> - DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n");
>>> - Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
>>> - if (IsHidden)
>>> - Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
>>> - else
>>> - Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
>>> +void DefinedGlobal::setVirtualAddress(uint32_t Value) {
>>> + DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value <<
>>> "\n");
>>> + assert(isGlobal());
>>> + VirtualAddress = Value;
>>> }
>>>
>>> std::string lld::toString(const wasm::Symbol &Sym) {
>>>
>>> Modified: lld/trunk/wasm/Symbols.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=325150&r1=325149&r2=325150&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/wasm/Symbols.h (original)
>>> +++ lld/trunk/wasm/Symbols.h Wed Feb 14 10:27:59 2018
>>> @@ -23,6 +23,7 @@ namespace wasm {
>>> class InputFile;
>>> class InputChunk;
>>>
>>> +// The base class for real symbol classes.
>>> class Symbol {
>>> public:
>>> enum Kind {
>>> @@ -37,9 +38,7 @@ public:
>>> InvalidKind,
>>> };
>>>
>>> - Symbol(StringRef Name, uint32_t Flags) : Flags(Flags), Name(Name) {}
>>> -
>>> - Kind getKind() const { return SymbolKind; }
>>> + Kind kind() const { return static_cast<Kind>(SymbolKind); }
>>>
>>> bool isLazy() const { return SymbolKind == LazyKind; }
>>> bool isDefined() const { return SymbolKind <= LastDefinedKind; }
>>> @@ -63,9 +62,6 @@ public:
>>> InputFile *getFile() const { return File; }
>>> InputChunk *getChunk() const { return Chunk; }
>>>
>>> - bool hasFunctionType() const { return FunctionType != nullptr; }
>>> - const WasmSignature &getFunctionType() const;
>>> - void setFunctionType(const WasmSignature *Type);
>>> void setHidden(bool IsHidden);
>>>
>>> uint32_t getOutputIndex() const;
>>> @@ -77,6 +73,28 @@ public:
>>> // space of the output object.
>>> void setOutputIndex(uint32_t Index);
>>>
>>> +protected:
>>> + Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
>>> InputChunk *C)
>>> + : Name(Name), SymbolKind(K), Flags(Flags), File(F), Chunk(C) {}
>>> +
>>> + StringRef Name;
>>> + Kind SymbolKind;
>>> + uint32_t Flags;
>>> + InputFile *File;
>>> + InputChunk *Chunk;
>>> + llvm::Optional<uint32_t> OutputIndex;
>>> +};
>>> +
>>> +class FunctionSymbol : public Symbol {
>>> +public:
>>> + static bool classof(const Symbol *S) {
>>> + return S->kind() == DefinedFunctionKind ||
>>> + S->kind() == UndefinedFunctionKind;
>>> + }
>>> +
>>> + bool hasFunctionType() const { return FunctionType != nullptr; }
>>> + const WasmSignature &getFunctionType() const;
>>> +
>>> uint32_t getTableIndex() const;
>>>
>>> // Returns true if a table index has been set for this symbol
>>> @@ -85,30 +103,99 @@ public:
>>> // Set the table index of the symbol
>>> void setTableIndex(uint32_t Index);
>>>
>>> - // Returns the virtual address of a defined global.
>>> - // Only works for globals, not functions.
>>> +protected:
>>> + void setFunctionType(const WasmSignature *Type);
>>> +
>>> + FunctionSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
>>> + InputChunk *C)
>>> + : Symbol(Name, K, Flags, F, C) {}
>>> +
>>> + llvm::Optional<uint32_t> TableIndex;
>>> +
>>> + // Explict function type, needed for undefined or synthetic functions
>>> only.
>>> + const WasmSignature *FunctionType = nullptr;
>>> +};
>>> +
>>> +class DefinedFunction : public FunctionSymbol {
>>> +public:
>>> + DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F =
>>> nullptr,
>>> + InputChunk *C = nullptr)
>>> + : FunctionSymbol(Name, DefinedFunctionKind, Flags, F, C) {}
>>> +
>>> + DefinedFunction(StringRef Name, uint32_t Flags, const WasmSignature
>>> *Type)
>>> + : FunctionSymbol(Name, DefinedFunctionKind, Flags, nullptr,
>>> nullptr) {
>>> + setFunctionType(Type);
>>> + }
>>> +
>>> + static bool classof(const Symbol *S) {
>>> + return S->kind() == DefinedFunctionKind;
>>> + }
>>> +};
>>> +
>>> +class UndefinedFunction : public FunctionSymbol {
>>> +public:
>>> + UndefinedFunction(StringRef Name, uint32_t Flags, InputFile *File =
>>> nullptr,
>>> + const WasmSignature *Type = nullptr)
>>> + : FunctionSymbol(Name, UndefinedFunctionKind, Flags, File,
>>> nullptr) {
>>> + setFunctionType(Type);
>>> + }
>>> +
>>> + static bool classof(const Symbol *S) {
>>> + return S->kind() == UndefinedFunctionKind;
>>> + }
>>> +};
>>> +
>>> +class GlobalSymbol : public Symbol {
>>> +public:
>>> + static bool classof(const Symbol *S) {
>>> + return S->kind() == DefinedGlobalKind || S->kind() ==
>>> UndefinedGlobalKind;
>>> + }
>>> +
>>> +protected:
>>> + GlobalSymbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F,
>>> + InputChunk *C)
>>> + : Symbol(Name, K, Flags, F, C) {}
>>> +};
>>> +
>>> +class DefinedGlobal : public GlobalSymbol {
>>> +public:
>>> + DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *F = nullptr,
>>> + InputChunk *C = nullptr, uint32_t Address = 0)
>>> + : GlobalSymbol(Name, DefinedGlobalKind, Flags, F, C),
>>> + VirtualAddress(Address) {}
>>> +
>>> + static bool classof(const Symbol *S) {
>>> + return S->kind() == DefinedGlobalKind;
>>> + }
>>> +
>>> uint32_t getVirtualAddress() const;
>>>
>>> void setVirtualAddress(uint32_t VA);
>>>
>>> - void update(Kind K, InputFile *F = nullptr, uint32_t Flags = 0,
>>> - InputChunk *chunk = nullptr, uint32_t Address =
>>> UINT32_MAX);
>>> +protected:
>>> + uint32_t VirtualAddress;
>>> +};
>>> +
>>> +class UndefinedGlobal : public GlobalSymbol {
>>> +public:
>>> + UndefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File =
>>> nullptr)
>>> + : GlobalSymbol(Name, UndefinedGlobalKind, Flags, File, nullptr) {}
>>> + static bool classof(const Symbol *S) {
>>> + return S->kind() == UndefinedGlobalKind;
>>> + }
>>> +};
>>> +
>>> +class LazySymbol : public Symbol {
>>> +public:
>>> + LazySymbol(StringRef Name, InputFile *File, const Archive::Symbol
>>> &Sym)
>>> + : Symbol(Name, LazyKind, 0, File, nullptr), ArchiveSymbol(Sym) {}
>>> +
>>> + static bool classof(const Symbol *S) { return S->kind() == LazyKind; }
>>>
>>> - void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol =
>>> Sym; }
>>> const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; }
>>>
>>> protected:
>>> - uint32_t Flags;
>>> - uint32_t VirtualAddress = 0;
>>> -
>>> - StringRef Name;
>>> - Archive::Symbol ArchiveSymbol = {nullptr, 0, 0};
>>> - Kind SymbolKind = InvalidKind;
>>> - InputFile *File = nullptr;
>>> - InputChunk *Chunk = nullptr;
>>> - llvm::Optional<uint32_t> OutputIndex;
>>> - llvm::Optional<uint32_t> TableIndex;
>>> - const WasmSignature *FunctionType = nullptr;
>>> + Archive::Symbol ArchiveSymbol;
>>> };
>>>
>>> // linker-generated symbols
>>> @@ -116,27 +203,50 @@ struct WasmSym {
>>> // __stack_pointer
>>> // Global that holds the address of the top of the explicit value
>>> stack in
>>> // linear memory.
>>> - static Symbol *StackPointer;
>>> + static DefinedGlobal *StackPointer;
>>>
>>> // __data_end
>>> // Symbol marking the end of the data and bss.
>>> - static Symbol *DataEnd;
>>> + static DefinedGlobal *DataEnd;
>>>
>>> // __heap_base
>>> // Symbol marking the end of the data, bss and explicit stack. Any
>>> linear
>>> // memory following this address is not used by the linked code and
>>> can
>>> // therefore be used as a backing store for brk()/malloc()
>>> implementations.
>>> - static Symbol *HeapBase;
>>> + static DefinedGlobal *HeapBase;
>>>
>>> // __wasm_call_ctors
>>> // Function that directly calls all ctors in priority order.
>>> - static Symbol *CallCtors;
>>> + static DefinedFunction *CallCtors;
>>>
>>> // __dso_handle
>>> // Global used in calls to __cxa_atexit to determine current DLL
>>> - static Symbol *DsoHandle;
>>> + static DefinedGlobal *DsoHandle;
>>> +};
>>> +
>>> +// A buffer class that is large enough to hold any Symbol-derived
>>> +// object. We allocate memory using this class and instantiate a symbol
>>> +// using the placement new.
>>> +union SymbolUnion {
>>> + alignas(DefinedFunction) char A[sizeof(DefinedFunction)];
>>> + alignas(DefinedGlobal) char B[sizeof(DefinedGlobal)];
>>> + alignas(LazySymbol) char C[sizeof(LazySymbol)];
>>> + alignas(UndefinedFunction) char D[sizeof(UndefinedFunction)];
>>> + alignas(UndefinedGlobal) char E[sizeof(UndefinedFunction)];
>>> };
>>>
>>> +template <typename T, typename... ArgT>
>>> +T *replaceSymbol(Symbol *S, ArgT &&... Arg) {
>>> + static_assert(std::is_trivially_destructible<T>(),
>>> + "Symbol types must be trivially destructible");
>>> + static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
>>> + static_assert(alignof(T) <= alignof(SymbolUnion),
>>> + "SymbolUnion not aligned enough");
>>> + assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
>>> + "Not a Symbol");
>>> + return new (S) T(std::forward<ArgT>(Arg)...);
>>> +}
>>> +
>>> } // namespace wasm
>>>
>>> // Returns a symbol name for an error message.
>>>
>>> Modified: lld/trunk/wasm/Writer.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=325150&r1=325149&r2=325150&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/wasm/Writer.cpp (original)
>>> +++ lld/trunk/wasm/Writer.cpp Wed Feb 14 10:27:59 2018
>>> @@ -119,12 +119,12 @@ private:
>>>
>>> std::vector<const WasmSignature *> Types;
>>> DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo>
>>> TypeIndices;
>>> - std::vector<const Symbol *> ImportedFunctions;
>>> - std::vector<const Symbol *> ImportedGlobals;
>>> + std::vector<const FunctionSymbol *> ImportedFunctions;
>>> + std::vector<const GlobalSymbol *> ImportedGlobals;
>>> std::vector<WasmExportEntry> ExportedSymbols;
>>> - std::vector<const Symbol *> DefinedGlobals;
>>> + std::vector<const DefinedGlobal *> DefinedGlobals;
>>> std::vector<InputFunction *> DefinedFunctions;
>>> - std::vector<const Symbol *> IndirectFunctions;
>>> + std::vector<const FunctionSymbol *> IndirectFunctions;
>>> std::vector<WasmInitFunc> InitFunctions;
>>>
>>> // Elements that are used to construct the final output
>>> @@ -164,7 +164,7 @@ void Writer::createImportSection() {
>>>
>>> writeUleb128(OS, NumImports, "import count");
>>>
>>> - for (const Symbol *Sym : ImportedFunctions) {
>>> + for (const FunctionSymbol *Sym : ImportedFunctions) {
>>> WasmImport Import;
>>> Import.Module = "env";
>>> Import.Field = Sym->getName();
>>> @@ -234,7 +234,7 @@ void Writer::createGlobalSection() {
>>> raw_ostream &OS = Section->getStream();
>>>
>>> writeUleb128(OS, DefinedGlobals.size(), "global count");
>>> - for (const Symbol *Sym : DefinedGlobals) {
>>> + for (const DefinedGlobal *Sym : DefinedGlobals) {
>>> WasmGlobal Global;
>>> Global.Type.Type = WASM_TYPE_I32;
>>> Global.Type.Mutable = Sym == WasmSym::StackPointer;
>>> @@ -316,7 +316,7 @@ void Writer::createElemSection() {
>>> writeUleb128(OS, IndirectFunctions.size(), "elem count");
>>>
>>> uint32_t TableIndex = kInitialTableOffset;
>>> - for (const Symbol *Sym : IndirectFunctions) {
>>> + for (const FunctionSymbol *Sym : IndirectFunctions) {
>>> assert(Sym->getTableIndex() == TableIndex);
>>> writeUleb128(OS, Sym->getOutputIndex(), "function index");
>>> ++TableIndex;
>>> @@ -619,12 +619,12 @@ void Writer::calculateImports() {
>>> if (!Sym->isUndefined() || (Sym->isWeak() && !Config->Relocatable))
>>> continue;
>>>
>>> - if (Sym->isFunction()) {
>>> - Sym->setOutputIndex(ImportedFunctions.size());
>>> - ImportedFunctions.push_back(Sym);
>>> - } else {
>>> - Sym->setOutputIndex(ImportedGlobals.size());
>>> - ImportedGlobals.push_back(Sym);
>>> + if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
>>> + F->setOutputIndex(ImportedFunctions.size());
>>> + ImportedFunctions.push_back(F);
>>> + } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
>>> + G->setOutputIndex(ImportedGlobals.size());
>>> + ImportedGlobals.push_back(G);
>>> }
>>> }
>>> }
>>> @@ -712,7 +712,7 @@ void Writer::calculateTypes() {
>>> File->TypeMap[I] = registerType(Types[I]);
>>> }
>>>
>>> - for (const Symbol *Sym : ImportedFunctions)
>>> + for (const FunctionSymbol *Sym : ImportedFunctions)
>>> registerType(Sym->getFunctionType());
>>>
>>> for (const InputFunction *F : DefinedFunctions)
>>> @@ -723,7 +723,7 @@ void Writer::assignIndexes() {
>>> uint32_t GlobalIndex = ImportedGlobals.size() + DefinedGlobals.size();
>>> uint32_t FunctionIndex = ImportedFunctions.size() +
>>> DefinedFunctions.size();
>>>
>>> - auto AddDefinedGlobal = [&](Symbol* Sym) {
>>> + auto AddDefinedGlobal = [&](DefinedGlobal *Sym) {
>>> if (Sym) {
>>> DefinedGlobals.emplace_back(Sym);
>>> Sym->setOutputIndex(GlobalIndex++);
>>> @@ -743,12 +743,10 @@ void Writer::assignIndexes() {
>>> DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
>>> for (Symbol *Sym : File->getSymbols()) {
>>> // Create wasm globals for data symbols defined in this file
>>> - if (!Sym->isDefined() || File != Sym->getFile())
>>> + if (File != Sym->getFile())
>>> continue;
>>> - if (Sym->isFunction())
>>> - continue;
>>> -
>>> - AddDefinedGlobal(Sym);
>>> + if (auto *G = dyn_cast<DefinedGlobal>(Sym))
>>> + AddDefinedGlobal(G);
>>> }
>>> }
>>> }
>>> @@ -772,7 +770,7 @@ void Writer::assignIndexes() {
>>> for (const WasmRelocation& Reloc : Chunk->getRelocations()) {
>>> if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
>>> Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
>>> - Symbol *Sym = File->getFunctionSymbol(Reloc.Index);
>>> + FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
>>> if (Sym->hasTableIndex() || !Sym->hasOutputIndex())
>>> continue;
>>> Sym->setTableIndex(TableIndex++);
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
More information about the llvm-commits
mailing list