mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[WebAssembly] Use llvm::Optional to store optional symbol attributes. NFC.
The changes the in-memory representation of wasm symbols such that their optional ImportName and ImportModule use llvm::Optional. ImportName is set whenever WASM_SYMBOL_EXPLICIT_NAME flag is set. ImportModule (for imports) is currently always set since it defaults to "env". In the future we can possibly extent to binary format distingish import which have explit module names. Tags: #llvm Differential Revision: https://reviews.llvm.org/D74109
This commit is contained in:
@@ -452,7 +452,7 @@ static void handleLibcall(StringRef name) {
|
||||
static UndefinedGlobal *
|
||||
createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) {
|
||||
auto *sym = cast<UndefinedGlobal>(symtab->addUndefinedGlobal(
|
||||
name, name, defaultModule, WASM_SYMBOL_UNDEFINED, nullptr, type));
|
||||
name, None, None, WASM_SYMBOL_UNDEFINED, nullptr, type));
|
||||
config->allowUndefinedSymbols.insert(sym->getName());
|
||||
sym->isUsedInRegularObj = true;
|
||||
return sym;
|
||||
@@ -590,7 +590,7 @@ struct WrappedSymbol {
|
||||
};
|
||||
|
||||
static Symbol *addUndefined(StringRef name) {
|
||||
return symtab->addUndefinedFunction(name, "", "", WASM_SYMBOL_UNDEFINED,
|
||||
return symtab->addUndefinedFunction(name, None, None, WASM_SYMBOL_UNDEFINED,
|
||||
nullptr, nullptr, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -526,7 +526,7 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &keptComdats,
|
||||
if (objSym.isUndefined() || excludedByComdat) {
|
||||
flags |= WASM_SYMBOL_UNDEFINED;
|
||||
if (objSym.isExecutable())
|
||||
return symtab->addUndefinedFunction(name, "", "", flags, &f, nullptr,
|
||||
return symtab->addUndefinedFunction(name, None, None, flags, &f, nullptr,
|
||||
true);
|
||||
return symtab->addUndefinedData(name, flags, &f);
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ BitcodeCompiler::~BitcodeCompiler() = default;
|
||||
|
||||
static void undefine(Symbol *s) {
|
||||
if (auto f = dyn_cast<DefinedFunction>(s))
|
||||
replaceSymbol<UndefinedFunction>(f, f->getName(), "", "", 0, f->getFile(),
|
||||
f->signature);
|
||||
replaceSymbol<UndefinedFunction>(f, f->getName(), None, None, 0,
|
||||
f->getFile(), f->signature);
|
||||
else if (isa<DefinedData>(s))
|
||||
replaceSymbol<UndefinedData>(s, s->getName(), 0, s->getFile());
|
||||
else
|
||||
|
||||
@@ -404,31 +404,33 @@ Symbol *SymbolTable::addDefinedEvent(StringRef name, uint32_t flags,
|
||||
// become available when the LTO object is read. In this case we silently
|
||||
// replace the empty attributes with the valid ones.
|
||||
template <typename T>
|
||||
static void setImportAttributes(T *existing, StringRef importName,
|
||||
StringRef importModule, InputFile *file) {
|
||||
if (!importName.empty()) {
|
||||
if (existing->importName.empty())
|
||||
static void setImportAttributes(T *existing, Optional<StringRef> importName,
|
||||
Optional<StringRef> importModule,
|
||||
InputFile *file) {
|
||||
if (importName) {
|
||||
if (!existing->importName)
|
||||
existing->importName = importName;
|
||||
if (existing->importName != importName)
|
||||
error("import name mismatch for symbol: " + toString(*existing) +
|
||||
"\n>>> defined as " + existing->importName + " in " +
|
||||
toString(existing->getFile()) + "\n>>> defined as " + importName +
|
||||
"\n>>> defined as " + *existing->importName + " in " +
|
||||
toString(existing->getFile()) + "\n>>> defined as " + *importName +
|
||||
" in " + toString(file));
|
||||
}
|
||||
|
||||
if (!importModule.empty()) {
|
||||
if (existing->importModule.empty())
|
||||
if (importModule) {
|
||||
if (!existing->importModule)
|
||||
existing->importModule = importModule;
|
||||
if (existing->importModule != importModule)
|
||||
error("import module mismatch for symbol: " + toString(*existing) +
|
||||
"\n>>> defined as " + existing->importModule + " in " +
|
||||
toString(existing->getFile()) + "\n>>> defined as " + importModule +
|
||||
" in " + toString(file));
|
||||
"\n>>> defined as " + *existing->importModule + " in " +
|
||||
toString(existing->getFile()) + "\n>>> defined as " +
|
||||
*importModule + " in " + toString(file));
|
||||
}
|
||||
}
|
||||
|
||||
Symbol *SymbolTable::addUndefinedFunction(StringRef name, StringRef importName,
|
||||
StringRef importModule,
|
||||
Symbol *SymbolTable::addUndefinedFunction(StringRef name,
|
||||
Optional<StringRef> importName,
|
||||
Optional<StringRef> importModule,
|
||||
uint32_t flags, InputFile *file,
|
||||
const WasmSignature *sig,
|
||||
bool isCalledDirectly) {
|
||||
@@ -497,9 +499,10 @@ Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
|
||||
return s;
|
||||
}
|
||||
|
||||
Symbol *SymbolTable::addUndefinedGlobal(StringRef name, StringRef importName,
|
||||
StringRef importModule, uint32_t flags,
|
||||
InputFile *file,
|
||||
Symbol *SymbolTable::addUndefinedGlobal(StringRef name,
|
||||
Optional<StringRef> importName,
|
||||
Optional<StringRef> importModule,
|
||||
uint32_t flags, InputFile *file,
|
||||
const WasmGlobalType *type) {
|
||||
LLVM_DEBUG(dbgs() << "addUndefinedGlobal: " << name << "\n");
|
||||
assert(flags & WASM_SYMBOL_UNDEFINED);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "lld/Common/LLVM.h"
|
||||
#include "llvm/ADT/CachedHashString.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
namespace lld {
|
||||
namespace wasm {
|
||||
@@ -59,14 +60,18 @@ public:
|
||||
Symbol *addDefinedEvent(StringRef name, uint32_t flags, InputFile *file,
|
||||
InputEvent *e);
|
||||
|
||||
Symbol *addUndefinedFunction(StringRef name, StringRef importName,
|
||||
StringRef importModule, uint32_t flags,
|
||||
InputFile *file, const WasmSignature *signature,
|
||||
Symbol *addUndefinedFunction(StringRef name,
|
||||
llvm::Optional<StringRef> importName,
|
||||
llvm::Optional<StringRef> importModule,
|
||||
uint32_t flags, InputFile *file,
|
||||
const WasmSignature *signature,
|
||||
bool isCalledDirectly);
|
||||
Symbol *addUndefinedData(StringRef name, uint32_t flags, InputFile *file);
|
||||
Symbol *addUndefinedGlobal(StringRef name, StringRef importName,
|
||||
StringRef importModule, uint32_t flags,
|
||||
InputFile *file, const WasmGlobalType *type);
|
||||
Symbol *addUndefinedGlobal(StringRef name,
|
||||
llvm::Optional<StringRef> importName,
|
||||
llvm::Optional<StringRef> importModule,
|
||||
uint32_t flags, InputFile *file,
|
||||
const WasmGlobalType *type);
|
||||
|
||||
void addLazy(ArchiveFile *f, const llvm::object::Archive::Symbol *sym);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "Config.h"
|
||||
#include "lld/Common/LLVM.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Object/Wasm.h"
|
||||
|
||||
@@ -203,20 +204,21 @@ public:
|
||||
|
||||
class UndefinedFunction : public FunctionSymbol {
|
||||
public:
|
||||
UndefinedFunction(StringRef name, StringRef importName,
|
||||
StringRef importModule, uint32_t flags,
|
||||
UndefinedFunction(StringRef name, llvm::Optional<StringRef> importName,
|
||||
llvm::Optional<StringRef> importModule, uint32_t flags,
|
||||
InputFile *file = nullptr,
|
||||
const WasmSignature *type = nullptr,
|
||||
bool isCalledDirectly = true)
|
||||
: FunctionSymbol(name, UndefinedFunctionKind, flags, file, type),
|
||||
importName(importName), importModule(importModule), isCalledDirectly(isCalledDirectly) {}
|
||||
importName(importName), importModule(importModule),
|
||||
isCalledDirectly(isCalledDirectly) {}
|
||||
|
||||
static bool classof(const Symbol *s) {
|
||||
return s->kind() == UndefinedFunctionKind;
|
||||
}
|
||||
|
||||
StringRef importName;
|
||||
StringRef importModule;
|
||||
llvm::Optional<StringRef> importName;
|
||||
llvm::Optional<StringRef> importModule;
|
||||
bool isCalledDirectly;
|
||||
};
|
||||
|
||||
@@ -335,8 +337,9 @@ public:
|
||||
|
||||
class UndefinedGlobal : public GlobalSymbol {
|
||||
public:
|
||||
UndefinedGlobal(StringRef name, StringRef importName, StringRef importModule,
|
||||
uint32_t flags, InputFile *file = nullptr,
|
||||
UndefinedGlobal(StringRef name, llvm::Optional<StringRef> importName,
|
||||
llvm::Optional<StringRef> importModule, uint32_t flags,
|
||||
InputFile *file = nullptr,
|
||||
const WasmGlobalType *type = nullptr)
|
||||
: GlobalSymbol(name, UndefinedGlobalKind, flags, file, type),
|
||||
importName(importName), importModule(importModule) {}
|
||||
@@ -345,8 +348,8 @@ public:
|
||||
return s->kind() == UndefinedGlobalKind;
|
||||
}
|
||||
|
||||
StringRef importName;
|
||||
StringRef importModule;
|
||||
llvm::Optional<StringRef> importName;
|
||||
llvm::Optional<StringRef> importModule;
|
||||
};
|
||||
|
||||
// Wasm events are features that suspend the current execution and transfer the
|
||||
@@ -510,7 +513,7 @@ union SymbolUnion {
|
||||
// It is important to keep the size of SymbolUnion small for performance and
|
||||
// memory usage reasons. 96 bytes is a soft limit based on the size of
|
||||
// UndefinedFunction on a 64-bit system.
|
||||
static_assert(sizeof(SymbolUnion) <= 96, "SymbolUnion too large");
|
||||
static_assert(sizeof(SymbolUnion) <= 112, "SymbolUnion too large");
|
||||
|
||||
void printTraceSymbol(Symbol *sym);
|
||||
void printTraceSymbolUndefined(StringRef name, const InputFile* file);
|
||||
|
||||
@@ -156,11 +156,11 @@ void ImportSection::writeBody() {
|
||||
for (const Symbol *sym : importedSymbols) {
|
||||
WasmImport import;
|
||||
if (auto *f = dyn_cast<UndefinedFunction>(sym)) {
|
||||
import.Field = f->importName;
|
||||
import.Module = f->importModule;
|
||||
import.Field = f->importName ? *f->importName : sym->getName();
|
||||
import.Module = f->importModule ? *f->importModule : defaultModule;
|
||||
} else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) {
|
||||
import.Field = g->importName;
|
||||
import.Module = g->importModule;
|
||||
import.Field = g->importName ? *g->importName : sym->getName();
|
||||
import.Module = g->importModule ? *g->importModule : defaultModule;
|
||||
} else {
|
||||
import.Field = sym->getName();
|
||||
import.Module = defaultModule;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define LLVM_BINARYFORMAT_WASM_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
@@ -178,9 +179,12 @@ struct WasmSymbolInfo {
|
||||
StringRef Name;
|
||||
uint8_t Kind;
|
||||
uint32_t Flags;
|
||||
StringRef ImportModule; // For undefined symbols the module of the import
|
||||
StringRef ImportName; // For undefined symbols the name of the import
|
||||
StringRef ExportName; // For symbols to be exported from the final module
|
||||
// For undefined symbols the module of the import
|
||||
Optional<StringRef> ImportModule;
|
||||
// For undefined symbols the name of the import
|
||||
Optional<StringRef> ImportName;
|
||||
// For symbols to be exported from the final module
|
||||
Optional<StringRef> ExportName;
|
||||
union {
|
||||
// For function or global symbols, the index in function or global index
|
||||
// space.
|
||||
|
||||
@@ -31,8 +31,6 @@ class MCSymbolWasm : public MCSymbol {
|
||||
const MCExpr *SymbolSize = nullptr;
|
||||
|
||||
public:
|
||||
// Use a module name of "env" for now, for compatibility with existing tools.
|
||||
// This is temporary, and may change, as the ABI is not yet stable.
|
||||
MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
|
||||
: MCSymbol(SymbolKindWasm, Name, isTemporary) {}
|
||||
static bool classof(const MCSymbol *S) { return S->isWasm(); }
|
||||
@@ -71,10 +69,15 @@ public:
|
||||
bool isComdat() const { return IsComdat; }
|
||||
void setComdat(bool isComdat) { IsComdat = isComdat; }
|
||||
|
||||
bool hasImportModule() const { return ImportModule.hasValue(); }
|
||||
const StringRef getImportModule() const {
|
||||
if (ImportModule.hasValue()) {
|
||||
return ImportModule.getValue();
|
||||
}
|
||||
// Use a default module name of "env" for now, for compatibility with
|
||||
// existing tools.
|
||||
// TODO(sbc): Find a way to specify a default value in the object format
|
||||
// without picking a hardcoded value like this.
|
||||
return "env";
|
||||
}
|
||||
void setImportModule(StringRef Name) {
|
||||
|
||||
@@ -508,13 +508,16 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
|
||||
Function.SymbolName = Info.Name;
|
||||
} else {
|
||||
wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
|
||||
Info.Name = readString(Ctx);
|
||||
else
|
||||
Info.ImportName = Import.Field;
|
||||
} else {
|
||||
Info.Name = Import.Field;
|
||||
}
|
||||
Signature = &Signatures[Import.SigIndex];
|
||||
Info.ImportName = Import.Field;
|
||||
Info.ImportModule = Import.Module;
|
||||
if (!Import.Module.empty()) {
|
||||
Info.ImportModule = Import.Module;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -537,13 +540,17 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
|
||||
Global.SymbolName = Info.Name;
|
||||
} else {
|
||||
wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
|
||||
Info.Name = readString(Ctx);
|
||||
else
|
||||
Info.ImportName = Import.Field;
|
||||
} else {
|
||||
Info.Name = Import.Field;
|
||||
}
|
||||
GlobalType = &Import.Global;
|
||||
Info.ImportName = Import.Field;
|
||||
Info.ImportModule = Import.Module;
|
||||
if (!Import.Module.empty()) {
|
||||
Info.ImportModule = Import.Module;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -597,14 +604,17 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
|
||||
|
||||
} else {
|
||||
wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
|
||||
Info.Name = readString(Ctx);
|
||||
else
|
||||
Info.ImportName = Import.Field;
|
||||
} else {
|
||||
Info.Name = Import.Field;
|
||||
}
|
||||
EventType = &Import.Event;
|
||||
Signature = &Signatures[EventType->SigIndex];
|
||||
Info.ImportName = Import.Field;
|
||||
Info.ImportModule = Import.Module;
|
||||
if (!Import.Module.empty()) {
|
||||
Info.ImportModule = Import.Module;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -185,8 +185,6 @@
|
||||
; CHECK-NEXT: Flags [ (0x10)
|
||||
; CHECK-NEXT: UNDEFINED (0x10)
|
||||
; CHECK-NEXT: ]
|
||||
; CHECK-NEXT: ImportName:
|
||||
; CHECK-NEXT: ImportModule:
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Symbol {
|
||||
; CHECK-NEXT: Name: ptr2
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
# CHECK-NEXT: Flags [ (0x10)
|
||||
# CHECK-NEXT: UNDEFINED (0x10)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: ImportName: puts
|
||||
# CHECK-NEXT: ImportModule: env
|
||||
# CHECK-NEXT: ElementIndex: 0x0
|
||||
# CHECK-NEXT: }
|
||||
@@ -44,7 +43,6 @@
|
||||
# CHECK-NEXT: Flags [ (0x10)
|
||||
# CHECK-NEXT: UNDEFINED (0x10)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: ImportName: SomeOtherFunction
|
||||
# CHECK-NEXT: ImportModule: env
|
||||
# CHECK-NEXT: ElementIndex: 0x1
|
||||
# CHECK-NEXT: }
|
||||
|
||||
@@ -107,7 +107,6 @@ Sections:
|
||||
# CHECK-NEXT: Flags [ (0x10)
|
||||
# CHECK-NEXT: UNDEFINED (0x10)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: ImportName: foo
|
||||
# CHECK-NEXT: ImportModule: red
|
||||
# CHECK-NEXT: ElementIndex: 0x0
|
||||
# CHECK-NEXT: }
|
||||
|
||||
@@ -227,8 +227,12 @@ void WasmDumper::printSymbol(const SymbolRef &Sym) {
|
||||
W.printFlags("Flags", Symbol.Info.Flags, makeArrayRef(WasmSymbolFlags));
|
||||
|
||||
if (Symbol.Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) {
|
||||
W.printString("ImportName", Symbol.Info.ImportName);
|
||||
W.printString("ImportModule", Symbol.Info.ImportModule);
|
||||
if (Symbol.Info.ImportName) {
|
||||
W.printString("ImportName", *Symbol.Info.ImportName);
|
||||
}
|
||||
if (Symbol.Info.ImportModule) {
|
||||
W.printString("ImportModule", *Symbol.Info.ImportModule);
|
||||
}
|
||||
}
|
||||
if (Symbol.Info.Kind != wasm::WASM_SYMBOL_TYPE_DATA) {
|
||||
W.printHex("ElementIndex", Symbol.Info.ElementIndex);
|
||||
|
||||
Reference in New Issue
Block a user