From f7deab52774c9712b6c21a47f86b8c3d2005b13c Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Thu, 22 Jul 2021 14:12:50 -0700 Subject: [PATCH] Reland: "[WebAssembly] Deduplicate imports of the same module name, field name, and type" When two symbols import the same thing, only one import should be emitted in the Wasm file. Fixes https://bugs.llvm.org/show_bug.cgi?id=50938 Reverted in: 16aac493e59519377071e900d119ba2e7e5b525d. Reviewed By: sbc100 Differential Revision: https://reviews.llvm.org/D105519 --- include/llvm/BinaryFormat/Wasm.h | 10 ++++++ include/llvm/BinaryFormat/WasmTraits.h | 43 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 61544c364a3..c38e6492852 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -429,6 +429,16 @@ inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) { return !(LHS == RHS); } +inline bool operator==(const WasmLimits &LHS, const WasmLimits &RHS) { + return LHS.Flags == RHS.Flags && LHS.Minimum == RHS.Minimum && + (LHS.Flags & WASM_LIMITS_FLAG_HAS_MAX ? LHS.Maximum == RHS.Maximum + : true); +} + +inline bool operator==(const WasmTableType &LHS, const WasmTableType &RHS) { + return LHS.ElemType == RHS.ElemType && LHS.Limits == RHS.Limits; +} + std::string toString(WasmSymbolType type); std::string relocTypetoString(uint32_t type); bool relocTypeHasAddend(uint32_t type); diff --git a/include/llvm/BinaryFormat/WasmTraits.h b/include/llvm/BinaryFormat/WasmTraits.h index e3418249918..930ee690bcc 100644 --- a/include/llvm/BinaryFormat/WasmTraits.h +++ b/include/llvm/BinaryFormat/WasmTraits.h @@ -63,6 +63,49 @@ template <> struct DenseMapInfo { } }; +// Traits for using WasmLimits in a DenseMap +template <> struct DenseMapInfo { + static wasm::WasmLimits getEmptyKey() { + return wasm::WasmLimits{0xff, 0xff, 0xff}; + } + static wasm::WasmLimits getTombstoneKey() { + return wasm::WasmLimits{0xee, 0xee, 0xee}; + } + static unsigned getHashValue(const wasm::WasmLimits &Limits) { + unsigned Hash = hash_value(Limits.Flags); + Hash = hash_combine(Hash, Limits.Minimum); + if (Limits.Flags & llvm::wasm::WASM_LIMITS_FLAG_HAS_MAX) { + Hash = hash_combine(Hash, Limits.Maximum); + } + return Hash; + } + static bool isEqual(const wasm::WasmLimits &LHS, + const wasm::WasmLimits &RHS) { + return LHS == RHS; + } +}; + +// Traits for using WasmTableType in a DenseMap +template <> struct DenseMapInfo { + static wasm::WasmTableType getEmptyKey() { + return wasm::WasmTableType{0, + DenseMapInfo::getEmptyKey()}; + } + static wasm::WasmTableType getTombstoneKey() { + return wasm::WasmTableType{ + 1, DenseMapInfo::getTombstoneKey()}; + } + static unsigned getHashValue(const wasm::WasmTableType &TableType) { + return hash_combine( + TableType.ElemType, + DenseMapInfo::getHashValue(TableType.Limits)); + } + static bool isEqual(const wasm::WasmTableType &LHS, + const wasm::WasmTableType &RHS) { + return LHS == RHS; + } +}; + } // end namespace llvm #endif // LLVM_BINARYFORMAT_WASMTRAITS_H