[WebAssembly] Don't duplicate functions in table output

Previously, we were ensuring that the "output index" for
InputFunctions was unique across all symbols that referenced
a function body, but allowing the same function body to have
multiple table indexes.

Now, we use the same mechanism for table indexes as we already
do for output indexes, ensuring that each InputFunction is only
placed in the table once.

This makes the LLD output table denser and smaller, but should
not change the behaviour.

Note that we still need the `Symbol::TableIndex` member, to
store the table index for function Symbols that don't have an
InputFunction, i.e. for address-taken imports.

Patch by Nicholas Wilson!

Differential Revision: https://reviews.llvm.org/D42476

llvm-svn: 323379
This commit is contained in:
Sam Clegg 2018-01-24 21:45:25 +00:00
parent 48bbd63fea
commit 67abf53961
5 changed files with 39 additions and 10 deletions

View File

@ -35,8 +35,8 @@ entry:
; CHECK-NEXT: - ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
; CHECK-NEXT: Initial: 0x00000003
; CHECK-NEXT: Maximum: 0x00000003
; CHECK-NEXT: Initial: 0x00000002
; CHECK-NEXT: Maximum: 0x00000002
; CHECK-NEXT: - Type: MEMORY
; CHECK-NEXT: Memories:
; CHECK-NEXT: - Initial: 0x00000002
@ -88,7 +88,7 @@ entry:
; CHECK-NEXT: - Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 1
; CHECK-NEXT: Functions: [ 1, 1 ]
; CHECK-NEXT: Functions: [ 1 ]
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Functions:
; CHECK-NEXT: - Index: 0
@ -112,7 +112,7 @@ entry:
; CHECK-NEXT: Locals:
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Count: 2
; CHECK-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081081808080002101200041106A24808080800020010B
; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
; CHECK-NEXT: - Index: 6
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 0B
@ -164,8 +164,8 @@ entry:
; RELOC-NEXT: - ElemType: ANYFUNC
; RELOC-NEXT: Limits:
; RELOC-NEXT: Flags: [ HAS_MAX ]
; RELOC-NEXT: Initial: 0x00000003
; RELOC-NEXT: Maximum: 0x00000003
; RELOC-NEXT: Initial: 0x00000002
; RELOC-NEXT: Maximum: 0x00000002
; RELOC-NEXT: - Type: MEMORY
; RELOC-NEXT: Memories:
; RELOC-NEXT: - Initial: 0x00000000
@ -197,7 +197,7 @@ entry:
; RELOC-NEXT: - Offset:
; RELOC-NEXT: Opcode: I32_CONST
; RELOC-NEXT: Value: 1
; RELOC-NEXT: Functions: [ 1, 1 ]
; RELOC-NEXT: Functions: [ 1 ]
; RELOC-NEXT: - Type: CODE
; RELOC-NEXT: Relocations:
; RELOC-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
@ -261,7 +261,7 @@ entry:
; RELOC-NEXT: Locals:
; RELOC-NEXT: - Type: I32
; RELOC-NEXT: Count: 2
; RELOC-NEXT: Body: 23808080800041106B220024808080800020004182808080003602081081808080002101200041106A24808080800020010B
; RELOC-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
; RELOC-NEXT: - Type: CUSTOM
; RELOC-NEXT: Name: linking
; RELOC-NEXT: DataSize: 0

View File

@ -117,3 +117,9 @@ void InputFunction::setOutputIndex(uint32_t Index) {
assert(!hasOutputIndex());
OutputIndex = Index;
}
void InputFunction::setTableIndex(uint32_t Index) {
DEBUG(dbgs() << "InputFunction::setTableIndex " << Index << "\n");
assert(!hasTableIndex());
TableIndex = Index;
}

View File

@ -120,6 +120,9 @@ public:
uint32_t getOutputIndex() const { return OutputIndex.getValue(); }
bool hasOutputIndex() const { return OutputIndex.hasValue(); }
void setOutputIndex(uint32_t Index);
uint32_t getTableIndex() const { return TableIndex.getValue(); }
bool hasTableIndex() const { return TableIndex.hasValue(); }
void setTableIndex(uint32_t Index);
const WasmSignature &Signature;
@ -134,6 +137,7 @@ protected:
const WasmFunction *Function;
llvm::Optional<uint32_t> OutputIndex;
llvm::Optional<uint32_t> TableIndex;
};
class SyntheticFunction : public InputFunction {

View File

@ -67,7 +67,26 @@ void Symbol::setOutputIndex(uint32_t Index) {
OutputIndex = Index;
}
uint32_t Symbol::getTableIndex() const {
if (Function)
return Function->getTableIndex();
return TableIndex.getValue();
}
bool Symbol::hasTableIndex() const {
if (Function)
return Function->hasTableIndex();
return TableIndex.hasValue();
}
void Symbol::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).
if (Function) {
Function->setTableIndex(Index);
return;
}
DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n");
assert(!TableIndex.hasValue());
TableIndex = Index;

View File

@ -77,10 +77,10 @@ public:
// space of the output object.
void setOutputIndex(uint32_t Index);
uint32_t getTableIndex() const { return TableIndex.getValue(); }
uint32_t getTableIndex() const;
// Returns true if a table index has been set for this symbol
bool hasTableIndex() const { return TableIndex.hasValue(); }
bool hasTableIndex() const;
// Set the table index of the symbol
void setTableIndex(uint32_t Index);